'use strict';

require('../chunk-DGUM43GV.js');
var React2 = require('react');
var clsx = require('clsx');
var lucideReact = require('lucide-react');
var JSZip = require('jszip');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var React2__default = /*#__PURE__*/_interopDefault(React2);
var JSZip__default = /*#__PURE__*/_interopDefault(JSZip);

// src/imageCrop/utils/cropUtils.ts
async function loadImageFromFile(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      const dataUrl = e.target?.result;
      const img = new Image();
      img.onload = () => {
        resolve({
          width: img.naturalWidth,
          height: img.naturalHeight,
          naturalWidth: img.naturalWidth,
          naturalHeight: img.naturalHeight,
          image: img,
          file
        });
      };
      img.onerror = () => {
        reject(new Error("\u56FE\u7247\u52A0\u8F7D\u5931\u8D25"));
      };
      img.src = dataUrl;
    };
    reader.onerror = () => {
      reject(new Error("\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25"));
    };
    reader.readAsDataURL(file);
  });
}
async function cropGridCell(imageInfo, cell, cellWidth, cellHeight, options = {}) {
  const {
    format = "image/png",
    quality = 0.92,
    filenamePrefix = "crop"
  } = options;
  if (!imageInfo.image) {
    throw new Error("\u56FE\u7247\u8D44\u6E90\u672A\u52A0\u8F7D");
  }
  const canvas = document.createElement("canvas");
  canvas.width = cellWidth;
  canvas.height = cellHeight;
  const ctx = canvas.getContext("2d");
  if (!ctx) {
    throw new Error("Canvas context \u521B\u5EFA\u5931\u8D25");
  }
  const sourceX = cell.offsetX;
  const sourceY = cell.offsetY;
  const sourceWidth = cellWidth;
  const sourceHeight = cellHeight;
  ctx.drawImage(
    imageInfo.image,
    sourceX,
    sourceY,
    sourceWidth,
    sourceHeight,
    0,
    0,
    cellWidth,
    cellHeight
  );
  const blob = await new Promise((resolve, reject) => {
    canvas.toBlob(
      (blob2) => {
        if (blob2) {
          resolve(blob2);
        } else {
          reject(new Error("\u56FE\u7247\u8F6C\u6362\u5931\u8D25"));
        }
      },
      format,
      quality
    );
  });
  const extension = format.split("/")[1] || "png";
  const filename = filenamePrefix + "_r" + cell.row + "_c" + cell.column + "." + extension;
  return {
    blob,
    dataUrl: canvas.toDataURL(format, quality),
    index: cell.row * 1e3 + cell.column,
    // 简单的索引生成
    row: cell.row,
    column: cell.column,
    cell,
    filename
  };
}
async function cropMultipleCells(imageInfo, cells, cellWidth, cellHeight, options = {}, onProgress) {
  const results = [];
  for (let i = 0; i < cells.length; i++) {
    const cell = cells[i];
    if (!cell || !cell.selected) continue;
    try {
      const result = await cropGridCell(imageInfo, cell, cellWidth, cellHeight, options);
      results.push(result);
      if (onProgress) {
        onProgress(i + 1, cells.length);
      }
    } catch (error) {
      console.error("\u88C1\u526A\u5355\u5143\u683C (" + cell.row + ", " + cell.column + ") \u5931\u8D25:", error);
    }
  }
  return results;
}
async function generateCellPreview(imageInfo, cell, cellWidth, cellHeight, previewSize = 100) {
  const canvas = document.createElement("canvas");
  const scale = Math.min(previewSize / cellWidth, previewSize / cellHeight);
  canvas.width = cellWidth * scale;
  canvas.height = cellHeight * scale;
  const ctx = canvas.getContext("2d");
  if (!ctx || !imageInfo.image) {
    throw new Error("Canvas context \u521B\u5EFA\u5931\u8D25\u6216\u56FE\u7247\u672A\u52A0\u8F7D");
  }
  ctx.drawImage(
    imageInfo.image,
    cell.offsetX,
    cell.offsetY,
    cellWidth,
    cellHeight,
    0,
    0,
    canvas.width,
    canvas.height
  );
  return canvas.toDataURL("image/png");
}
function validateCropArea(imageWidth, imageHeight, offsetX, offsetY, cropWidth, cropHeight) {
  return offsetX >= 0 && offsetY >= 0 && offsetX + cropWidth <= imageWidth && offsetY + cropHeight <= imageHeight;
}
function constrainOffset(imageWidth, imageHeight, offsetX, offsetY, cropWidth, cropHeight) {
  const constrainedX = Math.max(0, Math.min(offsetX, imageWidth - cropWidth));
  const constrainedY = Math.max(0, Math.min(offsetY, imageHeight - cropHeight));
  return {
    offsetX: constrainedX,
    offsetY: constrainedY
  };
}
async function downloadAsZip(results, zipFilename = "cropped_images.zip") {
  if (results.length === 0) {
    throw new Error("\u6CA1\u6709\u53EF\u4E0B\u8F7D\u7684\u56FE\u7247");
  }
  const zip = new JSZip__default.default();
  results.forEach((result, idx) => {
    const filename = result.filename || "crop_" + idx + ".png";
    zip.file(filename, result.blob);
  });
  const zipBlob = await zip.generateAsync({
    type: "blob",
    compression: "DEFLATE",
    compressionOptions: {
      level: 6
    }
  });
  downloadBlob(zipBlob, zipFilename);
}
function downloadBlob(blob, filename) {
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  setTimeout(() => {
    URL.revokeObjectURL(url);
  }, 100);
}
async function downloadMultipleFiles(results, delay = 100) {
  for (let i = 0; i < results.length; i++) {
    const result = results[i];
    if (!result) continue;
    const filename = result.filename || "crop_" + i + ".png";
    downloadBlob(result.blob, filename);
    if (i < results.length - 1) {
      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }
}
function calculateTotalSize(results) {
  return results.reduce((total, result) => total + result.blob.size, 0);
}
function formatFileSize(bytes) {
  if (bytes === 0) return "0 B";
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return (bytes / Math.pow(k, i)).toFixed(2) + " " + sizes[i];
}
var GridControls = ({
  config,
  onChange,
  disabled = false,
  maxRows = 20,
  maxColumns = 20,
  maxCellSize = 2e3,
  minCellSize = 10,
  showReset = true,
  onReset
}) => {
  const handleChange = (field, value) => {
    let constrainedValue = value;
    if (field === "rows") {
      constrainedValue = Math.max(1, Math.min(maxRows, value));
    } else if (field === "columns") {
      constrainedValue = Math.max(1, Math.min(maxColumns, value));
    } else if (field === "cellWidth" || field === "cellHeight") {
      constrainedValue = Math.max(minCellSize, Math.min(maxCellSize, value));
    }
    onChange({
      ...config,
      [field]: constrainedValue
    });
  };
  return /* @__PURE__ */ React2__default.default.createElement("div", { className: "space-y-4 p-4 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700" }, /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React2__default.default.createElement(lucideReact.Grid, { className: "w-5 h-5 text-blue-500" }), /* @__PURE__ */ React2__default.default.createElement("h3", { className: "text-lg font-semibold text-gray-800 dark:text-gray-200" }, "\u7F51\u683C\u8BBE\u7F6E")), showReset && /* @__PURE__ */ React2__default.default.createElement(
    "button",
    {
      onClick: onReset,
      disabled,
      className: "flex items-center gap-1 px-3 py-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
      title: "\u91CD\u7F6E\u4E3A\u9ED8\u8BA4\u503C"
    },
    /* @__PURE__ */ React2__default.default.createElement(lucideReact.RefreshCw, { className: "w-4 h-4" }),
    "\u91CD\u7F6E"
  )), /* @__PURE__ */ React2__default.default.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React2__default.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2__default.default.createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300" }, "\u884C\u6570"), /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React2__default.default.createElement(
    "input",
    {
      type: "number",
      min: 1,
      max: maxRows,
      value: config.rows,
      onChange: (e) => handleChange("rows", parseInt(e.target.value) || 1),
      disabled,
      className: "flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:opacity-50 disabled:cursor-not-allowed"
    }
  ), /* @__PURE__ */ React2__default.default.createElement(
    "input",
    {
      type: "range",
      min: 1,
      max: maxRows,
      value: config.rows,
      onChange: (e) => handleChange("rows", parseInt(e.target.value)),
      disabled,
      className: "flex-1 h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
    }
  ))), /* @__PURE__ */ React2__default.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2__default.default.createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300" }, "\u5217\u6570"), /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React2__default.default.createElement(
    "input",
    {
      type: "number",
      min: 1,
      max: maxColumns,
      value: config.columns,
      onChange: (e) => handleChange("columns", parseInt(e.target.value) || 1),
      disabled,
      className: "flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:opacity-50 disabled:cursor-not-allowed"
    }
  ), /* @__PURE__ */ React2__default.default.createElement(
    "input",
    {
      type: "range",
      min: 1,
      max: maxColumns,
      value: config.columns,
      onChange: (e) => handleChange("columns", parseInt(e.target.value)),
      disabled,
      className: "flex-1 h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
    }
  )))), /* @__PURE__ */ React2__default.default.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React2__default.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2__default.default.createElement("label", { className: "flex items-center gap-2 text-sm font-medium text-gray-700 dark:text-gray-300" }, /* @__PURE__ */ React2__default.default.createElement(lucideReact.Maximize2, { className: "w-4 h-4" }), "\u5355\u5143\u683C\u5BBD\u5EA6 (px)"), /* @__PURE__ */ React2__default.default.createElement(
    "input",
    {
      type: "number",
      min: minCellSize,
      max: maxCellSize,
      value: config.cellWidth,
      onChange: (e) => handleChange("cellWidth", parseInt(e.target.value) || minCellSize),
      disabled,
      className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:opacity-50 disabled:cursor-not-allowed"
    }
  )), /* @__PURE__ */ React2__default.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2__default.default.createElement("label", { className: "flex items-center gap-2 text-sm font-medium text-gray-700 dark:text-gray-300" }, /* @__PURE__ */ React2__default.default.createElement(lucideReact.Maximize2, { className: "w-4 h-4" }), "\u5355\u5143\u683C\u9AD8\u5EA6 (px)"), /* @__PURE__ */ React2__default.default.createElement(
    "input",
    {
      type: "number",
      min: minCellSize,
      max: maxCellSize,
      value: config.cellHeight,
      onChange: (e) => handleChange("cellHeight", parseInt(e.target.value) || minCellSize),
      disabled,
      className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:opacity-50 disabled:cursor-not-allowed"
    }
  ))), /* @__PURE__ */ React2__default.default.createElement("div", { className: "pt-3 border-t border-gray-200 dark:border-gray-700" }, /* @__PURE__ */ React2__default.default.createElement("div", { className: "grid grid-cols-2 gap-4 text-sm text-gray-600 dark:text-gray-400" }, /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex justify-between" }, /* @__PURE__ */ React2__default.default.createElement("span", null, "\u603B\u5355\u5143\u683C\u6570:"), /* @__PURE__ */ React2__default.default.createElement("span", { className: "font-medium text-gray-900 dark:text-gray-100" }, config.rows * config.columns)), /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex justify-between" }, /* @__PURE__ */ React2__default.default.createElement("span", null, "\u603B\u5C3A\u5BF8:"), /* @__PURE__ */ React2__default.default.createElement("span", { className: "font-medium text-gray-900 dark:text-gray-100" }, config.cellWidth * config.columns, " \xD7 ", config.cellHeight * config.rows)))));
};

// src/imageCrop/components/ImageGridCropper.tsx
var ImageGridCropper = ({
  config = {},
  onExportSuccess,
  onExportError,
  className = ""
}) => {
  const {
    defaultRows = 3,
    defaultColumns = 3,
    defaultCellWidth = 256,
    defaultCellHeight = 256,
    maxRows = 20,
    maxColumns = 20,
    maxCellSize = 2e3,
    minCellSize = 10
  } = config;
  const [imageInfo, setImageInfo] = React2.useState(null);
  const [gridConfig, setGridConfig] = React2.useState({
    rows: defaultRows,
    columns: defaultColumns,
    cellWidth: defaultCellWidth,
    cellHeight: defaultCellHeight
  });
  const [gridCells, setGridCells] = React2.useState([]);
  const [isProcessing, setIsProcessing] = React2.useState(false);
  const [progress, setProgress] = React2.useState({ current: 0, total: 0 });
  const [error, setError] = React2.useState(null);
  const canvasRef = React2.useRef(null);
  const fileInputRef = React2.useRef(null);
  const generateGridCells = React2.useCallback(() => {
    const cells = [];
    const { rows, columns, cellWidth, cellHeight } = gridConfig;
    for (let row = 0; row < rows; row++) {
      for (let col = 0; col < columns; col++) {
        const offsetX = col * cellWidth;
        const offsetY = row * cellHeight;
        cells.push({
          id: "cell_" + row + "_" + col,
          row,
          column: col,
          x: offsetX,
          y: offsetY,
          offsetX,
          offsetY,
          width: cellWidth,
          height: cellHeight,
          selected: true
          // 默认全选
        });
      }
    }
    setGridCells(cells);
  }, [gridConfig]);
  const handleFileSelect = async (event) => {
    const file = event.target.files?.[0];
    if (!file) return;
    if (!file.type.startsWith("image/")) {
      setError("\u8BF7\u9009\u62E9\u56FE\u7247\u6587\u4EF6");
      return;
    }
    try {
      setError(null);
      setIsProcessing(true);
      const info = await loadImageFromFile(file);
      setImageInfo(info);
      generateGridCells();
    } catch (err) {
      const errorMsg = err instanceof Error ? err.message : "\u56FE\u7247\u52A0\u8F7D\u5931\u8D25";
      setError(errorMsg);
      onExportError?.(errorMsg);
    } finally {
      setIsProcessing(false);
    }
    event.target.value = "";
  };
  const drawPreview = React2.useCallback(() => {
    if (!imageInfo || !canvasRef.current) return;
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;
    const maxWidth = 800;
    const maxHeight = 600;
    const scale = Math.min(
      maxWidth / imageInfo.width,
      maxHeight / imageInfo.height,
      1
    );
    canvas.width = imageInfo.width * scale;
    canvas.height = imageInfo.height * scale;
    if (!imageInfo.image) return;
    ctx.drawImage(imageInfo.image, 0, 0, canvas.width, canvas.height);
    ctx.strokeStyle = "rgba(59, 130, 246, 0.6)";
    ctx.lineWidth = 2;
    const { cellWidth, cellHeight } = gridConfig;
    gridCells.forEach((cell) => {
      const x = cell.offsetX * scale;
      const y = cell.offsetY * scale;
      const w = cellWidth * scale;
      const h = cellHeight * scale;
      if (cell.selected) {
        ctx.strokeStyle = "rgba(34, 197, 94, 0.8)";
      } else {
        ctx.strokeStyle = "rgba(156, 163, 175, 0.5)";
      }
      ctx.strokeRect(x, y, w, h);
      ctx.fillStyle = cell.selected ? "rgba(34, 197, 94, 0.9)" : "rgba(156, 163, 175, 0.7)";
      ctx.font = "12px sans-serif";
      ctx.fillText("R" + cell.row + "C" + cell.column, x + 5, y + 15);
    });
  }, [imageInfo, gridConfig, gridCells]);
  const toggleCellSelection = (cellId) => {
    setGridCells(
      (prev) => prev.map(
        (cell) => cell.id === cellId ? { ...cell, selected: !cell.selected } : cell
      )
    );
  };
  const toggleSelectAll = () => {
    const allSelected = gridCells.every((cell) => cell.selected);
    setGridCells(
      (prev) => prev.map((cell) => ({ ...cell, selected: !allSelected }))
    );
  };
  const handleExport = async (options = {}) => {
    if (!imageInfo) {
      setError("\u8BF7\u5148\u4E0A\u4F20\u56FE\u7247");
      return;
    }
    const selectedCells = gridCells.filter((cell) => cell.selected);
    if (selectedCells.length === 0) {
      setError("\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u5355\u5143\u683C");
      return;
    }
    try {
      setError(null);
      setIsProcessing(true);
      setProgress({ current: 0, total: selectedCells.length });
      const results = await cropMultipleCells(
        imageInfo,
        selectedCells,
        gridConfig.cellWidth,
        gridConfig.cellHeight,
        options.cropOptions,
        (current, total) => setProgress({ current, total })
      );
      if (results.length === 0) {
        throw new Error("\u6CA1\u6709\u6210\u529F\u88C1\u526A\u7684\u56FE\u7247");
      }
      const zipFilename = options.zipFilename || "cropped_" + Date.now() + ".zip";
      await downloadAsZip(results, zipFilename);
      onExportSuccess?.(results);
    } catch (err) {
      const errorMsg = err instanceof Error ? err.message : "\u5BFC\u51FA\u5931\u8D25";
      setError(errorMsg);
      onExportError?.(errorMsg);
    } finally {
      setIsProcessing(false);
      setProgress({ current: 0, total: 0 });
    }
  };
  const handleReset = () => {
    setGridConfig({
      rows: defaultRows,
      columns: defaultColumns,
      cellWidth: defaultCellWidth,
      cellHeight: defaultCellHeight
    });
  };
  React2.useEffect(() => {
    if (imageInfo) {
      generateGridCells();
    }
  }, [imageInfo, generateGridCells]);
  React2.useEffect(() => {
    drawPreview();
  }, [drawPreview]);
  const selectedCount = gridCells.filter((cell) => cell.selected).length;
  return /* @__PURE__ */ React2__default.default.createElement("div", { className: clsx.clsx("w-full space-y-6", className) }, /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React2__default.default.createElement(lucideReact.Scissors, { className: "w-7 h-7 text-blue-500" }), /* @__PURE__ */ React2__default.default.createElement("div", null, /* @__PURE__ */ React2__default.default.createElement("h2", { className: "text-2xl font-bold text-gray-800 dark:text-gray-200" }, "\u7F51\u683C\u5F0F\u56FE\u7247\u88C1\u526A\u5DE5\u5177"), /* @__PURE__ */ React2__default.default.createElement("p", { className: "text-sm text-gray-600 dark:text-gray-400" }, "\u4E0A\u4F20\u56FE\u7247\uFF0C\u8BBE\u7F6E\u7F51\u683C\uFF0C\u88C1\u526A\u5E76\u5BFC\u51FA")))), error && /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex items-center gap-2 p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg" }, /* @__PURE__ */ React2__default.default.createElement(lucideReact.AlertCircle, { className: "w-5 h-5 text-red-500" }), /* @__PURE__ */ React2__default.default.createElement("p", { className: "text-sm text-red-700 dark:text-red-400" }, error)), /* @__PURE__ */ React2__default.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React2__default.default.createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300" }, "\u4E0A\u4F20\u56FE\u7247"), /* @__PURE__ */ React2__default.default.createElement(
    "div",
    {
      className: "border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg p-8 text-center cursor-pointer hover:border-blue-400 dark:hover:border-blue-500 transition-colors",
      onClick: () => fileInputRef.current?.click()
    },
    /* @__PURE__ */ React2__default.default.createElement(lucideReact.Image, { className: "w-12 h-12 mx-auto mb-4 text-gray-400" }),
    /* @__PURE__ */ React2__default.default.createElement("p", { className: "text-gray-600 dark:text-gray-400 mb-2" }, "\u70B9\u51FB\u9009\u62E9\u56FE\u7247\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u8FD9\u91CC"),
    /* @__PURE__ */ React2__default.default.createElement("p", { className: "text-sm text-gray-500" }, "\u652F\u6301 PNG, JPG, WEBP \u7B49\u683C\u5F0F"),
    imageInfo && imageInfo.file && /* @__PURE__ */ React2__default.default.createElement("p", { className: "mt-4 text-sm text-green-600 dark:text-green-400" }, "\u2713 \u5DF2\u4E0A\u4F20: ", imageInfo.file.name, " (", imageInfo.width, " \xD7 ", imageInfo.height, ")")
  ), /* @__PURE__ */ React2__default.default.createElement(
    "input",
    {
      ref: fileInputRef,
      type: "file",
      accept: "image/*",
      onChange: handleFileSelect,
      className: "hidden"
    }
  )), imageInfo && /* @__PURE__ */ React2__default.default.createElement(
    GridControls,
    {
      config: gridConfig,
      onChange: setGridConfig,
      disabled: isProcessing,
      maxRows,
      maxColumns,
      maxCellSize,
      minCellSize,
      onReset: handleReset
    }
  ), imageInfo && /* @__PURE__ */ React2__default.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React2__default.default.createElement("h3", { className: "text-lg font-semibold text-gray-800 dark:text-gray-200" }, "\u9884\u89C8\u4E0E\u8C03\u6574"), /* @__PURE__ */ React2__default.default.createElement(
    "button",
    {
      onClick: toggleSelectAll,
      className: "px-4 py-2 text-sm text-blue-600 dark:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-md transition-colors"
    },
    gridCells.every((cell) => cell.selected) ? "\u53D6\u6D88\u5168\u9009" : "\u5168\u9009"
  )), /* @__PURE__ */ React2__default.default.createElement("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden bg-gray-50 dark:bg-gray-900 p-4" }, /* @__PURE__ */ React2__default.default.createElement(
    "canvas",
    {
      ref: canvasRef,
      className: "max-w-full mx-auto border border-gray-300 dark:border-gray-600"
    }
  )), /* @__PURE__ */ React2__default.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2__default.default.createElement("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, "\u5355\u5143\u683C\u5217\u8868 (", selectedCount, "/", gridCells.length, " \u5DF2\u9009\u4E2D)"), /* @__PURE__ */ React2__default.default.createElement("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2 max-h-64 overflow-y-auto" }, gridCells.map((cell) => /* @__PURE__ */ React2__default.default.createElement(
    "div",
    {
      key: cell.id,
      className: clsx.clsx("p-3 rounded border", cell.selected ? "border-green-500 bg-green-50 dark:bg-green-900/20" : "border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800", "cursor-pointer transition-colors"),
      onClick: () => toggleCellSelection(cell.id)
    },
    /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React2__default.default.createElement("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, "R", cell.row, " C", cell.column), cell.selected ? /* @__PURE__ */ React2__default.default.createElement(lucideReact.CheckCircle2, { className: "w-4 h-4 text-green-500" }) : /* @__PURE__ */ React2__default.default.createElement(lucideReact.XCircle, { className: "w-4 h-4 text-gray-400" })),
    /* @__PURE__ */ React2__default.default.createElement("div", { className: "text-xs text-gray-500 space-y-1" }, /* @__PURE__ */ React2__default.default.createElement("p", null, "X: ", cell.offsetX, "px"), /* @__PURE__ */ React2__default.default.createElement("p", null, "Y: ", cell.offsetY, "px"))
  ))))), imageInfo && /* @__PURE__ */ React2__default.default.createElement("div", { className: "flex items-center justify-between p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800" }, /* @__PURE__ */ React2__default.default.createElement("div", { className: "text-sm text-gray-700 dark:text-gray-300" }, /* @__PURE__ */ React2__default.default.createElement("p", { className: "font-medium" }, "\u51C6\u5907\u5BFC\u51FA ", selectedCount, " \u4E2A\u88C1\u526A\u56FE\u7247"), isProcessing && /* @__PURE__ */ React2__default.default.createElement("p", { className: "text-xs text-gray-600 dark:text-gray-400 mt-1" }, "\u8FDB\u5EA6: ", progress.current, "/", progress.total)), /* @__PURE__ */ React2__default.default.createElement(
    "button",
    {
      onClick: () => handleExport(),
      disabled: isProcessing || selectedCount === 0,
      className: "flex items-center gap-2 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
    },
    isProcessing ? /* @__PURE__ */ React2__default.default.createElement(React2__default.default.Fragment, null, /* @__PURE__ */ React2__default.default.createElement(lucideReact.Loader2, { className: "w-5 h-5 animate-spin" }), "\u5904\u7406\u4E2D...") : /* @__PURE__ */ React2__default.default.createElement(React2__default.default.Fragment, null, /* @__PURE__ */ React2__default.default.createElement(lucideReact.Download, { className: "w-5 h-5" }), "\u5BFC\u51FA\u4E3A ZIP")
  )));
};

exports.GridControls = GridControls;
exports.ImageGridCropper = ImageGridCropper;
exports.calculateTotalSize = calculateTotalSize;
exports.constrainOffset = constrainOffset;
exports.cropGridCell = cropGridCell;
exports.cropMultipleCells = cropMultipleCells;
exports.downloadAsZip = downloadAsZip;
exports.downloadBlob = downloadBlob;
exports.downloadMultipleFiles = downloadMultipleFiles;
exports.formatFileSize = formatFileSize;
exports.generateCellPreview = generateCellPreview;
exports.loadImageFromFile = loadImageFromFile;
exports.validateCropArea = validateCropArea;
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map