From cccff5befb4a587089dec1fe7fa6a331698fd4c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Tue, 8 Apr 2025 16:01:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=85=A5CSV=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cunkebao/api/wechat-accounts.ts | 55 +- Cunkebao/app/contact-import/page.tsx | 331 + Cunkebao/app/devices/page.tsx | 22 +- Cunkebao/app/excel-import-demo/page.tsx | 105 + .../app/plans/new/steps/BasicSettings.tsx | 14 +- Cunkebao/components/ExcelImporter.tsx | 341 + Cunkebao/components/ui/code.tsx | 20 + Cunkebao/types/xlsx.d.ts | 6 + Server/application/plan/model/TrafficPool.php | 138 - .../application/plan/model/TrafficSource.php | 151 - node_modules/.package-lock.json | 47 + node_modules/react-dom/LICENSE | 21 + node_modules/react-dom/README.md | 60 + .../cjs/react-dom-client.development.js | 24990 +++++++++++++++ .../cjs/react-dom-client.production.js | 15393 ++++++++++ .../cjs/react-dom-profiling.development.js | 25377 ++++++++++++++++ .../cjs/react-dom-profiling.profiling.js | 16218 ++++++++++ ...t-dom-server-legacy.browser.development.js | 9035 ++++++ ...ct-dom-server-legacy.browser.production.js | 5892 ++++ ...eact-dom-server-legacy.node.development.js | 9035 ++++++ ...react-dom-server-legacy.node.production.js | 5972 ++++ .../react-dom-server.browser.development.js | 9424 ++++++ .../react-dom-server.browser.production.js | 6384 ++++ .../cjs/react-dom-server.bun.development.js | 8739 ++++++ .../cjs/react-dom-server.bun.production.js | 5967 ++++ .../cjs/react-dom-server.edge.development.js | 9443 ++++++ .../cjs/react-dom-server.edge.production.js | 6477 ++++ .../cjs/react-dom-server.node.development.js | 9317 ++++++ .../cjs/react-dom-server.node.production.js | 6372 ++++ .../cjs/react-dom-test-utils.development.js | 24 + .../cjs/react-dom-test-utils.production.js | 21 + .../react-dom/cjs/react-dom.development.js | 424 + .../react-dom/cjs/react-dom.production.js | 210 + .../cjs/react-dom.react-server.development.js | 340 + .../cjs/react-dom.react-server.production.js | 152 + node_modules/react-dom/client.js | 38 + node_modules/react-dom/client.react-server.js | 5 + node_modules/react-dom/index.js | 38 + node_modules/react-dom/package.json | 117 + node_modules/react-dom/profiling.js | 38 + .../react-dom/profiling.react-server.js | 5 + .../react-dom/react-dom.react-server.js | 7 + node_modules/react-dom/server.browser.js | 18 + node_modules/react-dom/server.bun.js | 19 + node_modules/react-dom/server.edge.js | 19 + node_modules/react-dom/server.js | 3 + node_modules/react-dom/server.node.js | 18 + node_modules/react-dom/server.react-server.js | 5 + node_modules/react-dom/static.browser.js | 12 + node_modules/react-dom/static.edge.js | 12 + node_modules/react-dom/static.js | 3 + node_modules/react-dom/static.node.js | 12 + node_modules/react-dom/static.react-server.js | 5 + node_modules/react-dom/test-utils.js | 7 + node_modules/react/LICENSE | 21 + node_modules/react/README.md | 37 + .../cjs/react-compiler-runtime.development.js | 24 + .../cjs/react-compiler-runtime.production.js | 16 + .../cjs/react-compiler-runtime.profiling.js | 16 + .../cjs/react-jsx-dev-runtime.development.js | 349 + .../cjs/react-jsx-dev-runtime.production.js | 14 + .../cjs/react-jsx-dev-runtime.profiling.js | 14 + ...sx-dev-runtime.react-server.development.js | 385 + ...jsx-dev-runtime.react-server.production.js | 40 + .../cjs/react-jsx-runtime.development.js | 358 + .../react/cjs/react-jsx-runtime.production.js | 34 + .../react/cjs/react-jsx-runtime.profiling.js | 34 + ...ct-jsx-runtime.react-server.development.js | 385 + ...act-jsx-runtime.react-server.production.js | 40 + node_modules/react/cjs/react.development.js | 1242 + node_modules/react/cjs/react.production.js | 546 + .../cjs/react.react-server.development.js | 815 + .../cjs/react.react-server.production.js | 429 + node_modules/react/compiler-runtime.js | 14 + node_modules/react/index.js | 7 + node_modules/react/jsx-dev-runtime.js | 7 + .../react/jsx-dev-runtime.react-server.js | 7 + node_modules/react/jsx-runtime.js | 7 + .../react/jsx-runtime.react-server.js | 7 + node_modules/react/package.json | 51 + node_modules/react/react.react-server.js | 7 + node_modules/scheduler/LICENSE | 21 + node_modules/scheduler/README.md | 9 + .../scheduler-unstable_mock.development.js | 414 + .../cjs/scheduler-unstable_mock.production.js | 406 + ...cheduler-unstable_post_task.development.js | 150 + ...scheduler-unstable_post_task.production.js | 140 + .../scheduler/cjs/scheduler.development.js | 364 + .../cjs/scheduler.native.development.js | 350 + .../cjs/scheduler.native.production.js | 330 + .../scheduler/cjs/scheduler.production.js | 340 + node_modules/scheduler/index.js | 7 + node_modules/scheduler/index.native.js | 7 + node_modules/scheduler/package.json | 27 + node_modules/scheduler/unstable_mock.js | 7 + node_modules/scheduler/unstable_post_task.js | 7 + node_modules/sonner/LICENSE.md | 21 + node_modules/sonner/README.md | 33 + node_modules/sonner/dist/index.d.mts | 151 + node_modules/sonner/dist/index.d.ts | 151 + node_modules/sonner/dist/index.js | 1172 + node_modules/sonner/dist/index.mjs | 1163 + node_modules/sonner/dist/styles.css | 728 + node_modules/sonner/package.json | 66 + package-lock.json | 50 +- package.json | 5 + 106 files changed, 187604 insertions(+), 319 deletions(-) create mode 100644 Cunkebao/app/contact-import/page.tsx create mode 100644 Cunkebao/app/excel-import-demo/page.tsx create mode 100644 Cunkebao/components/ExcelImporter.tsx create mode 100644 Cunkebao/components/ui/code.tsx create mode 100644 Cunkebao/types/xlsx.d.ts delete mode 100644 Server/application/plan/model/TrafficPool.php delete mode 100644 Server/application/plan/model/TrafficSource.php create mode 100644 node_modules/.package-lock.json create mode 100644 node_modules/react-dom/LICENSE create mode 100644 node_modules/react-dom/README.md create mode 100644 node_modules/react-dom/cjs/react-dom-client.development.js create mode 100644 node_modules/react-dom/cjs/react-dom-client.production.js create mode 100644 node_modules/react-dom/cjs/react-dom-profiling.development.js create mode 100644 node_modules/react-dom/cjs/react-dom-profiling.profiling.js create mode 100644 node_modules/react-dom/cjs/react-dom-server-legacy.browser.development.js create mode 100644 node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js create mode 100644 node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js create mode 100644 node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js create mode 100644 node_modules/react-dom/cjs/react-dom-server.browser.development.js create mode 100644 node_modules/react-dom/cjs/react-dom-server.browser.production.js create mode 100644 node_modules/react-dom/cjs/react-dom-server.bun.development.js create mode 100644 node_modules/react-dom/cjs/react-dom-server.bun.production.js create mode 100644 node_modules/react-dom/cjs/react-dom-server.edge.development.js create mode 100644 node_modules/react-dom/cjs/react-dom-server.edge.production.js create mode 100644 node_modules/react-dom/cjs/react-dom-server.node.development.js create mode 100644 node_modules/react-dom/cjs/react-dom-server.node.production.js create mode 100644 node_modules/react-dom/cjs/react-dom-test-utils.development.js create mode 100644 node_modules/react-dom/cjs/react-dom-test-utils.production.js create mode 100644 node_modules/react-dom/cjs/react-dom.development.js create mode 100644 node_modules/react-dom/cjs/react-dom.production.js create mode 100644 node_modules/react-dom/cjs/react-dom.react-server.development.js create mode 100644 node_modules/react-dom/cjs/react-dom.react-server.production.js create mode 100644 node_modules/react-dom/client.js create mode 100644 node_modules/react-dom/client.react-server.js create mode 100644 node_modules/react-dom/index.js create mode 100644 node_modules/react-dom/package.json create mode 100644 node_modules/react-dom/profiling.js create mode 100644 node_modules/react-dom/profiling.react-server.js create mode 100644 node_modules/react-dom/react-dom.react-server.js create mode 100644 node_modules/react-dom/server.browser.js create mode 100644 node_modules/react-dom/server.bun.js create mode 100644 node_modules/react-dom/server.edge.js create mode 100644 node_modules/react-dom/server.js create mode 100644 node_modules/react-dom/server.node.js create mode 100644 node_modules/react-dom/server.react-server.js create mode 100644 node_modules/react-dom/static.browser.js create mode 100644 node_modules/react-dom/static.edge.js create mode 100644 node_modules/react-dom/static.js create mode 100644 node_modules/react-dom/static.node.js create mode 100644 node_modules/react-dom/static.react-server.js create mode 100644 node_modules/react-dom/test-utils.js create mode 100644 node_modules/react/LICENSE create mode 100644 node_modules/react/README.md create mode 100644 node_modules/react/cjs/react-compiler-runtime.development.js create mode 100644 node_modules/react/cjs/react-compiler-runtime.production.js create mode 100644 node_modules/react/cjs/react-compiler-runtime.profiling.js create mode 100644 node_modules/react/cjs/react-jsx-dev-runtime.development.js create mode 100644 node_modules/react/cjs/react-jsx-dev-runtime.production.js create mode 100644 node_modules/react/cjs/react-jsx-dev-runtime.profiling.js create mode 100644 node_modules/react/cjs/react-jsx-dev-runtime.react-server.development.js create mode 100644 node_modules/react/cjs/react-jsx-dev-runtime.react-server.production.js create mode 100644 node_modules/react/cjs/react-jsx-runtime.development.js create mode 100644 node_modules/react/cjs/react-jsx-runtime.production.js create mode 100644 node_modules/react/cjs/react-jsx-runtime.profiling.js create mode 100644 node_modules/react/cjs/react-jsx-runtime.react-server.development.js create mode 100644 node_modules/react/cjs/react-jsx-runtime.react-server.production.js create mode 100644 node_modules/react/cjs/react.development.js create mode 100644 node_modules/react/cjs/react.production.js create mode 100644 node_modules/react/cjs/react.react-server.development.js create mode 100644 node_modules/react/cjs/react.react-server.production.js create mode 100644 node_modules/react/compiler-runtime.js create mode 100644 node_modules/react/index.js create mode 100644 node_modules/react/jsx-dev-runtime.js create mode 100644 node_modules/react/jsx-dev-runtime.react-server.js create mode 100644 node_modules/react/jsx-runtime.js create mode 100644 node_modules/react/jsx-runtime.react-server.js create mode 100644 node_modules/react/package.json create mode 100644 node_modules/react/react.react-server.js create mode 100644 node_modules/scheduler/LICENSE create mode 100644 node_modules/scheduler/README.md create mode 100644 node_modules/scheduler/cjs/scheduler-unstable_mock.development.js create mode 100644 node_modules/scheduler/cjs/scheduler-unstable_mock.production.js create mode 100644 node_modules/scheduler/cjs/scheduler-unstable_post_task.development.js create mode 100644 node_modules/scheduler/cjs/scheduler-unstable_post_task.production.js create mode 100644 node_modules/scheduler/cjs/scheduler.development.js create mode 100644 node_modules/scheduler/cjs/scheduler.native.development.js create mode 100644 node_modules/scheduler/cjs/scheduler.native.production.js create mode 100644 node_modules/scheduler/cjs/scheduler.production.js create mode 100644 node_modules/scheduler/index.js create mode 100644 node_modules/scheduler/index.native.js create mode 100644 node_modules/scheduler/package.json create mode 100644 node_modules/scheduler/unstable_mock.js create mode 100644 node_modules/scheduler/unstable_post_task.js create mode 100644 node_modules/sonner/LICENSE.md create mode 100644 node_modules/sonner/README.md create mode 100644 node_modules/sonner/dist/index.d.mts create mode 100644 node_modules/sonner/dist/index.d.ts create mode 100644 node_modules/sonner/dist/index.js create mode 100644 node_modules/sonner/dist/index.mjs create mode 100644 node_modules/sonner/dist/styles.css create mode 100644 node_modules/sonner/package.json create mode 100644 package.json diff --git a/Cunkebao/api/wechat-accounts.ts b/Cunkebao/api/wechat-accounts.ts index 8190dd34..0f761498 100755 --- a/Cunkebao/api/wechat-accounts.ts +++ b/Cunkebao/api/wechat-accounts.ts @@ -65,9 +65,34 @@ export const transformWechatAccount = (serverAccount: any): import("@/types/wech let deviceName = ''; if (serverAccount.deviceInfo) { + // 尝试解析设备信息字符串 const deviceInfo = serverAccount.deviceInfo.split(' '); - deviceId = deviceInfo[0] || ''; - deviceName = deviceInfo[1] ? deviceInfo[1].replace(/[()]/g, '') : ''; + if (deviceInfo.length > 0) { + // 提取数字部分作为设备ID,确保是整数 + const possibleId = deviceInfo[0].trim(); + // 验证是否为数字 + deviceId = /^\d+$/.test(possibleId) ? possibleId : ''; + + // 提取设备名称 + if (deviceInfo.length > 1) { + deviceName = deviceInfo[1] ? deviceInfo[1].replace(/[()]/g, '').trim() : ''; + } + } + } + + // 如果从deviceInfo无法获取有效的设备ID,使用imei作为备选 + if (!deviceId && serverAccount.imei) { + deviceId = serverAccount.imei; + } + + // 如果仍然没有设备ID,使用微信账号的ID作为最后的备选 + if (!deviceId && serverAccount.id) { + deviceId = serverAccount.id.toString(); + } + + // 如果没有设备名称,使用备用名称 + if (!deviceName) { + deviceName = serverAccount.deviceMemo || '未命名设备'; } // 假设每天最多可添加20个好友 @@ -102,14 +127,34 @@ export const transformWechatAccountDetail = (detailResponse: WechatAccountDetail const { basicInfo, statistics, accountInfo, restrictions, friends } = detailResponse.data; - // 设备信息处理 + // 设备信息处理 - 改进处理方式 let deviceId = ''; let deviceName = ''; if (basicInfo.deviceInfo) { + // 尝试解析设备信息字符串 const deviceInfoParts = basicInfo.deviceInfo.split(' '); - deviceId = deviceInfoParts[0] || ''; - deviceName = deviceInfoParts[1] ? deviceInfoParts[1].replace(/[()]/g, '') : ''; + if (deviceInfoParts.length > 0) { + // 提取数字部分作为设备ID,确保是整数 + const possibleId = deviceInfoParts[0].trim(); + // 验证是否为数字 + deviceId = /^\d+$/.test(possibleId) ? possibleId : ''; + + // 提取设备名称 + if (deviceInfoParts.length > 1) { + deviceName = deviceInfoParts[1].replace(/[()]/g, '').trim(); + } + } + } + + // 如果从deviceInfo无法获取有效的设备ID,直接使用微信账号ID作为备选 + if (!deviceId && basicInfo.id) { + deviceId = basicInfo.id.toString(); + } + + // 如果没有设备名称,使用备用名称 + if (!deviceName) { + deviceName = '未命名设备'; } // 账号年龄计算 diff --git a/Cunkebao/app/contact-import/page.tsx b/Cunkebao/app/contact-import/page.tsx new file mode 100644 index 00000000..335dfed2 --- /dev/null +++ b/Cunkebao/app/contact-import/page.tsx @@ -0,0 +1,331 @@ +"use client"; + +import React, { useState } from "react"; +import * as XLSX from "xlsx"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Alert, AlertDescription } from "@/components/ui/alert"; +import { AlertCircle } from "lucide-react"; + +interface ContactData { + mobile: number; + from: string; + alias: string; +} + +export default function ContactImportPage() { + const [parsedData, setParsedData] = useState([]); + const [error, setError] = useState(null); + const [fileName, setFileName] = useState(""); + const [isImportSuccessful, setIsImportSuccessful] = useState(false); + const [isProcessing, setIsProcessing] = useState(false); + const [detectedColumns, setDetectedColumns] = useState<{ + mobile?: string; + from?: string; + alias?: string; + }>({}); + + const handleFileChange = (e: React.ChangeEvent) => { + const files = e.target.files; + if (!files || files.length === 0) { + return; + } + + // 重置状态 + setError(null); + setIsImportSuccessful(false); + setParsedData([]); + setDetectedColumns({}); + setIsProcessing(true); + + const file = files[0]; + setFileName(file.name); + + const reader = new FileReader(); + reader.onload = (event) => { + try { + const data = event.target?.result; + if (!data) { + setError("文件内容为空,请检查文件是否有效"); + setIsProcessing(false); + return; + } + + let workbook; + try { + workbook = XLSX.read(data, { type: "binary" }); + } catch (parseErr) { + console.error("解析Excel内容失败:", parseErr); + setError("无法解析文件内容,请确保上传的是有效的Excel文件(.xlsx或.xls格式)"); + setIsProcessing(false); + return; + } + + if (!workbook.SheetNames || workbook.SheetNames.length === 0) { + setError("Excel文件中没有找到工作表"); + setIsProcessing(false); + return; + } + + const sheetName = workbook.SheetNames[0]; + const worksheet = workbook.Sheets[sheetName]; + + if (!worksheet) { + setError(`无法读取工作表 "${sheetName}",请检查文件是否损坏`); + setIsProcessing(false); + return; + } + + // 转换为JSON + const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: "A" }); + + // 检查是否有数据 + if (!jsonData || jsonData.length === 0) { + setError("Excel 文件中没有数据"); + setIsProcessing(false); + return; + } + + // 查找栏位对应的列 + let mobileColumn: string | null = null; + let fromColumn: string | null = null; + let aliasColumn: string | null = null; + + // 遍历第一行查找栏位 + const firstRow = jsonData[0] as Record; + if (!firstRow) { + setError("Excel 文件的第一行为空,无法识别栏位"); + setIsProcessing(false); + return; + } + + for (const key in firstRow) { + if (!firstRow[key]) continue; // 跳过空值 + + const value = String(firstRow[key]).toLowerCase(); + + // 扩展匹配列表,提高识别成功率 + if (value.includes("手机") || value.includes("电话") || value.includes("mobile") || + value.includes("phone") || value.includes("tel") || value.includes("cell")) { + mobileColumn = key; + } else if (value.includes("来源") || value.includes("source") || value.includes("from") || + value.includes("channel") || value.includes("渠道")) { + fromColumn = key; + } else if (value.includes("微信") || value.includes("alias") || value.includes("wechat") || + value.includes("wx") || value.includes("id") || value.includes("账号")) { + aliasColumn = key; + } + } + + // 保存检测到的列名 + if (mobileColumn && firstRow[mobileColumn]) { + setDetectedColumns(prev => ({ ...prev, mobile: String(firstRow[mobileColumn]) })); + } + if (fromColumn && firstRow[fromColumn]) { + setDetectedColumns(prev => ({ ...prev, from: String(firstRow[fromColumn]) })); + } + if (aliasColumn && firstRow[aliasColumn]) { + setDetectedColumns(prev => ({ ...prev, alias: String(firstRow[aliasColumn]) })); + } + + if (!mobileColumn) { + setError("未找到手机号码栏位,请确保Excel中包含手机、电话、mobile或phone等栏位名称"); + setIsProcessing(false); + return; + } + + // 解析数据,跳过首行 + const importedData: ContactData[] = []; + for (let i = 1; i < jsonData.length; i++) { + const row = jsonData[i] as Record; + + // 检查行是否存在且有手机号列 + if (!row || row[mobileColumn] === undefined || row[mobileColumn] === null) { + continue; + } + + // 安全地转换并清理手机号 + const mobileStr = row[mobileColumn] !== undefined && row[mobileColumn] !== null + ? String(row[mobileColumn]).trim() + : ""; + + // 过滤非数字字符,确保手机号是纯数字 + const mobile = mobileStr.replace(/\D/g, ""); + + // 手机号为空的跳过 + if (!mobile) continue; + + // 安全地获取来源和别名 + const from = fromColumn && row[fromColumn] !== undefined && row[fromColumn] !== null + ? String(row[fromColumn]).trim() + : ""; + + const alias = aliasColumn && row[aliasColumn] !== undefined && row[aliasColumn] !== null + ? String(row[aliasColumn]).trim() + : ""; + + importedData.push({ + mobile: Number(mobile), + from, + alias + }); + } + + if (importedData.length === 0) { + setError("未找到有效数据,请确保Excel中至少有一行有效的手机号码"); + setIsProcessing(false); + return; + } + + setParsedData(importedData); + setIsProcessing(false); + } catch (err) { + console.error("解析Excel文件出错:", err); + setError("解析Excel文件时出错,请确保文件格式正确"); + setIsProcessing(false); + } + }; + + reader.onerror = () => { + setError("读取文件时出错,请重试"); + setIsProcessing(false); + }; + + reader.readAsBinaryString(file); + }; + + const handleImport = () => { + if (parsedData.length > 0) { + // 打印解析数据 + console.log("导入的联系人数据:"); + console.log(JSON.stringify(parsedData, null, 2)); + + // 在界面上显示成功消息 + setIsImportSuccessful(true); + } + }; + + const handleReset = () => { + setParsedData([]); + setFileName(""); + setError(null); + setIsImportSuccessful(false); + const fileInput = document.getElementById("file-input") as HTMLInputElement; + if (fileInput) { + fileInput.value = ""; + } + }; + + return ( +
+ +

联系人导入

+ +
+
+ + + {fileName && ( +

+ 当前文件: {fileName} +

+ )} +
+ 请确保Excel文件包含以下列: 手机号码(必需)、来源(可选)、微信号(可选) +
+
+ + {isProcessing && ( +
+
+

正在处理Excel文件...

+
+ )} + + {error && ( + + + {error} + + )} + + {isImportSuccessful && ( + + + 已成功导入 {parsedData.length} 条联系人数据!数据已打印到控制台。 + + + )} + + {parsedData.length > 0 && !isImportSuccessful && ( +
+

+ 已解析 {parsedData.length} 条有效数据,点击下方按钮确认导入。 +

+ + {Object.keys(detectedColumns).length > 0 && ( +
+

检测到的列名:

+
    + {detectedColumns.mobile &&
  • 手机号: {detectedColumns.mobile}
  • } + {detectedColumns.from &&
  • 来源: {detectedColumns.from}
  • } + {detectedColumns.alias &&
  • 微信号: {detectedColumns.alias}
  • } +
+
+ )} + +
+
+

数据示例:

+
+
{JSON.stringify(parsedData.slice(0, 3), null, 2)}
+ {parsedData.length > 3 &&

...共 {parsedData.length} 条

} +
+
+
+

数据结构:

+
+
{`[
+  {
+    "mobile": 13800000000,
+    "from": "小红书",
+    "alias": "xxxxxx"
+  },
+  ...
+]`}
+
+
+
+
+ )} + +
+ + +
+
+
+
+ ); +} \ No newline at end of file diff --git a/Cunkebao/app/devices/page.tsx b/Cunkebao/app/devices/page.tsx index 39a5e808..1ce4af73 100755 --- a/Cunkebao/app/devices/page.tsx +++ b/Cunkebao/app/devices/page.tsx @@ -464,11 +464,11 @@ export default function DevicesPage() { // 删除后刷新列表 if (successCount > 0) { - toast({ - title: "批量删除成功", + toast({ + title: "批量删除成功", description: `已删除 ${successCount} 个设备`, - }) - setSelectedDevices([]) + }) + setSelectedDevices([]) handleRefresh() } else { toast({ @@ -628,7 +628,7 @@ export default function DevicesPage() { {isLoading &&
加载中...
} {!hasMore && devices.length > 0 &&
没有更多设备了
} {!hasMore && devices.length === 0 &&
暂无设备
} - + @@ -731,7 +731,7 @@ export default function DevicesPage() {

为设备添加一个便于识别的名称

- +
- + -
- + + diff --git a/Cunkebao/app/excel-import-demo/page.tsx b/Cunkebao/app/excel-import-demo/page.tsx new file mode 100644 index 00000000..99642d16 --- /dev/null +++ b/Cunkebao/app/excel-import-demo/page.tsx @@ -0,0 +1,105 @@ +"use client"; + +import React, { useState } from "react"; +import { ExcelImporter } from "@/components/ExcelImporter"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { Code } from "@/components/ui/code"; +import { Separator } from "@/components/ui/separator"; + +interface ImportedData { + mobile: number; + from: string; + alias: string; +} + +export default function ExcelImportDemo() { + const [importedData, setImportedData] = useState([]); + const [showData, setShowData] = useState(false); + + const handleImport = (data: ImportedData[]) => { + setImportedData(data); + setShowData(true); + console.log("导入的数据:", data); + }; + + return ( +
+
+

Excel导入演示

+

+ 本演示页面用于测试Excel文件导入功能,将解析Excel中的手机号码、来源和微信号字段。 +

+
+ + + +
+
+

上传Excel文件

+ +
+ +
+

导入结果

+ + {importedData.length > 0 ? ( +
+

导入 {importedData.length} 条数据

+
+
+                    {JSON.stringify(importedData, null, 2)}
+                  
+
+
+ +
+
+ ) : ( +
+

尚未导入数据

+

请上传Excel文件并点击确认导入

+
+ )} +
+
+
+ + + +
+

使用说明

+
+ +

功能说明

+
    +
  • 支持上传.xlsx和.xls格式的Excel文件
  • +
  • 自动识别"手机号码"、"来源"和"微信号"栏位
  • +
  • 可以自动跳过没有手机号的行
  • +
  • 点击"确认导入"按钮将解析后的数据传给回调函数
  • +
+
+ + +

数据结构

+ + {`{ + mobile: "手机号码", // 必填 + from: "来源", // 选填 + alias: "微信号" // 选填 +}`} + +

+ 注意:手机号为空的行会被自动忽略,来源和微信号栏位如果没有数据,则为空字符串。 +

+
+
+
+
+ ); +} \ No newline at end of file diff --git a/Cunkebao/app/plans/new/steps/BasicSettings.tsx b/Cunkebao/app/plans/new/steps/BasicSettings.tsx index 28772087..4655425f 100755 --- a/Cunkebao/app/plans/new/steps/BasicSettings.tsx +++ b/Cunkebao/app/plans/new/steps/BasicSettings.tsx @@ -290,9 +290,9 @@ export function BasicSettings({ formData, onChange, onNext }: BasicSettingsProps const [phone, wechat, source, orderAmount, orderDate] = row.split(",") return { phone: phone.trim(), - wechat: wechat.trim(), + wechat: wechat?.trim(), source: source?.trim(), - orderAmount: orderAmount ? Number(orderAmount) : undefined, + orderAmount: orderAmount ? Number(orderAmount) : 0, orderDate: orderDate?.trim(), } }) @@ -588,18 +588,14 @@ export function BasicSettings({ formData, onChange, onNext }: BasicSettingsProps 电话号码 - 微信号 来源 - 订单金额 {importedTags.slice(0, 5).map((tag, index) => ( {tag.phone} - {tag.wechat} {tag.source} - {tag.orderAmount} ))} {importedTags.length > 5 && ( @@ -769,20 +765,14 @@ export function BasicSettings({ formData, onChange, onNext }: BasicSettingsProps 电话号码 - 微信号 来源 - 订单金额 - 下单日期 {importedTags.map((tag, index) => ( {tag.phone} - {tag.wechat} {tag.source} - {tag.orderAmount} - {tag.orderDate} ))} diff --git a/Cunkebao/components/ExcelImporter.tsx b/Cunkebao/components/ExcelImporter.tsx new file mode 100644 index 00000000..d0b55979 --- /dev/null +++ b/Cunkebao/components/ExcelImporter.tsx @@ -0,0 +1,341 @@ +"use client"; + +import React, { useState, useRef } from "react"; +import * as XLSX from "xlsx"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { Alert, AlertDescription } from "@/components/ui/alert"; +import { AlertCircle } from "lucide-react"; + +export interface ContactData { + mobile: number; + from?: string; + alias?: string; +} + +interface ExcelImporterProps { + onImport: (data: ContactData[]) => void; + onReset?: () => void; +} + +export default function ExcelImporter({ onImport, onReset }: ExcelImporterProps) { + const [parsedData, setParsedData] = useState([]); + const [error, setError] = useState(null); + const [fileName, setFileName] = useState(""); + const [isImportSuccessful, setIsImportSuccessful] = useState(false); + const [isProcessing, setIsProcessing] = useState(false); + const [detectedColumns, setDetectedColumns] = useState<{ + mobile?: string; + from?: string; + alias?: string; + }>({}); + + const handleFileChange = (e: React.ChangeEvent) => { + const files = e.target.files; + if (!files || files.length === 0) { + return; + } + + // 重置状态 + setError(null); + setIsImportSuccessful(false); + setParsedData([]); + setDetectedColumns({}); + setIsProcessing(true); + + const file = files[0]; + setFileName(file.name); + + const reader = new FileReader(); + reader.onload = (event) => { + try { + const data = event.target?.result; + + if (!data) { + setError("文件内容为空,请检查文件是否有效"); + setIsProcessing(false); + return; + } + + // 尝试将读取的二进制数据解析为Excel工作簿 + let workbook; + try { + workbook = XLSX.read(data, { type: 'binary' }); + } catch (parseErr) { + console.error("解析Excel内容失败:", parseErr); + setError("无法解析文件内容,请确保上传的是有效的Excel文件(.xlsx或.xls格式)"); + setIsProcessing(false); + return; + } + + if (!workbook.SheetNames || workbook.SheetNames.length === 0) { + setError("Excel文件中没有找到工作表"); + setIsProcessing(false); + return; + } + + // 取第一个工作表 + const sheetName = workbook.SheetNames[0]; + const worksheet = workbook.Sheets[sheetName]; + + if (!worksheet) { + setError(`无法读取工作表 "${sheetName}",请检查文件是否损坏`); + setIsProcessing(false); + return; + } + + // 将工作表转换为JSON + const jsonData = XLSX.utils.sheet_to_json(worksheet); + + if (!jsonData || jsonData.length === 0) { + setError("Excel 文件中没有数据"); + setIsProcessing(false); + return; + } + + // 查找栏位对应的列 + let mobileColumn: string | null = null; + let fromColumn: string | null = null; + let aliasColumn: string | null = null; + + // 遍历第一行查找栏位 + const firstRow = jsonData[0] as Record; + if (!firstRow) { + setError("Excel 文件的第一行为空,无法识别栏位"); + setIsProcessing(false); + return; + } + + for (const key in firstRow) { + if (!firstRow[key]) continue; // 跳过空值 + + const value = String(firstRow[key]).toLowerCase(); + + // 扩展匹配列表,提高识别成功率 + if (value.includes("手机") || value.includes("电话") || value.includes("mobile") || + value.includes("phone") || value.includes("tel") || value.includes("cell")) { + mobileColumn = key; + } else if (value.includes("来源") || value.includes("source") || value.includes("from") || + value.includes("channel") || value.includes("渠道")) { + fromColumn = key; + } else if (value.includes("微信") || value.includes("alias") || value.includes("wechat") || + value.includes("wx") || value.includes("id") || value.includes("账号")) { + aliasColumn = key; + } + } + + // 保存检测到的列名 + if (mobileColumn && firstRow[mobileColumn]) { + setDetectedColumns(prev => ({ ...prev, mobile: String(firstRow[mobileColumn]) })); + } + if (fromColumn && firstRow[fromColumn]) { + setDetectedColumns(prev => ({ ...prev, from: String(firstRow[fromColumn]) })); + } + if (aliasColumn && firstRow[aliasColumn]) { + setDetectedColumns(prev => ({ ...prev, alias: String(firstRow[aliasColumn]) })); + } + + if (!mobileColumn) { + setError("未找到手机号码栏位,请确保Excel中包含手机、电话、mobile或phone等栏位名称"); + setIsProcessing(false); + return; + } + + // 取第二行开始的数据(跳过标题行) + const importedData: ContactData[] = []; + for (let i = 1; i < jsonData.length; i++) { + const row = jsonData[i] as Record; + + // 确保手机号存在且不为空 + if (!row || !row[mobileColumn]) continue; + + // 处理手机号,去掉非数字字符 + let mobileValue = row[mobileColumn]; + let mobileNumber: number; + + if (typeof mobileValue === 'number') { + mobileNumber = mobileValue; + } else { + // 如果是字符串,去掉非数字字符 + const mobileStr = String(mobileValue).trim().replace(/\D/g, ''); + if (!mobileStr) continue; // 如果手机号为空,跳过该行 + mobileNumber = Number(mobileStr); + if (isNaN(mobileNumber)) continue; // 如果转换后不是数字,跳过该行 + } + + // 构建数据对象 + const contact: ContactData = { + mobile: mobileNumber + }; + + // 添加来源字段(如果存在) + if (fromColumn && row[fromColumn]) { + contact.from = String(row[fromColumn]).trim(); + } + + // 添加微信号字段(如果存在) + if (aliasColumn && row[aliasColumn]) { + contact.alias = String(row[aliasColumn]).trim(); + } + + importedData.push(contact); + } + + if (importedData.length === 0) { + setError("未找到有效数据,请确保Excel中至少有一行有效的手机号码"); + setIsProcessing(false); + return; + } + + setParsedData(importedData); + setIsProcessing(false); + } catch (err) { + console.error("解析Excel文件出错:", err); + setError("解析Excel文件时出错,请确保文件格式正确"); + setIsProcessing(false); + } + }; + + reader.onerror = () => { + setError("读取文件时出错,请重试"); + setIsProcessing(false); + }; + + reader.readAsBinaryString(file); + }; + + const handleImport = () => { + if (parsedData.length > 0) { + onImport(parsedData); + setIsImportSuccessful(true); + } + }; + + const handleReset = () => { + setParsedData([]); + setError(null); + setFileName(""); + setIsImportSuccessful(false); + setDetectedColumns({}); + if (onReset) { + onReset(); + } + }; + + return ( + +
+
+ + + {fileName && ( +

+ 当前文件: {fileName} +

+ )} +
+ 请确保Excel文件包含以下列: 手机号码(必需)、来源(可选)、微信号(可选) +
+
+ + {isProcessing && ( +
+
+

正在处理Excel文件...

+
+ )} + + {error && ( + + + {error} + + )} + + {isImportSuccessful && ( + + + 已成功导入 {parsedData.length} 条联系人数据! + + + )} + + {parsedData.length > 0 && !isImportSuccessful && ( +
+

+ 已解析 {parsedData.length} 条有效数据,点击下方按钮确认导入。 +

+ + {Object.keys(detectedColumns).length > 0 && ( +
+

检测到的列名:

+
    + {detectedColumns.mobile &&
  • 手机号: {detectedColumns.mobile}
  • } + {detectedColumns.from &&
  • 来源: {detectedColumns.from}
  • } + {detectedColumns.alias &&
  • 微信号: {detectedColumns.alias}
  • } +
+
+ )} + +
+
+

数据示例:

+
+
{JSON.stringify(parsedData.slice(0, 3), null, 2)}
+ {parsedData.length > 3 &&

...共 {parsedData.length} 条

} +
+
+
+

数据结构:

+
+
{`[
+  {
+    "mobile": 13800000000,
+    "from": "小红书",
+    "alias": "xxxxxx"
+  },
+  ...
+]`}
+
+
+
+
+ )} + +
+ + +
+
+
+ ); +} \ No newline at end of file diff --git a/Cunkebao/components/ui/code.tsx b/Cunkebao/components/ui/code.tsx new file mode 100644 index 00000000..929c6f1e --- /dev/null +++ b/Cunkebao/components/ui/code.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import { cn } from "@/lib/utils"; + +interface CodeProps { + children: React.ReactNode; + className?: string; +} + +export function Code({ children, className }: CodeProps) { + return ( + + {children} + + ); +} \ No newline at end of file diff --git a/Cunkebao/types/xlsx.d.ts b/Cunkebao/types/xlsx.d.ts new file mode 100644 index 00000000..a3700109 --- /dev/null +++ b/Cunkebao/types/xlsx.d.ts @@ -0,0 +1,6 @@ +declare module 'xlsx' { + export function read(data: any, opts?: any): any; + export namespace utils { + export function sheet_to_json(worksheet: any, opts?: any): any[]; + } +} \ No newline at end of file diff --git a/Server/application/plan/model/TrafficPool.php b/Server/application/plan/model/TrafficPool.php deleted file mode 100644 index 617b23b3..00000000 --- a/Server/application/plan/model/TrafficPool.php +++ /dev/null @@ -1,138 +0,0 @@ - 'integer', - 'gender' => 'integer', - 'age' => 'integer', - 'status' => 'integer', - 'last_used_time' => 'integer', - 'createTime' => 'integer', - 'updateTime' => 'integer', - 'deleteTime' => 'integer' - ]; - - /** - * 添加或更新流量信息 - * @param string $mobile 手机号 - * @param array $data 流量数据 - * @return int|bool 流量ID或更新结果 - */ - public static function addOrUpdateTraffic($mobile, $data = []) - { - // 查询是否已存在该手机号 - $exists = self::where('mobile', $mobile)->find(); - - // 设置通用数据 - $saveData = array_merge([ - 'mobile' => $mobile, - 'status' => 1, - 'last_used_time' => time() - ], $data); - - if ($exists) { - // 更新已存在的流量记录 - return self::where('id', $exists['id'])->update($saveData); - } else { - // 创建新的流量记录 - $model = new self(); - $model->save($saveData); - return $model->id; - } - } - - /** - * 获取可用的流量列表 - * @param array $where 查询条件 - * @param string $order 排序 - * @param int $page 页码 - * @param int $limit 每页数量 - * @return array 流量列表和总数 - */ - public static function getAvailableTraffic($where = [], $order = 'last_used_time ASC', $page = 1, $limit = 10) - { - // 确保只查询有效流量 - $where[] = ['status', '=', 1]; - - // 构建查询 - $query = self::where($where); - - // 计算总数 - $total = $query->count(); - - // 分页查询数据 - $list = $query->page($page, $limit) - ->order($order) - ->select(); - - return [ - 'list' => $list, - 'total' => $total, - 'page' => $page, - 'limit' => $limit - ]; - } - - /** - * 设置流量使用时间 - * @param int $id 流量ID - * @return bool 更新结果 - */ - public static function setTrafficUsed($id) - { - return self::where('id', $id)->update([ - 'last_used_time' => time() - ]); - } - - /** - * 获取流量详情 - * @param int $id 流量ID - * @return array|null 流量详情 - */ - public static function getTrafficDetail($id) - { - return self::where('id', $id)->find(); - } - - /** - * 根据手机号获取流量详情 - * @param string $mobile 手机号 - * @return array|null 流量详情 - */ - public static function getTrafficByMobile($mobile) - { - return self::where('mobile', $mobile)->find(); - } - - /** - * 关联流量来源 - */ - public function sources() - { - return $this->hasMany('TrafficSource', 'traffic_id'); - } -} \ No newline at end of file diff --git a/Server/application/plan/model/TrafficSource.php b/Server/application/plan/model/TrafficSource.php deleted file mode 100644 index 4d3d6528..00000000 --- a/Server/application/plan/model/TrafficSource.php +++ /dev/null @@ -1,151 +0,0 @@ - 'integer', - 'traffic_id' => 'integer', - 'plan_id' => 'integer', - 'scene_id' => 'integer', - 'source_detail' => 'json', - 'createTime' => 'integer' - ]; - - /** - * 渠道文本获取器 - * @param string $value 渠道值 - * @return string 渠道文本 - */ - public function getChannelTextAttr($value, $data) - { - $channels = [ - 'poster' => '海报', - 'order' => '订单', - 'douyin' => '抖音', - 'xiaohongshu' => '小红书', - 'phone' => '电话', - 'wechat' => '公众号', - 'group' => '微信群', - 'payment' => '付款码', - 'api' => 'API接口' - ]; - - return isset($channels[$data['channel']]) ? $channels[$data['channel']] : '未知'; - } - - /** - * 添加流量来源记录 - * @param int $trafficId 流量ID - * @param string $channel 渠道 - * @param array $data 额外数据 - * @return int 新增记录ID - */ - public static function addSource($trafficId, $channel, $data = []) - { - $model = new self(); - $model->save(array_merge([ - 'traffic_id' => $trafficId, - 'channel' => $channel, - 'ip' => request()->ip(), - 'user_agent' => request()->header('user-agent') - ], $data)); - - return $model->id; - } - - /** - * 获取流量来源列表 - * @param int $trafficId 流量ID - * @return array 来源列表 - */ - public static function getSourcesByTrafficId($trafficId) - { - return self::where('traffic_id', $trafficId) - ->order('createTime DESC') - ->select(); - } - - /** - * 获取来源统计 - * @param string $channel 渠道 - * @param int $planId 计划ID - * @param int $sceneId 场景ID - * @param string $startTime 开始时间 - * @param string $endTime 结束时间 - * @return array 统计数据 - */ - public static function getSourceStats($channel = null, $planId = null, $sceneId = null, $startTime = null, $endTime = null) - { - $where = []; - - if ($channel !== null) { - $where[] = ['channel', '=', $channel]; - } - - if ($planId !== null) { - $where[] = ['plan_id', '=', $planId]; - } - - if ($sceneId !== null) { - $where[] = ['scene_id', '=', $sceneId]; - } - - if ($startTime !== null) { - $where[] = ['createTime', '>=', strtotime($startTime)]; - } - - if ($endTime !== null) { - $where[] = ['createTime', '<=', strtotime($endTime)]; - } - - return self::where($where) - ->field('channel, COUNT(*) as count') - ->group('channel') - ->select(); - } - - /** - * 关联流量 - */ - public function traffic() - { - return $this->belongsTo('TrafficPool', 'traffic_id'); - } - - /** - * 关联计划 - */ - public function plan() - { - return $this->belongsTo('PlanTask', 'plan_id'); - } - - /** - * 关联场景 - */ - public function scene() - { - return $this->belongsTo('PlanScene', 'scene_id'); - } -} \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 00000000..5d0a9aa5 --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,47 @@ +{ + "name": "yi-shi", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT", + "peer": true + }, + "node_modules/sonner": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.3.tgz", + "integrity": "sha512-njQ4Hht92m0sMqqHVDL32V2Oun9W1+PHO9NDv9FHfJjT3JT22IG4Jpo3FPQy+mouRKCXFWO+r67v6MrHX2zeIA==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + } + } +} diff --git a/node_modules/react-dom/LICENSE b/node_modules/react-dom/LICENSE new file mode 100644 index 00000000..b93be905 --- /dev/null +++ b/node_modules/react-dom/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/react-dom/README.md b/node_modules/react-dom/README.md new file mode 100644 index 00000000..b078f194 --- /dev/null +++ b/node_modules/react-dom/README.md @@ -0,0 +1,60 @@ +# `react-dom` + +This package serves as the entry point to the DOM and server renderers for React. It is intended to be paired with the generic React package, which is shipped as `react` to npm. + +## Installation + +```sh +npm install react react-dom +``` + +## Usage + +### In the browser + +```js +import { createRoot } from 'react-dom/client'; + +function App() { + return
Hello World
; +} + +const root = createRoot(document.getElementById('root')); +root.render(); +``` + +### On the server + +```js +import { renderToPipeableStream } from 'react-dom/server'; + +function App() { + return
Hello World
; +} + +function handleRequest(res) { + // ... in your server handler ... + const stream = renderToPipeableStream(, { + onShellReady() { + res.statusCode = 200; + res.setHeader('Content-type', 'text/html'); + stream.pipe(res); + }, + // ... + }); +} +``` + +## API + +### `react-dom` + +See https://react.dev/reference/react-dom + +### `react-dom/client` + +See https://react.dev/reference/react-dom/client + +### `react-dom/server` + +See https://react.dev/reference/react-dom/server diff --git a/node_modules/react-dom/cjs/react-dom-client.development.js b/node_modules/react-dom/cjs/react-dom-client.development.js new file mode 100644 index 00000000..dd10829d --- /dev/null +++ b/node_modules/react-dom/cjs/react-dom-client.development.js @@ -0,0 +1,24990 @@ +/** + * @license React + * react-dom-client.development.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* + Modernizr 3.0.0pre (Custom Build) | MIT +*/ +"use strict"; +"production" !== process.env.NODE_ENV && + (function () { + function findHook(fiber, id) { + for (fiber = fiber.memoizedState; null !== fiber && 0 < id; ) + (fiber = fiber.next), id--; + return fiber; + } + function copyWithSetImpl(obj, path, index, value) { + if (index >= path.length) return value; + var key = path[index], + updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj); + updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); + return updated; + } + function copyWithRename(obj, oldPath, newPath) { + if (oldPath.length !== newPath.length) + console.warn("copyWithRename() expects paths of the same length"); + else { + for (var i = 0; i < newPath.length - 1; i++) + if (oldPath[i] !== newPath[i]) { + console.warn( + "copyWithRename() expects paths to be the same except for the deepest key" + ); + return; + } + return copyWithRenameImpl(obj, oldPath, newPath, 0); + } + } + function copyWithRenameImpl(obj, oldPath, newPath, index) { + var oldKey = oldPath[index], + updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj); + index + 1 === oldPath.length + ? ((updated[newPath[index]] = updated[oldKey]), + isArrayImpl(updated) + ? updated.splice(oldKey, 1) + : delete updated[oldKey]) + : (updated[oldKey] = copyWithRenameImpl( + obj[oldKey], + oldPath, + newPath, + index + 1 + )); + return updated; + } + function copyWithDeleteImpl(obj, path, index) { + var key = path[index], + updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj); + if (index + 1 === path.length) + return ( + isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], + updated + ); + updated[key] = copyWithDeleteImpl(obj[key], path, index + 1); + return updated; + } + function shouldSuspendImpl() { + return !1; + } + function shouldErrorImpl() { + return null; + } + function warnForMissingKey() {} + function warnInvalidHookAccess() { + console.error( + "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see https://react.dev/link/rules-of-hooks" + ); + } + function warnInvalidContextAccess() { + console.error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ); + } + function noop$2() {} + function setToSortedString(set) { + var array = []; + set.forEach(function (value) { + array.push(value); + }); + return array.sort().join(", "); + } + function createFiber(tag, pendingProps, key, mode) { + return new FiberNode(tag, pendingProps, key, mode); + } + function scheduleRoot(root, element) { + root.context === emptyContextObject && + (updateContainerImpl(root.current, 2, element, root, null, null), + flushSyncWork$1()); + } + function scheduleRefresh(root, update) { + if (null !== resolveFamily) { + var staleFamilies = update.staleFamilies; + update = update.updatedFamilies; + flushPendingEffects(); + scheduleFibersWithFamiliesRecursively( + root.current, + update, + staleFamilies + ); + flushSyncWork$1(); + } + } + function setRefreshHandler(handler) { + resolveFamily = handler; + } + function isValidContainer(node) { + return !( + !node || + (1 !== node.nodeType && 9 !== node.nodeType && 11 !== node.nodeType) + ); + } + function getNearestMountedFiber(fiber) { + var node = fiber, + nearestMounted = fiber; + if (fiber.alternate) for (; node.return; ) node = node.return; + else { + fiber = node; + do + (node = fiber), + 0 !== (node.flags & 4098) && (nearestMounted = node.return), + (fiber = node.return); + while (fiber); + } + return 3 === node.tag ? nearestMounted : null; + } + function getSuspenseInstanceFromFiber(fiber) { + if (13 === fiber.tag) { + var suspenseState = fiber.memoizedState; + null === suspenseState && + ((fiber = fiber.alternate), + null !== fiber && (suspenseState = fiber.memoizedState)); + if (null !== suspenseState) return suspenseState.dehydrated; + } + return null; + } + function assertIsMounted(fiber) { + if (getNearestMountedFiber(fiber) !== fiber) + throw Error("Unable to find node on an unmounted component."); + } + function findCurrentFiberUsingSlowPath(fiber) { + var alternate = fiber.alternate; + if (!alternate) { + alternate = getNearestMountedFiber(fiber); + if (null === alternate) + throw Error("Unable to find node on an unmounted component."); + return alternate !== fiber ? null : fiber; + } + for (var a = fiber, b = alternate; ; ) { + var parentA = a.return; + if (null === parentA) break; + var parentB = parentA.alternate; + if (null === parentB) { + b = parentA.return; + if (null !== b) { + a = b; + continue; + } + break; + } + if (parentA.child === parentB.child) { + for (parentB = parentA.child; parentB; ) { + if (parentB === a) return assertIsMounted(parentA), fiber; + if (parentB === b) return assertIsMounted(parentA), alternate; + parentB = parentB.sibling; + } + throw Error("Unable to find node on an unmounted component."); + } + if (a.return !== b.return) (a = parentA), (b = parentB); + else { + for (var didFindChild = !1, _child = parentA.child; _child; ) { + if (_child === a) { + didFindChild = !0; + a = parentA; + b = parentB; + break; + } + if (_child === b) { + didFindChild = !0; + b = parentA; + a = parentB; + break; + } + _child = _child.sibling; + } + if (!didFindChild) { + for (_child = parentB.child; _child; ) { + if (_child === a) { + didFindChild = !0; + a = parentB; + b = parentA; + break; + } + if (_child === b) { + didFindChild = !0; + b = parentB; + a = parentA; + break; + } + _child = _child.sibling; + } + if (!didFindChild) + throw Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ); + } + } + if (a.alternate !== b) + throw Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ); + } + if (3 !== a.tag) + throw Error("Unable to find node on an unmounted component."); + return a.stateNode.current === a ? fiber : alternate; + } + function findCurrentHostFiberImpl(node) { + var tag = node.tag; + if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return node; + for (node = node.child; null !== node; ) { + tag = findCurrentHostFiberImpl(node); + if (null !== tag) return tag; + node = node.sibling; + } + return null; + } + function getIteratorFn(maybeIterable) { + if (null === maybeIterable || "object" !== typeof maybeIterable) + return null; + maybeIterable = + (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || + maybeIterable["@@iterator"]; + return "function" === typeof maybeIterable ? maybeIterable : null; + } + function getComponentNameFromType(type) { + if (null == type) return null; + if ("function" === typeof type) + return type.$$typeof === REACT_CLIENT_REFERENCE + ? null + : type.displayName || type.name || null; + if ("string" === typeof type) return type; + switch (type) { + case REACT_FRAGMENT_TYPE: + return "Fragment"; + case REACT_PROFILER_TYPE: + return "Profiler"; + case REACT_STRICT_MODE_TYPE: + return "StrictMode"; + case REACT_SUSPENSE_TYPE: + return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; + case REACT_ACTIVITY_TYPE: + return "Activity"; + } + if ("object" === typeof type) + switch ( + ("number" === typeof type.tag && + console.error( + "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." + ), + type.$$typeof) + ) { + case REACT_PORTAL_TYPE: + return "Portal"; + case REACT_CONTEXT_TYPE: + return (type.displayName || "Context") + ".Provider"; + case REACT_CONSUMER_TYPE: + return (type._context.displayName || "Context") + ".Consumer"; + case REACT_FORWARD_REF_TYPE: + var innerType = type.render; + type = type.displayName; + type || + ((type = innerType.displayName || innerType.name || ""), + (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); + return type; + case REACT_MEMO_TYPE: + return ( + (innerType = type.displayName || null), + null !== innerType + ? innerType + : getComponentNameFromType(type.type) || "Memo" + ); + case REACT_LAZY_TYPE: + innerType = type._payload; + type = type._init; + try { + return getComponentNameFromType(type(innerType)); + } catch (x) {} + } + return null; + } + function getComponentNameFromOwner(owner) { + return "number" === typeof owner.tag + ? getComponentNameFromFiber(owner) + : "string" === typeof owner.name + ? owner.name + : null; + } + function getComponentNameFromFiber(fiber) { + var type = fiber.type; + switch (fiber.tag) { + case 31: + return "Activity"; + case 24: + return "Cache"; + case 9: + return (type._context.displayName || "Context") + ".Consumer"; + case 10: + return (type.displayName || "Context") + ".Provider"; + case 18: + return "DehydratedFragment"; + case 11: + return ( + (fiber = type.render), + (fiber = fiber.displayName || fiber.name || ""), + type.displayName || + ("" !== fiber ? "ForwardRef(" + fiber + ")" : "ForwardRef") + ); + case 7: + return "Fragment"; + case 26: + case 27: + case 5: + return type; + case 4: + return "Portal"; + case 3: + return "Root"; + case 6: + return "Text"; + case 16: + return getComponentNameFromType(type); + case 8: + return type === REACT_STRICT_MODE_TYPE ? "StrictMode" : "Mode"; + case 22: + return "Offscreen"; + case 12: + return "Profiler"; + case 21: + return "Scope"; + case 13: + return "Suspense"; + case 19: + return "SuspenseList"; + case 25: + return "TracingMarker"; + case 1: + case 0: + case 14: + case 15: + if ("function" === typeof type) + return type.displayName || type.name || null; + if ("string" === typeof type) return type; + break; + case 29: + type = fiber._debugInfo; + if (null != type) + for (var i = type.length - 1; 0 <= i; i--) + if ("string" === typeof type[i].name) return type[i].name; + if (null !== fiber.return) + return getComponentNameFromFiber(fiber.return); + } + return null; + } + function createCursor(defaultValue) { + return { current: defaultValue }; + } + function pop(cursor, fiber) { + 0 > index$jscomp$0 + ? console.error("Unexpected pop.") + : (fiber !== fiberStack[index$jscomp$0] && + console.error("Unexpected Fiber popped."), + (cursor.current = valueStack[index$jscomp$0]), + (valueStack[index$jscomp$0] = null), + (fiberStack[index$jscomp$0] = null), + index$jscomp$0--); + } + function push(cursor, value, fiber) { + index$jscomp$0++; + valueStack[index$jscomp$0] = cursor.current; + fiberStack[index$jscomp$0] = fiber; + cursor.current = value; + } + function requiredContext(c) { + null === c && + console.error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ); + return c; + } + function pushHostContainer(fiber, nextRootInstance) { + push(rootInstanceStackCursor, nextRootInstance, fiber); + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor, null, fiber); + var nextRootContext = nextRootInstance.nodeType; + switch (nextRootContext) { + case 9: + case 11: + nextRootContext = 9 === nextRootContext ? "#document" : "#fragment"; + nextRootInstance = (nextRootInstance = + nextRootInstance.documentElement) + ? (nextRootInstance = nextRootInstance.namespaceURI) + ? getOwnHostContext(nextRootInstance) + : HostContextNamespaceNone + : HostContextNamespaceNone; + break; + default: + if ( + ((nextRootContext = nextRootInstance.tagName), + (nextRootInstance = nextRootInstance.namespaceURI)) + ) + (nextRootInstance = getOwnHostContext(nextRootInstance)), + (nextRootInstance = getChildHostContextProd( + nextRootInstance, + nextRootContext + )); + else + switch (nextRootContext) { + case "svg": + nextRootInstance = HostContextNamespaceSvg; + break; + case "math": + nextRootInstance = HostContextNamespaceMath; + break; + default: + nextRootInstance = HostContextNamespaceNone; + } + } + nextRootContext = nextRootContext.toLowerCase(); + nextRootContext = updatedAncestorInfoDev(null, nextRootContext); + nextRootContext = { + context: nextRootInstance, + ancestorInfo: nextRootContext + }; + pop(contextStackCursor, fiber); + push(contextStackCursor, nextRootContext, fiber); + } + function popHostContainer(fiber) { + pop(contextStackCursor, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); + } + function getHostContext() { + return requiredContext(contextStackCursor.current); + } + function pushHostContext(fiber) { + null !== fiber.memoizedState && + push(hostTransitionProviderCursor, fiber, fiber); + var context = requiredContext(contextStackCursor.current); + var type = fiber.type; + var nextContext = getChildHostContextProd(context.context, type); + type = updatedAncestorInfoDev(context.ancestorInfo, type); + nextContext = { context: nextContext, ancestorInfo: type }; + context !== nextContext && + (push(contextFiberStackCursor, fiber, fiber), + push(contextStackCursor, nextContext, fiber)); + } + function popHostContext(fiber) { + contextFiberStackCursor.current === fiber && + (pop(contextStackCursor, fiber), pop(contextFiberStackCursor, fiber)); + hostTransitionProviderCursor.current === fiber && + (pop(hostTransitionProviderCursor, fiber), + (HostTransitionContext._currentValue = NotPendingTransition)); + } + function typeName(value) { + return ( + ("function" === typeof Symbol && + Symbol.toStringTag && + value[Symbol.toStringTag]) || + value.constructor.name || + "Object" + ); + } + function willCoercionThrow(value) { + try { + return testStringCoercion(value), !1; + } catch (e) { + return !0; + } + } + function testStringCoercion(value) { + return "" + value; + } + function checkAttributeStringCoercion(value, attributeName) { + if (willCoercionThrow(value)) + return ( + console.error( + "The provided `%s` attribute is an unsupported type %s. This value must be coerced to a string before using it here.", + attributeName, + typeName(value) + ), + testStringCoercion(value) + ); + } + function checkCSSPropertyStringCoercion(value, propName) { + if (willCoercionThrow(value)) + return ( + console.error( + "The provided `%s` CSS property is an unsupported type %s. This value must be coerced to a string before using it here.", + propName, + typeName(value) + ), + testStringCoercion(value) + ); + } + function checkFormFieldValueStringCoercion(value) { + if (willCoercionThrow(value)) + return ( + console.error( + "Form field values (value, checked, defaultValue, or defaultChecked props) must be strings, not %s. This value must be coerced to a string before using it here.", + typeName(value) + ), + testStringCoercion(value) + ); + } + function injectInternals(internals) { + if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (hook.isDisabled) return !0; + if (!hook.supportsFiber) + return ( + console.error( + "The installed version of React DevTools is too old and will not work with the current version of React. Please update React DevTools. https://react.dev/link/react-devtools" + ), + !0 + ); + try { + (rendererID = hook.inject(internals)), (injectedHook = hook); + } catch (err) { + console.error("React instrumentation encountered an error: %s.", err); + } + return hook.checkDCE ? !0 : !1; + } + function setIsStrictModeForDevtools(newIsStrictMode) { + "function" === typeof log$1 && + unstable_setDisableYieldValue(newIsStrictMode); + if (injectedHook && "function" === typeof injectedHook.setStrictMode) + try { + injectedHook.setStrictMode(rendererID, newIsStrictMode); + } catch (err) { + hasLoggedError || + ((hasLoggedError = !0), + console.error( + "React instrumentation encountered an error: %s", + err + )); + } + } + function injectProfilingHooks(profilingHooks) { + injectedProfilingHooks = profilingHooks; + } + function markCommitStopped() { + null !== injectedProfilingHooks && + "function" === typeof injectedProfilingHooks.markCommitStopped && + injectedProfilingHooks.markCommitStopped(); + } + function markComponentRenderStarted(fiber) { + null !== injectedProfilingHooks && + "function" === + typeof injectedProfilingHooks.markComponentRenderStarted && + injectedProfilingHooks.markComponentRenderStarted(fiber); + } + function markComponentRenderStopped() { + null !== injectedProfilingHooks && + "function" === + typeof injectedProfilingHooks.markComponentRenderStopped && + injectedProfilingHooks.markComponentRenderStopped(); + } + function markRenderStarted(lanes) { + null !== injectedProfilingHooks && + "function" === typeof injectedProfilingHooks.markRenderStarted && + injectedProfilingHooks.markRenderStarted(lanes); + } + function markRenderStopped() { + null !== injectedProfilingHooks && + "function" === typeof injectedProfilingHooks.markRenderStopped && + injectedProfilingHooks.markRenderStopped(); + } + function markStateUpdateScheduled(fiber, lane) { + null !== injectedProfilingHooks && + "function" === typeof injectedProfilingHooks.markStateUpdateScheduled && + injectedProfilingHooks.markStateUpdateScheduled(fiber, lane); + } + function clz32Fallback(x) { + x >>>= 0; + return 0 === x ? 32 : (31 - ((log(x) / LN2) | 0)) | 0; + } + function getLabelForLane(lane) { + if (lane & 1) return "SyncHydrationLane"; + if (lane & 2) return "Sync"; + if (lane & 4) return "InputContinuousHydration"; + if (lane & 8) return "InputContinuous"; + if (lane & 16) return "DefaultHydration"; + if (lane & 32) return "Default"; + if (lane & 128) return "TransitionHydration"; + if (lane & 4194048) return "Transition"; + if (lane & 62914560) return "Retry"; + if (lane & 67108864) return "SelectiveHydration"; + if (lane & 134217728) return "IdleHydration"; + if (lane & 268435456) return "Idle"; + if (lane & 536870912) return "Offscreen"; + if (lane & 1073741824) return "Deferred"; + } + function getHighestPriorityLanes(lanes) { + var pendingSyncLanes = lanes & 42; + if (0 !== pendingSyncLanes) return pendingSyncLanes; + switch (lanes & -lanes) { + case 1: + return 1; + case 2: + return 2; + case 4: + return 4; + case 8: + return 8; + case 16: + return 16; + case 32: + return 32; + case 64: + return 64; + case 128: + return 128; + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return lanes & 4194048; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + return lanes & 62914560; + case 67108864: + return 67108864; + case 134217728: + return 134217728; + case 268435456: + return 268435456; + case 536870912: + return 536870912; + case 1073741824: + return 0; + default: + return ( + console.error( + "Should have found matching lanes. This is a bug in React." + ), + lanes + ); + } + } + function getNextLanes(root, wipLanes, rootHasPendingCommit) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return 0; + var nextLanes = 0, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + root = root.warmLanes; + var nonIdlePendingLanes = pendingLanes & 134217727; + 0 !== nonIdlePendingLanes + ? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes), + 0 !== pendingLanes + ? (nextLanes = getHighestPriorityLanes(pendingLanes)) + : ((pingedLanes &= nonIdlePendingLanes), + 0 !== pingedLanes + ? (nextLanes = getHighestPriorityLanes(pingedLanes)) + : rootHasPendingCommit || + ((rootHasPendingCommit = nonIdlePendingLanes & ~root), + 0 !== rootHasPendingCommit && + (nextLanes = + getHighestPriorityLanes(rootHasPendingCommit))))) + : ((nonIdlePendingLanes = pendingLanes & ~suspendedLanes), + 0 !== nonIdlePendingLanes + ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes)) + : 0 !== pingedLanes + ? (nextLanes = getHighestPriorityLanes(pingedLanes)) + : rootHasPendingCommit || + ((rootHasPendingCommit = pendingLanes & ~root), + 0 !== rootHasPendingCommit && + (nextLanes = getHighestPriorityLanes(rootHasPendingCommit)))); + return 0 === nextLanes + ? 0 + : 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) && + ((suspendedLanes = nextLanes & -nextLanes), + (rootHasPendingCommit = wipLanes & -wipLanes), + suspendedLanes >= rootHasPendingCommit || + (32 === suspendedLanes && 0 !== (rootHasPendingCommit & 4194048))) + ? wipLanes + : nextLanes; + } + function checkIfRootIsPrerendering(root, renderLanes) { + return ( + 0 === + (root.pendingLanes & + ~(root.suspendedLanes & ~root.pingedLanes) & + renderLanes) + ); + } + function computeExpirationTime(lane, currentTime) { + switch (lane) { + case 1: + case 2: + case 4: + case 8: + case 64: + return currentTime + 250; + case 16: + case 32: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return currentTime + 5e3; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + return -1; + case 67108864: + case 134217728: + case 268435456: + case 536870912: + case 1073741824: + return -1; + default: + return ( + console.error( + "Should have found matching lanes. This is a bug in React." + ), + -1 + ); + } + } + function claimNextTransitionLane() { + var lane = nextTransitionLane; + nextTransitionLane <<= 1; + 0 === (nextTransitionLane & 4194048) && (nextTransitionLane = 256); + return lane; + } + function claimNextRetryLane() { + var lane = nextRetryLane; + nextRetryLane <<= 1; + 0 === (nextRetryLane & 62914560) && (nextRetryLane = 4194304); + return lane; + } + function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; + } + function markRootUpdated$1(root, updateLane) { + root.pendingLanes |= updateLane; + 268435456 !== updateLane && + ((root.suspendedLanes = 0), + (root.pingedLanes = 0), + (root.warmLanes = 0)); + } + function markRootFinished( + root, + finishedLanes, + remainingLanes, + spawnedLane, + updatedLanes, + suspendedRetryLanes + ) { + var previouslyPendingLanes = root.pendingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.warmLanes = 0; + root.expiredLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + root.errorRecoveryDisabledLanes &= remainingLanes; + root.shellSuspendCounter = 0; + var entanglements = root.entanglements, + expirationTimes = root.expirationTimes, + hiddenUpdates = root.hiddenUpdates; + for ( + remainingLanes = previouslyPendingLanes & ~remainingLanes; + 0 < remainingLanes; + + ) { + var index = 31 - clz32(remainingLanes), + lane = 1 << index; + entanglements[index] = 0; + expirationTimes[index] = -1; + var hiddenUpdatesForLane = hiddenUpdates[index]; + if (null !== hiddenUpdatesForLane) + for ( + hiddenUpdates[index] = null, index = 0; + index < hiddenUpdatesForLane.length; + index++ + ) { + var update = hiddenUpdatesForLane[index]; + null !== update && (update.lane &= -536870913); + } + remainingLanes &= ~lane; + } + 0 !== spawnedLane && markSpawnedDeferredLane(root, spawnedLane, 0); + 0 !== suspendedRetryLanes && + 0 === updatedLanes && + 0 !== root.tag && + (root.suspendedLanes |= + suspendedRetryLanes & ~(previouslyPendingLanes & ~finishedLanes)); + } + function markSpawnedDeferredLane(root, spawnedLane, entangledLanes) { + root.pendingLanes |= spawnedLane; + root.suspendedLanes &= ~spawnedLane; + var spawnedLaneIndex = 31 - clz32(spawnedLane); + root.entangledLanes |= spawnedLane; + root.entanglements[spawnedLaneIndex] = + root.entanglements[spawnedLaneIndex] | + 1073741824 | + (entangledLanes & 4194090); + } + function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index = 31 - clz32(rootEntangledLanes), + lane = 1 << index; + (lane & entangledLanes) | (root[index] & entangledLanes) && + (root[index] |= entangledLanes); + rootEntangledLanes &= ~lane; + } + } + function getBumpedLaneForHydrationByLane(lane) { + switch (lane) { + case 2: + lane = 1; + break; + case 8: + lane = 4; + break; + case 32: + lane = 16; + break; + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + lane = 128; + break; + case 268435456: + lane = 134217728; + break; + default: + lane = 0; + } + return lane; + } + function addFiberToLanesMap(root, fiber, lanes) { + if (isDevToolsPresent) + for (root = root.pendingUpdatersLaneMap; 0 < lanes; ) { + var index = 31 - clz32(lanes), + lane = 1 << index; + root[index].add(fiber); + lanes &= ~lane; + } + } + function movePendingFibersToMemoized(root, lanes) { + if (isDevToolsPresent) + for ( + var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap, + memoizedUpdaters = root.memoizedUpdaters; + 0 < lanes; + + ) { + var index = 31 - clz32(lanes); + root = 1 << index; + index = pendingUpdatersLaneMap[index]; + 0 < index.size && + (index.forEach(function (fiber) { + var alternate = fiber.alternate; + (null !== alternate && memoizedUpdaters.has(alternate)) || + memoizedUpdaters.add(fiber); + }), + index.clear()); + lanes &= ~root; + } + } + function lanesToEventPriority(lanes) { + lanes &= -lanes; + return 0 !== DiscreteEventPriority && DiscreteEventPriority < lanes + ? 0 !== ContinuousEventPriority && ContinuousEventPriority < lanes + ? 0 !== (lanes & 134217727) + ? DefaultEventPriority + : IdleEventPriority + : ContinuousEventPriority + : DiscreteEventPriority; + } + function resolveUpdatePriority() { + var updatePriority = ReactDOMSharedInternals.p; + if (0 !== updatePriority) return updatePriority; + updatePriority = window.event; + return void 0 === updatePriority + ? DefaultEventPriority + : getEventPriority(updatePriority.type); + } + function runWithPriority(priority, fn) { + var previousPriority = ReactDOMSharedInternals.p; + try { + return (ReactDOMSharedInternals.p = priority), fn(); + } finally { + ReactDOMSharedInternals.p = previousPriority; + } + } + function detachDeletedInstance(node) { + delete node[internalInstanceKey]; + delete node[internalPropsKey]; + delete node[internalEventHandlersKey]; + delete node[internalEventHandlerListenersKey]; + delete node[internalEventHandlesSetKey]; + } + function getClosestInstanceFromNode(targetNode) { + var targetInst = targetNode[internalInstanceKey]; + if (targetInst) return targetInst; + for (var parentNode = targetNode.parentNode; parentNode; ) { + if ( + (targetInst = + parentNode[internalContainerInstanceKey] || + parentNode[internalInstanceKey]) + ) { + parentNode = targetInst.alternate; + if ( + null !== targetInst.child || + (null !== parentNode && null !== parentNode.child) + ) + for ( + targetNode = getParentSuspenseInstance(targetNode); + null !== targetNode; + + ) { + if ((parentNode = targetNode[internalInstanceKey])) + return parentNode; + targetNode = getParentSuspenseInstance(targetNode); + } + return targetInst; + } + targetNode = parentNode; + parentNode = targetNode.parentNode; + } + return null; + } + function getInstanceFromNode(node) { + if ( + (node = node[internalInstanceKey] || node[internalContainerInstanceKey]) + ) { + var tag = node.tag; + if ( + 5 === tag || + 6 === tag || + 13 === tag || + 26 === tag || + 27 === tag || + 3 === tag + ) + return node; + } + return null; + } + function getNodeFromInstance(inst) { + var tag = inst.tag; + if (5 === tag || 26 === tag || 27 === tag || 6 === tag) + return inst.stateNode; + throw Error("getNodeFromInstance: Invalid argument."); + } + function getResourcesFromRoot(root) { + var resources = root[internalRootNodeResourcesKey]; + resources || + (resources = root[internalRootNodeResourcesKey] = + { hoistableStyles: new Map(), hoistableScripts: new Map() }); + return resources; + } + function markNodeAsHoistable(node) { + node[internalHoistableMarker] = !0; + } + function registerTwoPhaseEvent(registrationName, dependencies) { + registerDirectEvent(registrationName, dependencies); + registerDirectEvent(registrationName + "Capture", dependencies); + } + function registerDirectEvent(registrationName, dependencies) { + registrationNameDependencies[registrationName] && + console.error( + "EventRegistry: More than one plugin attempted to publish the same registration name, `%s`.", + registrationName + ); + registrationNameDependencies[registrationName] = dependencies; + var lowerCasedName = registrationName.toLowerCase(); + possibleRegistrationNames[lowerCasedName] = registrationName; + "onDoubleClick" === registrationName && + (possibleRegistrationNames.ondblclick = registrationName); + for ( + registrationName = 0; + registrationName < dependencies.length; + registrationName++ + ) + allNativeEvents.add(dependencies[registrationName]); + } + function checkControlledValueProps(tagName, props) { + hasReadOnlyValue[props.type] || + props.onChange || + props.onInput || + props.readOnly || + props.disabled || + null == props.value || + ("select" === tagName + ? console.error( + "You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set `onChange`." + ) + : console.error( + "You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`." + )); + props.onChange || + props.readOnly || + props.disabled || + null == props.checked || + console.error( + "You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`." + ); + } + function isAttributeNameSafe(attributeName) { + if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) + return !0; + if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) + return !1; + if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) + return (validatedAttributeNameCache[attributeName] = !0); + illegalAttributeNameCache[attributeName] = !0; + console.error("Invalid attribute name: `%s`", attributeName); + return !1; + } + function getValueForAttributeOnCustomComponent(node, name, expected) { + if (isAttributeNameSafe(name)) { + if (!node.hasAttribute(name)) { + switch (typeof expected) { + case "symbol": + case "object": + return expected; + case "function": + return expected; + case "boolean": + if (!1 === expected) return expected; + } + return void 0 === expected ? void 0 : null; + } + node = node.getAttribute(name); + if ("" === node && !0 === expected) return !0; + checkAttributeStringCoercion(expected, name); + return node === "" + expected ? expected : node; + } + } + function setValueForAttribute(node, name, value) { + if (isAttributeNameSafe(name)) + if (null === value) node.removeAttribute(name); + else { + switch (typeof value) { + case "undefined": + case "function": + case "symbol": + node.removeAttribute(name); + return; + case "boolean": + var prefix = name.toLowerCase().slice(0, 5); + if ("data-" !== prefix && "aria-" !== prefix) { + node.removeAttribute(name); + return; + } + } + checkAttributeStringCoercion(value, name); + node.setAttribute(name, "" + value); + } + } + function setValueForKnownAttribute(node, name, value) { + if (null === value) node.removeAttribute(name); + else { + switch (typeof value) { + case "undefined": + case "function": + case "symbol": + case "boolean": + node.removeAttribute(name); + return; + } + checkAttributeStringCoercion(value, name); + node.setAttribute(name, "" + value); + } + } + function setValueForNamespacedAttribute(node, namespace, name, value) { + if (null === value) node.removeAttribute(name); + else { + switch (typeof value) { + case "undefined": + case "function": + case "symbol": + case "boolean": + node.removeAttribute(name); + return; + } + checkAttributeStringCoercion(value, name); + node.setAttributeNS(namespace, name, "" + value); + } + } + function disabledLog() {} + function disableLogs() { + if (0 === disabledDepth) { + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; + var props = { + configurable: !0, + enumerable: !0, + value: disabledLog, + writable: !0 + }; + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + } + disabledDepth++; + } + function reenableLogs() { + disabledDepth--; + if (0 === disabledDepth) { + var props = { configurable: !0, enumerable: !0, writable: !0 }; + Object.defineProperties(console, { + log: assign({}, props, { value: prevLog }), + info: assign({}, props, { value: prevInfo }), + warn: assign({}, props, { value: prevWarn }), + error: assign({}, props, { value: prevError }), + group: assign({}, props, { value: prevGroup }), + groupCollapsed: assign({}, props, { value: prevGroupCollapsed }), + groupEnd: assign({}, props, { value: prevGroupEnd }) + }); + } + 0 > disabledDepth && + console.error( + "disabledDepth fell below zero. This is a bug in React. Please file an issue." + ); + } + function describeBuiltInComponentFrame(name) { + if (void 0 === prefix) + try { + throw Error(); + } catch (x) { + var match = x.stack.trim().match(/\n( *(at )?)/); + prefix = (match && match[1]) || ""; + suffix = + -1 < x.stack.indexOf("\n at") + ? " ()" + : -1 < x.stack.indexOf("@") + ? "@unknown:0:0" + : ""; + } + return "\n" + prefix + name + suffix; + } + function describeNativeComponentFrame(fn, construct) { + if (!fn || reentry) return ""; + var frame = componentFrameCache.get(fn); + if (void 0 !== frame) return frame; + reentry = !0; + frame = Error.prepareStackTrace; + Error.prepareStackTrace = void 0; + var previousDispatcher = null; + previousDispatcher = ReactSharedInternals.H; + ReactSharedInternals.H = null; + disableLogs(); + try { + var RunInRootFrame = { + DetermineComponentFrameRoot: function () { + try { + if (construct) { + var Fake = function () { + throw Error(); + }; + Object.defineProperty(Fake.prototype, "props", { + set: function () { + throw Error(); + } + }); + if ("object" === typeof Reflect && Reflect.construct) { + try { + Reflect.construct(Fake, []); + } catch (x) { + var control = x; + } + Reflect.construct(fn, [], Fake); + } else { + try { + Fake.call(); + } catch (x$0) { + control = x$0; + } + fn.call(Fake.prototype); + } + } else { + try { + throw Error(); + } catch (x$1) { + control = x$1; + } + (Fake = fn()) && + "function" === typeof Fake.catch && + Fake.catch(function () {}); + } + } catch (sample) { + if (sample && control && "string" === typeof sample.stack) + return [sample.stack, control.stack]; + } + return [null, null]; + } + }; + RunInRootFrame.DetermineComponentFrameRoot.displayName = + "DetermineComponentFrameRoot"; + var namePropDescriptor = Object.getOwnPropertyDescriptor( + RunInRootFrame.DetermineComponentFrameRoot, + "name" + ); + namePropDescriptor && + namePropDescriptor.configurable && + Object.defineProperty( + RunInRootFrame.DetermineComponentFrameRoot, + "name", + { value: "DetermineComponentFrameRoot" } + ); + var _RunInRootFrame$Deter = + RunInRootFrame.DetermineComponentFrameRoot(), + sampleStack = _RunInRootFrame$Deter[0], + controlStack = _RunInRootFrame$Deter[1]; + if (sampleStack && controlStack) { + var sampleLines = sampleStack.split("\n"), + controlLines = controlStack.split("\n"); + for ( + _RunInRootFrame$Deter = namePropDescriptor = 0; + namePropDescriptor < sampleLines.length && + !sampleLines[namePropDescriptor].includes( + "DetermineComponentFrameRoot" + ); + + ) + namePropDescriptor++; + for ( + ; + _RunInRootFrame$Deter < controlLines.length && + !controlLines[_RunInRootFrame$Deter].includes( + "DetermineComponentFrameRoot" + ); + + ) + _RunInRootFrame$Deter++; + if ( + namePropDescriptor === sampleLines.length || + _RunInRootFrame$Deter === controlLines.length + ) + for ( + namePropDescriptor = sampleLines.length - 1, + _RunInRootFrame$Deter = controlLines.length - 1; + 1 <= namePropDescriptor && + 0 <= _RunInRootFrame$Deter && + sampleLines[namePropDescriptor] !== + controlLines[_RunInRootFrame$Deter]; + + ) + _RunInRootFrame$Deter--; + for ( + ; + 1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter; + namePropDescriptor--, _RunInRootFrame$Deter-- + ) + if ( + sampleLines[namePropDescriptor] !== + controlLines[_RunInRootFrame$Deter] + ) { + if (1 !== namePropDescriptor || 1 !== _RunInRootFrame$Deter) { + do + if ( + (namePropDescriptor--, + _RunInRootFrame$Deter--, + 0 > _RunInRootFrame$Deter || + sampleLines[namePropDescriptor] !== + controlLines[_RunInRootFrame$Deter]) + ) { + var _frame = + "\n" + + sampleLines[namePropDescriptor].replace( + " at new ", + " at " + ); + fn.displayName && + _frame.includes("") && + (_frame = _frame.replace("", fn.displayName)); + "function" === typeof fn && + componentFrameCache.set(fn, _frame); + return _frame; + } + while (1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter); + } + break; + } + } + } finally { + (reentry = !1), + (ReactSharedInternals.H = previousDispatcher), + reenableLogs(), + (Error.prepareStackTrace = frame); + } + sampleLines = (sampleLines = fn ? fn.displayName || fn.name : "") + ? describeBuiltInComponentFrame(sampleLines) + : ""; + "function" === typeof fn && componentFrameCache.set(fn, sampleLines); + return sampleLines; + } + function formatOwnerStack(error) { + var prevPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = void 0; + error = error.stack; + Error.prepareStackTrace = prevPrepareStackTrace; + error.startsWith("Error: react-stack-top-frame\n") && + (error = error.slice(29)); + prevPrepareStackTrace = error.indexOf("\n"); + -1 !== prevPrepareStackTrace && + (error = error.slice(prevPrepareStackTrace + 1)); + prevPrepareStackTrace = error.indexOf("react-stack-bottom-frame"); + -1 !== prevPrepareStackTrace && + (prevPrepareStackTrace = error.lastIndexOf( + "\n", + prevPrepareStackTrace + )); + if (-1 !== prevPrepareStackTrace) + error = error.slice(0, prevPrepareStackTrace); + else return ""; + return error; + } + function describeFiber(fiber) { + switch (fiber.tag) { + case 26: + case 27: + case 5: + return describeBuiltInComponentFrame(fiber.type); + case 16: + return describeBuiltInComponentFrame("Lazy"); + case 13: + return describeBuiltInComponentFrame("Suspense"); + case 19: + return describeBuiltInComponentFrame("SuspenseList"); + case 0: + case 15: + return describeNativeComponentFrame(fiber.type, !1); + case 11: + return describeNativeComponentFrame(fiber.type.render, !1); + case 1: + return describeNativeComponentFrame(fiber.type, !0); + case 31: + return describeBuiltInComponentFrame("Activity"); + default: + return ""; + } + } + function getStackByFiberInDevAndProd(workInProgress) { + try { + var info = ""; + do { + info += describeFiber(workInProgress); + var debugInfo = workInProgress._debugInfo; + if (debugInfo) + for (var i = debugInfo.length - 1; 0 <= i; i--) { + var entry = debugInfo[i]; + if ("string" === typeof entry.name) { + var JSCompiler_temp_const = info, + env = entry.env; + var JSCompiler_inline_result = describeBuiltInComponentFrame( + entry.name + (env ? " [" + env + "]" : "") + ); + info = JSCompiler_temp_const + JSCompiler_inline_result; + } + } + workInProgress = workInProgress.return; + } while (workInProgress); + return info; + } catch (x) { + return "\nError generating stack: " + x.message + "\n" + x.stack; + } + } + function describeFunctionComponentFrameWithoutLineNumber(fn) { + return (fn = fn ? fn.displayName || fn.name : "") + ? describeBuiltInComponentFrame(fn) + : ""; + } + function getCurrentFiberOwnerNameInDevOrNull() { + if (null === current) return null; + var owner = current._debugOwner; + return null != owner ? getComponentNameFromOwner(owner) : null; + } + function getCurrentFiberStackInDev() { + if (null === current) return ""; + var workInProgress = current; + try { + var info = ""; + 6 === workInProgress.tag && (workInProgress = workInProgress.return); + switch (workInProgress.tag) { + case 26: + case 27: + case 5: + info += describeBuiltInComponentFrame(workInProgress.type); + break; + case 13: + info += describeBuiltInComponentFrame("Suspense"); + break; + case 19: + info += describeBuiltInComponentFrame("SuspenseList"); + break; + case 31: + info += describeBuiltInComponentFrame("Activity"); + break; + case 30: + case 0: + case 15: + case 1: + workInProgress._debugOwner || + "" !== info || + (info += describeFunctionComponentFrameWithoutLineNumber( + workInProgress.type + )); + break; + case 11: + workInProgress._debugOwner || + "" !== info || + (info += describeFunctionComponentFrameWithoutLineNumber( + workInProgress.type.render + )); + } + for (; workInProgress; ) + if ("number" === typeof workInProgress.tag) { + var fiber = workInProgress; + workInProgress = fiber._debugOwner; + var debugStack = fiber._debugStack; + workInProgress && + debugStack && + ("string" !== typeof debugStack && + (fiber._debugStack = debugStack = formatOwnerStack(debugStack)), + "" !== debugStack && (info += "\n" + debugStack)); + } else if (null != workInProgress.debugStack) { + var ownerStack = workInProgress.debugStack; + (workInProgress = workInProgress.owner) && + ownerStack && + (info += "\n" + formatOwnerStack(ownerStack)); + } else break; + var JSCompiler_inline_result = info; + } catch (x) { + JSCompiler_inline_result = + "\nError generating stack: " + x.message + "\n" + x.stack; + } + return JSCompiler_inline_result; + } + function runWithFiberInDEV(fiber, callback, arg0, arg1, arg2, arg3, arg4) { + var previousFiber = current; + setCurrentFiber(fiber); + try { + return null !== fiber && fiber._debugTask + ? fiber._debugTask.run( + callback.bind(null, arg0, arg1, arg2, arg3, arg4) + ) + : callback(arg0, arg1, arg2, arg3, arg4); + } finally { + setCurrentFiber(previousFiber); + } + throw Error( + "runWithFiberInDEV should never be called in production. This is a bug in React." + ); + } + function setCurrentFiber(fiber) { + ReactSharedInternals.getCurrentStack = + null === fiber ? null : getCurrentFiberStackInDev; + isRendering = !1; + current = fiber; + } + function getToStringValue(value) { + switch (typeof value) { + case "bigint": + case "boolean": + case "number": + case "string": + case "undefined": + return value; + case "object": + return checkFormFieldValueStringCoercion(value), value; + default: + return ""; + } + } + function isCheckable(elem) { + var type = elem.type; + return ( + (elem = elem.nodeName) && + "input" === elem.toLowerCase() && + ("checkbox" === type || "radio" === type) + ); + } + function trackValueOnNode(node) { + var valueField = isCheckable(node) ? "checked" : "value", + descriptor = Object.getOwnPropertyDescriptor( + node.constructor.prototype, + valueField + ); + checkFormFieldValueStringCoercion(node[valueField]); + var currentValue = "" + node[valueField]; + if ( + !node.hasOwnProperty(valueField) && + "undefined" !== typeof descriptor && + "function" === typeof descriptor.get && + "function" === typeof descriptor.set + ) { + var get = descriptor.get, + set = descriptor.set; + Object.defineProperty(node, valueField, { + configurable: !0, + get: function () { + return get.call(this); + }, + set: function (value) { + checkFormFieldValueStringCoercion(value); + currentValue = "" + value; + set.call(this, value); + } + }); + Object.defineProperty(node, valueField, { + enumerable: descriptor.enumerable + }); + return { + getValue: function () { + return currentValue; + }, + setValue: function (value) { + checkFormFieldValueStringCoercion(value); + currentValue = "" + value; + }, + stopTracking: function () { + node._valueTracker = null; + delete node[valueField]; + } + }; + } + } + function track(node) { + node._valueTracker || (node._valueTracker = trackValueOnNode(node)); + } + function updateValueIfChanged(node) { + if (!node) return !1; + var tracker = node._valueTracker; + if (!tracker) return !0; + var lastValue = tracker.getValue(); + var value = ""; + node && + (value = isCheckable(node) + ? node.checked + ? "true" + : "false" + : node.value); + node = value; + return node !== lastValue ? (tracker.setValue(node), !0) : !1; + } + function getActiveElement(doc) { + doc = doc || ("undefined" !== typeof document ? document : void 0); + if ("undefined" === typeof doc) return null; + try { + return doc.activeElement || doc.body; + } catch (e) { + return doc.body; + } + } + function escapeSelectorAttributeValueInsideDoubleQuotes(value) { + return value.replace( + escapeSelectorAttributeValueInsideDoubleQuotesRegex, + function (ch) { + return "\\" + ch.charCodeAt(0).toString(16) + " "; + } + ); + } + function validateInputProps(element, props) { + void 0 === props.checked || + void 0 === props.defaultChecked || + didWarnCheckedDefaultChecked || + (console.error( + "%s contains an input of type %s with both checked and defaultChecked props. Input elements must be either controlled or uncontrolled (specify either the checked prop, or the defaultChecked prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://react.dev/link/controlled-components", + getCurrentFiberOwnerNameInDevOrNull() || "A component", + props.type + ), + (didWarnCheckedDefaultChecked = !0)); + void 0 === props.value || + void 0 === props.defaultValue || + didWarnValueDefaultValue$1 || + (console.error( + "%s contains an input of type %s with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://react.dev/link/controlled-components", + getCurrentFiberOwnerNameInDevOrNull() || "A component", + props.type + ), + (didWarnValueDefaultValue$1 = !0)); + } + function updateInput( + element, + value, + defaultValue, + lastDefaultValue, + checked, + defaultChecked, + type, + name + ) { + element.name = ""; + null != type && + "function" !== typeof type && + "symbol" !== typeof type && + "boolean" !== typeof type + ? (checkAttributeStringCoercion(type, "type"), (element.type = type)) + : element.removeAttribute("type"); + if (null != value) + if ("number" === type) { + if ((0 === value && "" === element.value) || element.value != value) + element.value = "" + getToStringValue(value); + } else + element.value !== "" + getToStringValue(value) && + (element.value = "" + getToStringValue(value)); + else + ("submit" !== type && "reset" !== type) || + element.removeAttribute("value"); + null != value + ? setDefaultValue(element, type, getToStringValue(value)) + : null != defaultValue + ? setDefaultValue(element, type, getToStringValue(defaultValue)) + : null != lastDefaultValue && element.removeAttribute("value"); + null == checked && + null != defaultChecked && + (element.defaultChecked = !!defaultChecked); + null != checked && + (element.checked = + checked && + "function" !== typeof checked && + "symbol" !== typeof checked); + null != name && + "function" !== typeof name && + "symbol" !== typeof name && + "boolean" !== typeof name + ? (checkAttributeStringCoercion(name, "name"), + (element.name = "" + getToStringValue(name))) + : element.removeAttribute("name"); + } + function initInput( + element, + value, + defaultValue, + checked, + defaultChecked, + type, + name, + isHydrating + ) { + null != type && + "function" !== typeof type && + "symbol" !== typeof type && + "boolean" !== typeof type && + (checkAttributeStringCoercion(type, "type"), (element.type = type)); + if (null != value || null != defaultValue) { + if ( + !( + ("submit" !== type && "reset" !== type) || + (void 0 !== value && null !== value) + ) + ) + return; + defaultValue = + null != defaultValue ? "" + getToStringValue(defaultValue) : ""; + value = null != value ? "" + getToStringValue(value) : defaultValue; + isHydrating || value === element.value || (element.value = value); + element.defaultValue = value; + } + checked = null != checked ? checked : defaultChecked; + checked = + "function" !== typeof checked && + "symbol" !== typeof checked && + !!checked; + element.checked = isHydrating ? element.checked : !!checked; + element.defaultChecked = !!checked; + null != name && + "function" !== typeof name && + "symbol" !== typeof name && + "boolean" !== typeof name && + (checkAttributeStringCoercion(name, "name"), (element.name = name)); + } + function setDefaultValue(node, type, value) { + ("number" === type && getActiveElement(node.ownerDocument) === node) || + node.defaultValue === "" + value || + (node.defaultValue = "" + value); + } + function validateOptionProps(element, props) { + null == props.value && + ("object" === typeof props.children && null !== props.children + ? React.Children.forEach(props.children, function (child) { + null == child || + "string" === typeof child || + "number" === typeof child || + "bigint" === typeof child || + didWarnInvalidChild || + ((didWarnInvalidChild = !0), + console.error( + "Cannot infer the option value of complex children. Pass a `value` prop or use a plain string as children to