diff --git a/api/package-lock.json b/api/package-lock.json index 1a7189d..f135748 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -15,6 +15,7 @@ "@modelcontextprotocol/sdk": "^1.17.2", "@peace/node_server": "^2.0.1", "cheerio": "^1.0.0", + "dotenv": "^17.4.2", "html-docx-js": "^0.3.1", "iconv-lite": "^0.6.3", "image-size": "^2.0.2", @@ -1614,6 +1615,18 @@ "tslib": "^2.0.3" } }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dottie": { "version": "2.0.6", "resolved": "https://nexus.ngaiot.com/repository/fs-npm/dottie/-/dottie-2.0.6.tgz", diff --git a/web/client/src/sections/aichat/router.js b/web/client/src/sections/aichat/router.js index 066e76f..20a461b 100644 --- a/web/client/src/sections/aichat/router.js +++ b/web/client/src/sections/aichat/router.js @@ -4,7 +4,7 @@ export default { type: 'outer', route: { key: 'aichat', - path: "/aichat", + path: "/aichatv1", component: AiChat } }; diff --git a/web/client/src/sections/superAgent/actions/api.js b/web/client/src/sections/superAgent/actions/api.js index 7ef7061..90a4e8e 100644 --- a/web/client/src/sections/superAgent/actions/api.js +++ b/web/client/src/sections/superAgent/actions/api.js @@ -1,7 +1,7 @@ /** * 文件作用:superAgent 超级智能体模块文件 * 职责范围: - * 1. 承载 superAgent 业务 session、workspace、附件以及保留的旧聊天能力 + * 1. 承载 superAgent 业务 session、workspace 和附件能力 * 2. 在不影响 newAiChat 的前提下复用现有组件和接口 * 3. 支撑标书任务工作区的前端编排 * @@ -11,7 +11,7 @@ * - 封装 v2 useStream 协议;新版流由 useSuperAgentStream 直接交给 SDK 管理 * * 维护说明: - * - sendChat、checkpoint 和旧 history action 为回滚能力,不得由新版容器调用 + * - 不负责消息流、thread 快照或 interrupt 恢复,这些能力统一由 useStream 管理 */ "use strict"; @@ -84,18 +84,6 @@ export const createSuperAgentSession = (options = {}) => async () => { return { payload: { data } }; }; -export const getSuperAgentSessionHistory = createDirectJsonAction({ - method: "GET", - path: superAgentServiceApiTable.sessionHistory, - fallbackMessage: "获取超级智能体历史消息失败", -}); - -export const getSuperAgentSessionState = createDirectJsonAction({ - method: "GET", - path: superAgentServiceApiTable.sessionState, - fallbackMessage: "获取超级智能体会话状态失败", -}); - export const getSuperAgentSessionSections = createDirectJsonAction({ method: "GET", path: superAgentServiceApiTable.sessionSections, diff --git a/web/client/src/sections/superAgent/components/SuperAgentConversation.jsx b/web/client/src/sections/superAgent/components/SuperAgentConversation.jsx index bda90e4..6155553 100644 --- a/web/client/src/sections/superAgent/components/SuperAgentConversation.jsx +++ b/web/client/src/sections/superAgent/components/SuperAgentConversation.jsx @@ -213,6 +213,7 @@ const SuperAgentConversation = ({ chatWelcomeContent, taskWelcomeTitle, taskWelcomeContent, + isWaitingForInterrupt = false, agentCategory, setAgentCategory, agentKeyword, @@ -535,12 +536,22 @@ const SuperAgentConversation = ({ const checkpoint = normalizeCheckpoint(item); const progressTask = latestProgressTask || item.task; - if (isBodyProgressCheckpoint(item, progressTask)) return null; - if (isStaleCatalogCheckpoint(item, progressTask)) return null; + //[LangGraph interrupt 的 suspended 是等待输入,不应在确认卡上显示为已暂停] + const checkpointProgressTask = + isWaitingForInterrupt && + String(progressTask?.status || "").toLowerCase() === "suspended" + ? { + ...progressTask, + status: "waiting_interrupt", + session_status: "waiting_interrupt", + } + : progressTask; + if (isBodyProgressCheckpoint(item, checkpointProgressTask)) return null; + if (isStaleCatalogCheckpoint(item, checkpointProgressTask)) return null; return ( handleCheckpointAction(item, action)} /> @@ -629,7 +640,8 @@ const SuperAgentConversation = ({ (Array.isArray(item.runLog?.entries) && item.runLog.entries.some((entry) => entry?.status === "running")); const shouldShowActiveLoading = - !hasStructuredCard && (showLoadingIndicator || hasRunningTool); + !hasStructuredCard && + (showLoadingIndicator || (isStreamingAnswer && hasRunningTool)); const shouldShowLoading = !hasStructuredCard && !item.content && @@ -686,9 +698,20 @@ const SuperAgentConversation = ({ const renderConversationMessages = () => { const messageNodeList = []; const displayConversationMessages = mergeDisplayConversationMessages(conversationMessages); - const latestAssistantIndex = [...displayConversationMessages] - .map((item) => item.role) - .lastIndexOf("assistant"); + const latestAssistantIndex = displayConversationMessages.reduce( + (latestIndex, item, index) => { + const isRenderableAssistantMessage = + item.role === "assistant" && + !["taskProgress", "checkpoint", "content"].includes(item.type); + return isRenderableAssistantMessage ? index : latestIndex; + }, + -1 + ); + const lastConversationMessage = + displayConversationMessages[displayConversationMessages.length - 1]; + const hasTrailingLoadingMessage = + isStreamingAnswer && + (lastConversationMessage?.role === "user" || latestAssistantIndex < 0); let messageIndex = 0; while (messageIndex < displayConversationMessages.length) { @@ -701,12 +724,27 @@ const SuperAgentConversation = ({ messageNodeList.push( renderSingleConversationMessage(currentMessage, { showLoadingIndicator: - isStreamingAnswer && messageIndex === latestAssistantIndex, + isStreamingAnswer && + !hasTrailingLoadingMessage && + messageIndex === latestAssistantIndex, }) ); messageIndex += 1; } + if (hasTrailingLoadingMessage) { + messageNodeList.push( + renderSingleConversationMessage( + { + key: "stream-loading-placeholder", + role: "assistant", + content: "", + }, + { showLoadingIndicator: true } + ) + ); + } + return messageNodeList; }; diff --git a/web/client/src/sections/superAgent/components/TaskProgressCard.jsx b/web/client/src/sections/superAgent/components/TaskProgressCard.jsx index a8fef6b..6ec1f3c 100644 --- a/web/client/src/sections/superAgent/components/TaskProgressCard.jsx +++ b/web/client/src/sections/superAgent/components/TaskProgressCard.jsx @@ -18,6 +18,7 @@ import React from "react"; import { Button } from "antd"; import { CheckCircleOutlined, + CloseCircleOutlined, DownloadOutlined, FileWordOutlined, LoadingOutlined, @@ -61,7 +62,7 @@ const TaskProgressCard = ({ item = {}, onOpenWorkspace, onDownloadFile }) => { ? "已生成" : "正在生成"; const statusIcon = isFailed - ? null + ? : isSuspended ? : isCompleted @@ -96,7 +97,7 @@ const TaskProgressCard = ({ item = {}, onOpenWorkspace, onDownloadFile }) => {
{fileName}
-
+
{statusIcon} {statusText}
diff --git a/web/client/src/sections/superAgent/constants.js b/web/client/src/sections/superAgent/constants.js index 47c27ba..82193ea 100644 --- a/web/client/src/sections/superAgent/constants.js +++ b/web/client/src/sections/superAgent/constants.js @@ -192,7 +192,7 @@ export const quickTaskList = [ key: "legal", title: "法务评估", desc: "归集项目和材料,生成评估报告和起诉状。", - enabled: true, + enabled: false, icon: KnowledgeIcon, }, { diff --git a/web/client/src/sections/superAgent/container/index.jsx b/web/client/src/sections/superAgent/container/index.jsx index a3a31b1..46b78d1 100644 --- a/web/client/src/sections/superAgent/container/index.jsx +++ b/web/client/src/sections/superAgent/container/index.jsx @@ -34,8 +34,6 @@ import useSuperAgentProfile from "../hooks/useSuperAgentProfile"; import useSuperAgentWorkspace from "../hooks/useSuperAgentWorkspace"; import { cancelSuperAgentSession, - getSuperAgentSessionSections, - getSuperAgentSessionState, } from "../actions/api"; import { getCompatibleAuthUserInfo } from "../../../utils/authCompat"; import { @@ -73,34 +71,8 @@ import { } from "../utils/debugLog"; import "./index.less"; -const getActionData = (res) => { - const payload = res?.payload ?? res; - return payload?.data ?? payload; -}; - -const ensureActionSuccess = (res, fallbackMessage) => { - const payload = res?.payload ?? res; - if (payload?.success === false) { - throw new Error(payload?.message || payload?.error || fallbackMessage); - } - return getActionData(res); -}; - -const buildSessionParams = (sessionId) => ({ - sessionId, - ":sessionId": sessionId, -}); - const MOBILE_LAYOUT_BREAKPOINT = 768; -const getSessionSectionList = (sectionPayload) => { - const sectionData = sectionPayload?.data || sectionPayload || {}; - if (Array.isArray(sectionData)) return sectionData; - if (Array.isArray(sectionData.sections)) return sectionData.sections; - if (Array.isArray(sectionData.chapters)) return sectionData.chapters; - return []; -}; - const COMPLETED_SECTION_STATUSES = new Set([ "done", "completed", @@ -231,19 +203,6 @@ const TERMINAL_SESSION_STATUSES = new Set([ "suspended", ]); -const isCompletedSessionWithWritingTask = (sessionStatus, task = {}) => - String(sessionStatus || "").toLowerCase() === "completed" && - String(task?.status || "").toLowerCase() === "writing"; - -const getSessionRuntimeStatus = (sessionState = {}) => { - const status = - sessionState.status || - sessionState.task?.status || - sessionState.task_status || - ""; - return String(status || "").trim().toLowerCase(); -}; - const getCheckpointId = (checkpoint = {}) => String( checkpoint?.checkpoint_id || @@ -304,8 +263,6 @@ const SuperAgent = () => { const [collapsed, setCollapsed] = useState(false); const [workspaceOpen, setWorkspaceOpen] = useState(false); const [restoredSessionTask, setRestoredSessionTask] = useState(null); - const [restoredSessionRuntimeStatus, setRestoredSessionRuntimeStatus] = useState(""); - const [restoredSessionInterrupts, setRestoredSessionInterrupts] = useState([]); const [workspaceWidth, setWorkspaceWidth] = useState(null); const [activeAgentApp, setActiveAgentApp] = useState(null); const [isMobileLayout, setIsMobileLayout] = useState(false); @@ -322,7 +279,6 @@ const SuperAgent = () => { const checkpointSubmittingIdsRef = useRef(new Set()); const completedSectionIdsRef = useRef(new Set()); const latestProgressTaskRef = useRef(null); - const bodyTaskSnapshotRef = useRef(null); const activeSessionRestoredRef = useRef(false); const transientPublishUiIdsRef = useRef(new Set()); const publishUiBaselineIdsRef = useRef(new Set()); @@ -518,7 +474,6 @@ const SuperAgent = () => { updateActiveTask, updateConversationMessage, removeConversationMessage, - refreshSessionHistoryMessages, createAndActivateSession, handleCreateNewChat, handleCreateNewTask, @@ -543,10 +498,7 @@ const SuperAgent = () => { activeSessionIdRef.current = String(activeSessionId || ""); completedSectionIdsRef.current.clear(); latestProgressTaskRef.current = null; - bodyTaskSnapshotRef.current = null; setRestoredSessionTask(null); - setRestoredSessionRuntimeStatus(""); - setRestoredSessionInterrupts([]); setDismissedGeneratedInterruptIds(new Set()); setHiddenCheckpointIds(new Set()); }, [activeSessionId]); @@ -608,11 +560,11 @@ const SuperAgent = () => { const hasTerminalSessionStatus = TERMINAL_SESSION_STATUSES.has(sessionStatus); const normalizedProgressData = { ...progressData, + session_id: sessionId, session_status: payload.session_status || payload.sessionStatus || progressData.session_status || - restoredSessionRuntimeStatus || "", ...(hasTerminalSessionStatus ? { status: sessionStatus } : {}), progress: Number.isFinite(rawProgress) ? Math.round(rawProgress) : 0, @@ -636,7 +588,6 @@ const SuperAgent = () => { }); syncSessionProgressSections({ sessionId, progressData: normalizedProgressData }); }, [ - restoredSessionRuntimeStatus, syncSessionProgressSections, updateActiveTask, upsertAssistantMessage, @@ -651,6 +602,9 @@ const SuperAgent = () => { const eventType = String(payload.type || ""); const sessionId = payload.task_id || payload.taskId || activeSessionId; if (!sessionId || sessionId !== activeSessionId) return; + const canRefreshCurrentWorkspace = + workspaceOpen && + String(workspaceData?.sessionId || "") === String(sessionId || ""); const isGenerationProgress = [ "generation.started", "generation.progress", @@ -726,16 +680,13 @@ const SuperAgent = () => { calculatedProgress, Number(previousTask.progress || 0) ); - const status = - eventType === "section.failed" - ? "failed" - : isSectionProgress - ? previousTask.status || "running" - : rawTask.status || payload.status || previousTask.status || "running"; + const status = eventType === "section.failed" ? "failed" : "running"; const progressData = { ...payload, ...rawTask, + session_id: sessionId, task_type: rawTask.task_type || rawTask.taskType || payload.task_type || previousTask.task_type || "artifact_build", + session_status: "running", status, progress, done, @@ -751,9 +702,9 @@ const SuperAgent = () => { payload.sectionTitle || "", section_status: isSectionCompleted ? "completed" : rawSection.status || "", - }; + }; commitProgressTask(sessionId, progressData, payload); - if (payload.refresh_required) { + if (payload.refresh_required && canRefreshCurrentWorkspace) { const refreshedSections = await refreshSessionContentWorkspace({ sessionId, silent: true, @@ -771,28 +722,31 @@ const SuperAgent = () => { } } if (eventType === "workspace.updated" || eventType === "sections.rewrite.requested") { - const refreshedSections = await refreshSessionContentWorkspace({ + const previousTask = latestProgressTaskRef.current || {}; + commitProgressTask( sessionId, - silent: true, - }); - if (Array.isArray(refreshedSections)) { + buildContentProgressTask({ + previousTask, + payload, + }) + ); + if (!canRefreshCurrentWorkspace) return; + window.setTimeout(async () => { + const refreshedSections = await refreshSessionContentWorkspace({ + sessionId, + silent: true, + }); + if (Array.isArray(refreshedSections)) { commitProgressTask( sessionId, buildContentProgressTask({ - sectionList: refreshedSections, - previousTask: latestProgressTaskRef.current || {}, - payload, - }) - ); - } else if (eventType === "sections.rewrite.requested") { - commitProgressTask( - sessionId, - buildContentProgressTask({ - previousTask: latestProgressTaskRef.current || {}, - payload, - }) - ); - } + sectionList: refreshedSections, + previousTask: latestProgressTaskRef.current || previousTask, + payload, + }) + ); + } + }, 0); } if ([ "generation.completed", @@ -800,25 +754,41 @@ const SuperAgent = () => { "generation.cancelled", "generation.error", ].includes(eventType)) { - const refreshedSections = - eventType === "generation.completed" - ? await refreshSessionContentWorkspace({ sessionId, silent: true }) - : []; commitProgressTask( sessionId, buildContentProgressTask({ - sectionList: refreshedSections, previousTask: latestProgressTaskRef.current || {}, payload, statusOverride: eventType === "generation.completed" ? "completed" : "failed", }) ); + if (eventType === "generation.completed" && canRefreshCurrentWorkspace) { + window.setTimeout(async () => { + const refreshedSections = await refreshSessionContentWorkspace({ + sessionId, + silent: true, + }); + if (Array.isArray(refreshedSections)) { + commitProgressTask( + sessionId, + buildContentProgressTask({ + sectionList: refreshedSections, + previousTask: latestProgressTaskRef.current || {}, + payload, + statusOverride: "completed", + }) + ); + } + }, 0); + } } if (eventType === "section.failed") message.warning(payload.message || "章节生成失败"); }, [ activeSessionId, commitProgressTask, refreshSessionContentWorkspace, + workspaceData?.sessionId, + workspaceOpen, ]); const handleProtocolError = useCallback((error) => { @@ -832,47 +802,107 @@ const SuperAgent = () => { onStreamError: handleProtocolError, }); - const prepareForSessionSwitch = () => { - stream.prepareForSessionSwitch(); + const prepareForSessionSwitch = async () => { + await stream.prepareForSessionSwitch(); }; const hasActiveSession = Boolean(activeSessionId); const streamMatchesActiveSession = hasActiveSession && String(stream.threadId || "") === String(activeSessionId || ""); - //[正文任务状态可能同时来自 state、stream 和业务事件,按当前会话合并] + const streamReadyForActiveSession = + streamMatchesActiveSession && + (stream.isThreadReady || stream.isThreadProjectionReady); + // useStream 切换 threadId 时会先更新 thread,再异步替换快照;快照中的 task 仍可能属于上一会话。 + // 任务卡只能消费 task 自带的会话 ID 与当前会话一致的状态。 + const rawActiveStreamTask = streamReadyForActiveSession ? stream.task : null; + const rawActiveStreamTaskId = String( + rawActiveStreamTask?.task_id || + rawActiveStreamTask?.taskId || + rawActiveStreamTask?.session_id || + rawActiveStreamTask?.sessionId || + "" + ); + const activeStreamTask = + rawActiveStreamTask && + (!rawActiveStreamTaskId || rawActiveStreamTaskId === String(activeSessionId || "")) + ? rawActiveStreamTask + : null; + const activeStreamInterrupts = streamReadyForActiveSession ? stream.interrupts || [] : []; + const activeStreamCheckpointDeliveries = streamReadyForActiveSession + ? stream.checkpointDeliveries || [] + : []; + //[interrupt 等待期间后端可能把 task.status 标记为 suspended,不能直接当作用户停止] + const hasPendingInterruptSignal = + activeStreamInterrupts.length > 0 || + Boolean(String(stream.currentInterruptId || "").trim()) || + stream.isWaitingForInterrupt === true || + ["awaiting_interrupt", "waiting_interrupt"].includes( + String(stream.runPhase || "").toLowerCase() + ); + const restoredTaskSessionId = String( + restoredSessionTask?.session_id || + restoredSessionTask?.sessionId || + restoredSessionTask?.task_id || + restoredSessionTask?.taskId || + "" + ); + const activeRestoredSessionTask = + restoredTaskSessionId === String(activeSessionId || "") + ? restoredSessionTask + : null; + //[正文任务状态只来自当前 useStream thread 和其业务事件] const runtimeTaskSources = { - ...(activeTask || {}), - ...(workspaceData?.task || {}), - ...(restoredSessionTask || {}), - ...(stream.task || {}), + ...(activeRestoredSessionTask || {}), + ...(activeStreamTask || {}), }; const runtimeTaskSourceType = String( runtimeTaskSources?.task_type || runtimeTaskSources?.taskType || "" ).toLowerCase(); - const runtimeTaskSourceStatus = String( - runtimeTaskSources?.status || "" - ).toLowerCase(); - const runtimeTaskSourceTotal = Number(runtimeTaskSources?.total || 0); - const hasRuntimeBodyTaskSource = - runtimeTaskSourceType === "artifact_build" || runtimeTaskSourceTotal > 0; - const shouldUseBodyTaskSnapshot = - !hasRuntimeBodyTaskSource && bodyTaskSnapshotRef.current; - const runtimeTask = shouldUseBodyTaskSnapshot - ? { - ...runtimeTaskSources, - ...bodyTaskSnapshotRef.current, - } - : runtimeTaskSources; + const runtimeTask = runtimeTaskSources; const taskStatus = String(runtimeTask?.status || "").toLowerCase(); const runtimeSessionStatus = String( - restoredSessionRuntimeStatus || runtimeTask.session_status || runtimeTask.sessionStatus || "" ).toLowerCase(); - const runtimeTaskType = String( - runtimeTask?.task_type || runtimeTask?.taskType || "" - ).toLowerCase(); - const runtimeTaskTotal = Number(runtimeTask?.total || 0); + const runtimeTaskType = String( + runtimeTask?.task_type || runtimeTask?.taskType || "" + ).toLowerCase(); + const runtimeTaskTotal = Number(runtimeTask?.total || 0); + const hasPersistedActiveThread = + streamReadyForActiveSession && stream.isPersistedThreadActive === true; + const hasRuntimeExecutionSignal = + !hasPendingInterruptSignal && + ( + stream.isBusinessRunning || + stream.isLocalRunActive || + ["running", "resuming"].includes(String(stream.runPhase || "").toLowerCase()) + ); + const displayTaskStatus = + hasRuntimeExecutionSignal && taskStatus === "suspended" + ? "running" + : taskStatus; + const displayRuntimeSessionStatus = + hasRuntimeExecutionSignal && runtimeSessionStatus === "suspended" + ? "running" + : runtimeSessionStatus; + const hasSuspendedRuntimeStatus = + displayTaskStatus === "suspended" || displayRuntimeSessionStatus === "suspended"; + const displayActiveStreamTask = activeStreamTask + ? { + ...activeStreamTask, + status: displayTaskStatus || activeStreamTask.status, + session_status: + displayRuntimeSessionStatus || + activeStreamTask.session_status || + activeStreamTask.sessionStatus || + "", + } + : activeStreamTask; + const isSuspendedByInterrupt = + hasPendingInterruptSignal && + (taskStatus === "suspended" || runtimeSessionStatus === "suspended"); + const hasPersistedRunningThread = + hasPersistedActiveThread && !hasSuspendedRuntimeStatus; const isTerminalRuntimeSession = [ "failed", "completed", @@ -880,22 +910,34 @@ const SuperAgent = () => { "canceled", "stopped", "suspended", - ].includes(runtimeSessionStatus); + ].includes(displayRuntimeSessionStatus) && !isSuspendedByInterrupt; const runtimeBodyTaskShape = runtimeTaskType === "artifact_build" || (taskStage === TASK_STAGE.CONTENT && runtimeTaskTotal > 0); const isBodyGenerationRuntimeActive = runtimeBodyTaskShape && - taskStatus === "writing" && - (runtimeSessionStatus - ? runtimeSessionStatus === "running" + [ + "queued", + "starting", + "started", + "running", + "pending", + "processing", + "generating", + "writing", + "active", + "streaming", + "resuming", + "awaiting_interrupt", + ].includes(displayTaskStatus) && + (displayRuntimeSessionStatus + ? displayRuntimeSessionStatus === "running" : ["running", "resuming"].includes(stream.runPhase)); - if (isBodyGenerationRuntimeActive) { - bodyTaskSnapshotRef.current = runtimeTask; - } const isFailedTask = - ["failed", "error"].includes(taskStatus) || stream.runPhase === "failed"; - const isTerminalTask = !isBodyGenerationRuntimeActive && [ + ["failed", "error"].includes(displayTaskStatus) || + ["failed", "error"].includes(displayRuntimeSessionStatus) || + (stream.runPhase === "failed" && !hasPendingInterruptSignal); + const hasTerminalTaskStatus = [ "completed", "done", "success", @@ -905,9 +947,12 @@ const SuperAgent = () => { "canceled", "stopped", "suspended", - ].includes(taskStatus) || + ].includes(displayTaskStatus) && !isSuspendedByInterrupt; + const isTerminalTask = + (hasSuspendedRuntimeStatus && !isSuspendedByInterrupt) || + (!hasPersistedActiveThread && !isBodyGenerationRuntimeActive && hasTerminalTaskStatus) || isTerminalRuntimeSession || - ["failed", "completed"].includes(stream.runPhase); + (["failed", "completed"].includes(stream.runPhase) && !hasPendingInterruptSignal); const hasRunningTaskStatus = [ "queued", "starting", @@ -921,7 +966,7 @@ const SuperAgent = () => { "streaming", "resuming", "awaiting_interrupt", - ].includes(taskStatus) || + ].includes(displayTaskStatus) || [ "queued", "starting", @@ -935,23 +980,27 @@ const SuperAgent = () => { "streaming", "resuming", "awaiting_interrupt", - ].includes(runtimeSessionStatus); + ].includes(displayRuntimeSessionStatus); const hasActiveToolCall = stream.toolCalls.some(isActiveToolCall); const hasActiveToolCallSignal = !isTerminalTask && hasActiveToolCall; const hasStreamExecutionSignal = - stream.isLoading || - (streamMatchesActiveSession && hasRunningTaskStatus) || - (streamMatchesActiveSession && hasActiveToolCallSignal); + streamReadyForActiveSession && + (stream.isLoading || + hasRunningTaskStatus || + hasActiveToolCallSignal); + // 本次发送后的本地 runPhase 优先于快照中的终态;终态只代表发送前的历史状态。 const hasActiveStreamRunPhase = - !isTerminalTask && - ["running", "awaiting_interrupt", "resuming"].includes(stream.runPhase); + hasActiveSession && + ["running", "awaiting_interrupt", "resuming"].includes(stream.runPhase) && + (!isTerminalTask || stream.isLocalRunActive); const isStreamRunning = + hasPersistedRunningThread || isBodyGenerationRuntimeActive || hasActiveStreamRunPhase || (hasStreamExecutionSignal && (!isTerminalTask || hasRunningTaskStatus || hasActiveToolCallSignal)); const projectedStreamMessages = stream.messages; - const streamConversationMessages = streamMatchesActiveSession + const streamConversationMessages = streamReadyForActiveSession ? buildStreamConversationMessages( projectedStreamMessages, stream.toolCalls, @@ -1006,7 +1055,7 @@ const SuperAgent = () => { ); hiddenCheckpointIds.forEach((checkpointId) => terminalCheckpointIds.add(checkpointId)); const bodyTask = runtimeTask; - const bodyTaskStatus = String(bodyTask.status || "").toLowerCase(); + const bodyTaskStatus = displayTaskStatus || String(bodyTask.status || "").toLowerCase(); const bodyTaskType = String(bodyTask.task_type || bodyTask.taskType || "").toLowerCase(); const hasBodyTaskShape = bodyTaskType === "artifact_build" || @@ -1014,13 +1063,23 @@ const SuperAgent = () => { const isBodyGenerationActive = isBodyGenerationRuntimeActive && hasBodyTaskShape && - bodyTaskStatus === "writing"; + ![ + "completed", + "done", + "success", + "failed", + "error", + "cancelled", + "canceled", + "stopped", + "suspended", + ].includes(bodyTaskStatus); const isSessionWaitingForInput = - WAITING_USER_SESSION_STATUSES.has(restoredSessionRuntimeStatus) || - stream.runPhase === "waiting_interrupt"; + WAITING_USER_SESSION_STATUSES.has(displayRuntimeSessionStatus) || + hasPendingInterruptSignal; const canHideHistoricalGeneratedInterrupt = isBodyGenerationActive && - Boolean(restoredSessionRuntimeStatus) && + Boolean(runtimeSessionStatus) && !isSessionWaitingForInput; const shouldHideCheckpointMessage = (item) => { if (isTerminalCheckpointMessage(item, terminalCheckpointIds)) return true; @@ -1040,7 +1099,7 @@ const SuperAgent = () => { ); }; const generatedInterruptCandidates = new Map(); - [...(stream.interrupts || []), ...restoredSessionInterrupts].forEach((item) => { + activeStreamInterrupts.forEach((item) => { const payload = item?.value || item?.payload || {}; const interruptId = String(item?.id || ""); if ( @@ -1064,31 +1123,31 @@ const SuperAgent = () => { }); const activeGeneratedInterruptCandidates = [...generatedInterruptCandidates.values()]; const currentInterruptId = String(stream.currentInterruptId || ""); - const activeGeneratedInterrupt = streamMatchesActiveSession + const activeGeneratedInterrupt = streamReadyForActiveSession ? activeGeneratedInterruptCandidates.find( (item) => String(item?.id || "") === currentInterruptId ) || activeGeneratedInterruptCandidates[activeGeneratedInterruptCandidates.length - 1] || null : null; - const visibleStreamMessages = streamMessagesWithFiles.filter( - (item) => !shouldHideCheckpointMessage(item) - ); - const localHistoryMessages = Array.isArray(localConversationMessages) - ? localConversationMessages.filter( - (item) => - item?.sessionId && - String(item.sessionId) === String(activeSessionId || "") && - item.type !== "taskProgress" && - item.type !== "content" && - !shouldHideCheckpointMessage(item) - ) - : []; - const streamMessageKeys = new Set( - visibleStreamMessages.map((item) => String(item?.key || item?.id || "")) - ); - const unmatchedLocalHistoryMessages = localHistoryMessages.filter( - (item) => !streamMessageKeys.has(String(item?.key || item?.id || "")) - ); - const isStreamingAnswer = !activeGeneratedInterrupt && isStreamRunning; + const visibleStreamMessages = streamMessagesWithFiles.filter( + (item) => !shouldHideCheckpointMessage(item) + ); + const uploadedUserMessages = [ + ...localUserFileMessages, + ...visibleStreamMessages, + ]; + const latestUploadedFile = uploadedUserMessages + .reverse() + .find( + (item) => + item.role === "user" && + (item.files?.length || item.fileName || item.file_name) + ); + const latestUploadedFileName = + latestUploadedFile?.files?.[0]?.name || + latestUploadedFile?.fileName || + latestUploadedFile?.file_name || + ""; + const isStreamingAnswer = !activeGeneratedInterrupt && isStreamRunning; const contentWorkspaceMessage = workspaceData?.type === "content" && String(workspaceData.sessionId || "") === String(activeSessionId || "") @@ -1107,7 +1166,7 @@ const SuperAgent = () => { } : null; const inlineCheckpointMessages = isTaskRoute - ? (stream.interrupts || []) + ? activeStreamInterrupts .filter((item) => !shouldHideCheckpointMessage(item)) .map((item) => { const payload = item?.value || item?.payload || {}; @@ -1126,13 +1185,13 @@ const SuperAgent = () => { interruptId: item.id, namespace: item.namespace, sessionId: activeSessionId, - task: stream.task, + task: displayActiveStreamTask, }; }) .filter(Boolean) : []; const deliveryCheckpointMessages = isTaskRoute - ? (stream.checkpointDeliveries || []) + ? activeStreamCheckpointDeliveries .filter((item) => !shouldHideCheckpointMessage(item)) .map((payload) => { const checkpoint = normalizeCheckpoint({ checkpoint: payload }); @@ -1150,17 +1209,15 @@ const SuperAgent = () => { checkpoint: payload, checkpointStatus: checkpoint.checkpoint_status, sessionId: activeSessionId, - task: stream.task, + task: displayActiveStreamTask, }; }) .filter(Boolean) : []; const isStreamReadyForActiveSession = - streamMatchesActiveSession && - (!stream.isThreadLoading || stream.messages.length > 0); + streamReadyForActiveSession; const hasActiveInterrupt = - Boolean(stream.isWaitingForInterrupt) || - (Array.isArray(restoredSessionInterrupts) && restoredSessionInterrupts.length > 0); + hasPendingInterruptSignal; const currentTaskProgressKey = `session_progress_${activeSessionId}`; const localTaskProgressMessages = !hasActiveInterrupt && Array.isArray(localConversationMessages) ? localConversationMessages.filter( @@ -1170,13 +1227,43 @@ const SuperAgent = () => { item.key !== currentTaskProgressKey ) : []; - const bodyTaskForCard = { - ...bodyTask, - session_status: - bodyTask.session_status || bodyTask.sessionStatus || runtimeSessionStatus || "", + const bodyTaskForCard = { + ...bodyTask, + file_name: + latestUploadedFileName || + bodyTask.file_name || + bodyTask.fileName || + "投标文件正文", + status: displayTaskStatus || bodyTask.status, + session_status: + displayRuntimeSessionStatus || bodyTask.session_status || bodyTask.sessionStatus || "", }; + const isBodyTaskTerminalCardStatus = [ + "completed", + "done", + "success", + "writed", + "reviewing", + "failed", + "error", + "cancelled", + "canceled", + "suspended", + ].includes(bodyTaskStatus) || [ + "completed", + "failed", + "error", + "cancelled", + "canceled", + "suspended", + ].includes(displayRuntimeSessionStatus); + const shouldRenderBodyProgressCard = + !hasActiveInterrupt && + Boolean(activeSessionId) && + hasBodyTaskShape && + (isBodyGenerationActive || isBodyTaskTerminalCardStatus); const derivedBodyProgressMessage = - !hasActiveInterrupt && isBodyGenerationActive && activeSessionId + shouldRenderBodyProgressCard ? { key: currentTaskProgressKey, role: "assistant", @@ -1198,17 +1285,16 @@ const SuperAgent = () => { ...localTaskProgressMessages, derivedBodyProgressMessage || currentTaskProgressMessage, ].filter(Boolean); - const baseConversationMessages = isStreamReadyForActiveSession - ? [ - ...visibleStreamMessages, - ...unmatchedLocalHistoryMessages, - ...unmatchedLocalUserFileMessages, - ...inlineCheckpointMessages, - ...deliveryCheckpointMessages, - ...(contentWorkspaceMessage ? [contentWorkspaceMessage] : []), - ] - : []; - //[正文任务卡是 state/stream 的运行态投影,不能依赖 history 流是否加载完成] + const baseConversationMessages = [ + ...(isStreamReadyForActiveSession ? visibleStreamMessages : []), + ...unmatchedLocalUserFileMessages, + ...(isStreamReadyForActiveSession ? inlineCheckpointMessages : []), + ...(isStreamReadyForActiveSession ? deliveryCheckpointMessages : []), + ...(isStreamReadyForActiveSession && contentWorkspaceMessage + ? [contentWorkspaceMessage] + : []), + ]; + //[正文任务卡是 useStream 事件流的运行态投影] const conversationMessagesWithTaskProgress = [ ...baseConversationMessages, ...taskProgressMessages, @@ -1222,6 +1308,19 @@ const SuperAgent = () => { content: stream.error.message || "智能体流式连接异常,请稍后重试。", } : null; + const taskFailureMessage = isFailedTask && !streamErrorMessage + ? { + key: `task-failed-${activeSessionId}`, + id: `task-failed-${activeSessionId}`, + role: "assistant", + title: "任务失败", + content: String( + runtimeTask.message || + runtimeTask.error || + "任务执行失败,请检查失败原因后重试。" + ), + } + : null; //[流式 loading 由 SuperAgentConversation 根据当前 assistant 消息统一渲染,避免额外占位消息重复显示] const conversationBaseMessages = conversationMessagesWithTaskProgress; const streamTerminalStatus = [ @@ -1234,7 +1333,7 @@ const SuperAgent = () => { ].includes(stream.runPhase) ? stream.runPhase : ""; - const conversationSessionStatus = streamTerminalStatus || runtimeSessionStatus; + const conversationSessionStatus = streamTerminalStatus || displayRuntimeSessionStatus; const normalizedConversationMessages = (messages = []) => messages.map((item) => { if (item?.type !== "taskProgress" || !item.task) return item; return { @@ -1246,9 +1345,15 @@ const SuperAgent = () => { }, }; }); - const conversationMessages = normalizedConversationMessages(streamErrorMessage - ? [...conversationBaseMessages, streamErrorMessage] - : conversationBaseMessages); + const conversationMessages = normalizedConversationMessages( + streamErrorMessage || taskFailureMessage + ? [ + ...conversationBaseMessages, + ...(streamErrorMessage ? [streamErrorMessage] : []), + ...(taskFailureMessage ? [taskFailureMessage] : []), + ] + : conversationBaseMessages + ); const bodyTaskSyncKey = [ activeSessionId, @@ -1258,6 +1363,7 @@ const SuperAgent = () => { bodyTaskForCard.done || 0, bodyTaskForCard.total || 0, bodyTaskForCard.section_id || bodyTaskForCard.sectionId || "", + bodyTaskForCard.file_name || bodyTaskForCard.fileName || "", bodyTaskForCard.session_status || "", ].join("_"); const existingBodyTaskProgress = (Array.isArray(localConversationMessages) @@ -1277,6 +1383,7 @@ const SuperAgent = () => { existingBodyTask.done || 0, existingBodyTask.total || 0, existingBodyTask.section_id || existingBodyTask.sectionId || "", + existingBodyTask.file_name || existingBodyTask.fileName || "", existingBodyTask.session_status || existingBodyTask.sessionStatus || "", ].join("_"); @@ -1411,7 +1518,7 @@ const SuperAgent = () => { }; const respondCheckpointToAgent = ({ response, interruptId, namespace, respondBody = {} }) => { - const matchingInterrupt = stream.interrupts.find((item) => { + const matchingInterrupt = activeStreamInterrupts.find((item) => { const payload = item?.value || item?.payload || {}; return payload.checkpoint_id === respondBody.checkpoint_id; }); @@ -1428,18 +1535,11 @@ const SuperAgent = () => { const handleStopAndCancel = async () => { const sessionId = activeSessionId || activeTaskId; const currentTask = - latestProgressTaskRef.current || restoredSessionTask || stream.task || {}; + latestProgressTaskRef.current || restoredSessionTask || activeStreamTask || {}; const suspendedTask = { ...currentTask, status: "suspended", }; - if (sessionId) { - commitProgressTask(sessionId, suspendedTask, { status: "suspended" }); - } else { - setRestoredSessionTask(suspendedTask); - updateActiveTask({ status: "suspended" }); - } - const stopOperations = [stream.stopRun()]; if (sessionId && currentUserId) { stopOperations.push( @@ -1454,6 +1554,13 @@ const SuperAgent = () => { const failedOperation = results.find((result) => result.status === "rejected"); if (failedOperation) { message.error(failedOperation.reason?.message || "停止运行失败"); + return; + } + if (sessionId) { + commitProgressTask(sessionId, suspendedTask, { status: "suspended" }); + } else { + setRestoredSessionTask(suspendedTask); + updateActiveTask({ status: "suspended" }); } }; @@ -1486,7 +1593,7 @@ const SuperAgent = () => { const handleSelectTask = async (task) => { // useStream 会在 threadId 变化时自动 hydrate 新线程。 - // disconnect 会永久销毁 controller,只能用于页面卸载,不能用于任务切换。 + // 会话切换前由 prepareForSessionSwitch 断开旧订阅,不发送停止命令。 return selectLegacyTask(task); }; @@ -1515,7 +1622,7 @@ const SuperAgent = () => { namespace: interruptState.namespace, sessionId: activeSessionId, checkpointStatus: "pending", - task: stream.task, + task: activeStreamTask, }; openWorkspaceOnMobile({ @@ -1524,7 +1631,7 @@ const SuperAgent = () => { checkpointKey: checkpointItem.key, kind: "tender", sessionId: activeSessionId, - task: stream.task, + task: activeStreamTask, submitLabel: "提交修改", }); }; @@ -1662,6 +1769,10 @@ const SuperAgent = () => { const sessionId = latestArtifactProgressMessage.sessionId; const task = latestArtifactProgressMessage.task || {}; + if ( + !workspaceOpen || + String(workspaceData?.sessionId || "") !== String(sessionId || "") + ) return undefined; if (!sessionId) { superAgentLog("container.artifact", "skip_refresh_effect", { reason: "missing_session", @@ -1752,169 +1863,25 @@ const SuperAgent = () => { return undefined; }, [latestArtifactProgressKey]); - const fetchSessionState = async (sessionId) => { - const stateData = await dispatch(getSuperAgentSessionState({ - params: buildSessionParams(sessionId), - query: { userId: currentUserId }, - })).then((res) => ensureActionSuccess(res, "获取任务状态失败")); - - return stateData?.data || stateData || {}; - }; - const handleStopAnswer = () => { return handleStopAndCancel(); }; - - const restoreSelectedSessionState = async (sessionId, latestSessionState = null) => { - try { - if (activeSessionIdRef.current !== String(sessionId || "")) return; - const sessionState = latestSessionState || await fetchSessionState(sessionId); - if (activeSessionIdRef.current !== String(sessionId || "")) return; - setRestoredSessionRuntimeStatus(getSessionRuntimeStatus(sessionState)); - setRestoredSessionInterrupts( - Array.isArray(sessionState.interrupts) ? sessionState.interrupts : [] - ); - const stateTask = sessionState.task || null; - const sessionStatus = getSessionRuntimeStatus(sessionState); - const displayTask = stateTask - ? { - ...stateTask, - session_status: sessionStatus, - ...(TERMINAL_SESSION_STATUSES.has(sessionStatus) - ? { status: sessionStatus } - : {}), - } - : stateTask; - const isStaleWritingTask = isCompletedSessionWithWritingTask( - sessionStatus, - stateTask - ); - setRestoredSessionTask(displayTask); - const checkpoint = sessionState.checkpoint || null; - const hasCheckpoint = - checkpoint && - typeof checkpoint === "object" && - Object.keys(checkpoint).length > 0; - const contentEntryKey = `session_content_entry_${sessionId}`; - const shouldLoadSections = !isStaleWritingTask && shouldShowBodyWorkspaceEntry({ - stateTask: displayTask, - checkpoint, - allowOutlineSkeleton: true, - }); - const sectionsData = shouldLoadSections - ? await dispatch(getSuperAgentSessionSections({ - params: buildSessionParams(sessionId), - query: { userId: currentUserId }, - })) - .then((res) => ensureActionSuccess(res, "获取任务章节失败")) - .catch(() => null) - : null; - if (activeSessionIdRef.current !== String(sessionId || "")) return; - const sectionList = getSessionSectionList(sectionsData); - const shouldRestoreBodyWorkspace = - !isStaleWritingTask && - (shouldLoadSections || - shouldShowBodyWorkspaceEntry({ - sectionList, - stateTask: displayTask, - checkpoint, - allowOutlineSkeleton: true, - })); - - //[正文入口由右侧工作区承载,清理旧版本遗留的前端合成卡片] - if (activeSessionIdRef.current !== String(sessionId || "")) return; - removeConversationMessage(contentEntryKey); - if (isStaleWritingTask) { - removeConversationMessage(`session_progress_${sessionId}`); - } - - //[History 不返回正文 checkpoint 时,仍以 state + sections 恢复进度和正文工作区] - if (shouldRestoreBodyWorkspace) { - upsertAssistantMessage({ - key: `session_progress_${sessionId}`, - role: "assistant", - type: "taskProgress", - title: "正文生成", - task: displayTask, - sessionId, - }); - await refreshSessionContentWorkspace({ - sessionId, - task: displayTask, - fallbackSections: sectionList, - silent: true, - }); - } - - if (activeSessionIdRef.current !== String(sessionId || "")) return; - if (hasCheckpoint) { - const checkpointType = String( - checkpoint.checkpoint_type || checkpoint.type || "" - ).toLowerCase(); - const checkpointStatus = String( - checkpoint.checkpoint_status || checkpoint.status || "pending" - ).toLowerCase(); - const taskType = String( - stateTask?.task_type || stateTask?.taskType || "" - ).toLowerCase(); - const taskStatus = String(stateTask?.status || "").toLowerCase(); - const isCatalogAlreadyConfirmed = - ["outline_edit", "catalog_edit"].includes(checkpointType) && - (shouldRestoreBodyWorkspace || taskType === "artifact_build") && - !["failed", "cancelled", "canceled", "error"].includes(taskStatus); - const restoredCheckpointStatus = isCatalogAlreadyConfirmed - ? "confirmed" - : checkpointStatus; - if (TERMINAL_CHECKPOINT_STATUSES.has(restoredCheckpointStatus)) { - const restoredCheckpointId = getCheckpointId(checkpoint); - if (restoredCheckpointId) { - setHiddenCheckpointIds((currentIds) => { - if (currentIds.has(restoredCheckpointId)) return currentIds; - const nextIds = new Set(currentIds); - nextIds.add(restoredCheckpointId); - return nextIds; - }); - } - } - const checkpointKey = `state_checkpoint_${sessionId}_${ - checkpoint.checkpoint_id || checkpoint.checkpoint_type || "latest" - }`; - upsertAssistantMessage({ - key: checkpointKey, - type: "checkpoint", - title: checkpoint.title || "需要确认", - content: checkpoint.description || "", - checkpoint, - sessionId, - task: displayTask, - sections: sectionList, - checkpointStatus: restoredCheckpointStatus, - }); - } - - } catch (error) { - message.error(error?.message || "获取任务状态失败"); + const handleSelectTaskByStream = async (task) => { + const sessionId = String(task?.id || task?.taskId || ""); + if (sessionId && sessionId === String(activeSessionIdRef.current || "")) { + return { success: true, unchanged: true }; } + await prepareForSessionSwitch(); + return handleSelectTask(task); }; - const handleSelectTaskWithState = async (task) => { - const sessionId = task?.id || task?.chatId; - prepareForSessionSwitch(); - const selectResult = await handleSelectTask(task); - const isSelected = selectResult?.success ?? Boolean(selectResult); - if (!isSelected || !sessionId || selectResult?.isEmptyHistory) return selectResult; - restoreSelectedSessionState(sessionId).catch(() => undefined); - return selectResult; - }; - - const handleSelectChatWithState = async (chatItem) => { - const sessionId = chatItem?.id || chatItem?.chatId; - prepareForSessionSwitch(); - const selectResult = await handleSelectChat(chatItem); - const isSelected = selectResult?.success ?? Boolean(selectResult); - if (!isSelected || !sessionId || selectResult?.isEmptyHistory) return selectResult; - restoreSelectedSessionState(sessionId).catch(() => undefined); - return selectResult; + const handleSelectChatByStream = async (chatItem) => { + const sessionId = String(chatItem?.id || chatItem?.chatId || ""); + if (sessionId && sessionId === String(activeSessionIdRef.current || "")) { + return { success: true, unchanged: true }; + } + await prepareForSessionSwitch(); + return handleSelectChat(chatItem); }; useEffect(() => { @@ -1930,8 +1897,7 @@ const SuperAgent = () => { if (activeSessionId === cachedSessionId) { activeSessionRestoredRef.current = true; - //[页面启动时会话已经被 session 层选中,仍需读取 state 恢复正文任务卡和工作区] - restoreSelectedSessionState(activeSessionId).catch(() => undefined); + //[页面启动时由 useStream 按 activeSessionId 恢复当前 thread] return; } @@ -1944,10 +1910,10 @@ const SuperAgent = () => { activeSessionRestoredRef.current = true; if (matchedSession.realm === "task") { - handleSelectTaskWithState(matchedSession.session); + handleSelectTaskByStream(matchedSession.session); return; } - handleSelectChatWithState(matchedSession.session); + handleSelectChatByStream(matchedSession.session); }, [activeSessionId, currentUserId, isLoadingSessions, sidebarTree]); const handleOpenAgentSquare = () => { @@ -2018,38 +1984,24 @@ const SuperAgent = () => { }; const ensureCheckpointStillPending = async (sessionId, checkpointId) => { - const sessionState = await fetchSessionState(sessionId); - const runtimeStatus = getSessionRuntimeStatus(sessionState); - const latestCheckpoint = sessionState.checkpoint || {}; - const latestCheckpointId = getCheckpointId(latestCheckpoint); - - if (stream.isLoading) { - throw new Error("任务正在运行,请稍后再操作"); - } - - if (WAITING_USER_SESSION_STATUSES.has(runtimeStatus)) { - if (!latestCheckpointId) { - await restoreSelectedSessionState(sessionId, sessionState); - throw new Error("当前任务等待确认,但后端未返回确认项,请刷新后重试"); - } - if (latestCheckpointId !== checkpointId) { - await restoreSelectedSessionState(sessionId, sessionState); - throw new Error("确认项已更新,请基于最新确认卡片操作"); - } - return sessionState; - } - - if (!latestCheckpointId) { - await refreshSessionHistoryMessages(sessionId); - throw new Error("当前确认项已失效,已刷新任务消息"); + if (String(activeSessionId || "") !== String(sessionId || "")) { + throw new Error("当前会话已切换,请重新操作"); } - if (latestCheckpointId !== checkpointId) { - await restoreSelectedSessionState(sessionId, sessionState); - throw new Error("确认项已更新,请基于最新确认卡片操作"); + const currentInterrupt = activeStreamInterrupts.find((item) => { + const payload = item?.value || item?.payload || {}; + const currentId = getCheckpointId(payload); + return currentId === String(checkpointId || ""); + }); + if (!currentInterrupt) { + throw new Error("当前确认项已失效,请基于最新确认卡片操作"); } - return sessionState; + return { + status: stream.runPhase, + checkpoint: currentInterrupt.value || currentInterrupt.payload || {}, + interrupts: activeStreamInterrupts, + }; }; const handleGeneratedUiSubmit = async (item, decision = {}) => { @@ -2102,8 +2054,6 @@ const SuperAgent = () => { nextIds.add(String(interruptId)); return nextIds; }); - // 恢复流负责维护任务状态,不能用固定 running 覆盖 completed。 - setRestoredSessionRuntimeStatus(""); return true; } catch (error) { setDismissedGeneratedInterruptIds((currentIds) => { @@ -2339,7 +2289,7 @@ const SuperAgent = () => { } //[checkpoint/respond 自身返回 SSE,成功后直接消费恢复事件;不再二次调用 /api/chat] - //[onFirstEvent时只调用state不刷新history,SSE流结束后再刷新history,避免删除流式消息] + //[确认响应自身就是 useStream 事件流,不再额外读取状态或消息] superAgentLog("container.checkpoint", "respond.start", { itemKey: item?.key, sessionId, @@ -2347,7 +2297,6 @@ const SuperAgent = () => { checkpointType, respondBody, }); - let stateCalled = false; try { const respondState = await respondCheckpointToAgent({ sessionId, @@ -2355,66 +2304,13 @@ const SuperAgent = () => { actionText, interruptId: item?.interruptId, namespace: item?.namespace, - onFirstEvent: async () => { - //[respond开始响应后调用state,仅轻量更新工作区卡片,不覆盖respond信息] - if (!stateCalled) { - stateCalled = true; - try { - const latestSessionState = await fetchSessionState(sessionId); - const stateTask = latestSessionState?.task || null; - const sessionStatus = getSessionRuntimeStatus(latestSessionState); - const displayTask = stateTask - ? { - ...stateTask, - session_status: sessionStatus, - ...(TERMINAL_SESSION_STATUSES.has(sessionStatus) - ? { status: sessionStatus } - : {}), - } - : stateTask; - const isStaleWritingTask = isCompletedSessionWithWritingTask( - sessionStatus, - stateTask - ); - const checkpoint = latestSessionState?.checkpoint || null; - const shouldShowBody = - !isStaleWritingTask && shouldShowBodyWorkspaceEntry({ - stateTask: displayTask, - checkpoint, - allowOutlineSkeleton: true, - }); - if (isStaleWritingTask) { - removeConversationMessage(`session_progress_${sessionId}`); - } - if (shouldShowBody) { - upsertAssistantMessage({ - key: `session_progress_${sessionId}`, - role: "assistant", - type: "taskProgress", - title: "正文生成", - task: displayTask, - sessionId, - }); - await refreshSessionContentWorkspace({ - sessionId, - task: displayTask, - silent: true, - }); - } - } catch (_stateErr) { - superAgentError("container.checkpoint", "state.error", _stateErr); - } - } - }, }); checkpointStreamHadEvent = Boolean(respondState?.hasEvent); } finally { checkpointSubmittingIdsRef.current.delete(checkpointId); } - //[SSE流已实时消费事件并更新消息,不再刷新history避免覆盖respond响应] + //[SSE流已实时消费事件并更新消息] checkpointResponded = true; - // 恢复流负责维护任务状态,不能用固定 running 覆盖 completed。 - setRestoredSessionRuntimeStatus(""); setHiddenCheckpointIds((currentIds) => { if (currentIds.has(checkpointId)) return currentIds; const nextIds = new Set(currentIds); @@ -2461,18 +2357,7 @@ const SuperAgent = () => { checkpointStatus: shouldKeepRespondedState ? resolvedCheckpointStatus : "pending", }); if (checkpointStreamHadEvent) { - try { - const latestSessionState = await fetchSessionState(sessionId); - await refreshSessionHistoryMessages(sessionId); - await restoreSelectedSessionState(sessionId, latestSessionState); - } catch (refreshError) { - superAgentWarn("container.checkpoint", "refresh_after_stream_error_failed", { - sessionId, - checkpointId, - refreshError, - }); - } - message.warning("连接已中断,已尝试刷新任务状态"); + message.warning("连接已中断,请重新打开当前会话继续接收事件"); return; } if (!checkpointResponded && options.reopenOnError && isWorkspaceSubmit) { @@ -2541,23 +2426,25 @@ const SuperAgent = () => { userInitial, userName, formatChatTime, - onCreateNewChat: () => { + onCreateNewChat: async () => { setMobileSidebarOpen(false); - handleCreateNewChat(); + await prepareForSessionSwitch(); + return handleCreateNewChat(); }, - onCreateNewTask: () => { + onCreateNewTask: async () => { setMobileSidebarOpen(false); - handleCreateNewTask(); + await prepareForSessionSwitch(); + return handleCreateNewTask(); }, onOpenAgentSquare: handleOpenAgentSquare, onOpenResourceLibrary: handleOpenResourceLibrary, onSelectTask: (task) => { setMobileSidebarOpen(false); - handleSelectTaskWithState(task); + handleSelectTaskByStream(task); }, onSelectChat: (chatItem) => { setMobileSidebarOpen(false); - handleSelectChatWithState(chatItem); + handleSelectChatByStream(chatItem); }, onCreateFolder: handleCreateFolder, onRenameFolder: handleRenameFolder, @@ -2712,6 +2599,7 @@ const SuperAgent = () => { chatWelcomeContent={CHAT_WELCOME_CONTENT} taskWelcomeTitle={TASK_WELCOME_TITLE} taskWelcomeContent={TASK_WELCOME_CONTENT} + isWaitingForInterrupt={hasPendingInterruptSignal} agentCategory={agentCategory} setAgentCategory={setAgentCategory} agentKeyword={agentKeyword} diff --git a/web/client/src/sections/superAgent/hooks/useSuperAgentChat.js b/web/client/src/sections/superAgent/hooks/useSuperAgentChat.js index e390a1e..bb4361d 100644 --- a/web/client/src/sections/superAgent/hooks/useSuperAgentChat.js +++ b/web/client/src/sections/superAgent/hooks/useSuperAgentChat.js @@ -21,7 +21,6 @@ import { cancelSuperAgentSession, createSuperAgentSession, deleteSuperAgentSession, - getSuperAgentSessionHistory, respondSuperAgentCheckpointStream, sendSuperAgentChat, uploadSuperAgentFile, @@ -46,7 +45,6 @@ import { isSuperAgentRunLogTool, markTenderSessionId, markPendingEmptySession, - normalizeHistoryMessages, removeTenderSessionId, resolveApiFolderId, saveActiveSessionId, @@ -117,7 +115,6 @@ const useSuperAgentChat = ({ setWorkspaceOpen, actions, dispatch, - protocolMode = "legacy", }) => { const [routeType, setRouteType] = useState("chat"); const [inputValue, setInputValue] = useState(""); @@ -158,7 +155,6 @@ const useSuperAgentChat = ({ const chatRunActiveRef = useRef(false); const creatingSessionRef = useRef(false); const sidebarRefreshTimerRef = useRef(null); - const historyRefreshTimerRef = useRef(null); const artifactProgressSessionRef = useRef(""); const taskProgressUpsertAtRef = useRef(0); const taskProgressPendingRef = useRef(null); @@ -287,24 +283,6 @@ const useSuperAgentChat = ({ } setConversationMessages((prev) => { - if (messageData.type === "content") { - const hasCurrentContentEntry = prev.some( - (item) => item.key === messageKey && item.type === "content" - ); - const hasHistoryContentWorkspace = prev.some((item) => { - const checkpoint = item?.checkpoint?.checkpoint || item?.checkpoint || {}; - const checkpointType = checkpoint.checkpoint_type || checkpoint.type || ""; - const title = checkpoint.title || item.title || ""; - return ( - item.type === "checkpoint" && - (checkpointType === "content_edit" || - checkpointType === "progress_view" || - title === "正文工作区") - ); - }); - if (!hasCurrentContentEntry && hasHistoryContentWorkspace) return prev; - } - const hasMessage = prev.some((item) => item.key === messageKey); if (!hasMessage) { return [ @@ -371,147 +349,6 @@ const useSuperAgentChat = ({ setConversationMessages((prev) => prev.filter((item) => item.key !== messageKey)); }; - //[生成稳定签名,用于轮询 history 时判断消息是否真的变化] - const buildConversationMessageSignature = (item = {}) => { - const runLogEntries = Array.isArray(item.runLog?.entries) - ? item.runLog.entries.map((entry) => ({ - id: entry.id || "", - name: entry.name || "", - kind: entry.kind || "", - status: entry.status || "", - arguments: entry.arguments || "", - result: entry.result || "", - })) - : []; - return JSON.stringify({ - key: item.key || "", - role: item.role || "", - type: item.type || "", - title: item.title || "", - content: item.content || "", - loadingText: item.loadingText || "", - checkpointStatus: item.checkpointStatus || "", - checkpoint: item.checkpoint || null, - task: item.task || null, - files: item.files || [], - runLogEntries, - }); - }; - - //[按 key 做 history diff,未变化的消息沿用原对象,减少轮询导致的重绘] - const mergeHistoryMessagesByDiff = (currentMessages = [], historyMessages = []) => { - const currentMap = new Map(currentMessages.map((item) => [item.key, item])); - const historyKeySet = new Set(historyMessages.map((item) => item.key)); - const shouldPreserveLocalRuntimeMessage = (item = {}) => { - if (!item.key || historyKeySet.has(item.key)) return false; - if (item.type === "taskProgress") return true; - return String(item.key).startsWith("session_running_"); - }; - const nextHistoryMessages = historyMessages.map((historyItem) => { - const currentItem = currentMap.get(historyItem.key); - if ( - currentItem && - buildConversationMessageSignature(currentItem) === - buildConversationMessageSignature(historyItem) - ) { - return currentItem; - } - return historyItem; - }); - const localRuntimeMessages = currentMessages.filter(shouldPreserveLocalRuntimeMessage); - const nextMessages = [...nextHistoryMessages, ...localRuntimeMessages]; - const currentSignature = currentMessages.map(buildConversationMessageSignature).join("\n"); - const nextSignature = nextMessages.map(buildConversationMessageSignature).join("\n"); - - if (currentSignature === nextSignature) return currentMessages; - return nextMessages; - }; - - /** - * 功能:重新读取当前会话 history,并用持久化消息更新对话区 - * 使用场景:正文生成完成后,恢复后端写入的“正文工作区” checkpoint - * - * 入参:sessionId 当前正文任务会话 ID - * 返回:是否成功更新对话消息 - * - * 注意:空 history 或用户已切换会话时保留当前消息,避免异步响应覆盖其他会话 - */ - const refreshSessionHistoryMessages = useCallback(async ( - sessionId, - { requireBodyWorkspace = false } = {} - ) => { - if (!sessionId || activeSessionIdRef.current !== sessionId) return false; - - try { - const data = await dispatch(getSuperAgentSessionHistory({ - params: buildSessionParams(sessionId), - query: { userId: currentUserId }, - })).then((res) => ensureActionSuccess(res, "获取任务历史失败")); - const historyData = data?.data || data || {}; - const historyMessages = normalizeHistoryMessages( - historyData?.messages || [], - sessionId - ); - - if ( - !historyMessages.length || - activeSessionIdRef.current !== sessionId - ) { - return false; - } - - const hasBodyWorkspace = historyMessages.some((item) => { - const checkpoint = item?.checkpoint?.checkpoint || item?.checkpoint || {}; - const checkpointType = checkpoint.checkpoint_type || checkpoint.type || ""; - const title = checkpoint.title || item.title || ""; - return ( - checkpointType === "content_edit" || - checkpointType === "progress_view" || - title === "正文工作区" - ); - }); - if (requireBodyWorkspace && !hasBodyWorkspace) return false; - - setConversationMessages((prev) => mergeHistoryMessagesByDiff(prev, historyMessages)); - return true; - } catch (error) { - superAgentWarn("chat.history", "refresh_after_artifact_failed", { - sessionId, - error, - }); - return false; - } - }, [actions, currentUserId, dispatch, protocolMode]); - - //[正文完成后以 SSE 生命周期为准刷新 history,不依赖可能被 checkpoint 替换的进度卡] - const scheduleArtifactHistoryRefresh = useCallback((sessionId, attempt = 0) => { - if (!sessionId || activeSessionIdRef.current !== sessionId) return; - if (historyRefreshTimerRef.current) { - window.clearTimeout(historyRefreshTimerRef.current); - } - - historyRefreshTimerRef.current = window.setTimeout(async () => { - historyRefreshTimerRef.current = null; - superAgentLog("chat.history", "refresh_after_artifact_start", { - sessionId, - attempt, - }); - const refreshed = await refreshSessionHistoryMessages(sessionId, { - requireBodyWorkspace: true, - }); - if (refreshed) { - superAgentLog("chat.history", "refresh_after_artifact_done", { - sessionId, - attempt, - }); - return; - } - if (attempt < 2 && activeSessionIdRef.current === sessionId) { - scheduleArtifactHistoryRefresh(sessionId, attempt + 1); - } - }, attempt === 0 ? 800 : 1200); - }, [refreshSessionHistoryMessages]); - useEffect(() => { return () => { if (chatAbortControllerRef.current) { @@ -520,9 +357,6 @@ const useSuperAgentChat = ({ if (sidebarRefreshTimerRef.current) { window.clearTimeout(sidebarRefreshTimerRef.current); } - if (historyRefreshTimerRef.current) { - window.clearTimeout(historyRefreshTimerRef.current); - } if (taskProgressTimerRef.current) { window.clearTimeout(taskProgressTimerRef.current); } @@ -914,7 +748,6 @@ const useSuperAgentChat = ({ artifactProgressSessionRef.current = options.sessionId; } if (isArtifactCompleted) { - scheduleArtifactHistoryRefresh(options.sessionId); } updateConversationMessage(assistantMessageKey, (item) => ({ title: progress >= 100 ? "正文生成完成" : `正在生成:${sectionTitle}`, @@ -1056,7 +889,6 @@ const useSuperAgentChat = ({ if (eventName === "done") { if (artifactProgressSessionRef.current === options.sessionId) { artifactProgressSessionRef.current = ""; - scheduleArtifactHistoryRefresh(options.sessionId); } clearWaitingNoticeMessages(); updateConversationMessage(assistantMessageKey, (item) => { @@ -1226,10 +1058,9 @@ const useSuperAgentChat = ({ }, }); - //[部分服务不会发送 done 事件;流结束后仍需按本轮 artifact 进度刷新 history] + //[部分服务不会发送 done 事件;本轮进度仍由 useStream 业务事件维护] if (artifactProgressSessionRef.current === sessionId) { artifactProgressSessionRef.current = ""; - scheduleArtifactHistoryRefresh(sessionId); } superAgentLog("chat.send", "run.done", { @@ -1406,7 +1237,6 @@ const useSuperAgentChat = ({ if (artifactProgressSessionRef.current === sessionId) { artifactProgressSessionRef.current = ""; - scheduleArtifactHistoryRefresh(sessionId); } superAgentLog("chat.checkpoint", "respond.done", { @@ -1915,8 +1745,6 @@ const useSuperAgentChat = ({ }; const handleSelectTask = async (task) => { - //[切换会话时中止当前SSE并重置流式状态,避免running状态泄漏到新会话] - handleStopAnswer(); activeSessionIdRef.current = task.id; setActiveTaskId(task.id); setActiveSessionId(task.id); @@ -1927,51 +1755,12 @@ const useSuperAgentChat = ({ setUploadedFileList([]); setSelectedTaskType(null); setConversationMessages([]); - if (protocolMode === "v2") { - return { success: true, isEmptyHistory: false }; - } - try { - const data = await dispatch(getSuperAgentSessionHistory({ - params: buildSessionParams(task.id), - query: { userId: currentUserId }, - })).then((res) => ensureActionSuccess(res, "获取任务历史失败")); - //[陈旧会话检查:异步操作完成后确认当前激活的会话ID未改变] - if (activeSessionIdRef.current !== task.id) { - return { success: false, isEmptyHistory: false, reason: "stale_session" }; - } - const historyData = data?.data || data || {}; - const rawHistoryMessages = Array.isArray(historyData?.messages) - ? historyData.messages - : []; - const historyMessages = normalizeHistoryMessages( - rawHistoryMessages, - task.id - ); - //[空任务会话:展示任务大厅,而非直接进入标书引导] - if (!rawHistoryMessages.length) { - setConversationMessages([buildEmptyTaskStartMessage()]); - return { success: true, isEmptyHistory: true }; - } else { - setSelectedTaskType("tender"); - setConversationMessages(historyMessages); - } - return { success: true, isEmptyHistory: false }; - } catch (error) { - const isSessionMissing = /404|not found|不存在/i.test(String(error?.message || "")); - if (isSessionMissing) { - removeSidebarSessionLocally(task.id, "task"); - clearActiveSidebarSession(task.id, true); - message.warning("该任务记录已不存在,已从列表移除"); - return { success: false, isEmptyHistory: false }; - } - message.error(error?.message || "获取任务历史失败"); - return { success: false, isEmptyHistory: false }; - } + //[useStream 是唯一会话恢复来源,stream.messages 负责在当前 thread 完成快照加载后还原消息] + setConversationMessages([buildEmptyTaskStartMessage()]); + return { success: true }; }; const handleSelectChat = async (chat) => { - //[切换会话时中止当前SSE并重置流式状态,避免running状态泄漏到新会话] - handleStopAnswer(); const sessionId = chat.id || chat.chatId; activeSessionIdRef.current = sessionId; setActiveSessionId(sessionId); @@ -1983,35 +1772,8 @@ const useSuperAgentChat = ({ setUploadedFileList([]); setSelectedTaskType(null); setConversationMessages([]); - if (protocolMode === "v2") { - return { success: true, isEmptyHistory: false }; - } - try { - const data = await dispatch(getSuperAgentSessionHistory({ - params: buildSessionParams(sessionId), - query: { userId: currentUserId }, - })).then((res) => ensureActionSuccess(res, "获取对话历史失败")); - //[陈旧会话检查:异步操作完成后确认当前激活的会话ID未改变] - if (activeSessionIdRef.current !== sessionId) { - return { success: false, isEmptyHistory: false, reason: "stale_session" }; - } - const historyData = data?.data || data || {}; - const rawHistoryMessages = Array.isArray(historyData?.messages) - ? historyData.messages - : []; - setConversationMessages(normalizeHistoryMessages(rawHistoryMessages, sessionId)); - return { success: true, isEmptyHistory: rawHistoryMessages.length === 0 }; - } catch (error) { - const isSessionMissing = /404|not found|不存在/i.test(String(error?.message || "")); - if (isSessionMissing) { - removeSidebarSessionLocally(sessionId, "chat"); - clearActiveSidebarSession(sessionId, true); - message.warning("该对话记录已不存在,已从列表移除"); - return { success: false, isEmptyHistory: false }; - } - message.error(error?.message || "获取对话历史失败"); - return { success: false, isEmptyHistory: false }; - } + //[useStream 是唯一会话恢复来源,stream.messages 负责在当前 thread 完成快照加载后还原消息] + return { success: true }; }; const handleDeleteSidebarSession = async (item, itemType) => { @@ -2076,7 +1838,6 @@ const useSuperAgentChat = ({ updateActiveTask, updateConversationMessage, removeConversationMessage, - refreshSessionHistoryMessages, createAndActivateSession, sendMessageToAgent, respondCheckpointToAgent, diff --git a/web/client/src/sections/superAgent/hooks/useSuperAgentSession.js b/web/client/src/sections/superAgent/hooks/useSuperAgentSession.js index 0974e2b..1f50b40 100644 --- a/web/client/src/sections/superAgent/hooks/useSuperAgentSession.js +++ b/web/client/src/sections/superAgent/hooks/useSuperAgentSession.js @@ -4,21 +4,20 @@ * * 职责: * 1. 复用成熟的 session、侧栏、文件上传和业务页面状态。 - * 2. 固定启用 v2 模式,禁止旧 history 在任务打开、切换和刷新时发起请求。 + * 2. 会话切换只设置 useStream 的 active thread,不主动读取消息或任务快照。 * * 不负责: * 1. 消息流、interrupt、tool call、停止运行或 SSE 生命周期。 * * 维护说明: - * v2 协议能力统一由 useSuperAgentStream 承担;此适配层不可暴露旧发送和 checkpoint 方法给容器。 + * useStream 协议能力统一由 useSuperAgentStream 承担;此适配层只保留 session/sidebar 能力。 */ "use strict"; import useSuperAgentChat from "./useSuperAgentChat"; const useSuperAgentSession = (options) => { - const legacySession = useSuperAgentChat({ ...options, protocolMode: "v2" }); - const session = { ...legacySession }; + const session = { ...useSuperAgentChat(options) }; [ "sendMessageToAgent", "respondCheckpointToAgent", diff --git a/web/client/src/sections/superAgent/hooks/useSuperAgentStream.js b/web/client/src/sections/superAgent/hooks/useSuperAgentStream.js index 366b186..57c6faa 100644 --- a/web/client/src/sections/superAgent/hooks/useSuperAgentStream.js +++ b/web/client/src/sections/superAgent/hooks/useSuperAgentStream.js @@ -8,8 +8,8 @@ * 3. 订阅业务 custom channel,并通知容器刷新 workspace/sections。 * * 不负责: - * 1. 创建业务 session、加载 workspace/sections 或兼容旧聊天协议。 - * 2. 手写 SSE、调用旧 history/checkpoint 或管理业务会话。 + * 1. 创建业务 session、加载 workspace/sections 或管理业务会话。 + * 2. 手写 SSE、调用旧聊天协议或维护独立恢复接口。 * * 维护说明: * Agent v2 不可用时只暴露错误,调用方不得回退 /api/chat 或 runs/stream。 @@ -43,6 +43,21 @@ const TERMINAL_INTERRUPT_STATUSES = new Set([ "canceled", ]); +const ACTIVE_TASK_STATUSES = new Set([ + "queued", + "starting", + "started", + "running", + "pending", + "processing", + "generating", + "writing", + "active", + "streaming", + "resuming", + "awaiting_interrupt", +]); + const getInterruptStatus = (item = {}) => { const payload = item?.value || item?.payload || {}; return String( @@ -63,6 +78,11 @@ const isSuperAgentEventRequest = (input) => { return /\/threads\/[^/]+\/stream\/events(?:\?|$)/.test(requestUrl); }; +const isUseStreamHistoryDiscoveryRequest = (input) => { + const requestUrl = String(input?.url || input || ""); + return /\/(?:threads|tasks)\/[^/]+\/history(?:\?|$)/.test(requestUrl); +}; + const isLifecycleWatcherRequest = (input, init = {}) => { if (!isSuperAgentEventRequest(input) || typeof init.body !== "string") { return false; @@ -182,14 +202,32 @@ const fetchEventStreamWithRecovery = async (input, init) => { class SingleSubscriberSseTransportAdapter extends ProtocolSseTransportAdapter { activeEventStream = null; eventHandles = new Set(); + latestState = null; + onStateChange = null; + stateRequestVersion = 0; + + async getState() { + const requestVersion = ++this.stateRequestVersion; + const requestedThreadId = String(this.threadId || "").trim(); + const state = await super.getState(); + // getState 可能在切换 thread 后才返回;旧请求不能覆盖新 thread 的快照。 + if ( + requestVersion === this.stateRequestVersion && + String(this.threadId || "").trim() === requestedThreadId + ) { + this.latestState = state; + this.onStateChange?.(); + } + return state; + } openEventStream(params) { const isLifecycleWatcher = isLifecycleWatcherFilter(params); const threadId = String(this.threadId || "").trim(); if (isLifecycleWatcher) { - // fetchWithHistoryCompatibility 会把这个 watcher 转成本地空流, - // 不要让它参与主事件流的连接排他和释放等待。 + // useStream 的 root pump 已经覆盖 lifecycle/input,额外 watcher + // 不参与主事件流的连接排他和释放等待。 return super.openEventStream(params); } @@ -310,131 +348,6 @@ const getEventPayload = (event) => event?.params?.data ?? event; -//[兼容历史消息]旧会话中的 tool 消息可能缺少 tool_call_id,LangChain 无法将其转换为 ToolMessage。 -const isInvalidSerializedToolMessage = (message) => - message?.type === "tool" && !message.tool_call_id && !message.toolCallId; - -//[兼容历史消息]仅清理无法被 SDK 转换的 tool 消息,保留其他状态字段和可用消息。 -const sanitizeLangGraphPayload = (value, parentKey = "") => { - if (Array.isArray(value)) { - return value - .filter((item) => parentKey !== "messages" || !isInvalidSerializedToolMessage(item)) - .map((item) => sanitizeLangGraphPayload(item, parentKey)); - } - - if (!value || typeof value !== "object") return value; - - return Object.fromEntries( - Object.entries(value).map(([key, item]) => [key, sanitizeLangGraphPayload(item, key)]) - ); -}; - -//[保留同一会话的最近有效消息,避免 hydrate 短暂返回不完整快照时丢失流式内容] -const mergeStreamMessageSnapshots = (previousMessages = [], currentMessages = []) => { - const previous = Array.isArray(previousMessages) ? previousMessages : []; - const current = Array.isArray(currentMessages) ? currentMessages : []; - if (!previous.length) return current; - if (!current.length) return previous; - - const currentById = new Map( - current - .filter((message) => message?.id) - .map((message) => [String(message.id), message]) - ); - const merged = []; - const usedIds = new Set(); - - previous.forEach((message) => { - const messageId = String(message?.id || ""); - if (!messageId) return; - merged.push(currentById.get(messageId) || message); - usedIds.add(messageId); - }); - - current.forEach((message) => { - const messageId = String(message?.id || ""); - if (!messageId || usedIds.has(messageId)) return; - merged.push(message); - }); - - return merged; -}; - -//[直接消费 root messages 事件,避免 history hydrate 覆盖正在生成的增量消息] -const applyMessageEventToState = (currentState, event) => { - const data = event?.params?.data || {}; - const eventType = String(data.event || ""); - const nextMessages = new Map(currentState.messages); - let activeMessageId = currentState.activeMessageId; - const messageId = String(data.id || activeMessageId || "").trim(); - if (!messageId) return currentState; - - const previousMessage = nextMessages.get(messageId) || { - id: messageId, - type: "ai", - role: "ai", - content: "", - tool_calls: [], - }; - const nextMessage = { - ...previousMessage, - tool_calls: Array.isArray(previousMessage.tool_calls) - ? [...previousMessage.tool_calls] - : [], - }; - - if (eventType === "message-start") { - activeMessageId = messageId; - nextMessage.role = data.role || nextMessage.role || "ai"; - nextMessage.type = nextMessage.role; - } - - if (eventType === "content-block-delta") { - const delta = data.delta || {}; - if (delta.type === "text-delta") { - nextMessage.content = `${String(nextMessage.content || "")}${String(delta.text || "")}`; - } - if (delta.type === "tool-call-delta") { - const toolCallIndex = Number(data.index || 0); - const previousToolCall = nextMessage.tool_calls[toolCallIndex] || {}; - const deltaArgs = delta.args; - const nextArgs = - previousToolCall.args && - typeof previousToolCall.args === "object" && - deltaArgs && - typeof deltaArgs === "object" - ? { ...previousToolCall.args, ...deltaArgs } - : deltaArgs ?? previousToolCall.args; - nextMessage.tool_calls[toolCallIndex] = { - ...previousToolCall, - args: nextArgs, - status: "running", - }; - } - } - - if (eventType === "content-block-finish") { - const content = data.content || {}; - if (content.type === "text") { - nextMessage.content = content.text || nextMessage.content || ""; - } - if (content.type === "tool_call") { - const toolCallIndex = Number(data.index || 0); - nextMessage.tool_calls[toolCallIndex] = { - ...(nextMessage.tool_calls[toolCallIndex] || {}), - ...content, - status: "success", - }; - } - } - - nextMessages.set(messageId, nextMessage); - return { - messages: nextMessages, - activeMessageId, - }; -}; - const getEventDedupeKey = (event) => { if (event?.event_id) return String(event.event_id); const payload = getEventPayload(event) || {}; @@ -474,20 +387,22 @@ const useSuperAgentStream = ({ const pendingInterruptRef = useRef(false); const awaitingInterruptRef = useRef(false); const [runPhase, setRunPhase] = useState("idle"); + const [isLocalRunActive, setIsLocalRunActive] = useState(false); const [isRespondingInterrupt, setIsRespondingInterrupt] = useState(false); const [isBusinessRunning, setIsBusinessRunning] = useState(false); const [runtimeCheckpointDeliveries, setRuntimeCheckpointDeliveries] = useState([]); const [runtimeInterrupts, setRuntimeInterrupts] = useState([]); const [dismissedInterruptIds, setDismissedInterruptIds] = useState(new Set()); + const resolvedInterruptIdsRef = useRef(new Set()); const [currentInterruptId, setCurrentInterruptId] = useState(""); + const [hydratedThreadId, setHydratedThreadId] = useState(""); + const [transportStateRevision, setTransportStateRevision] = useState(0); const eventRequestControllersRef = useRef(new Map()); - const streamSnapshotCacheRef = useRef(new Map()); - const eventMessageStateRef = useRef({ + const pendingSubmitThreadIdRef = useRef(""); + const hydrationSessionRef = useRef({ sessionId: "", - activeMessageId: "", - messages: new Map(), + hasSeenLoading: false, }); - const [eventStreamMessages, setEventStreamMessages] = useState([]); const localRunActiveRef = useRef(false); const localRunHasSeenLoadingRef = useRef(false); const activeSessionIdRef = useRef(""); @@ -504,8 +419,17 @@ const useSuperAgentStream = ({ }), [token, userId] ); - const fetchWithHistoryCompatibility = useCallback(async (...args) => { + const fetchUseStreamTransport = useCallback(async (...args) => { const [input, init = {}] = args; + if (isUseStreamHistoryDiscoveryRequest(input)) { + // 当前 SDK hydrate 会为 namespace discovery 自动读取 history。 + // SuperAgent 只以 thread state 和 event stream 为准,禁止该 + // 非业务读取落到服务端,避免 history 再次参与会话恢复。 + return new Response("[]", { + status: 200, + headers: { "content-type": "application/json" }, + }); + } if (isLifecycleWatcherRequest(input, init)) { // Agent 服务每个 thread 只允许一个 events subscriber。useStream // 的 root pump 已覆盖 lifecycle/input,额外 watcher 会稳定触发 429。 @@ -515,7 +439,9 @@ const useSuperAgentStream = ({ }); } let requestInit = init; - const sessionKey = String(activeSessionIdRef.current || "").trim(); + const sessionKey = String( + pendingSubmitThreadIdRef.current || activeSessionIdRef.current || "" + ).trim(); if (sessionKey && isSuperAgentEventRequest(input)) { let sessionController = eventRequestControllersRef.current.get(sessionKey); if (!sessionController) { @@ -528,40 +454,31 @@ const useSuperAgentStream = ({ }; } - const response = await fetchEventStreamWithRecovery(input, requestInit); - const contentType = response.headers.get("content-type") || ""; - if (!/json/i.test(contentType)) return response; - - try { - const payload = await response.clone().json(); - const sanitizedPayload = sanitizeLangGraphPayload(payload); - const headers = new Headers(response.headers); - headers.delete("content-length"); - return new Response(JSON.stringify(sanitizedPayload), { - status: response.status, - statusText: response.statusText, - headers, - }); - } catch { - return response; - } + return fetchEventStreamWithRecovery(input, requestInit); }, []); const eventTransport = useMemo( - () => - new SingleSubscriberSseTransportAdapter({ + () => { + const transport = new SingleSubscriberSseTransportAdapter({ apiUrl: getSuperAgentApiUrl(), defaultHeaders, - fetch: fetchWithHistoryCompatibility, + fetch: fetchUseStreamTransport, maxReconnectAttempts: 5, - }), - [defaultHeaders, fetchWithHistoryCompatibility] + }); + transport.onStateChange = () => { + setTransportStateRevision((revision) => revision + 1); + }; + return transport; + }, + [activeSessionId, defaultHeaders, fetchUseStreamTransport] ); // StreamController 在 hydrate 时会先通过 transport.getState() 取新 thread; // 自定义 adapter 需在该 effect 运行前同步绑定目标 thread,避免读到旧会话。 - eventTransport.setThreadId(activeSessionId || ""); + eventTransport.setThreadId( + activeSessionId || pendingSubmitThreadIdRef.current || "" + ); const callerOptions = useMemo( - () => ({ fetch: fetchWithHistoryCompatibility }), - [fetchWithHistoryCompatibility] + () => ({ fetch: fetchUseStreamTransport }), + [fetchUseStreamTransport] ); const stream = useStream({ assistantId: "freesun_agent", @@ -616,6 +533,7 @@ const useSuperAgentStream = ({ const handleStreamError = useCallback((error) => { localRunActiveRef.current = false; + setIsLocalRunActive(false); localRunHasSeenLoadingRef.current = false; interruptResumeRef.current = { active: false, running: false }; pendingInterruptRef.current = false; @@ -641,14 +559,16 @@ const useSuperAgentStream = ({ }, [activeSessionId, eventTransport]); useEffect(() => { - eventMessageStateRef.current = { + if (pendingSubmitThreadIdRef.current === String(activeSessionId || "")) { + pendingSubmitThreadIdRef.current = ""; + } + hydrationSessionRef.current = { sessionId: String(activeSessionId || ""), - activeMessageId: "", - messages: new Map(), + hasSeenLoading: false, }; - setEventStreamMessages([]); handledEventKeysRef.current.clear(); localRunActiveRef.current = false; + setIsLocalRunActive(false); localRunHasSeenLoadingRef.current = false; interruptResumeRef.current = { active: false, running: false }; pendingInterruptRef.current = false; @@ -659,41 +579,58 @@ const useSuperAgentStream = ({ setRuntimeCheckpointDeliveries([]); setRuntimeInterrupts([]); setDismissedInterruptIds(new Set()); + resolvedInterruptIdsRef.current.clear(); setCurrentInterruptId(""); + setHydratedThreadId(""); }, [activeSessionId]); - const handleMessageEvent = useCallback((event) => { - if (event?.method !== "messages") return; - const namespace = event?.params?.namespace; - if (Array.isArray(namespace) && namespace.length > 0) return; - - const sessionId = String(activeSessionIdRef.current || "").trim(); - if (!sessionId) return; - if (eventMessageStateRef.current.sessionId !== sessionId) { - eventMessageStateRef.current = { - sessionId, - activeMessageId: "", - messages: new Map(), - }; - } + useEffect(() => { + const sessionId = String(activeSessionId || ""); + const threadId = String(stream.threadId || ""); + if (!sessionId || sessionId !== threadId) return undefined; + + let cancelled = false; + // isThreadLoading 在 useStream hydrate 切换的中间阶段可能仍是 false, + // 不能用它作为快照完成标志;hydrationPromise 才代表当前 thread 的 state + // 已经写入 root store。 + Promise.resolve(stream.hydrationPromise) + .then(() => { + if (cancelled || activeSessionIdRef.current !== sessionId) return; + setHydratedThreadId(sessionId); + }) + .catch(() => undefined); - const nextState = applyMessageEventToState(eventMessageStateRef.current, event); - if (nextState === eventMessageStateRef.current) return; - eventMessageStateRef.current = nextState; - setEventStreamMessages([...nextState.messages.values()]); - }, []); + return () => { + cancelled = true; + }; + }, [ + activeSessionId, + stream.hydrationPromise, + stream.threadId, + transportStateRevision, + ]); const checkpointDeliveries = useMemo(() => { const deliveries = new Map(); - const hydratedDeliveries = Array.isArray(stream.values?.checkpoint_deliveries) - ? stream.values.checkpoint_deliveries - : []; + const hydratedDeliveries = [ + ...(Array.isArray(stream.values?.checkpoint_deliveries) + ? stream.values.checkpoint_deliveries + : []), + ...(Array.isArray(eventTransport.latestState?.values?.checkpoint_deliveries) + ? eventTransport.latestState.values.checkpoint_deliveries + : []), + ]; [...hydratedDeliveries, ...runtimeCheckpointDeliveries].forEach((item) => { if (!item?.checkpoint_id) return; deliveries.set(item.checkpoint_id, item); }); return [...deliveries.values()]; - }, [runtimeCheckpointDeliveries, stream.values?.checkpoint_deliveries]); + }, [ + eventTransport.latestState, + runtimeCheckpointDeliveries, + stream.values?.checkpoint_deliveries, + transportStateRevision, + ]); useEffect(() => { if (stream.error) handleStreamError(stream.error); @@ -709,6 +646,7 @@ const useSuperAgentStream = ({ localRunActiveRef.current = false; localRunHasSeenLoadingRef.current = false; + setIsLocalRunActive(false); setRunPhase((currentPhase) => ["running", "resuming"].includes(currentPhase) ? "completed" : currentPhase ); @@ -722,23 +660,27 @@ const useSuperAgentStream = ({ String(stream.threadId || "") === String(activeSessionId || ""); if (!isCurrentThread) return undefined; + const listenerSessionId = String(activeSessionId || ""); const currentThread = stream.getThread?.(); if (!currentThread) return undefined; return currentThread.onEvent((event) => { - handleMessageEvent(event); + // 切换会话后旧 Thread 的监听器可能在清理前再收到一个事件, + // 不能把旧会话的事件写入新会话的流式消息状态。 + if (activeSessionIdRef.current !== listenerSessionId) return; if (event?.method === "input.requested") { const data = event.params?.data || {}; const interruptId = String(data.interrupt_id || "").trim(); - if (interruptId) { + if (interruptId && !resolvedInterruptIdsRef.current.has(interruptId)) { + localRunActiveRef.current = false; + setIsLocalRunActive(false); setCurrentInterruptId(interruptId); - pendingInterruptRef.current = true; - awaitingInterruptRef.current = false; - setRunPhase("waiting_interrupt"); - setRuntimeInterrupts((current) => { - if (current.some((item) => item.id === interruptId)) return current; + setRuntimeInterrupts((currentInterrupts) => { + const nextInterrupts = currentInterrupts.filter( + (item) => String(item?.id || "") !== interruptId + ); return [ - ...current, + ...nextInterrupts, { id: interruptId, value: data.payload, @@ -748,6 +690,9 @@ const useSuperAgentStream = ({ }, ]; }); + pendingInterruptRef.current = true; + awaitingInterruptRef.current = false; + setRunPhase("waiting_interrupt"); } } if (event?.method === "lifecycle" && Array.isArray(event?.params?.namespace) && event.params.namespace.length === 0) { @@ -767,6 +712,8 @@ const useSuperAgentStream = ({ stream.interrupts.length > 0 || threadInterrupts.length > 0; if (hasRealInterrupt) { + localRunActiveRef.current = false; + setIsLocalRunActive(false); awaitingInterruptRef.current = false; setRunPhase("waiting_interrupt"); } else { @@ -780,6 +727,8 @@ const useSuperAgentStream = ({ setRunPhase("waiting_interrupt"); } else { awaitingInterruptRef.current = false; + localRunActiveRef.current = false; + setIsLocalRunActive(false); // aborted 表示本轮已结束,不能让 started 留下的 running 状态继续生效。 setRunPhase(lifecycleEvent === "aborted" ? "completed" : lifecycleEvent); } @@ -793,10 +742,18 @@ const useSuperAgentStream = ({ if (!BUSINESS_CHANNELS.includes(event?.method)) return; handleBusinessEvent(event); }); - }, [activeSessionId, handleBusinessEvent, handleMessageEvent, stream.isThreadLoading, stream.threadId]); + }, [activeSessionId, handleBusinessEvent, stream.threadId]); const prepareForSessionSwitch = useCallback(() => { + // 先让旧 thread 的事件监听失效。activeSessionId 在 React 下一次渲染 + // 前仍可能是旧值,单靠监听器里的 sessionId 判断不够。 + activeSessionIdRef.current = ""; + // pendingSubmitThreadId 只服务于“创建会话后首次发送”这一瞬间; + // 切换会话时必须清掉,否则新 transport 会继续绑定旧 thread。 + pendingSubmitThreadIdRef.current = ""; + setHydratedThreadId(""); localRunActiveRef.current = false; + setIsLocalRunActive(false); localRunHasSeenLoadingRef.current = false; interruptResumeRef.current = { active: false, running: false }; pendingInterruptRef.current = false; @@ -804,18 +761,21 @@ const useSuperAgentStream = ({ setRunPhase("idle"); setIsRespondingInterrupt(false); setIsBusinessRunning(false); + setRuntimeInterrupts([]); + resolvedInterruptIdsRef.current.clear(); - if (stream.isLoading) { - void stream.stop().catch(() => undefined); - } - + // 会话切换只断开当前浏览器订阅,不能发送 stop/cancel 命令。 + // stopRun 只由用户点击停止按钮触发,否则后端会把原会话改为 suspended。 // useStream 切换 threadId 时会等待旧 root pump 清理;直接关闭当前 // ThreadStream 可以立即中止旧 /events 请求,避免阻塞新会话接管。 const currentThread = stream.getThread?.(); - if (currentThread) { - void currentThread.close().catch(() => undefined); - } - }, [stream]); + eventTransport.close(); + + return Promise.allSettled([ + stream.disconnect(), + currentThread ? currentThread.close() : Promise.resolve(), + ]); + }, [eventTransport, stream]); const submitMessage = useCallback(async ({ content, @@ -828,32 +788,55 @@ const useSuperAgentStream = ({ }) => { const targetThreadId = String(threadId || activeSessionId || "").trim(); if (!targetThreadId) throw new Error("请先创建任务"); - const isBlockedByInterrupt = isRespondingInterrupt && !allowDuringInterruptResponse; - const isSwitchingThread = String(stream.threadId || "") !== targetThreadId; - if ((stream.isThreadLoading && !isSwitchingThread) || isBlockedByInterrupt) { + const isBlockedByInterrupt = isRespondingInterrupt && !allowDuringInterruptResponse; + const isSwitchingThread = String(stream.threadId || "") !== targetThreadId; + // isThreadLoading 只表示当前 thread 的快照还在 hydrate,不能阻止首条消息提交。 + // 真正表示本轮任务仍在运行的是 isLoading;否则新建会话会先创建成功, + // 但首条消息被这里提前拒绝,页面最终只剩空会话。 + if ((stream.isLoading && !isSwitchingThread) || isBlockedByInterrupt) { throw new Error("任务正在处理,请稍后再试"); + } + if (stream.isThreadLoading && !isSwitchingThread) { + // 新建会话的 state 可能还未写入 root store。等待 hydrate 完成后再提交, + // 避免 optimistic 消息被空快照或旧事件回放覆盖。 + await Promise.resolve(stream.hydrationPromise).catch(() => undefined); + } + // activeSessionId 的 React 状态更新可能晚于首次提交;先绑定 transport + // 和事件请求所属会话,避免首轮响应仍落到旧 thread。 + if (hydrationSessionRef.current.sessionId === targetThreadId) { + hydrationSessionRef.current.hasSeenLoading = true; } + pendingSubmitThreadIdRef.current = targetThreadId; + eventTransport.setThreadId(targetThreadId); localRunActiveRef.current = true; + setIsLocalRunActive(true); localRunHasSeenLoadingRef.current = false; setRunPhase("running"); - await stream.submit({ - messages: [{ - type: "human", - id: createClientMessageId(), - content: String(content || ""), - }], - display_content: String(displayContent ?? content ?? ""), - attachment_ids: Array.isArray(attachmentIds) ? attachmentIds : [], - }, { - threadId: targetThreadId, - multitaskStrategy, - metadata: { source: "super-agent-web" }, - }); - }, [activeSessionId, isRespondingInterrupt, stream]); + try { + await stream.submit({ + messages: [{ + type: "human", + id: createClientMessageId(), + content: String(content || ""), + }], + display_content: String(displayContent ?? content ?? ""), + attachment_ids: Array.isArray(attachmentIds) ? attachmentIds : [], + }, { + threadId: targetThreadId, + multitaskStrategy, + metadata: { source: "super-agent-web" }, + }); + } catch (error) { + localRunActiveRef.current = false; + setIsLocalRunActive(false); + throw error; + } + }, [activeSessionId, eventTransport, isRespondingInterrupt, stream]); const respondInterrupt = useCallback((response, options = {}) => { const interruptId = String(options.interruptId || "").trim(); localRunActiveRef.current = true; + setIsLocalRunActive(true); localRunHasSeenLoadingRef.current = false; interruptResumeRef.current = { active: true, running: false }; pendingInterruptRef.current = false; @@ -878,8 +861,11 @@ const useSuperAgentStream = ({ namespace: options.namespace, }).then((result) => { if (interruptId) { - setRuntimeInterrupts((current) => - current.filter((item) => item.id !== interruptId) + resolvedInterruptIdsRef.current.add(interruptId); + setRuntimeInterrupts((currentInterrupts) => + currentInterrupts.filter( + (item) => String(item?.id || "") !== interruptId + ) ); } // respond 只代表恢复命令已提交,不代表后端本轮运行完成。 @@ -888,6 +874,7 @@ const useSuperAgentStream = ({ }).catch((error) => { if (interruptId) { // 恢复失败时撤销临时隐藏,让用户可以重新提交。 + resolvedInterruptIdsRef.current.delete(interruptId); setDismissedInterruptIds((current) => { const next = new Set(current); next.delete(interruptId); @@ -896,6 +883,8 @@ const useSuperAgentStream = ({ setCurrentInterruptId((currentId) => currentId || interruptId); } interruptResumeRef.current = { active: false, running: false }; + localRunActiveRef.current = false; + setIsLocalRunActive(false); pendingInterruptRef.current = true; setRunPhase("waiting_interrupt"); setIsRespondingInterrupt(false); @@ -905,6 +894,7 @@ const useSuperAgentStream = ({ const stopRun = useCallback(async () => { localRunActiveRef.current = false; + setIsLocalRunActive(false); localRunHasSeenLoadingRef.current = false; interruptResumeRef.current = { active: false, running: false }; pendingInterruptRef.current = false; @@ -915,50 +905,213 @@ const useSuperAgentStream = ({ await stream.stop(); }, [stream]); - const currentSessionId = String(activeSessionId || ""); - const currentThreadId = String(stream.threadId || ""); - const isThreadBound = - Boolean(currentSessionId) && currentSessionId === currentThreadId; - const cachedSnapshot = streamSnapshotCacheRef.current.get(currentSessionId) || { - messages: [], - toolCalls: [], - values: {}, - }; - const currentValues = isThreadBound && stream.values ? stream.values : {}; - const currentValueMessages = Array.isArray(currentValues.messages) - ? currentValues.messages - : []; - const currentMessages = isThreadBound ? stream.messages : []; - const hydratedMessages = mergeStreamMessageSnapshots( - mergeStreamMessageSnapshots(cachedSnapshot.messages, currentValueMessages), - currentMessages - ); - const nextMessages = mergeStreamMessageSnapshots( - hydratedMessages, - isThreadBound ? eventStreamMessages : [] - ); - const nextToolCalls = isThreadBound && stream.toolCalls.length - ? stream.toolCalls - : cachedSnapshot.toolCalls; - const nextValues = isThreadBound - ? { ...cachedSnapshot.values, ...currentValues } - : cachedSnapshot.values; - if (isThreadBound && (nextMessages.length || nextToolCalls.length || Object.keys(nextValues).length)) { - streamSnapshotCacheRef.current.set(currentSessionId, { - messages: nextMessages, - toolCalls: nextToolCalls, - values: { - ...nextValues, - ...(nextMessages.length ? { messages: nextMessages } : {}), - }, - }); - } - const isCurrentThread = isThreadBound && !stream.isThreadLoading; - const streamMessages = isThreadBound ? nextMessages : []; - const streamToolCalls = isThreadBound ? nextToolCalls : []; - const streamValues = isThreadBound ? nextValues : {}; + const currentSessionId = String(activeSessionId || ""); + const currentThreadId = String(stream.threadId || ""); + const projectedThreadId = String( + pendingSubmitThreadIdRef.current || currentThreadId + ); + const isThreadBound = + Boolean(currentSessionId) && currentSessionId === currentThreadId; + const isProjectedThreadBound = + Boolean(currentSessionId) && currentSessionId === projectedThreadId; + if (hydrationSessionRef.current.sessionId !== currentSessionId) { + hydrationSessionRef.current = { + sessionId: currentSessionId, + hasSeenLoading: false, + }; + } + if (isThreadBound && stream.isThreadLoading) { + hydrationSessionRef.current.hasSeenLoading = true; + } + const isThreadReady = + isThreadBound && + !stream.isThreadLoading && + hydratedThreadId === currentSessionId; + const isPendingSubmitThread = + isProjectedThreadBound && + pendingSubmitThreadIdRef.current === currentSessionId; + const isStreamProjectionReady = + isThreadReady || isPendingSubmitThread; + const isInterruptProjectionReady = + isThreadBound && runtimeInterrupts.length > 0; + const isCurrentThread = isThreadReady; + const hydratedStateThreadId = String( + eventTransport.latestState?.checkpoint?.thread_id || + eventTransport.latestState?.checkpoint?.threadId || + eventTransport.latestState?.values?.task?.task_id || + eventTransport.latestState?.values?.task?.taskId || + "" + ); + const hydratedState = + isThreadReady && + hydratedStateThreadId === currentSessionId + ? eventTransport.latestState + : null; + const rawStreamMessages = isStreamProjectionReady ? stream.messages : []; + const rawStreamValues = isStreamProjectionReady ? stream.values || {} : {}; + const hydratedMessages = Array.isArray(hydratedState?.values?.messages) + ? hydratedState.values.messages + : []; + // 只有 hydrate 真正拿到消息后,才能解除首次提交的 thread 投影保护。 + // 仅有 task 快照不代表消息已完成落库,否则 task 先到时会让当前消息再次被隐藏。 + const hasHydratedSessionContent = hydratedMessages.length > 0; + useEffect(() => { + if (!isThreadReady || !isPendingSubmitThread || !hasHydratedSessionContent) return; + pendingSubmitThreadIdRef.current = ""; + }, [ + hasHydratedSessionContent, + isPendingSubmitThread, + isThreadReady, + ]); + + const hydratedTailIds = hydratedMessages + .slice(-3) + .map((item) => String(item?.id || "").trim()) + .filter(Boolean); + const rawStreamMessageIds = new Set( + rawStreamMessages + .map((item) => String(item?.id || "").trim()) + .filter(Boolean) + ); + const hydratedTaskStatus = String( + hydratedState?.values?.status || + hydratedState?.values?.session_status || + hydratedState?.values?.sessionStatus || + hydratedState?.values?.task?.session_status || + hydratedState?.values?.task?.sessionStatus || + hydratedState?.values?.task?.status || + "" + ).toLowerCase(); + const rawTaskStatus = String( + rawStreamValues.status || + rawStreamValues.session_status || + rawStreamValues.sessionStatus || + rawStreamValues.task?.session_status || + rawStreamValues.task?.sessionStatus || + rawStreamValues.task?.status || + "" + ).toLowerCase(); + const hydratedCheckpointDeliveryCount = Array.isArray( + hydratedState?.values?.checkpoint_deliveries + ) + ? hydratedState.values.checkpoint_deliveries.length + : 0; + const rawCheckpointDeliveryCount = Array.isArray(rawStreamValues.checkpoint_deliveries) + ? rawStreamValues.checkpoint_deliveries.length + : 0; + const shouldPreferHydratedRuntimeState = + Boolean(hydratedState) && + Boolean(hydratedTaskStatus || hydratedCheckpointDeliveryCount) && + (!rawTaskStatus && !rawCheckpointDeliveryCount || + hydratedTaskStatus !== rawTaskStatus || + hydratedCheckpointDeliveryCount > rawCheckpointDeliveryCount); + //[state 是当前 thread 的最新快照,SSE 重连可能先重放更早的 values] + // 消息和 task/value 的权威来源不能共用一个切换条件。 + // hydrate 返回空 messages 时,仍可能带有较新的 task 状态;此时只能更新 + // task/value,不能让空快照覆盖事件流已经收到的消息。 + const shouldPreferHydratedMessages = + hydratedMessages.length > 0 && + (rawStreamMessages.length < hydratedMessages.length || + (hydratedTailIds.length > 0 && + !hydratedTailIds.every((messageId) => rawStreamMessageIds.has(messageId)))); + const shouldPreferHydratedState = + shouldPreferHydratedRuntimeState || shouldPreferHydratedMessages; + const streamMessages = shouldPreferHydratedMessages + ? hydratedMessages + : rawStreamMessages; + const streamToolCalls = isStreamProjectionReady ? stream.toolCalls : []; + const streamValues = shouldPreferHydratedState + ? hydratedState?.values || {} + : rawStreamValues; + const streamSessionStatus = String( + streamValues.status || + streamValues.session_status || + streamValues.sessionStatus || + streamValues.task?.session_status || + streamValues.task?.sessionStatus || + "" + ).toLowerCase(); + const streamTask = streamValues?.task + ? { + ...streamValues.task, + ...(streamSessionStatus + ? { session_status: streamSessionStatus } + : {}), + } + : null; + const persistedTaskStatus = String( + streamSessionStatus || streamTask?.status || "" + ).toLowerCase(); + const isPersistedTaskActive = ACTIVE_TASK_STATUSES.has(persistedTaskStatus); + const hasPersistedNextNodes = + Array.isArray(hydratedState?.next) && hydratedState.next.length > 0; + const hydratedInterrupts = [ + ...(Array.isArray(hydratedState?.interrupts) + ? hydratedState.interrupts + : []), + ...(Array.isArray(hydratedState?.values?.__interrupt__) + ? hydratedState.values.__interrupt__.map((item) => ({ + ...item, + id: item?.id || item?.interruptId, + value: item?.value ?? item?.payload, + namespace: Array.isArray(item?.namespace) ? item.namespace : [], + })) + : []), + ]; + const hasPersistedInterrupts = hydratedInterrupts.length > 0; + const persistedInterrupts = + hydratedState + ? hydratedInterrupts + : isStreamProjectionReady + ? stream.interrupts + : []; + const streamInterrupts = [ + ...(Array.isArray(persistedInterrupts) ? persistedInterrupts : []), + ...runtimeInterrupts, + ]; + const shouldResetStaleWaitingPhase = + Boolean(hydratedState) && + !hasPersistedInterrupts && + ["waiting_interrupt", "awaiting_interrupt"].includes(runPhase); + const isPersistedThreadActive = + isPersistedTaskActive || hasPersistedNextNodes || hasPersistedInterrupts; + const isPersistedExecutionActive = + isPersistedThreadActive && + ![ + "suspended", + "waiting_user", + "awaiting_interrupt", + "waiting_interrupt", + ].includes(persistedTaskStatus) && + !hasPersistedInterrupts; + const hasRuntimeExecutionSignal = + localRunActiveRef.current || + isLocalRunActive || + isBusinessRunning || + ["running", "resuming"].includes(runPhase); + const isPersistedSuspended = + persistedTaskStatus === "suspended" && + !hasPersistedInterrupts && + !hasRuntimeExecutionSignal; + const isTerminalRunPhase = [ + "completed", + "aborted", + "failed", + "cancelled", + "canceled", + ].includes(runPhase); + const effectiveRunPhase = + isPersistedSuspended + ? "idle" + : shouldResetStaleWaitingPhase + ? "running" + : isPersistedExecutionActive && (runPhase === "idle" || isTerminalRunPhase) + ? "running" + : runPhase; + const effectiveIsLocalRunActive = isPersistedSuspended ? false : isLocalRunActive; + const effectiveIsBusinessRunning = isPersistedSuspended ? false : isBusinessRunning; const visibleInterrupts = useMemo(() => { - if (!isThreadBound) return []; + if (!isStreamProjectionReady && !isInterruptProjectionReady) return []; const merged = new Map(); const appendInterrupt = (item, fallback = {}) => { @@ -977,35 +1130,61 @@ const useSuperAgentStream = ({ }); }; - stream.interrupts.forEach((item) => appendInterrupt(item)); - runtimeInterrupts.forEach((item) => appendInterrupt(item)); - const threadInterrupts = stream.getThread?.()?.interrupts || []; - threadInterrupts.forEach((item) => appendInterrupt(item)); + streamInterrupts.forEach((item) => appendInterrupt(item)); return [...merged.values()].filter( (item) => !dismissedInterruptIds.has(String(item.id || "")) && !isTerminalInterrupt(item) ); - }, [dismissedInterruptIds, isCurrentThread, isThreadBound, runtimeInterrupts, stream]); - - const isRunPhaseActive = ["running", "awaiting_interrupt", "resuming"].includes(runPhase); + }, [ + dismissedInterruptIds, + isInterruptProjectionReady, + isStreamProjectionReady, + streamInterrupts, + ]); + + const isRunPhaseActive = ["running", "awaiting_interrupt", "resuming"].includes( + effectiveRunPhase + ); + const effectiveIsLoading = + isPersistedSuspended + ? isRespondingInterrupt + : stream.isLoading || + isRespondingInterrupt || + isBusinessRunning || + isRunPhaseActive || + isPersistedExecutionActive; return { messages: streamMessages, toolCalls: streamToolCalls, + interrupt: visibleInterrupts[0] || null, interrupts: visibleInterrupts, values: streamValues, - checkpointDeliveries: isCurrentThread ? checkpointDeliveries : [], - task: streamValues?.task || null, - isLoading: stream.isLoading || isRespondingInterrupt || isBusinessRunning || isRunPhaseActive, - runPhase, - currentInterruptId, - isWaitingForInterrupt: runPhase === "waiting_interrupt" || visibleInterrupts.length > 0, - isAwaitingInterrupt: runPhase === "awaiting_interrupt", - isBusinessRunning, + checkpointDeliveries: isStreamProjectionReady ? checkpointDeliveries : [], + task: streamTask, + sessionStatus: streamSessionStatus, + isLoading: effectiveIsLoading, + isLocalRunActive: effectiveIsLocalRunActive, + runPhase: effectiveRunPhase, + isPersistedThreadActive, + currentInterruptId: + hydratedState && + hydratedInterrupts.length === 0 && + runtimeInterrupts.length === 0 + ? "" + : currentInterruptId, + isWaitingForInterrupt: + visibleInterrupts.length > 0 || + (effectiveRunPhase === "waiting_interrupt" && !isPersistedThreadActive), + isAwaitingInterrupt: effectiveRunPhase === "awaiting_interrupt", + isBusinessRunning: effectiveIsBusinessRunning, isThreadLoading: stream.isThreadLoading, + isThreadReady, + isThreadProjectionReady: + isStreamProjectionReady || isInterruptProjectionReady, error: isCurrentThread && stream.error ? normalizeStreamError(stream.error) : null, - threadId: stream.threadId, + threadId: projectedThreadId, submitMessage, respondInterrupt, respondAllInterrupts: stream.respondAll, diff --git a/web/client/src/sections/superAgent/router.js b/web/client/src/sections/superAgent/router.js index a33d637..e0c2ead 100644 --- a/web/client/src/sections/superAgent/router.js +++ b/web/client/src/sections/superAgent/router.js @@ -18,7 +18,7 @@ export default { type: "outer", route: { key: "superAgent", - path: "/superAgent", + path: "/aichat", component: SuperAgent, nav: false, }, diff --git a/web/client/src/sections/superAgent/utils/streamMessage.js b/web/client/src/sections/superAgent/utils/streamMessage.js index 10cb058..a27bf16 100644 --- a/web/client/src/sections/superAgent/utils/streamMessage.js +++ b/web/client/src/sections/superAgent/utils/streamMessage.js @@ -47,8 +47,12 @@ const normalizeMessageContent = (content) => { const text = readTextContent(content); const lines = text.split(/\r?\n/); const fileUrls = lines.filter(isUploadedFileUrl); + const fileNames = fileUrls.map(getUploadedFileName).filter(Boolean); + const messageText = lines.filter((line) => !isUploadedFileUrl(line)).join("\n").trim(); return { - content: lines.filter((line) => !isUploadedFileUrl(line)).join("\n").trim(), + // URL 继续放入 files 供附件 tag 使用;正文文本只展示解码后的文件名, + // 避免把带 token 的上传地址直接展示给用户。 + content: [...fileNames, messageText].filter(Boolean).join("\n"), files: fileUrls.map((url) => ({ id: url, name: getUploadedFileName(url), diff --git a/web/package-lock.json b/web/package-lock.json index edb1c89..de9bd1f 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -13,6 +13,9 @@ "@json-render/core": "^0.19.0", "@json-render/react": "^0.19.0", "@koa/multer": "^3.0.2", + "@langchain/core": "1.2.5", + "@langchain/langgraph-sdk": "1.9.28", + "@langchain/react": "1.0.29", "@peace/react_client": "^5.0.8", "@tiptap/extension-dropcursor": "^2.8.0", "@tiptap/extension-gapcursor": "^2.8.0", @@ -41,6 +44,13 @@ "mermaid": "^11.12.2", "moment": "^2.30.1", "multer": "^1.4.5-lts.2", + "pdfjs-dist": "^5.6.205", + "pg": "^8.22.0", + "quill": "^1.3.7", + "quill-better-table": "^1.2.10", + "quill-blot-formatter": "^1.0.5", + "quill-image-resize-module": "^3.0.0", + "react-json-pretty": "^2.2.0", "react-markdown": "^10.1.0", "rehype-autolink-headings": "^7.1.0", "rehype-highlight": "^7.0.2", @@ -527,6 +537,12 @@ "integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==", "license": "MIT" }, + "node_modules/@cfworker/json-schema": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/@cfworker/json-schema/-/json-schema-4.1.1.tgz", + "integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==", + "license": "MIT" + }, "node_modules/@chevrotain/types": { "version": "11.1.2", "resolved": "https://registry.npmmirror.com/@chevrotain/types/-/types-11.1.2.tgz", @@ -1041,6 +1057,110 @@ "node": ">= 18" } }, + "node_modules/@langchain/core": { + "version": "1.2.5", + "resolved": "https://registry.npmmirror.com/@langchain/core/-/core-1.2.5.tgz", + "integrity": "sha512-4lXj3fTPQYGdEtOG9gWDnvmp6wpXNMo9MmWzfZxxPUxMcjulZJa93pYAZ90luFLg2YVdVuUl2tuwdD7tY5K9MA==", + "license": "MIT", + "dependencies": { + "@cfworker/json-schema": "^4.0.2", + "@standard-schema/spec": "^1.1.0", + "js-tiktoken": "^1.0.12", + "langsmith": ">=0.5.0 <1.0.0", + "mustache": "^4.2.0", + "p-queue": "^6.6.2", + "zod": "^3.25.76 || ^4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@langchain/langgraph-sdk": { + "version": "1.9.28", + "resolved": "https://registry.npmmirror.com/@langchain/langgraph-sdk/-/langgraph-sdk-1.9.28.tgz", + "integrity": "sha512-4j3XuM0PvtmAbL8mPfBS99ez3+ytRfgbOpAR/nOeaejTRF3Q9dNw2QnaGLGng8wLPtGLoSj+SYgUOVxy9Bv9vg==", + "license": "MIT", + "dependencies": { + "@langchain/protocol": "^0.0.18", + "@types/json-schema": "^7.0.15", + "p-queue": "^9.0.1", + "p-retry": "^7.1.1" + }, + "peerDependencies": { + "@langchain/core": "^1.1.48", + "react": "^18 || ^19", + "react-dom": "^18 || ^19", + "svelte": "^4.0.0 || ^5.0.0", + "vue": "^3.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "svelte": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/@langchain/langgraph-sdk/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/@langchain/langgraph-sdk/node_modules/p-queue": { + "version": "9.3.3", + "resolved": "https://registry.npmmirror.com/p-queue/-/p-queue-9.3.3.tgz", + "integrity": "sha512-NXAOdnEe5FsZJfT4oK84lE1Y5cFFdWlRuOo5tww8DyNMxyRXwn39fIkUtNLKppcPC+UYU/bXujNCUGDv01y7CA==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.4", + "p-timeout": "^7.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@langchain/langgraph-sdk/node_modules/p-timeout": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/p-timeout/-/p-timeout-7.0.1.tgz", + "integrity": "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@langchain/protocol": { + "version": "0.0.18", + "resolved": "https://registry.npmmirror.com/@langchain/protocol/-/protocol-0.0.18.tgz", + "integrity": "sha512-XW1egQtPfsGI41w2AMZNFZrUIwFSQHTjVMZs0OaTpCAvht/QLoaPN8FQcsysMVypOhupG28J29yOorrc70otBQ==", + "license": "MIT" + }, + "node_modules/@langchain/react": { + "version": "1.0.29", + "resolved": "https://registry.npmmirror.com/@langchain/react/-/react-1.0.29.tgz", + "integrity": "sha512-SR+Rr0qtgEAfT/C7MsRLDx8dBZCS6x4DqAEisFul5nkCyt7u3AzGiEijJPpTyag9PdLDOqRCgzlhZxIWh+WDEA==", + "license": "MIT", + "dependencies": { + "@langchain/langgraph-sdk": "1.9.28" + }, + "peerDependencies": { + "@langchain/core": "^1.1.48", + "react": "^18 || ^19" + } + }, "node_modules/@mermaid-js/parser": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/@mermaid-js/parser/-/parser-1.2.0.tgz", @@ -1050,6 +1170,256 @@ "@chevrotain/types": "~11.1.2" } }, + "node_modules/@napi-rs/canvas": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas/-/canvas-0.1.100.tgz", + "integrity": "sha512-xglYA6q3XO5P3BNJYxVZ1IV7DLVjp1Py6nwag88YntrS+3vKHyYcMqXVS4ZztJmwz2uGvz1FWhI/4LgbR5uQDA==", + "license": "MIT", + "optional": true, + "workspaces": [ + "e2e/*" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/canvas-android-arm64": "0.1.100", + "@napi-rs/canvas-darwin-arm64": "0.1.100", + "@napi-rs/canvas-darwin-x64": "0.1.100", + "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.100", + "@napi-rs/canvas-linux-arm64-gnu": "0.1.100", + "@napi-rs/canvas-linux-arm64-musl": "0.1.100", + "@napi-rs/canvas-linux-riscv64-gnu": "0.1.100", + "@napi-rs/canvas-linux-x64-gnu": "0.1.100", + "@napi-rs/canvas-linux-x64-musl": "0.1.100", + "@napi-rs/canvas-win32-arm64-msvc": "0.1.100", + "@napi-rs/canvas-win32-x64-msvc": "0.1.100" + } + }, + "node_modules/@napi-rs/canvas-android-arm64": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.100.tgz", + "integrity": "sha512-hjhCKhntPv9+t4ckHymdx0phYNcVW+GKQR6Lzw2zE+pOVjOplSmtx9nNNknTjbEDLcuLZqA1y8ufKg1XfgftzQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-darwin-arm64": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.100.tgz", + "integrity": "sha512-2PcswRaC7Ly645DGt88///zuFDhJxJYdKAs1uU3mfk1atYkXufgcgLfBpk6Tm12nCQBaNt1wpybuPZ4qOhTo8A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-darwin-x64": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.100.tgz", + "integrity": "sha512-ePNZtj7pNIva/siZMg+HmbeozkIjqUIYdoymH8HaA3qK7LfzFN4WMBM8G6HQ9ZC+H3+Dnn5pqtiXpgLykaPOhw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm-gnueabihf": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.100.tgz", + "integrity": "sha512-d5cDB48oWFGU8/XPhUOFAlySgb/VAu7D+s8fi55K1Pcfg8aPplHWqMgibhVLU8ky7Pyg/fuiVLz4Nf3JrSTuUA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-gnu": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.100.tgz", + "integrity": "sha512-rDxgxRu69RvDlX/bh9o22DxLsGr8EqsNgotL9+RwQE1S0b0cqeatqsw6aW45mukm0B42DIAaAacKaYQ8cqS1nw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-musl": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.100.tgz", + "integrity": "sha512-K3mDW66N+xT2/V439u1alFANiBUjdEx2gLiNYnCmUsva5jZMxWTjafBYwTzYK+EMFMHrUoabuU+T1BIP5CgbYQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-riscv64-gnu": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.100.tgz", + "integrity": "sha512-mooqUBTIsccZpnoQC4NgrC1v6C1vof39etLNMnBwCY+p0gajWJvAHLGQ6g/gGyS5YrpDW+GefSN4+Cvcr08UWw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-gnu": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.100.tgz", + "integrity": "sha512-1eCvkDCazm7FFhsT7DfGOdSaHgZVK3bt/dSBl5EWHOWmnz+I7j8tPseJqqD81NF+MH21jKUK4wQSDjN0mdhnTg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-musl": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.100.tgz", + "integrity": "sha512-20arT6lnI19S68qNlii73TSEDbECNgzMz2EpldC1V3mZFuRkeujXkcebRk0LRJe9SEUAooYiLokfMViY8IX7yA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-win32-arm64-msvc": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-win32-arm64-msvc/-/canvas-win32-arm64-msvc-0.1.100.tgz", + "integrity": "sha512-DZFFT1wIAg37LJw37yhMRFfjATd3vTQzjZ1Yki8u2vhO6Hi5VE6BVaGQ1aaDu7xb4iMErz+9EOwjpS7xcxFeBw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-win32-x64-msvc": { + "version": "0.1.100", + "resolved": "https://registry.npmmirror.com/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.100.tgz", + "integrity": "sha512-MyT1j3mHC2+Lu4pBi9mKyMJhtP6U7k7EldY7sj/uS5gJA65gTXt8MefJQXLJo5d/vZbuWmfxzkEUNc/urV3pHA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, "node_modules/@napi-rs/lzma-linux-x64-gnu": { "version": "1.5.1", "resolved": "https://registry.npmmirror.com/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", @@ -2594,6 +2964,12 @@ "@types/unist": "*" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, "node_modules/@types/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmmirror.com/@types/linkify-it/-/linkify-it-5.0.0.tgz", @@ -3193,6 +3569,15 @@ "wrap-ansi": "^5.1.0" } }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmmirror.com/co/-/co-4.6.0.tgz", @@ -4033,6 +4418,15 @@ "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", "license": "MIT" }, + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/delaunator": { "version": "5.1.0", "resolved": "https://registry.npmmirror.com/delaunator/-/delaunator-5.1.0.tgz", @@ -4396,6 +4790,12 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, + "node_modules/fast-diff": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/fast-diff/-/fast-diff-1.1.2.tgz", + "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==", + "license": "Apache-2.0" + }, "node_modules/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmmirror.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", @@ -5064,6 +5464,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-network-error": { + "version": "1.3.2", + "resolved": "https://registry.npmmirror.com/is-network-error/-/is-network-error-1.3.2.tgz", + "integrity": "sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -5129,6 +5541,15 @@ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "license": "MIT" }, + "node_modules/js-tiktoken": { + "version": "1.0.21", + "resolved": "https://registry.npmmirror.com/js-tiktoken/-/js-tiktoken-1.0.21.tgz", + "integrity": "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==", + "license": "MIT", + "dependencies": { + "base64-js": "^1.5.1" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5358,6 +5779,39 @@ "node": ">= 0.6" } }, + "node_modules/langsmith": { + "version": "0.8.11", + "resolved": "https://registry.npmmirror.com/langsmith/-/langsmith-0.8.11.tgz", + "integrity": "sha512-dNKtyEiNS6L10qsRGKExQVHoMsRGBJt+xiBHn6G8JxslapedUhXVkvcDkhi00EuiIMeil+RevAVG8k6VM0B9ew==", + "license": "MIT", + "dependencies": { + "p-queue": "6.6.2" + }, + "peerDependencies": { + "@opentelemetry/api": "*", + "@opentelemetry/exporter-trace-otlp-proto": "*", + "@opentelemetry/sdk-trace-base": "*", + "openai": "*", + "ws": ">=7" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/exporter-trace-otlp-proto": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { + "optional": true + }, + "openai": { + "optional": true + }, + "ws": { + "optional": true + } + } + }, "node_modules/layout-base": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/layout-base/-/layout-base-1.0.2.tgz", @@ -5477,6 +5931,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lop": { "version": "0.4.2", "resolved": "https://registry.npmmirror.com/lop/-/lop-0.4.2.tgz", @@ -6666,6 +7132,15 @@ "node": ">= 6.0.0" } }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, "node_modules/nanoid": { "version": "5.1.16", "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-5.1.16.tgz", @@ -6788,6 +7263,15 @@ "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", "license": "MIT" }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz", @@ -6815,6 +7299,49 @@ "node": ">=6" } }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmmirror.com/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/p-retry/-/p-retry-7.1.1.tgz", + "integrity": "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w==", + "license": "MIT", + "dependencies": { + "is-network-error": "^1.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz", @@ -6846,6 +7373,12 @@ "tslib": "^2.0.3" } }, + "node_modules/parchment": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/parchment/-/parchment-1.1.4.tgz", + "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==", + "license": "BSD-3-Clause" + }, "node_modules/parse-entities": { "version": "4.0.2", "resolved": "https://registry.npmmirror.com/parse-entities/-/parse-entities-4.0.2.tgz", @@ -6993,6 +7526,107 @@ "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "license": "MIT" }, + "node_modules/pdfjs-dist": { + "version": "5.7.284", + "resolved": "https://registry.npmmirror.com/pdfjs-dist/-/pdfjs-dist-5.7.284.tgz", + "integrity": "sha512-h4EdYQczmGhbOlqc3PPZwxevn7ApdWPbovAuWXOB/DjIyigSnwfy2oze7c6mRcSr9XgLp3eN3EeL4DyySTPMFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=22.13.0 || >=24" + }, + "optionalDependencies": { + "@napi-rs/canvas": "^0.1.100" + } + }, + "node_modules/pg": { + "version": "8.23.0", + "resolved": "https://registry.npmmirror.com/pg/-/pg-8.23.0.tgz", + "integrity": "sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.14.0", + "pg-pool": "^3.14.0", + "pg-protocol": "^1.16.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.4.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/pg-cloudflare/-/pg-cloudflare-1.4.0.tgz", + "integrity": "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.14.0", + "resolved": "https://registry.npmmirror.com/pg-connection-string/-/pg-connection-string-2.14.0.tgz", + "integrity": "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.14.0", + "resolved": "https://registry.npmmirror.com/pg-pool/-/pg-pool-3.14.0.tgz", + "integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.16.0", + "resolved": "https://registry.npmmirror.com/pg-protocol/-/pg-protocol-1.16.0.tgz", + "integrity": "sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", @@ -7061,6 +7695,45 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/probe-image-size": { "version": "7.3.0", "resolved": "https://registry.npmmirror.com/probe-image-size/-/probe-image-size-7.3.0.tgz", @@ -7130,6 +7803,23 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmmirror.com/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/property-information": { "version": "7.2.0", "resolved": "https://registry.npmmirror.com/property-information/-/property-information-7.2.0.tgz", @@ -7367,117 +8057,3004 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/rc-cascader": { - "version": "3.34.0", - "resolved": "https://registry.npmmirror.com/rc-cascader/-/rc-cascader-3.34.0.tgz", - "integrity": "sha512-KpXypcvju9ptjW9FaN2NFcA2QH9E9LHKq169Y0eWtH4e/wHQ5Wh5qZakAgvb8EKZ736WZ3B0zLLOBsrsja5Dag==", - "dev": true, - "license": "MIT", + "node_modules/quill": { + "version": "1.3.7", + "resolved": "https://registry.npmmirror.com/quill/-/quill-1.3.7.tgz", + "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==", + "license": "BSD-3-Clause", "dependencies": { - "@babel/runtime": "^7.25.7", - "classnames": "^2.3.1", - "rc-select": "~14.16.2", - "rc-tree": "~5.13.0", - "rc-util": "^5.43.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" + "clone": "^2.1.1", + "deep-equal": "^1.0.1", + "eventemitter3": "^2.0.3", + "extend": "^3.0.2", + "parchment": "^1.1.4", + "quill-delta": "^3.6.2" } }, - "node_modules/rc-cascader/node_modules/@babel/runtime": { - "version": "7.29.7", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.7.tgz", - "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } + "node_modules/quill-better-table": { + "version": "1.2.10", + "resolved": "https://registry.npmmirror.com/quill-better-table/-/quill-better-table-1.2.10.tgz", + "integrity": "sha512-CFwxAQzt4EPCQuynQ65R/FU7Yu//kcDBb/rmBBOsFfO758+q50zvG/PDt4Lenv9DcrSgwnyNkfo4yeA5fzzVYQ==", + "license": "MIT" }, - "node_modules/rc-checkbox": { - "version": "3.5.0", - "resolved": "https://registry.npmmirror.com/rc-checkbox/-/rc-checkbox-3.5.0.tgz", - "integrity": "sha512-aOAQc3E98HteIIsSqm6Xk2FPKIER6+5vyEFMZfo73TqM+VVAIqOkHoPjgKLqSNtVLWScoaM7vY2ZrGEheI79yg==", - "dev": true, - "license": "MIT", + "node_modules/quill-blot-formatter": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/quill-blot-formatter/-/quill-blot-formatter-1.0.5.tgz", + "integrity": "sha512-iVmuEdmMIpvERBnnDfosWul6VAVN6tqQRruUzAEwA9ZbQ/Ef7DTHGZDUR4KklXpxM+z50opFp6m1NhNdN6HJhw==", + "license": "Apache-2.0", "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "^2.3.2", - "rc-util": "^5.25.2" + "deepmerge": "^2.0.0" }, "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-checkbox/node_modules/@babel/runtime": { - "version": "7.29.7", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.7.tgz", - "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" + "quill": "^1.3.4" } }, - "node_modules/rc-collapse": { - "version": "3.9.0", - "resolved": "https://registry.npmmirror.com/rc-collapse/-/rc-collapse-3.9.0.tgz", - "integrity": "sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==", - "dev": true, + "node_modules/quill-delta": { + "version": "3.6.3", + "resolved": "https://registry.npmmirror.com/quill-delta/-/quill-delta-3.6.3.tgz", + "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "2.x", - "rc-motion": "^2.3.4", - "rc-util": "^5.27.0" + "deep-equal": "^1.0.1", + "extend": "^3.0.2", + "fast-diff": "1.1.2" }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-collapse/node_modules/@babel/runtime": { - "version": "7.29.7", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.7.tgz", - "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=0.10" } }, - "node_modules/rc-dialog": { - "version": "9.6.0", - "resolved": "https://registry.npmmirror.com/rc-dialog/-/rc-dialog-9.6.0.tgz", - "integrity": "sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==", - "dev": true, + "node_modules/quill-image-resize-module": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/quill-image-resize-module/-/quill-image-resize-module-3.0.0.tgz", + "integrity": "sha512-1TZBnUxU/WIx5dPyVjQ9yN7C6mLZSp04HyWBEMqT320DIq4MW4JgzlOPDZX5ZpBM3bU6sacU4kTLUc8VgYQZYw==", + "hasShrinkwrap": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.10.1", - "@rc-component/portal": "^1.0.0-8", - "classnames": "^2.2.6", - "rc-motion": "^2.3.0", - "rc-util": "^5.21.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" + "lodash": "^4.17.4", + "quill": "^1.2.2", + "raw-loader": "^0.5.1" } }, - "node_modules/rc-dialog/node_modules/@babel/runtime": { - "version": "7.29.7", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.7.tgz", - "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } + "node_modules/quill-image-resize-module/node_modules/acorn": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.0.2.tgz", + "extraneous": true }, - "node_modules/rc-drawer": { - "version": "7.3.0", + "node_modules/quill-image-resize-module/node_modules/acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/acorn-dynamic-import/node_modules/acorn": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.11.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/acorn-jsx/node_modules/acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/ajv": { + "version": "4.11.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/anymatch": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/aria-query": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-0.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/arr-flatten": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/array.prototype.find": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/asn1.js": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-cli": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.24.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-code-frame": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-core": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.24.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-eslint": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-generator": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.24.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-call-delegate": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-define-map": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-explode-assignable-expression": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-function-name": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-get-function-arity": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-hoist-variables": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-optimise-call-expression": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-regex": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-remap-async-to-generator": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helper-replace-supers": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-helpers": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-loader": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-6.4.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-async-to-generator": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-class-properties": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-block-scoping": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-classes": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-computed-properties": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-function-name": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-object-super": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-parameters": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-sticky-regex": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-es2015-unicode-regex": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-exponentiation-operator": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-regenerator": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-plugin-transform-strict-mode": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.22.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-polyfill": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-preset-env": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.3.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-preset-es2015": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-register": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-template": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-traverse": { + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.23.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babel-types": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.23.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/babylon": { + "version": "6.16.1", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.16.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/base64-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/big.js": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/binary-extensions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.8.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/brace-expansion": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/browserify-aes": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/caniuse-db": { + "version": "1.0.30000646", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000646.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/chokidar": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/cipher-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/circular-json": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/cli-width": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/convert-source-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/core-js": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/create-hash": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/create-hmac": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/crypto-browserify": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/damerau-levenshtein": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/debug": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/doctrine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/electron-to-chromium": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/emoji-regex": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.4.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/enhanced-resolve": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/errno": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/es-abstract": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.7.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/es5-ext": { + "version": "0.10.15", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.15.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/es6-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-config-airbnb": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-14.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-config-airbnb-base": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-import-resolver-node": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-module-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-module-utils/node_modules/debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-module-utils/node_modules/ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-plugin-import": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-plugin-jsx-a11y": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-4.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-plugin-react": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eslint/node_modules/user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/espree": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.4.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/esrecurse": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/esrecurse/node_modules/estraverse": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/evp_bytestokey": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/extend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fast-diff": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/filename-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/flat-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fs-readdir-recursive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.1.tgz", + "extraneous": true, + "hasInstallScript": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/abbrev": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/aproba": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/are-we-there-yet": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/brace-expansion": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/dashdash/node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/deep-extend": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/extend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/extsprintf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/form-data": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/fstream": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.10.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/fstream-ignore": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/gauge": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/getpass": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/getpass/node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/is-my-json-valid": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/jodid25519": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/jsprim": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/mime-db": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/mime-types": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/node-pre-gyp": { + "version": "0.6.33", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.33.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/npmlog": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/qs": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/rc": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.7.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/rc/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/readable-stream": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/rimraf": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/sshpk": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/sshpk/node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/tar-pack": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/tar-pack/node_modules/once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/tar-pack/node_modules/readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/tough-cookie": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/uid-number": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/uuid": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/verror": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/wide-align": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/fsevents/node_modules/xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/function-bind": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/globals": { + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.17.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/hash.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/hmac-drbg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/hosted-git-info": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/https-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/ignore": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.2.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/interpret": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-dotfile": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-my-json-valid": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-resolvable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/js-tokens": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/js-yaml": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/json-loader": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/jsx-ast-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/kind-of": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/load-json-file/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz" + }, + "node_modules/quill-image-resize-module/node_modules/lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/miller-rabin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/nan": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.5.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/node-libs-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/normalize-package-data": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/object.assign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/optionator/node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/os-browserify": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/output-file-sync": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/parchment": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/parchment/-/parchment-1.0.8.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/pbkdf2": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.9.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/private": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/process": { + "version": "0.11.9", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.9.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/quill": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/quill/-/quill-1.2.3.tgz" + }, + "node_modules/quill-image-resize-module/node_modules/quill-delta": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.5.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/randomatic": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/randombytes": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/raw-loader": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz" + }, + "node_modules/quill-image-resize-module/node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/readable-stream": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/regenerate": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/regenerator-runtime": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/regenerator-transform": { + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.8.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/regex-cache": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/remove-trailing-separator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/resolve": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/ripemd160": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/sha.js": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/shelljs": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.7.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/source-list-map": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-1.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/source-map-support": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.14.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/stream-http": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/table/node_modules/string-width": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/tapable": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/timers-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/to-fast-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/tryit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/uglify-js": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.20.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/util/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/v8flags": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.0.12.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/watchpack": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.3.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/webpack": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.3.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/webpack-sources": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/webpack/node_modules/acorn": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.11.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/webpack/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/webpack/node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/webpack/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/webpack/node_modules/yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "extraneous": true + }, + "node_modules/quill-image-resize-module/node_modules/yargs-parser/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "extraneous": true + }, + "node_modules/quill/node_modules/eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==", + "license": "MIT" + }, + "node_modules/rc-cascader": { + "version": "3.34.0", + "resolved": "https://registry.npmmirror.com/rc-cascader/-/rc-cascader-3.34.0.tgz", + "integrity": "sha512-KpXypcvju9ptjW9FaN2NFcA2QH9E9LHKq169Y0eWtH4e/wHQ5Wh5qZakAgvb8EKZ736WZ3B0zLLOBsrsja5Dag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "classnames": "^2.3.1", + "rc-select": "~14.16.2", + "rc-tree": "~5.13.0", + "rc-util": "^5.43.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-cascader/node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/rc-checkbox": { + "version": "3.5.0", + "resolved": "https://registry.npmmirror.com/rc-checkbox/-/rc-checkbox-3.5.0.tgz", + "integrity": "sha512-aOAQc3E98HteIIsSqm6Xk2FPKIER6+5vyEFMZfo73TqM+VVAIqOkHoPjgKLqSNtVLWScoaM7vY2ZrGEheI79yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.3.2", + "rc-util": "^5.25.2" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-checkbox/node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/rc-collapse": { + "version": "3.9.0", + "resolved": "https://registry.npmmirror.com/rc-collapse/-/rc-collapse-3.9.0.tgz", + "integrity": "sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.3.4", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-collapse/node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/rc-dialog": { + "version": "9.6.0", + "resolved": "https://registry.npmmirror.com/rc-dialog/-/rc-dialog-9.6.0.tgz", + "integrity": "sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/portal": "^1.0.0-8", + "classnames": "^2.2.6", + "rc-motion": "^2.3.0", + "rc-util": "^5.21.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dialog/node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/rc-drawer": { + "version": "7.3.0", "resolved": "https://registry.npmmirror.com/rc-drawer/-/rc-drawer-7.3.0.tgz", "integrity": "sha512-DX6CIgiBWNpJIMGFO8BAISFkxiuKitoizooj4BDyee8/SnBn0zwO2FHrNDpqqepj0E/TFTDpmEBCyFuTgC7MOg==", "dev": true, @@ -8375,6 +11952,19 @@ "dev": true, "license": "MIT" }, + "node_modules/react-json-pretty": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/react-json-pretty/-/react-json-pretty-2.2.0.tgz", + "integrity": "sha512-3UMzlAXkJ4R8S4vmkRKtvJHTewG4/rn1Q18n0zqdu/ipZbUPLVZD+QwC7uVcD/IAY3s8iNVHlgR2dMzIUS0n1A==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=15.0", + "react-dom": ">=15.0" + } + }, "node_modules/react-markdown": { "version": "10.1.0", "resolved": "https://registry.npmmirror.com/react-markdown/-/react-markdown-10.1.0.tgz", @@ -8991,6 +12581,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz",