diff --git a/app/components/reviews/AIAnalysis.tsx b/app/components/reviews/AIAnalysis.tsx new file mode 100644 index 0000000..3ef4afc --- /dev/null +++ b/app/components/reviews/AIAnalysis.tsx @@ -0,0 +1,132 @@ +/** + * AI智能分析组件 + * 显示AI对文档的分析结果、风险提示和优化建议 + */ + +// 分析项类型 +interface AnalysisItem { + title: string; + content: string; + description: string; +} + +// 分析数据类型 +interface AnalysisData { + riskAlerts: AnalysisItem[]; + suggestions: AnalysisItem[]; + summary: string; +} + +interface AIAnalysisProps { + analysisData: AnalysisData; + score: number; + onConfirmResults: () => void; +} + +export function AIAnalysis({ analysisData, score, onConfirmResults }: AIAnalysisProps) { + const handleExportReport = () => { + alert('导出评查报告功能'); + }; + + // 渲染风险提示项 + const renderRiskAlerts = () => { + return analysisData.riskAlerts.map((item, index) => ( +
+
+ +
+

+ {item.title}: + {item.content} +

+

{item.description}

+
+
+
+ )); + }; + + // 渲染优化建议项 + const renderSuggestions = () => { + return analysisData.suggestions.map((item, index) => ( +
+
+ +
+

+ {item.title}: + {item.content} +

+

{item.description}

+
+
+
+ )); + }; + + // 获取评分对应的颜色类 + const getScoreColorClass = (score: number) => { + if (score >= 90) return 'text-success'; + if (score >= 70) return 'text-warning'; + return 'text-error'; + }; + + // 获取评分条对应的颜色类 + const getScoreBarColorClass = (score: number) => { + if (score >= 90) return 'bg-success'; + if (score >= 70) return 'bg-warning'; + return 'bg-error'; + }; + + return ( +
+
+

AI智能分析

+ + {/* 风险提示 */} + {analysisData.riskAlerts.length > 0 && renderRiskAlerts()} + + {/* 优化建议 */} + {analysisData.suggestions.length > 0 && renderSuggestions()} +
+ +
+

综合评价

+
+ {/* 评价摘要 */} +

{analysisData.summary}

+ + {/* 评分 */} +
+

+ 合规性评分: + {score}分 +

+
+
+
+
+ + {/* 操作按钮 */} +
+ + +
+
+
+
+ ); +} \ No newline at end of file diff --git a/app/components/reviews/FileDetails.tsx b/app/components/reviews/FileDetails.tsx new file mode 100644 index 0000000..2ab4392 --- /dev/null +++ b/app/components/reviews/FileDetails.tsx @@ -0,0 +1,150 @@ +/** + * 文件详情组件 + * 显示文件基本信息、合同信息和评查信息 + */ +import { ReactNode } from 'react'; + +// 文件基本信息 +interface FileInfo { + fileName: string; + contractNumber: string; + fileSize: string; + fileFormat: string; + pageCount: number; + uploadTime: string; + uploadUser: string; +} + +// 合同信息 +interface ContractInfo { + contractType: string; + signDate: string; + parties: { + partyA: string; + partyB: string; + }; + amount: string; + period: string; +} + +// 评查信息 +interface ReviewInfo { + reviewTime: string; + reviewModel: string; + ruleGroup: string; + result: string; + issueCount: number; +} + +interface FileDetailsProps { + fileInfo: FileInfo; + contractInfo: ContractInfo; + reviewInfo: ReviewInfo; +} + +export function FileDetails({ fileInfo, contractInfo, reviewInfo }: FileDetailsProps) { + // 情况状态对应的标签 + const renderResultBadge = (result: string) => { + switch (result) { + case 'success': + return ( + + 通过 + + ); + case 'warning': + return ( + + 警告 + + ); + case 'error': + return ( + + 不通过 + + ); + default: + return ( + + 警告 + + ); + } + }; + + // 渲染信息区块 + const renderInfoSection = (title: string, icon: string, color: string, children: ReactNode) => { + return ( +
+
+ +

{title}

+
+
+ {children} +
+
+ ); + }; + + // 渲染信息行 + const renderInfoRow = (label: string, value: string | ReactNode) => { + return ( +
+
{label}:
+
{value}
+
+ ); + }; + + return ( +
+ {/* 文件基本信息 */} + {renderInfoSection('文件基本信息', 'ri-file-info-line', 'blue', ( +
+ {renderInfoRow('文件名称', fileInfo.fileName)} + {renderInfoRow('合同编号', fileInfo.contractNumber)} + {renderInfoRow('文件大小', fileInfo.fileSize)} + {renderInfoRow('文件格式', fileInfo.fileFormat)} + {renderInfoRow('页数', `${fileInfo.pageCount}页`)} + {renderInfoRow('上传时间', fileInfo.uploadTime)} + {renderInfoRow('上传用户', fileInfo.uploadUser)} +
+ ))} + + {/* 合同信息 */} + {renderInfoSection('合同信息', 'ri-file-paper-2-line', 'green', ( +
+ {renderInfoRow('合同类型', contractInfo.contractType)} + {renderInfoRow('签约日期', contractInfo.signDate)} + {renderInfoRow('合同当事人', ( +
+
甲方:{contractInfo.parties.partyA}
+
乙方:{contractInfo.parties.partyB}
+
+ ))} + {renderInfoRow('合同金额', contractInfo.amount)} + {renderInfoRow('履行期限', contractInfo.period)} +
+ ))} + + {/* 评查信息 */} + {renderInfoSection('评查信息', 'ri-search-eye-line', 'purple', ( + <> +
+ {renderInfoRow('评查时间', reviewInfo.reviewTime)} + {renderInfoRow('评查模型', reviewInfo.reviewModel)} + {renderInfoRow('评查规则组', reviewInfo.ruleGroup)} + {renderInfoRow('评查结果', ( +
+ {renderResultBadge(reviewInfo.result)} + (共发现{reviewInfo.issueCount}个问题) +
+ ))} +
+ + ))} +
+ ); +} \ No newline at end of file diff --git a/app/components/reviews/FileInfo.tsx b/app/components/reviews/FileInfo.tsx new file mode 100644 index 0000000..ecb8546 --- /dev/null +++ b/app/components/reviews/FileInfo.tsx @@ -0,0 +1,72 @@ +/** + * 文件信息组件 + * 显示文件名称、状态信息以及操作按钮(下载原文件、导出评查报告、确认评查结果) + */ + +interface FileInfoProps { + fileInfo: { + fileName: string; + contractNumber: string; + fileSize?: string; + fileFormat?: string; + pageCount?: number; + uploadTime?: string; + uploadUser?: string; + }; + onConfirmResults: () => void; +} + +export function FileInfo({ fileInfo, onConfirmResults }: FileInfoProps) { + const handleDownloadFile = () => { + alert('下载原文件功能'); + }; + + const handleExportReport = () => { + alert('导出评查报告功能'); + }; + + return ( +
+
+
+

+ {fileInfo.fileName} + + 合同编号:{fileInfo.contractNumber} + + {fileInfo.fileSize && ( + + {fileInfo.fileSize} | {fileInfo.fileFormat} | {fileInfo.pageCount}页 + + )} +

+ {fileInfo.uploadTime && ( +
+ 上传时间:{fileInfo.uploadTime} | 上传用户:{fileInfo.uploadUser} +
+ )} +
+
+ + + +
+
+
+ ); +} \ No newline at end of file diff --git a/app/components/reviews/FilePreview.tsx b/app/components/reviews/FilePreview.tsx new file mode 100644 index 0000000..1009c06 --- /dev/null +++ b/app/components/reviews/FilePreview.tsx @@ -0,0 +1,200 @@ +/** + * 文件预览组件 + * 显示文档内容和评查点高亮 + */ +import { useState, useEffect, useRef } from 'react'; + +// 定义评查点类型 +interface ReviewPoint { + id: string; + title: string; + status: string; + content: string; + suggestion: string; + position?: { + section: string; + index: number; + }; +} + +// 定义文档内容类型 +interface FileContent { + title: string; + contractNumber: string; + parties: { + partyA: { + name: string; + address: string; + representative: string; + phone: string; + }; + partyB: { + name: string; + address: string; + representative: string; + phone: string; + }; + }; + sections: { + title: string; + content: string; + }[]; +} + +interface FilePreviewProps { + fileContent: FileContent; + reviewPoints: ReviewPoint[]; + activeReviewPointId: string | null; +} + +export function FilePreview({ fileContent, reviewPoints, activeReviewPointId }: FilePreviewProps) { + const [zoomLevel, setZoomLevel] = useState(100); + const [highlightsVisible, setHighlightsVisible] = useState(true); + const contentRef = useRef(null); + + // 放大文档 + const handleZoomIn = () => { + if (zoomLevel < 200) { + setZoomLevel(prevZoom => prevZoom + 10); + } + }; + + // 缩小文档 + const handleZoomOut = () => { + if (zoomLevel > 50) { + setZoomLevel(prevZoom => prevZoom - 10); + } + }; + + // 切换高亮显示 + const toggleHighlights = () => { + setHighlightsVisible(!highlightsVisible); + }; + + // 当选中的评查点变化时,滚动到对应位置 + useEffect(() => { + if (activeReviewPointId && contentRef.current) { + const highlightElement = contentRef.current.querySelector(`[data-review-id="${activeReviewPointId}"]`); + if (highlightElement) { + highlightElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); + + // 添加临时突出显示效果 + highlightElement.classList.add('highlight-focus'); + setTimeout(() => { + highlightElement.classList.remove('highlight-focus'); + }, 1500); + } + } + }, [activeReviewPointId]); + + // 获取评查点对应的样式类 + const getHighlightClass = (status: string) => { + switch (status) { + case 'warning': + return 'warning'; + case 'error': + return 'error'; + case 'success': + return 'success'; + default: + return 'warning'; + } + }; + + // 渲染文档内容 + const renderDocumentContent = () => { + return ( +
+

{fileContent.title}

+

合同编号:{fileContent.contractNumber}

+ +
+

甲方(供方):{fileContent.parties.partyA.name}

+

地址:{fileContent.parties.partyA.address}

+

法定代表人:{fileContent.parties.partyA.representative}

+

联系电话:{fileContent.parties.partyA.phone}

+

 

+

乙方(需方):{fileContent.parties.partyB.name}

+

地址:{fileContent.parties.partyB.address}

+

法定代表人:{fileContent.parties.partyB.representative}

+

联系电话:{fileContent.parties.partyB.phone}

+
+ +

根据《中华人民共和国合同法》及有关法律法规的规定,经双方协商一致,签订本合同,共同遵守。

+ + {fileContent.sections.map((section, sectionIndex) => ( +
+

{section.title}

+ {renderSectionContent(section.content, section.title, sectionIndex)} +
+ ))} +
+ ); + }; + + // 渲染章节内容,处理高亮 + const renderSectionContent = (content: string, sectionTitle: string, sectionIndex: number) => { + const lines = content.split('\n'); + + return lines.map((line, lineIndex) => { + // 查找该行对应的评查点 + const reviewPoint = reviewPoints.find(point => + point.position && + point.position.section === sectionTitle && + point.position.index === lineIndex + ); + + if (reviewPoint && highlightsVisible) { + // 如果有对应的评查点,添加高亮 + const isActive = reviewPoint.id === activeReviewPointId; + return ( +
+

{line}

+
+ ); + } else { + // 没有评查点,正常显示 + return

{line}

; + } + }); + }; + + return ( +
+
+
+ + 文件预览 +
+
+ + + +
+
+
+ {renderDocumentContent()} +
+
+ ); +} \ No newline at end of file diff --git a/app/components/reviews/ReviewPointsList.tsx b/app/components/reviews/ReviewPointsList.tsx new file mode 100644 index 0000000..065d71c --- /dev/null +++ b/app/components/reviews/ReviewPointsList.tsx @@ -0,0 +1,441 @@ +/** + * 评查点列表组件 + * 显示评查结果统计和所有评查点列表 + */ +import { useState } from 'react'; + +// 评查点类型定义 +interface ReviewPoint { + id: string; + title: string; + location: string; + status: string; + content: string; + suggestion: string; + needsHumanReview?: boolean; + humanReviewNote?: string; + humanReviewBy?: string; + humanReviewTime?: string; + position?: { + section: string; + index: number; + }; +} + +// 统计数据类型 +interface Statistics { + total: number; + success: number; + warning: number; + error: number; + score: number; +} + +interface ReviewPointsListProps { + reviewPoints: ReviewPoint[]; + statistics: Statistics; + activeReviewPointId: string | null; + onReviewPointSelect: (id: string) => void; + onStatusChange: (id: string, status: string) => void; +} + +export function ReviewPointsList({ + reviewPoints, + statistics, + activeReviewPointId, + onReviewPointSelect, + onStatusChange +}: ReviewPointsListProps) { + const [editingReviewPoint, setEditingReviewPoint] = useState(null); + const [userInputText, setUserInputText] = useState(''); + const [searchText, setSearchText] = useState(''); + const [statusFilter, setStatusFilter] = useState(null); + + // 过滤评查点 + const filteredReviewPoints = reviewPoints.filter(point => { + const matchesSearch = searchText === '' || + point.title.toLowerCase().includes(searchText.toLowerCase()) || + point.location.toLowerCase().includes(searchText.toLowerCase()) || + point.content.toLowerCase().includes(searchText.toLowerCase()); + + const matchesStatus = statusFilter === null || point.status === statusFilter; + + return matchesSearch && matchesStatus; + }); + + // 处理点击"一键替换"按钮 + const handleReplace = (reviewPointId: string) => { + // 在实际应用中,这里应该调用API进行内容替换 + // 模拟替换操作 + alert(`将为评查点 ${reviewPointId} 执行一键替换操作`); + + // 更新评查点状态为成功 + onStatusChange(reviewPointId, 'success'); + }; + + // 处理评查点审核操作 + const handleReviewAction = (reviewPointId: string, action: 'approve' | 'reject') => { + // 更新评查点状态 + onStatusChange(reviewPointId, action === 'approve' ? 'success' : 'error'); + + // 清除编辑状态 + setEditingReviewPoint(null); + setUserInputText(''); + + alert(`${action === 'approve' ? '通过' : '不通过'}了评查点 ${reviewPointId}`); + }; + + // 显示评查点详情编辑界面 + const handleEditReviewPoint = (reviewPointId: string) => { + setEditingReviewPoint(reviewPointId); + + // 获取评查点的建议内容作为初始值 + const reviewPoint = reviewPoints.find(point => point.id === reviewPointId); + if (reviewPoint) { + setUserInputText(reviewPoint.suggestion || ''); + } + }; + + // 渲染评查统计信息 + const renderStatistics = () => { + return ( +
+
+
+
+ {statistics.total} +
+ 总计 +
+
+
+ + 通过 +
+
+
+ + 警告 +
+
+
+ + 错误 +
+
+
+ ); + }; + + // 渲染搜索框 + const renderSearchBar = () => { + return ( +
+
+ setSearchText(e.target.value)} + /> + + {searchText && ( + + )} +
+
+ ); + }; + + // 渲染评查点状态标签 + const renderStatusBadge = (status: string) => { + switch (status) { + case 'success': + return ( + + 通过 + + ); + case 'warning': + return ( + + 警告 + + ); + case 'error': + return ( + + 不通过 + + ); + case 'processing': + return ( + + 处理中 + + ); + default: + return ( + + 警告 + + ); + } + }; + + // 渲染人工审核标记 + const renderHumanReviewBadge = (reviewPoint: ReviewPoint) => { + if (reviewPoint.needsHumanReview) { + return ( + + 需人工 + + ); + } + return null; + }; + + // 渲染人工审核注释 + const renderHumanReviewNote = (reviewPoint: ReviewPoint) => { + if (reviewPoint.needsHumanReview && reviewPoint.humanReviewNote) { + return ( +
+ {reviewPoint.humanReviewNote} + {reviewPoint.humanReviewBy && reviewPoint.humanReviewTime && ( +
+ 审核人:{reviewPoint.humanReviewBy} | 时间:{reviewPoint.humanReviewTime} +
+ )} +
+ ); + } + return null; + }; + + // 渲染评查点内容与建议 + const renderReviewPointContent = (reviewPoint: ReviewPoint) => { + // 如果当前评查点不处于编辑状态,只显示简单信息 + if (editingReviewPoint !== reviewPoint.id) { + if (reviewPoint.status === 'success') { + // 已通过的评查点只显示基本信息和人工审核注释 + if (reviewPoint.needsHumanReview && reviewPoint.humanReviewNote) { + return ( +
+
+

已处理

+ {reviewPoint.suggestion && ( +
+

{reviewPoint.suggestion}

+
+ )} +
+
+ ); + } + return null; + } + + return ( +
+
+
+ 当前值 + + {reviewPoint.status === 'error' ? '不符合规范' : '需优化'} + +
+

{reviewPoint.content || '(内容为空)'}

+ + {reviewPoint.suggestion && ( +
+
+ 建议修改为 + + 符合规范 + +
+ +
+ + +
+
+
+ ); + }; + + // 渲染无匹配结果提示 + const renderEmptyState = () => { + return ( +
+ +

没有找到匹配的评查点

+

请尝试不同的搜索词或清除筛选条件

+ {(searchText || statusFilter) && ( + + )} +
+ ); + }; + + return ( +
+
+ + 评查结果 +
+ + {/* 评查统计 */} + {renderStatistics()} + + {/* 搜索框 */} + {renderSearchBar()} + + {/* 评查点列表 */} +
+ {filteredReviewPoints.length > 0 ? ( + filteredReviewPoints.map(reviewPoint => ( + + )) + ) : ( + renderEmptyState() + )} +
+
+ ); +} \ No newline at end of file diff --git a/app/components/reviews/ReviewTabs.tsx b/app/components/reviews/ReviewTabs.tsx new file mode 100644 index 0000000..08221e4 --- /dev/null +++ b/app/components/reviews/ReviewTabs.tsx @@ -0,0 +1,48 @@ +/** + * 评查选项卡组件 + * 提供三个选项卡:评查结果、AI智能分析、文件信息 + */ +import { ReactNode } from 'react'; + +interface ReviewTabsProps { + activeTab: string; + onTabChange: (tabKey: string) => void; + children: ReactNode; +} + +export function ReviewTabs({ activeTab, onTabChange, children }: ReviewTabsProps) { + return ( +
+
+ + + +
+ +
+ {children} +
+
+ ); +} \ No newline at end of file diff --git a/app/components/reviews/index.ts b/app/components/reviews/index.ts new file mode 100644 index 0000000..d6d23c8 --- /dev/null +++ b/app/components/reviews/index.ts @@ -0,0 +1,10 @@ +/** + * 评查详情组件导出文件 + */ + +export { FileInfo } from './FileInfo'; +export { ReviewTabs } from './ReviewTabs'; +export { FilePreview } from './FilePreview'; +export { ReviewPointsList } from './ReviewPointsList'; +export { AIAnalysis } from './AIAnalysis'; +export { FileDetails } from './FileDetails'; \ No newline at end of file diff --git a/app/routes/reviews.tsx b/app/routes/reviews.tsx new file mode 100644 index 0000000..67d798e --- /dev/null +++ b/app/routes/reviews.tsx @@ -0,0 +1,458 @@ +/** + * 评查详情页面 + * + * 功能概述: + * - 显示文档评查结果和详细信息 + * - 支持查看文档内容及评查点高亮标记 + * - 提供评查点列表,分为通过、警告和错误三种类型 + * - 支持评查点处理,如一键替换、人工审核等功能 + * - 支持导出评查报告和下载原文件 + * + * 组件结构: + * - FileInfo: 显示文件基本信息和操作按钮 + * - ReviewTabs: 页面选项卡,包括评查结果、AI智能分析和文件信息 + * - FilePreview: 文档预览组件,显示文档内容及高亮问题 + * - ReviewPointsList: 评查点列表组件,显示所有评查结果 + * - AIAnalysis: AI智能分析结果,提供综合评价 + * - FileDetails: 文件详情信息 + * + * 数据流转: + * 1. 页面加载时从API获取评查详情数据 + * 2. 根据评查点ID关联文档中的高亮区域 + * 3. 点击评查点时在文档中定位对应位置 + * 4. 处理评查点时更新状态并反馈到UI + * + * @author 中国烟草AI合同及卷宗审核系统开发团队 + */ + +import { type MetaFunction } from "@remix-run/node"; +import { useState, useEffect } from "react"; +import { useNavigate } from "@remix-run/react"; +import reviewsStyles from "~/styles/reviews.css?url"; + +// 导入评查详情页面组件 +import { + FileInfo, + ReviewTabs, + FilePreview, + ReviewPointsList, + AIAnalysis, + FileDetails +} from "~/components/reviews"; + +// 定义评查点类型 +interface ReviewPoint { + id: string; + title: string; + location: string; + status: string; + content: string; + suggestion: string; + needsHumanReview?: boolean; + humanReviewNote?: string; + humanReviewBy?: string; + humanReviewTime?: string; + position?: { + section: string; + index: number; + }; +} + +// 定义统计数据类型 +interface Statistics { + total: number; + success: number; + warning: number; + error: number; + score: number; +} + +// 定义文件信息类型 +interface FileInfo { + fileName: string; + contractNumber: string; + fileSize: string; + fileFormat: string; + pageCount: number; + uploadTime: string; + uploadUser: string; +} + +// 定义合同信息类型 +interface ContractInfo { + contractType: string; + signDate: string; + parties: { + partyA: string; + partyB: string; + }; + amount: string; + period: string; +} + +// 定义评查信息类型 +interface ReviewInfo { + reviewTime: string; + reviewModel: string; + ruleGroup: string; + result: string; + issueCount: number; +} + +// 定义文档内容类型 +interface FileContent { + title: string; + contractNumber: string; + parties: { + partyA: { + name: string; + address: string; + representative: string; + phone: string; + }; + partyB: { + name: string; + address: string; + representative: string; + phone: string; + }; + }; + sections: { + title: string; + content: string; + }[]; +} + +// 定义分析项类型 +interface AnalysisItem { + title: string; + content: string; + description: string; +} + +// 定义分析数据类型 +interface AnalysisData { + riskAlerts: AnalysisItem[]; + suggestions: AnalysisItem[]; + summary: string; +} + +// 定义评查数据类型 +interface ReviewData { + fileInfo: FileInfo; + contractInfo: ContractInfo; + reviewInfo: ReviewInfo; + statistics: Statistics; + fileContent: FileContent; + reviewPoints: ReviewPoint[]; + aiAnalysis: AnalysisData; +} + +export const meta: MetaFunction = () => { + return [ + { title: "评查详情 - 中国烟草AI合同及卷宗审核系统" }, + { + name: "description", + content: "查看文档评查结果,处理问题点,确认评查结果" + } + ]; +}; + +export function links() { + return [{ rel: "stylesheet", href: reviewsStyles }]; +} + +export const handle = { + breadcrumb: "评查详情" +}; + +export default function ReviewDetails() { + const navigate = useNavigate(); + const [isLoading, setIsLoading] = useState(true); + const [activeTab, setActiveTab] = useState('preview'); // 'preview', 'analysis', 'fileinfo' + const [reviewData, setReviewData] = useState(null); + const [activeReviewPointId, setActiveReviewPointId] = useState(null); + + // 模拟获取评查数据 + useEffect(() => { + // 模拟API请求延迟 + const timer = setTimeout(() => { + // 模拟评查数据 + const mockData = getMockReviewData(); + setReviewData(mockData); + setIsLoading(false); + + // 默认选中第一个评查点 + if (mockData.reviewPoints.length > 0) { + setActiveReviewPointId(mockData.reviewPoints[0].id); + } + }, 800); + + return () => clearTimeout(timer); + }, []); + + const handleTabChange = (tabKey: string) => { + setActiveTab(tabKey); + }; + + const handleReviewPointSelect = (reviewPointId: string) => { + setActiveReviewPointId(reviewPointId); + }; + + const handleReviewPointStatusChange = (reviewPointId: string, newStatus: string) => { + // 更新评查点状态 + if (reviewData) { + const updatedReviewPoints = reviewData.reviewPoints.map(point => + point.id === reviewPointId ? { ...point, status: newStatus } : point + ); + + setReviewData({ + ...reviewData, + reviewPoints: updatedReviewPoints, + statistics: calculateStatistics(updatedReviewPoints) + }); + } + }; + + const handleConfirmResults = () => { + alert('评查结果已确认'); + navigate('/reviews'); // 假设评查列表页面路径为 /reviews + }; + + return ( +
+ {isLoading ? ( +
+
+ 加载中... +
+ ) : reviewData && ( + <> + {/* 文件信息和操作按钮 */} + + + {/* 选项卡 */} + + {/* 评查结果选项卡内容 */} + {activeTab === 'preview' && ( +
+ {/* 左侧:文件预览 */} +
+ +
+ + {/* 右侧:评查结果 */} +
+ +
+
+ )} + + {/* AI智能分析选项卡内容 */} + {activeTab === 'analysis' && ( + + )} + + {/* 文件信息选项卡内容 */} + {activeTab === 'fileinfo' && ( + + )} +
+ + )} +
+ ); +} + +// 计算评查统计数据 +function calculateStatistics(reviewPoints: ReviewPoint[]): Statistics { + const total = reviewPoints.length; + const success = reviewPoints.filter(point => point.status === 'success').length; + const warning = reviewPoints.filter(point => point.status === 'warning').length; + const error = reviewPoints.filter(point => point.status === 'error').length; + + // 计算评分:通过占总数的百分比,错误项有额外惩罚 + const score = Math.round((success / total) * 100 - (error * 5)); + + return { + total, + success, + warning, + error, + score: Math.max(0, Math.min(100, score)) // 确保分数在0-100之间 + }; +} + +// 模拟评查数据 +function getMockReviewData(): ReviewData { + return { + fileInfo: { + fileName: "烟草产品销售合同(2023版).docx", + contractNumber: "XS-2023-1025-001", + fileSize: "5.2MB", + fileFormat: "DOCX", + pageCount: 5, + uploadTime: "2023-10-25 14:30:45", + uploadUser: "张三" + }, + contractInfo: { + contractType: "销售合同", + signDate: "2023年10月20日", + parties: { + partyA: "XX烟草公司", + partyB: "YY贸易有限公司" + }, + amount: "¥ 1,580,000.00", + period: "2023年11月1日至2024年10月31日" + }, + reviewInfo: { + reviewTime: "2023-10-25 14:35:12", + reviewModel: "DeepSeek", + ruleGroup: "合同标准规则组", + result: "warning", + issueCount: 9 + }, + statistics: { + total: 15, + success: 6, + warning: 7, + error: 2, + score: 75 + }, + fileContent: { + title: "烟草产品销售合同", + contractNumber: "XS-2023-1025-001", + parties: { + partyA: { + name: "XX烟草公司", + address: "XX省XX市XX区XX路XX号", + representative: "张XX", + phone: "123-4567-8901" + }, + partyB: { + name: "YY贸易有限公司", + address: "XX省XX市XX区YY路YY号", + representative: "李YY", + phone: "123-4567-8902" + } + }, + sections: [ + { + title: "总则", + content: "1.1 本合同适用于甲乙双方之间的烟草制品买卖事宜。\n1.2 双方应本着平等互利、诚实信用的原则履行本合同。" + }, + { + title: "合同标的物", + content: "2.1 产品名称:烟草制品\n2.2 规格型号:如附件所列\n2.3 数量:5000箱\n2.4 质量要求:符合国家标准GB/T XXXXX-XXXX" + }, + { + title: "交货与付款", + content: "3.1 交货时间:自合同签订之日起30日内。\n3.2 乙方应在收到货物之日起5个工作日内支付合同款项,甲方应在收到乙方全部付款后开具增值税专用发票,乙方应在收到发票后支付剩余款项。\n3.3 交货地点:乙方指定的仓库。\n3.4 运输方式:陆运,运费由甲方承担。" + }, + { + title: "合同文本", + content: "本合同一式两份,甲乙双方各执一份,具有同等法律效力。" + } + ] + }, + reviewPoints: [ + { + id: "1", + title: "付款条件描述不明确", + location: "付款条款清晰性", + status: "error", + content: "乙方应在收到货物之日起5个工作日内支付合同款项,甲方应在收到乙方全部付款后开具增值税专用发票,乙方应在收到发票后支付剩余款项。", + suggestion: "乙方应在收到货物验收合格之日起5个工作日内支付合同总额的70%,甲方收到该部分款项后3个工作日内向乙方开具等额增值税专用发票;乙方应在收到发票之日起5个工作日内支付剩余30%款项。", + position: { section: "交货与付款", index: 2 } + }, + { + id: "2", + title: "违约责任条款缺失", + location: "合同权利义务对等性", + status: "warning", + content: "如合同发生纠纷,双方应协商解决。", + suggestion: "如合同发生纠纷,双方应友好协商解决;协商不成的,任何一方均有权向甲方所在地人民法院提起诉讼。任何一方未能履行本合同约定义务,应向守约方支付合同总金额的10%作为违约金;给对方造成损失的,还应赔偿由此产生的全部损失。", + position: { section: "争议解决", index: 0 } + }, + { + id: "3", + title: "签章不完整", + location: "合同签署规范性", + status: "warning", + content: "乙方(盖章):YY贸易有限公司\n代表人签字:李YY\n日期:2023年10月20日", + suggestion: "需要联系甲方补充公章", + needsHumanReview: true, + humanReviewNote: "需要联系甲方补充公章", + position: { section: "签章", index: 0 } + }, + { + id: "9", + title: "交货方式描述模糊", + location: "履行条款明确性", + status: "success", + content: "3.4 运输方式:陆运,运费由甲方承担。", + suggestion: "建议补充具体的运输方式和时间", + needsHumanReview: true, + humanReviewNote: "经核实,该交货方式虽然描述不够详细,但符合行业惯例且双方已经多次合作,不会造成实际履行障碍。", + humanReviewBy: "王法务", + humanReviewTime: "2023-11-05 14:30:22", + position: { section: "交货与付款", index: 4 } + }, + { + id: "10", + title: "法律适用条款缺失", + location: "争议解决条款完整性", + status: "error", + content: "", + suggestion: "第十三条 法律适用\n本合同的订立、效力、解释、履行及争议的解决均适用中华人民共和国法律。因本合同引起的或与本合同有关的任何争议,双方应友好协商解决。协商不成的,提交甲方所在地人民法院诉讼解决。", + position: { section: "缺失", index: 0 } + } + ], + aiAnalysis: { + riskAlerts: [ + { + title: "风险提示", + content: "本合同缺少违约责任条款,可能导致权责不明。", + description: "根据《中华人民共和国民法典》第五百七十七条规定,建议增加违约责任条款,明确双方违约责任及赔偿方式。" + }, + { + title: "完整性检查", + content: "本合同缺少法律适用条款。", + description: "根据行业惯例,销售合同应明确约定适用法律和纠纷解决方式,以避免后续争议解决时的不确定性。" + } + ], + suggestions: [ + { + title: "优化建议", + content: "建议完善付款条件描述。", + description: "目前合同中关于付款条件的描述存在歧义,可能导致付款时间和条件不明确。建议按系统修改建议优化。" + } + ], + summary: "本合同基本结构完整,主体内容清晰,但存在多处条款描述不完善的问题,主要体现在支付条件、违约责任、不可抗力、保密条款、合同终止条件等方面。这些问题虽不影响合同的基本合规性,但可能在合同履行过程中引发争议和纠纷。同时,合同签章不完整,也影响了合同的法律效力。建议对上述问题进行修改完善后再行签署。" + } + }; +} diff --git a/app/styles/reviews.css b/app/styles/reviews.css new file mode 100644 index 0000000..b2a6afe --- /dev/null +++ b/app/styles/reviews.css @@ -0,0 +1,385 @@ +:root { + --primary-color: #00684a; + --primary-hover: #005a40; + --primary-light: rgba(0, 104, 74, 0.1); + --success-color: #52c41a; + --warning-color: #faad14; + --error-color: #ff4d4f; + --text-color: rgba(0, 0, 0, 0.85); + --text-secondary: rgba(0, 0, 0, 0.45); + --border-color: #f0f0f0; + --bg-gray: #f5f5f5; +} + +/* 文件信息和操作按钮区域 */ +.file-info-header { + margin-bottom: 16px; +} + +/* 选项卡样式 */ +.tab-container { + margin-bottom: 16px; +} + +.tab-nav { + display: flex; + border-bottom: 1px solid var(--border-color); + background-color: white; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + overflow: hidden; +} + +.tab-nav-item { + padding: 12px 20px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + border-bottom: 2px solid transparent; + transition: all 0.3s; + display: flex; + align-items: center; +} + +.tab-nav-item i { + margin-right: 6px; + font-size: 16px; +} + +.tab-nav-item:hover { + color: var(--primary-color); +} + +.tab-nav-item.active { + color: var(--primary-color); + border-bottom-color: var(--primary-color); +} + +.tab-content { + background-color: white; + border: 1px solid var(--border-color); + border-top: none; + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + padding: 20px; +} + +/* 文件预览区域 */ +.file-preview { + background-color: white; + border: 1px solid var(--border-color); + border-radius: 6px; + height: calc(100vh - 220px); + min-height: 500px; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.file-preview-header { + padding: 12px 16px; + border-bottom: 1px solid var(--border-color); + display: flex; + justify-content: space-between; + align-items: center; + background-color: var(--primary-light); + height: 36px; +} + +.file-preview-content { + flex: 1; + overflow-y: auto; + position: relative; +} + +.file-preview-actions { + display: flex; + gap: 8px; +} + +/* 文档内容样式 */ +.word-document { + padding: 40px; + background-color: white; + font-family: 'SimSun', serif; + line-height: 1.8; +} + +.word-document h1 { + font-size: 18px; + text-align: center; + font-weight: bold; + margin-bottom: 20px; +} + +.word-document h2 { + font-size: 16px; + font-weight: bold; + margin-top: 16px; + margin-bottom: 8px; +} + +.word-document p { + text-indent: 2em; + margin-bottom: 10px; +} + +/* 高亮区域 */ +.highlight-area { + display: inline-block; + position: relative; + padding: 2px; + margin: -2px; + cursor: pointer; + transition: all 0.2s; +} + +.highlight-area:hover { + box-shadow: 0 0 0 3px rgba(250, 173, 20, 0.6); +} + +.highlight-area.warning { + background-color: rgba(250, 173, 20, 0.2); + border: 2px solid var(--warning-color); +} + +.highlight-area.error { + background-color: rgba(255, 77, 79, 0.2); + border: 2px solid var(--error-color); +} + +.highlight-area.success { + background-color: rgba(82, 196, 26, 0.2); + border: 2px solid var(--success-color); +} + +/* 评查点列表区域 */ +.review-points-panel { + background-color: white; + border: 1px solid var(--border-color); + border-radius: 6px; + height: calc(100vh - 220px); + min-height: 500px; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.review-panel-header { + border-bottom: 1px solid var(--border-color); + background-color: var(--primary-light); + height: 36px; + display: flex; + align-items: center; + padding: 0 16px; +} + +.review-statistics { + padding: 16px; + border-bottom: 1px solid var(--border-color); + background-color: white; +} + +.review-points-list { + flex: 1; + overflow-y: auto; + padding: 0; +} + +.review-point-item { + padding: 20px; + border-bottom: 1px solid var(--border-color); + cursor: pointer; + transition: background-color 0.3s; + width: 100%; +} + +.review-point-item:hover { + background-color: #f5f5f5; +} + +.review-point-item.active { + background-color: var(--primary-light); +} + +.review-point-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 8px; + flex-wrap: wrap; +} + +.review-point-title { + font-weight: 500; + font-size: 13px; + line-height: 1.3; + margin-right: 8px; + margin-bottom: 3px; +} + +.review-point-location { + display: flex; + align-items: center; + font-size: 12px; + color: var(--text-secondary); + background-color: #f5f5f5; + border-radius: 4px; + padding: 2px 8px; + width: fit-content; + align-self: flex-start; +} + +/* 状态标签 */ +.status-badge { + display: inline-flex; + align-items: center; + padding: 2px 8px; + border-radius: 4px; + font-size: 12px; + font-weight: 500; + white-space: nowrap; +} + +.status-waiting { + background-color: #f9f0ff; + color: #722ed1; +} + +.status-processing { + background-color: #e6f7ff; + color: #1890ff; +} + +.status-success { + background-color: #f6ffed; + color: #52c41a; +} + +.status-error { + background-color: #fff1f0; + color: #f5222d; +} + +.status-warning { + background-color: #fffbe6; + color: #faad14; +} + +/* 替换动作按钮 */ +.replace-action { + background-color: #1890ff; + color: white; + border: none; + padding: 4px 8px; + border-radius: 4px; + font-size: 12px; + cursor: pointer; + margin-top: 6px; + display: inline-flex; + align-items: center; + justify-content: center; + width: 100%; +} + +.replace-action i { + margin-right: 4px; +} + +.replace-action:hover { + background-color: #40a9ff; +} + +/* 人工审核标记 */ +.human-review-badge { + display: inline-flex; + align-items: center; + background-color: #e6f7ff; + color: #1890ff; + padding: 1px 4px; + border-radius: 4px; + font-size: 11px; + margin-left: 4px; + line-height: 1.2; +} + +.human-review-note { + background-color: #e6f7ff; + border-left: 3px solid #1890ff; + padding: 6px 10px; + margin-top: 6px; + font-size: 12px; + color: #333; + text-align: left; +} + +/* AI智能分析区域 */ +.analysis-card { + margin-bottom: 16px; +} + +.analysis-item { + background-color: #f5f5f5; + border-radius: 4px; + padding: 16px; + margin-bottom: 16px; +} + +.analysis-title { + font-weight: 500; + margin-bottom: 8px; +} + +.analysis-content { + color: var(--text-secondary); + font-size: 14px; +} + +.score-container { + margin-top: 16px; +} + +.score-bar { + height: 10px; + background-color: #eee; + border-radius: 5px; + margin-top: 8px; + overflow: hidden; +} + +.score-fill { + height: 100%; + background-color: var(--warning-color); +} + +/* 文件详情页面 */ +.info-section { + margin-bottom: 24px; + border-radius: 6px; + overflow: hidden; +} + +.info-header { + padding: 12px 16px; + display: flex; + align-items: center; +} + +.info-content { + padding: 16px; + background-color: white; +} + +.info-row { + display: flex; + margin-bottom: 12px; +} + +.info-label { + width: 120px; + color: var(--text-secondary); +} + +.info-value { + flex: 1; +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d34d6b6..030ba7c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,12 +8,20 @@ "dependencies": { "@codemirror/lang-javascript": "^6.2.3", "@codemirror/theme-one-dark": "^6.1.2", + "@react-pdf-viewer/core": "^3.12.0", + "@react-pdf-viewer/highlight": "^3.12.0", + "@react-pdf-viewer/search": "^3.12.0", "@remix-run/node": "^2.16.2", "@remix-run/react": "^2.16.2", "@remix-run/serve": "^2.16.2", "@uiw/react-codemirror": "^4.23.10", "dayjs": "^1.11.13", + "diff": "^7.0.0", + "html-docx-js": "^0.3.1", "isbot": "^4.1.0", + "mammoth": "^1.9.0", + "pdf-lib": "^1.17.1", + "pdfjs-dist": "^3.11.174", "pg": "^8.14.1", "prismjs": "^1.30.0", "react": "^18.2.0", @@ -1335,6 +1343,26 @@ "@lezer/common": "^1.0.0" } }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, "node_modules/@marijn/find-cluster-break": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", @@ -1495,6 +1523,32 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/@pdf-lib/standard-fonts": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", + "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==", + "dependencies": { + "pako": "^1.0.6" + } + }, + "node_modules/@pdf-lib/standard-fonts/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/@pdf-lib/upng": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@pdf-lib/upng/-/upng-1.0.1.tgz", + "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==", + "dependencies": { + "pako": "^1.0.10" + } + }, + "node_modules/@pdf-lib/upng/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1505,6 +1559,40 @@ "node": ">=14" } }, + "node_modules/@react-pdf-viewer/core": { + "version": "3.12.0", + "resolved": "https://registry.npmmirror.com/@react-pdf-viewer/core/-/core-3.12.0.tgz", + "integrity": "sha512-8MsdlQJ4jaw3GT+zpCHS33nwnvzpY0ED6DEahZg9WngG++A5RMhk8LSlxdHelwaFFHFiXBjmOaj2Kpxh50VQRg==", + "peerDependencies": { + "pdfjs-dist": "^2.16.105 || ^3.0.279", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@react-pdf-viewer/highlight": { + "version": "3.12.0", + "resolved": "https://registry.npmmirror.com/@react-pdf-viewer/highlight/-/highlight-3.12.0.tgz", + "integrity": "sha512-UxdnvnvTjikugOUEj/RIeJm3Lm93aVu+Xr0jMa7d+wrZlHh5b7wTd+FeI6gNk9wdJDrB70oHiCzn6MTbepkc5g==", + "dependencies": { + "@react-pdf-viewer/core": "3.12.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@react-pdf-viewer/search": { + "version": "3.12.0", + "resolved": "https://registry.npmmirror.com/@react-pdf-viewer/search/-/search-3.12.0.tgz", + "integrity": "sha512-jAkLpis49fsDDY/HrbUZIOIhzF5vynONQNA4INQKI38r/MjveblrkNv7qbr9j5lQ/WFic5+gD1e+Mtpf1/7DiA==", + "dependencies": { + "@react-pdf-viewer/core": "3.12.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@remix-run/dev": { "version": "2.16.2", "resolved": "https://registry.npmmirror.com/@remix-run/dev/-/dev-2.16.2.tgz", @@ -3930,12 +4018,26 @@ "resolved": "https://registry.npmmirror.com/@web3-storage/multipart-parser/-/multipart-parser-1.0.0.tgz", "integrity": "sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw==" }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@zxing/text-encoding": { "version": "0.9.0", "resolved": "https://registry.npmmirror.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz", "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", "optional": true }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/abort-controller/-/abort-controller-3.0.0.tgz", @@ -3988,6 +4090,18 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -4021,7 +4135,7 @@ "version": "5.0.1", "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -4059,6 +4173,26 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz", @@ -4351,13 +4485,12 @@ "version": "1.0.2", "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "devOptional": true }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -4411,6 +4544,11 @@ "readable-stream": "^3.4.0" } }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + }, "node_modules/body-parser": { "version": "1.20.3", "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.3.tgz", @@ -4668,6 +4806,21 @@ } ] }, + "node_modules/canvas": { + "version": "2.11.2", + "resolved": "https://registry.npmmirror.com/canvas/-/canvas-2.11.2.tgz", + "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.17.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/ccount/-/ccount-2.0.1.tgz", @@ -4761,7 +4914,7 @@ "version": "2.0.0", "resolved": "https://registry.npmmirror.com/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">=10" } @@ -4840,6 +4993,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true, + "bin": { + "color-support": "bin.js" + } + }, "node_modules/comma-separated-tokens": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", @@ -4904,7 +5066,7 @@ "version": "0.0.1", "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "devOptional": true }, "node_modules/confbox": { "version": "0.2.1", @@ -4912,6 +5074,12 @@ "integrity": "sha512-hkT3yDPFbs95mNCy1+7qNKC6Pro+/ibzYxtM2iqEigpf0sVw+bg4Zh9/snjsBcf990vfIsg5+1U7VyiyBb3etg==", "dev": true }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz", @@ -4956,8 +5124,7 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/crelt": { "version": "1.0.6", @@ -5097,7 +5264,7 @@ "version": "4.4.0", "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dev": true, + "devOptional": true, "dependencies": { "ms": "^2.1.3" }, @@ -5123,6 +5290,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dedent": { "version": "1.5.3", "resolved": "https://registry.npmmirror.com/dedent/-/dedent-1.5.3.tgz", @@ -5203,6 +5382,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", @@ -5229,6 +5414,15 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz", @@ -5236,14 +5430,18 @@ "dev": true }, "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmmirror.com/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "engines": { "node": ">=0.3.1" } }, + "node_modules/dingbat-to-unicode": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz", + "integrity": "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w==" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz", @@ -5286,6 +5484,14 @@ "url": "https://dotenvx.com" } }, + "node_modules/duck": { + "version": "0.1.12", + "resolved": "https://registry.npmmirror.com/duck/-/duck-0.1.12.tgz", + "integrity": "sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg==", + "dependencies": { + "underscore": "^1.13.1" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -6677,7 +6883,7 @@ "version": "1.0.0", "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "devOptional": true }, "node_modules/fsevents": { "version": "2.3.3", @@ -6729,6 +6935,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "optional": true + }, + "node_modules/gauge/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "optional": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/generic-names": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/generic-names/-/generic-names-4.0.0.tgz", @@ -7028,6 +7275,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz", @@ -7097,6 +7350,47 @@ "node": ">=12" } }, + "node_modules/html-docx-js": { + "version": "0.3.1", + "resolved": "https://registry.npmmirror.com/html-docx-js/-/html-docx-js-0.3.1.tgz", + "integrity": "sha512-QSrMiRhxesqxYCa3f+2Z3ttIHPzSjDOL1tCOmIDIEET7HdabxXND6tAbsFMXAgRG4RADQ3wbl74ydMmjidaDPA==", + "dependencies": { + "jszip": "^2.3.0", + "lodash.escape": "^3.0.0", + "lodash.merge": "^3.2.0" + } + }, + "node_modules/html-docx-js/node_modules/jszip": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/jszip/-/jszip-2.7.0.tgz", + "integrity": "sha512-JIsRKRVC3gTRo2vM4Wy9WBC3TRcfnIZU8k65Phi3izkvPH975FowRYtKGT6PxevA0XnJ/yO8b0QwV0ydVyQwfw==", + "dependencies": { + "pako": "~1.0.2" + } + }, + "node_modules/html-docx-js/node_modules/lodash.merge": { + "version": "3.3.2", + "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-3.3.2.tgz", + "integrity": "sha512-ZgGZpRhWLjivGUbjtApZR4HyLv/UAyoYqESVYkK4aLBJVHRrbFpG+GNnE9JPijliME4LkKM0SFI/WyOiBiv1+w==", + "dependencies": { + "lodash._arraycopy": "^3.0.0", + "lodash._arrayeach": "^3.0.0", + "lodash._createassigner": "^3.0.0", + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0", + "lodash.isplainobject": "^3.0.0", + "lodash.istypedarray": "^3.0.0", + "lodash.keys": "^3.0.0", + "lodash.keysin": "^3.0.0", + "lodash.toplainobject": "^3.0.0" + } + }, + "node_modules/html-docx-js/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", @@ -7112,6 +7406,19 @@ "node": ">= 0.8" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz", @@ -7173,6 +7480,11 @@ "node": ">= 4" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmmirror.com/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz", @@ -7212,7 +7524,7 @@ "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, + "devOptional": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -7502,7 +7814,7 @@ "version": "3.0.0", "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -7949,6 +8261,54 @@ "node": ">=4.0" } }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmmirror.com/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/jszip/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz", @@ -7998,6 +8358,14 @@ "node": ">= 0.8.0" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.3.tgz", @@ -8063,6 +8431,56 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash._arraycopy": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", + "integrity": "sha512-RHShTDnPKP7aWxlvXKiDT6IX2jCs6YZLCtNhOru/OX2Q/tzX295vVBK5oX1ECtN+2r86S0Ogy8ykP1sgCZAN0A==" + }, + "node_modules/lodash._arrayeach": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz", + "integrity": "sha512-Mn7HidOVcl3mkQtbPsuKR0Fj0N6Q6DQB77CtYncZcJc0bx5qv2q4Gl6a0LC1AN+GSxpnBDNnK3CKEm9XNA4zqQ==" + }, + "node_modules/lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha512-rFR6Vpm4HeCK1WPGvjZSJ+7yik8d8PVUdCJx5rT2pogG4Ve/2ZS7kfmO5l5T2o5V2mqlNIfSF5MZlr1+xOoYQQ==" + }, + "node_modules/lodash._basefor": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/lodash._basefor/-/lodash._basefor-3.0.3.tgz", + "integrity": "sha512-6bc3b8grkpMgDcVJv9JYZAk/mHgcqMljzm7OsbmcE2FGUMmmLQTPHlh/dFqR8LA0GQ7z4K67JSotVKu5058v1A==" + }, + "node_modules/lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==" + }, + "node_modules/lodash._createassigner": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", + "integrity": "sha512-LziVL7IDnJjQeeV95Wvhw6G28Z8Q6da87LWKOPWmzBLv4u6FAT/x5v00pyGW0u38UoogNF2JnD3bGgZZDaNEBw==", + "dependencies": { + "lodash._bindcallback": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash.restparam": "^3.0.0" + } + }, + "node_modules/lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmmirror.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==" + }, + "node_modules/lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmmirror.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha512-De+ZbrMu6eThFti/CSzhRvTKMgQToLxbij58LMfM8JnYDNSOjkjTCIaa8ixglOeGh2nyPlakbt5bJWJ7gvpYlQ==" + }, + "node_modules/lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ==" + }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -8075,12 +8493,78 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "node_modules/lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha512-n1PZMXgaaDWZDSvuNZ/8XOcYO2hOKDqZel5adtR30VKQAtoWs/5AOeFA0vPV8moiPzlqe7F4cP2tzpFewQyelQ==", + "dependencies": { + "lodash._root": "^3.0.0" + } + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" + }, + "node_modules/lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==" + }, + "node_modules/lodash.isplainobject": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-3.2.0.tgz", + "integrity": "sha512-P4wZnho5curNqeEq/x292Pb57e1v+woR7DJ84DURelKB46lby8aDEGVobSaYtzHdQBWQrJSdxcCwjlGOvvdIyg==", + "dependencies": { + "lodash._basefor": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.keysin": "^3.0.0" + } + }, + "node_modules/lodash.istypedarray": { + "version": "3.0.6", + "resolved": "https://registry.npmmirror.com/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz", + "integrity": "sha512-lGWJ6N8AA3KSv+ZZxlTdn4f6A7kMfpJboeyvbFdE7IU9YAgweODqmOgdUHOA+c6lVWeVLysdaxciFXi+foVsWw==" + }, + "node_modules/lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==", + "dependencies": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "node_modules/lodash.keysin": { + "version": "3.0.8", + "resolved": "https://registry.npmmirror.com/lodash.keysin/-/lodash.keysin-3.0.8.tgz", + "integrity": "sha512-YDB/5xkL3fBKFMDaC+cfGV00pbiJ6XoJIfRmBhv7aR6wWtbCW6IzkiWnTfkiHTF6ALD7ff83dAtB3OEaSoyQPg==", + "dependencies": { + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmmirror.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw==" + }, + "node_modules/lodash.toplainobject": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/lodash.toplainobject/-/lodash.toplainobject-3.0.0.tgz", + "integrity": "sha512-wMI0Ju1bvSmnBS3EcRRH/3zDnZOPpDtMtNDzbbNMKuTrEpALsf+sPyMeogmv63Y11qZQO7H1xFzohIEGRMjPYA==", + "dependencies": { + "lodash._basecopy": "^3.0.0", + "lodash.keysin": "^3.0.0" + } + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmmirror.com/log-symbols/-/log-symbols-4.1.0.tgz", @@ -8118,6 +8602,16 @@ "loose-envify": "cli.js" } }, + "node_modules/lop": { + "version": "0.4.2", + "resolved": "https://registry.npmmirror.com/lop/-/lop-0.4.2.tgz", + "integrity": "sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw==", + "dependencies": { + "duck": "^0.1.12", + "option": "~0.2.1", + "underscore": "^1.13.1" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", @@ -8127,6 +8621,61 @@ "yallist": "^3.0.2" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "optional": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/mammoth": { + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/mammoth/-/mammoth-1.9.0.tgz", + "integrity": "sha512-F+0NxzankQV9XSUAuVKvkdQK0GbtGGuqVnND9aVf9VSeUA82LQa29GjLqYU6Eez8LHqSJG3eGiDW3224OKdpZg==", + "dependencies": { + "@xmldom/xmldom": "^0.8.6", + "argparse": "~1.0.3", + "base64-js": "^1.5.1", + "bluebird": "~3.4.0", + "dingbat-to-unicode": "^1.0.1", + "jszip": "^3.7.1", + "lop": "^0.4.2", + "path-is-absolute": "^1.0.0", + "underscore": "^1.13.1", + "xmlbuilder": "^10.0.0" + }, + "bin": { + "mammoth": "bin/mammoth" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/mammoth/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/markdown-extensions": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/markdown-extensions/-/markdown-extensions-1.1.1.tgz", @@ -9060,6 +9609,18 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", @@ -9187,7 +9748,7 @@ "version": "2.1.2", "resolved": "https://registry.npmmirror.com/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, + "devOptional": true, "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -9200,7 +9761,7 @@ "version": "3.3.6", "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, + "devOptional": true, "dependencies": { "yallist": "^4.0.0" }, @@ -9212,13 +9773,13 @@ "version": "4.0.0", "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "devOptional": true }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, + "devOptional": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -9345,6 +9906,12 @@ "thenify-all": "^1.0.0" } }, + "node_modules/nan": { + "version": "2.22.2", + "resolved": "https://registry.npmmirror.com/nan/-/nan-2.22.2.tgz", + "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==", + "optional": true + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", @@ -9377,12 +9944,47 @@ "node": ">= 0.6" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/normalize-package-data": { "version": "5.0.0", "resolved": "https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-5.0.0.tgz", @@ -9478,11 +10080,24 @@ "node": ">=8" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -9624,7 +10239,7 @@ "version": "1.4.0", "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, + "devOptional": true, "dependencies": { "wrappy": "1" } @@ -9644,6 +10259,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/option": { + "version": "0.2.4", + "resolved": "https://registry.npmmirror.com/option/-/option-0.2.4.tgz", + "integrity": "sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A==" + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz", @@ -9825,7 +10445,6 @@ "version": "1.0.1", "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -9881,12 +10500,54 @@ "node": ">=8" } }, + "node_modules/path2d-polyfill": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz", + "integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmmirror.com/pathe/-/pathe-1.1.2.tgz", "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true }, + "node_modules/pdf-lib": { + "version": "1.17.1", + "resolved": "https://registry.npmmirror.com/pdf-lib/-/pdf-lib-1.17.1.tgz", + "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==", + "dependencies": { + "@pdf-lib/standard-fonts": "^1.0.0", + "@pdf-lib/upng": "^1.0.1", + "pako": "^1.0.11", + "tslib": "^1.11.1" + } + }, + "node_modules/pdf-lib/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/pdf-lib/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/pdfjs-dist": { + "version": "3.11.174", + "resolved": "https://registry.npmmirror.com/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz", + "integrity": "sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==", + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "canvas": "^2.11.2", + "path2d-polyfill": "^2.0.1" + } + }, "node_modules/peek-stream": { "version": "1.1.3", "resolved": "https://registry.npmmirror.com/peek-stream/-/peek-stream-1.1.3.tgz", @@ -10402,8 +11063,7 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/promise-inflight": { "version": "1.0.1", @@ -10640,7 +11300,7 @@ "version": "3.6.2", "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, + "devOptional": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -10892,7 +11552,7 @@ "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, + "devOptional": true, "dependencies": { "glob": "^7.1.3" }, @@ -10907,7 +11567,7 @@ "version": "1.1.11", "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "devOptional": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -10918,7 +11578,7 @@ "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, + "devOptional": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -10938,7 +11598,7 @@ "version": "3.1.2", "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "devOptional": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -11129,7 +11789,7 @@ "version": "7.7.1", "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.1.tgz", "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, + "devOptional": true, "bin": { "semver": "bin/semver.js" }, @@ -11195,6 +11855,12 @@ "node": ">= 0.8.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "optional": true + }, "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmmirror.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", @@ -11245,6 +11911,11 @@ "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -11343,7 +12014,38 @@ "version": "3.0.7", "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "devOptional": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } }, "node_modules/slash": { "version": "3.0.0", @@ -11438,6 +12140,11 @@ "node": ">= 10.x" } }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, "node_modules/ssri": { "version": "10.0.6", "resolved": "https://registry.npmmirror.com/ssri/-/ssri-10.0.6.tgz", @@ -11479,7 +12186,7 @@ "version": "1.3.0", "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, + "devOptional": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -11680,7 +12387,7 @@ "version": "6.0.1", "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "devOptional": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -11857,7 +12564,7 @@ "version": "6.2.1", "resolved": "https://registry.npmmirror.com/tar/-/tar-6.2.1.tgz", "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, + "devOptional": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -11918,7 +12625,7 @@ "version": "2.1.0", "resolved": "https://registry.npmmirror.com/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, + "devOptional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -11930,7 +12637,7 @@ "version": "3.3.6", "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, + "devOptional": true, "dependencies": { "yallist": "^4.0.0" }, @@ -11942,7 +12649,7 @@ "version": "5.0.0", "resolved": "https://registry.npmmirror.com/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -11951,7 +12658,7 @@ "version": "4.0.0", "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "devOptional": true }, "node_modules/text-table": { "version": "0.2.0", @@ -12093,6 +12800,12 @@ "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", "dev": true }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/trim-lines/-/trim-lines-3.0.1.tgz", @@ -12324,6 +13037,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://registry.npmmirror.com/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==" + }, "node_modules/undici": { "version": "6.21.2", "resolved": "https://registry.npmmirror.com/undici/-/undici-6.21.2.tgz", @@ -12569,8 +13287,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utils-merge": { "version": "1.0.1", @@ -12598,6 +13315,15 @@ "node": ">=8" } }, + "node_modules/uvu/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/valibot": { "version": "0.41.0", "resolved": "https://registry.npmmirror.com/valibot/-/valibot-0.41.0.tgz", @@ -12814,6 +13540,22 @@ "node": ">= 8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/which/-/which-3.0.1.tgz", @@ -12913,6 +13655,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmmirror.com/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wide-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "optional": true + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "optional": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz", @@ -13020,7 +13791,7 @@ "version": "1.0.2", "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "devOptional": true }, "node_modules/ws": { "version": "7.5.10", @@ -13043,6 +13814,14 @@ } } }, + "node_modules/xmlbuilder": { + "version": "10.1.1", + "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-10.1.1.tgz", + "integrity": "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==", + "engines": { + "node": ">=4.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index d702d06..9753dc3 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,20 @@ "dependencies": { "@codemirror/lang-javascript": "^6.2.3", "@codemirror/theme-one-dark": "^6.1.2", + "@react-pdf-viewer/core": "^3.12.0", + "@react-pdf-viewer/highlight": "^3.12.0", + "@react-pdf-viewer/search": "^3.12.0", "@remix-run/node": "^2.16.2", "@remix-run/react": "^2.16.2", "@remix-run/serve": "^2.16.2", - "dayjs": "^1.11.13", "@uiw/react-codemirror": "^4.23.10", + "dayjs": "^1.11.13", + "diff": "^7.0.0", + "html-docx-js": "^0.3.1", "isbot": "^4.1.0", + "mammoth": "^1.9.0", + "pdf-lib": "^1.17.1", + "pdfjs-dist": "^3.11.174", "pg": "^8.14.1", "prismjs": "^1.30.0", "react": "^18.2.0",