update code

main
lijun 2024-09-15 16:27:31 +08:00
parent dfa39efef9
commit 2a179d5711
25 changed files with 1299 additions and 261 deletions

View File

@ -5,7 +5,7 @@ VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/api'
#VITE_APP_API_URL = http://62.234.3.186/mk/ai/api
# 线上接口地址
#VITE_APP_API_URL = http://10.5.1.137:8800
#VITE_APP_API_URL = http://10.5.1.21:8800
VITE_APP_API_URL = http://62.234.3.186/api
# 开发接口地址
# VITE_APP_API_URL = http://localhost:8989

View File

@ -56,12 +56,14 @@
"echarts": "^5.5.0",
"element-plus": "^2.7.2",
"js-md5": "^0.8.3",
"json-editor-vue3": "^1.1.1",
"lodash-es": "^4.17.21",
"net": "^1.0.2",
"nprogress": "^0.2.0",
"path-browserify": "^1.0.1",
"path-to-regexp": "^6.2.2",
"pinia": "^2.1.7",
"print-js": "^1.6.0",
"sockjs-client": "1.6.1",
"sortablejs": "^1.15.2",
"stompjs": "^2.3.3",
@ -91,7 +93,6 @@
"commitizen": "^4.3.0",
"cz-git": "^1.9.1",
"eslint": "^8.57.0",
"rollup-plugin-terser": "^7.0.2",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3",
@ -103,6 +104,7 @@
"postcss-html": "^1.6.0",
"postcss-scss": "^4.0.9",
"prettier": "^3.2.5",
"rollup-plugin-terser": "^7.0.2",
"sass": "^1.76.0",
"stylelint": "^16.5.0",
"stylelint-config-html": "^1.1.0",

View File

@ -37,9 +37,9 @@ const compileDeploy=(operation_id)=>{
}
//获取推理最新的模型推理日志
const inferenceTaskLatest=task_id=>{
const inferenceTaskLatest=(task_id,DeviceId)=>{
return request({
url: `/logs/inference/${task_id}/latest`,
url: `/logs/inference/${task_id}/latest?DeviceId=${DeviceId}&LogCount=50`,
method: "get"
});
}

View File

@ -34,7 +34,7 @@ class MenuAPI {
alwaysShow: false,
},
},
]
],
},
{
path: "/modelMgr",
@ -87,7 +87,7 @@ class MenuAPI {
keepAlive: true,
alwaysShow: false,
},
}
},
],
},
{
@ -141,7 +141,7 @@ class MenuAPI {
keepAlive: true,
alwaysShow: false,
},
}
},
],
},
{
@ -169,19 +169,47 @@ class MenuAPI {
keepAlive: true,
alwaysShow: false,
},
},{
path: "taskDesc",
component: "simulationEvaluation/taskDesc",
name: "simulationEvaluationTaskDesc",
},
{
path: "reportList",
component: "simulationEvaluation/reportList",
name: "simulationEvaluationReportList",
meta: {
title: "评估报告-查看",
title: "评估报告",
icon: "user",
hidden: false,
roles: ["ADMIN", "GUEST"],
keepAlive: true,
alwaysShow: false,
},
},
{
path: "addReport",
component: "simulationEvaluation/addReport",
name: "simulationEvaluationAddReport",
meta: {
title: "新建评估报告",
icon: "user",
hidden: true,
roles: ["ADMIN", "GUEST"],
keepAlive: true,
alwaysShow: false,
},
},{
},
{
path: "reportDesc",
component: "simulationEvaluation/reportDesc",
name: "simulationEvaluationReportDesc",
meta: {
title: "评估报告详情",
icon: "user",
hidden: true,
roles: ["ADMIN", "GUEST"],
keepAlive: true,
alwaysShow: false,
},
},
{
path: "addTask",
component: "simulationEvaluation/addTask",
name: "simulationEvaluationAddTask",
@ -206,7 +234,8 @@ class MenuAPI {
keepAlive: true,
alwaysShow: false,
},
},{
},
{
path: "hisTaskList",
component: "simulationEvaluation/hisTaskList",
name: "simulationEvaluationHisTaskList",
@ -471,7 +500,7 @@ class MenuAPI {
roles: ["ADMIN6", "GUEST", "ADMIN"],
keepAlive: true,
alwaysShow: false,
}
},
},
{
path: "otherToolDetail",
@ -483,7 +512,7 @@ class MenuAPI {
roles: ["ADMIN6", "GUEST", "ADMIN"],
keepAlive: true,
alwaysShow: false,
}
},
},
],
},

View File

@ -0,0 +1,39 @@
import request from "@/utils/request";
//获取评估报告列表
const reports = (data) => {
return request({
url: "/reports",
method: "get",
params: data,
});
};
const addReport=data=>{
return request({
url: "/reports",
method: "post",
data: data,
});
}
const deleteReport=id=>{
return request({
url: "/reports/"+id,
method: "delete",
});
}
const getReport=id=>{
return request({
url: "/reports/"+id,
method: "get",
});
}
export default {
reports,
addReport,
deleteReport,
getReport
};

View File

@ -11,7 +11,7 @@ class UserAPI {
"userId": 2,
"username": "admin",
"nickname": "系统管理员",
"avatar": "https://oss.youlai.tech/youlai-boot/2023/05/16/811270ef31f548af9cffc026dfc3777b.gif",
"avatar": "",
"roles": [
"ADMIN"
],

View File

@ -1,5 +1,5 @@
<template>
<div class="model-flow">{{ info }}
<div class="model-flow">
<el-row class="row-1">
<div class="card-item">
<div class="title-text">算法上传</div>

View File

@ -0,0 +1,331 @@
<template>
<div class="app-container add-report">
<div class="scroll div-content-scroll">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-card>
<template #header><svg-icon icon-class="pause" style="width: 20px; height: 20px" />报告基本信息
</template>
<el-row>
<el-col :span="8">
<el-form-item label="报告名称" prop="reportName">
<el-input v-model="form.reportName" placeholder="请输入数据集名称" />
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="报告说明" prop="reportDesc">
<el-input v-model="form.reportDesc" placeholder="请输入数据集版本" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<el-card style="margin-top: 10px;">
<template #header><svg-icon icon-class="pause" style="width: 20px; height: 20px" />推理任务
</template>
<el-table :data="info.tableData" stripe class="data-table1">
<el-table-column label="任务名称" align="left" prop="task_name" />
<el-table-column label="任务说明" align="left" prop="task_desc" />
<el-table-column label="使用数据集" align="left" prop="dataset_name" />
<el-table-column label="运行模型" align="left" prop="model_name" width="120" />
<el-table-column label="模型网络" align="left" prop="modl_net_type" width="120" />
<el-table-column label="创建时间" align="left" prop="create_time" width="120" v-if="1 == 2" />
<el-table-column label="完成时间" align="left" prop="finish_time" width="120" />
<el-table-column label="操作" fixed="right" align="center" width="100">
<template #default="scope">
<el-button text type="primary" size="small"
@click="doDelete(scope.row)"><i-ep-close-bold />删除</el-button>
</template>
</el-table-column>
<template #empty>
<el-button type="primary" @click="choiceTask"></el-button>
</template>
</el-table>
<div style="margin-top: 10px;"
v-if="['detection', 'classification', 'tracking'].indexOf(info.modl_sub_type) >= 0">
<div class="div-nav-header"><el-icon color="#409eff">
<Warning />
</el-icon></div>
<el-row class="row-norm">
<el-col :span="12">
<el-form-item label="算法性能指标">
<span v-for="(it, idx) in info.norm.lvl1" :key="idx">{{ it }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实时响应指标">
<span v-for="(it, idx) in info.norm.lvl2" :key="idx">{{ it }}</span>
</el-form-item>
</el-col>
</el-row>
</div>
<div style="margin-top: 10px;" v-if="['detection', 'classification'].indexOf(info.modl_sub_type) >= 0">
<div class="div-nav-header"><el-icon color="#409eff">
<Warning />
</el-icon></div>
<el-row>
<el-col :span="8">
<el-form-item label="置信度阈值" prop="score_threshold">
<el-input v-model="form.score_threshold" style="width: 120px;" class="txt-number"
placeholder="请输入置信度阈值" type="number" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="IoU阈值" prop="nms_threshold">
<el-input v-model="form.nms_threshold" style="width: 120px;" class="txt-number"
placeholder="请输入置信度阈值" type="number" />
</el-form-item>
</el-col>
</el-row>
</div>
</el-card>
<el-card style="margin-top: 10px;" v-if="info.modl_sub_type">
<template #header><svg-icon icon-class="pause" style="width: 20px; height: 20px" />更多测评
</template>
<el-table :data="info.tableData2" stripe class="data-table2">
<el-table-column label="任务名称" align="left" prop="task_name" />
<el-table-column label="任务说明" align="left" prop="task_desc" />
<el-table-column label="使用数据集" align="left" prop="dataset_name" />
<el-table-column label="运行模型" align="left" prop="model_name" width="120" />
<el-table-column label="模型网络" align="left" prop="modl_net_type" width="120" />
<el-table-column label="创建时间" align="left" prop="create_time" width="120" v-if="1 == 2" />
<el-table-column label="完成时间" align="left" prop="finish_time" width="120" />
<el-table-column label="操作" fixed="right" align="center" width="100">
<template #default="scope">
<el-button text type="primary" size="small" v-if="!scope.row.old"
@click="doDeleteComp(scope.row)"><i-ep-close-bold />删除</el-button>
</template>
</el-table-column>
<template #empty>
<el-button type="primary" @click="choiceRobustTask"></el-button>
<el-button type="primary" @click="choiceCompTask"></el-button>
</template>
</el-table>
</el-card>
</el-form>
</div>
<choiceTaskDlg ref="taskDlg" @success="doChoiceSuccess" />
<el-card class="card-footer">
<el-button type="primary" @click="doSave"></el-button>
</el-card>
</div>
</template>
<script setup>
import choiceTaskDlg from './components/choiceTaskDlg.vue'
import ReportApi from '@/api/report'
const router = useRouter();
const info = reactive({
tableData: [],
tableData2: [],
modl_sub_type: '',
norm: {
lvl1: [],
lvl2: [],
},
choiceType: '',
})
const formRef=ref();
const form = ref({}); //
const taskDlg = ref()
const validateScore = (r, v, callback) => {
if (+v < 0 || +v >= 1) {
return callback(new Error('值在0-1之间'))
}
callback()
}
//
const rules = reactive({
reportName: [{ required: true, message: "数据集名称不能为空", trigger: "blur" }],
score_threshold: [
{ required: true, message: "置信度阈值不能为空", trigger: "blur" },
{ validator: validateScore, trigger: 'blur' }
],
nms_threshold: [{ required: true, message: "IoU阈值不能为空", trigger: "blur" },
{ validator: validateScore, trigger: 'blur' }
],
});
//()
function doSave() {
formRef.value.validate(d=>{
if(d){
if(!info.tableData || info.tableData.length==0){
ElMessage.error("请选择任务!");
return;
}
doMakeReport();//
}
});
}
//
function doMakeReport(){
let postData={
report_name:form.value.reportName,
report_desc:form.value.reportDesc,
task_id_list:info.tableData2 && info.tableData2.length>1?info.tableData2.map(d=>d.task_id):info.tableData.map(d=>d.task_id),
extra_evaluation_type:info.choiceType
};
if(info.choiceType=='horizontal_comparison'){
postData.threshold={
score_threshold:form.value.score_threshold,
nms_threshold:form.value.nms_threshold
};
}
ReportApi.addReport(postData).then(d=>{
let reportId=d.data?.data?.report_id||'';
if(reportId){
router.push({ path: "/simulationEvaluation/reportDesc", query: { id:reportId} });
ElMessage.success("生成报告成功!");
}else{
ElMessage.error("生成报告失败!");
}
});
}
//
function doDelete(row) {
info.tableData = [];
info.modl_sub_type = "";
}
//
function doDeleteComp(row) {
let idx = info.tableData2.indexOf(row)
if (idx >= 0) {
info.tableData2 = info.tableData2.splice(idx, 1);
if (info.tableData2.length == 1) {
info.tableData2 = [];
info.choiceType=''
}
}
}
//
function choiceTask() {
info.choiceType = 'select'
taskDlg.value.showDialog({});
}
//
function choiceRobustTask() {
info.choiceType = 'robustness'
let taskId = info.tableData && info.tableData.length > 0 ? info.tableData[0].task_id : '';
taskDlg.value.showDialog({
disTaskId: taskId,
mult: false
});
}
//
function choiceCompTask() {
info.choiceType = 'horizontal_comparison'
let taskId = info.tableData && info.tableData.length > 0 ? info.tableData[0].task_id : '';
taskDlg.value.showDialog({
disTaskId: taskId,
mult: true
});
}
function doChoiceSuccess(d) {
if (info.choiceType !== 'select') {
info.tableData2 = [];
let it = info.tableData[0];
it.old = true;
info.tableData2 = [it, ...d];
}
info.tableData = d || [];
info.modl_sub_type = info.tableData != null && info.tableData.length > 0 ? info.tableData[0].modl_sub_type || '' : '';
if (['tracking'].indexOf(info.modl_sub_type) >= 0) {
info.norm = {
lvl1: "1. IDSWID跳变,2. MT跟踪次数,3. ML丢失次数,4. FM打断次数,5. MOTA跟踪准确度,6. IDF1目标匹配F1分数".split(","),
lvl2: "1. 平均推理时间,2. 系统延迟时间".split(",")
}
form.value.score_threshold = 0.5;
form.value.nms_threshold = 0.5;
} else if (['detection', 'classification'].indexOf(info.modl_sub_type) >= 0) {
info.norm = {
lvl1: "1. Accuracy准确度,2. Precision精确度,3. Recall召回率,4. F1-ScoreF1分数,5. Micro F1,6. Macro F1,7. 加权F1-Score,8. AP平均精度,9. mAP多类平均精度,10. ROC曲线,11. PR曲线".split(","),
lvl2: "1. 平均推理时间,2. 系统延迟时间".split(",")
}
form.value.score_threshold = 0.5;
form.value.nms_threshold = 0.5;
} else {
info.norm = {
lvl1: [],
lvl2: []
}
}
}
</script>
<style lang="scss">
.add-report {
.el-card__header {
padding: 8px 4px;
display: flex;
align-items: center;
}
.data-table1 {
.el-table__empty-block {
display: block;
text-align: right;
}
}
.txt-number {
input::-webkit-inner-spin-button,
input::-webkit-outer-spin-button {
-webkit-appearance: none;
}
}
.row-norm {
.el-form-item__content {
background: #eee;
border-radius: 10px;
padding: 10px;
line-height: 20px;
font-weight: bold;
}
}
.div-nav-header {
font-size: 14px;
font-weight: bold;
color: #333;
position: relative;
.el-icon {
position: relative;
margin-right: 4px;
top: 2px;
}
}
.card-footer {
position: fixed;
width: calc(100% - 215px);
bottom: 0px;
.el-card__body {
padding: 10px;
.el-pagination {
justify-content: end;
}
}
}
.div-content-scroll{
margin-bottom: 60px;
max-height: calc(100vh - 140px);
overflow-y: auto;
}
}
</style>

View File

@ -4,32 +4,34 @@
<el-steps style="width: 900px;max-width: 900px;" :space="200" :active="active" finish-status="success">
<el-step title="Step1" :class="active == 0 ? 'active' : ''" description="评估基本信息填写" />
<el-step title="Step2" :class="active == 1 ? 'active' : ''" description="选择模型" />
<el-step title="Step3" :class="active == 2 ? 'active' : ''" description="选择设备" />
<el-step title="Step4" :class="active == 3 ? 'active' : ''" description="评估数据集选择" />
<el-step title="Step3" :class="active == 2 ? 'active' : ''" description="上传推理参数" />
<el-step title="Step4" :class="active == 3 ? 'active' : ''" description="选择设备" />
<el-step title="Step5" :class="active == 4 ? 'active' : ''" description="评估数据集选择" />
</el-steps>
</el-card>
<div style="margin-bottom:100px;" class="card-content">
<addStep1 ref="step1" v-if="active == 1" />
<addStep2 ref="step2" v-if="active == 2" />
<addStep3 ref="step3" v-if="active == 3" :modelInfo="modelInfo" @compile="doCompile" />
<addStep4 ref="step4" v-if="active == 4" />
<addStep3 ref="step3" v-if="active==3" :modelInfo="modelInfo"/>
<addStep4 ref="step4" v-if="active == 4" :modelInfo="modelInfo" @compile="doCompile" />
<addStep5 ref="step5" v-if="active == 5" />
</div>
<el-card class="card-footer">
<!--
<el-button type="primary" v-if="active == 3 && state == 0" @click="doCompile"></el-button>-->
<el-button type="primary" v-if="active == 3 && state == 1" loading disabled>编译中...</el-button>
<el-button type="primary" v-if="active == 3 && state == 2" loading disabled>部署中...</el-button>
<el-button type="primary" v-if="active == 4" @click="doStart" :loading="state > 0" :disabled="state > 0">{{ state
<el-button type="primary" v-if="active == 4 && state == 1" loading disabled>编译中...</el-button>
<el-button type="primary" v-if="active == 4 && state == 2" loading disabled>部署中...</el-button>
<el-button type="primary" v-if="active == 5" @click="doStart" :loading="state > 0" :disabled="state > 0">{{ state
==
0 ? "开始推理" : "推理中..." }}</el-button>
<el-button type="primary" v-if="active > 0 && active < 3 && active != 3" @click="doPrev"></el-button>
<template v-if="(active == 3 && (state == 0 || state == 3)) || (active == 4 && state == 0)">
<el-button type="primary" v-if="active > 0 && active < 4 && active != 4" @click="doPrev"></el-button>
<template v-if="(active == 4 && (state == 0 || state == 3)) || (active == 5 && state == 0)">
<el-button type="primary" @click="doPrev"></el-button>
</template>
<template v-if="active == 3 && state == 3">
<template v-if="active == 4 && state == 3">
<el-button @click="doNext"></el-button>
</template>
<el-button @click="doNext" v-if="active < 3"></el-button>
<el-button @click="doNext" v-if="active < 4"></el-button>
</el-card>
</div>
</template>
@ -39,16 +41,18 @@ import inferenceApi from '@/api/inference'
import logsApi from '@/api/log'
import taskApi from '@/api/task'
import request from 'axios'
import addStep1 from './addStep1.vue'
import addStep2 from './addStep2.vue'
import addStep3 from './addStep3.vue'
import addStep4 from './addStep4.vue'
import addStep1 from './components/addStep1.vue'
import addStep2 from './components/addStep2.vue'
import addStep3 from './components/addStep3.vue'
import addStep4 from './components/addStep4.vue'
import addStep5 from './components/addStep5.vue'
const router = useRouter();
const active = ref(1)
const step1 = ref()
const step2 = ref()
const step3 = ref()
const step4 = ref()
const step5 = ref()
let modelInfo = reactive({});
let state = ref(0);
@ -60,10 +64,11 @@ let info = reactive({
datas: null,
taskId: 0,
inferenceId: 0,
parameters:''
})
//
const doStart = () => {
let tmp = step4.value.checkForm();
let tmp = step5.value.checkForm();
if (tmp) {
info.datas = tmp;
state.value = 1;
@ -111,12 +116,11 @@ const startInference = () => {
}
const doCompile = (row) => {
debugger
let tmp = row;
if (tmp) {
info.devices = [tmp];
state.value = 1;
step3.value.updateState(state.value);
step4.value.updateState(state.value);
startComplie();//
//ElMessage.success("!");
} else {
@ -149,7 +153,7 @@ const startComplie = () => {
};
const addLogs = msg => {
info.logs = [msg, ...info.logs];
step3.value.updateLogs(info.logs);
step4.value.updateLogs(info.logs);
}
//
const doGetComplieLogs = () => {
@ -179,7 +183,7 @@ const doGetComplieLogs = () => {
}
const doDeploy = () => {
state.value = 2;
step3.value.updateState(state.value);
step4.value.updateState(state.value);
addLogs({ msg: "开始部署....", type: 'info' })
let ajaxs = info.devices.map(d => {
return inferenceApi.doDeploy({
@ -221,14 +225,14 @@ const doGetDeployLogs = () => {
} else {
addLogs({ msg: "编译部署完成", type: 'success' })
state.value = 3;
step3.value.updateState(state.value);
step4.value.updateState(state.value);
}
});
};
const doPrev = () => {
active.value--;
if (active.value == 3) {
if (active.value == 4) {
state.value = 0;
info.logs = [];
info.optIds = [];
@ -254,9 +258,15 @@ const doNext = () => {
ElMessage.error("请选择模型!");
}
} else if (active.value == 3) {
let tmp = step3.value.checkForm();
if (tmp) {
info.parameters=JSON.stringify(tmp);
active.value++;
}
} else if (active.value == 4) {
active.value++;
state.value = 0;
} else if (active.value == 4) {
} else if (active.value == 5) {
} else {
active.value++;

View File

@ -0,0 +1,179 @@
<template>
<el-card style="margin-top:12px" class="simulation-add-add-step31">
<template #header>已选择模型</template>
<el-row class="model-info">
<el-col :span="8">
<span>模型名称:</span>
<span>{{ modelInfo.model_name }}</span>
</el-col>
<el-col :span="8">
<span>模型类型:</span>
<span>{{ modelInfo.modl_net_type }}</span>
</el-col>
<el-col :span="8">
<span>互联名称:</span>
<span>{{ modelInfo.connection_name }}</span>
</el-col>
</el-row>
<div class="param-file">
<span class="sp-label">推理参数文件:</span>
<span class="sp-form">
<el-upload ref="uploadRef" class="upload-demo upload-demo-1" :on-change="handleFileChange"
:on-remove="handleFileRemove" :on-exceed="handleFileExceed" :auto-upload="false" :limit="1"
accept="application/json">
<el-button type="primary"><el-icon class="el-icon--upload"> <i-ep-upload-filled />
</el-icon></el-button>
<template #tip>
<div class="el-upload__tip">
请上传大小不超过 <strong style="color: red">10M</strong>格式为
<strong style="color: red">json</strong> 的文件
</div>
</template>
</el-upload>
<JsonEditorVue v-if="info.file" class="json-editor" v-model="info.jsonData" :modeList="['code']"
language="zh-CN" :expanded-on-start="true" @change="updateJson"></JsonEditorVue>
</span>
</div>
</el-card>
</template>
<script setup>
import 'jsoneditor'
import JsonEditorVue from 'json-editor-vue3'
const info = reactive({
jsonData: {},
file: null
})
const props = defineProps({
modelInfo: {
type: Object,
require: true,
default: null,
},
});
const uploadRef = ref();
function handleFileChange(file) {
if (typeof FileReader === "undefined") {
this.$message({
type: "info",
message: "您的浏览器不支持文件读取。",
});
return;
}
uploadFile(file).then((res) => {
if (isJSON(res, true)) {
if (info.file) {
ElMessageBox.confirm("确认是替换当前编辑的内容?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(function () {
info.jsonData = JSON.parse(res);
});
} else {
info.jsonData = JSON.parse(res);
}
info.file=file;
uploadRef.value.clearFiles();
}
});
}
/** 解析json */
function isJSON(str, showMsg) {
try {
//
JSON.parse(str);
if (showMsg) {
ElMessage.success("JSON文件解析成功");
}
return true;
//
} catch (error) {
//
if (showMsg) {
ElMessage.error("JSON文件解析失败");
}
return false;
}
}
function updateJson(val){
info.jsonData=val;
}
//
function uploadFile(file) {
return new Promise(function (resolve, reject) {
let reader = new FileReader();
reader.readAsArrayBuffer(file.raw);
reader.onload = function (e) {
var ints = new Uint8Array(e.target.result); //使Uint8Array
let snippets = new TextDecoder("UTF-8").decode(ints); //
resolve(snippets);
};
});
}
function handleFileRemove() {
debugger
}
function handleFileExceed() {
}
function checkForm(){
if(info.file){
return info.jsonData
}else{
ElMessage.error("请选择推理参数文件!");
return null
}
}
defineExpose({
checkForm
})
</script>
<style lang="scss" scoped>
.model-info {
font-size: 12px;
color: #666;
}
</style>
<style lang="scss">
.simulation-add-add-step31 {
.param-file {
margin-top: 20px;
display: flex;
.sp-label {
display: block;
width: 120px;
font-weight: bold;
color: #666;
font-size: 16px;
}
.sp-form {
display: block;
flex-grow: 1;
}
.json-editor {
height: 45vh;
.jsoneditor-modes {
display: none;
}
.full-screen {
right: 10px !important;
}
.jsoneditor-poweredBy {
display: none;
}
.jsoneditor-menu {
background-color: #409eff;
}
}
}
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<el-card style="margin-top: 12px" class="simulation-add-add-step31">
<el-card style="margin-top: 12px" class="simulation-add-add-step41">
<template #header>已选择模型</template>
<el-row class="model-info">
<el-col :span="8">
@ -16,7 +16,7 @@
</el-col>
</el-row>
</el-card>
<el-card style="margin-top: 12px; position: relative" class="simulation-add-add-step32">
<el-card style="margin-top: 12px; position: relative" class="simulation-add-add-step42">
<template #header>
<span>设备选择</span>
<el-form ref="queryFormRef" :inline="true" style="
@ -206,7 +206,7 @@ defineExpose({
}
</style>
<style lang="scss">
.simulation-add-add-step32 {
.simulation-add-add-step42 {
.device-state {
&.state-1 {
color: var(--el-color-primary);

View File

@ -0,0 +1,67 @@
<!-- 线 + 柱混合图 -->
<template>
<div>
<div :id="id" :class="className" :style="{ height, width }"></div>
</div>
</template>
<script setup lang="ts">
import * as echarts from "echarts";
const props = defineProps({
id: {
type: String,
default: "barChart1",
},
className: {
type: String,
default: "",
},
width: {
type: String,
default: "400px",
required: true,
},
height: {
type: String,
default: "400px",
required: true,
},
render: {
type: Function
}
});
const chart = ref<any>("");
const setOption = (opt: any) => {
opt = opt || {};
if (props.render) {
opt = props.render(opt);
}
chart.value.setOption(opt);
}
onMounted(() => {
//
chart.value = markRaw(
echarts.init(document.getElementById(props.id) as HTMLDivElement)
);
setTimeout(() => {
setOption({});
}, 400);
//
window.addEventListener("resize", () => {
chart.value.resize();
});
});
onActivated(() => {
if (chart.value) {
chart.value.resize();
}
});
defineExpose({
setOption
})
</script>

View File

@ -0,0 +1,137 @@
<template>
<el-dialog v-model="info.show" title="选择推理任务" :close-on-press-escape="false" :close-on-click-modal="false"
align-center append-to-body width="960px" modal-class="choice-task-dlg">
<div style="margin-bottom: 10px;text-align: right;">
<el-input v-model="queryParams.task_name" style="width:160px;margin-right:10px;" />
<el-button type="primary" @click="handleQuery"><i-ep-search />搜索</el-button>
<el-button @click="resetQuery">
<i-ep-refresh />
重置</el-button>
</div>
<el-table v-loading="info.loading" :data="info.tableData" stripe @row-click="doRowClick" max-height="400px">
<el-table-column align="center" width="55" label="选择">
<template #default="scope">
<el-checkbox v-if="info.mult" v-model="scope.row.checked" :label="scope.row.task_id + ''"
:disabled="info.disTaskId==scope.row.task_id"
@change="handleChange(scope.row)"/>
<el-radio v-else v-model="info.selData" :label="scope.row.task_id + ''" :disabled="info.disTaskId==scope.row.task_id"
@change="handleChange(scope.row)"/>
</template>
</el-table-column>
<el-table-column label="任务名称" align="left" prop="task_name" />
<el-table-column label="模型名称" align="left" prop="model_name" />
<el-table-column label="模型子类型" align="left" prop="modl_sub_type" />
<el-table-column label="连接名称" align="left" prop="connection_name" />
<el-table-column label="推理数据集名称" align="left" prop="dataset_name" />
<el-table-column label="图片数量" align="left" prop="image_count" />
<el-table-column label="设备名称" align="left" prop="device_name" />
<el-table-column label="完成时间" align="left" prop="finish_time" />
</el-table>
<pagination v-if="info.total > 0" v-model:total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="loadData" />
<template #footer>
<div style="text-align: center">
<el-button type="primary" @click="doOk"></el-button>
<el-button @click="doCancel"></el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import TaskApi from '@/api/task'
let info = reactive({
loading: false,
show: false,
data: null,
total: 0,
selData: "",
tableData: [],
showItem: null,
showJsonDlg: false,
disTaskId:'',
mult:false
});
let queryParams = reactive({
task_name: '',
pageNum: 1,
pageSize: 10,
});
const emit = defineEmits(["success"]);
const doRowClick = (row) => {
if(row.task_id!=info.disTaskId){
if(info.mult){
row.checked=!row.checked;
}else{
info.selData = row.task_id + "";
}
}
}
const doOk = () => {
if(!info.mult){
if (info.selData) {
let items = info.tableData.filter(d => d.task_id == info.selData);
if (items.length > 0) {
emit("success", items);
info.show = false;
return;
}
}
ElMessage.error("请选择任务!");
}else{
let tmps=info.tableData.filter(d=>d.checked);
if(tmps.length>0){
emit("success",tmps);
info.show=false;
}else{
ElMessage.error("请选择任务!");
}
}
}
const doCancel = () => {
info.show = false;
}
const showDialog = (opt) => {
info.show = true;
info.data = opt;
info.selData = opt.taskId||'';
info.disTaskId=opt.disTaskId;
info.mult=opt.mult;
resetQuery();
}
function resetQuery() {
queryParams.task_name = "";
queryParams.pageNum = 1;
loadData();
}
function handleQuery() {
queryParams.pageNum = 1;
loadData();
}
const loadData = () => {
info.loading = true;
TaskApi.tasks(queryParams).then(d => {
info.loading = false;
info.total = d.data.data.total || 0;
info.tableData = (d.data.data.task_list || []).map(it=>{
it.checked=false;
return it;
});
})
}
defineExpose({
showDialog
})
</script>
<style lang="scss">
.choice-task-dlg{
.el-radio__label,.el-checkbox__label{
display: none;
}
}
</style>

View File

@ -61,10 +61,15 @@ function handleQuery(a) {
}
const loadLogs = () => {
let ajaxs = info.dataList.filter(it => it.state == 0).map(it => {
return LogsApi.inferenceTaskLatest(it.task_id)
return LogsApi.inferenceTaskLatest(it.task_id,it.device_id)
});
request.all(ajaxs).then(d => {
debugger
d.forEach(res=>{
let logs=res.data?.data?.latest_log_list||[];
logs.forEach(log=>{
logList.push(log);
});
});
});
};

View File

@ -18,13 +18,14 @@
<el-table v-loading="loading" :data="info.tableData" stripe @selection-change="handleSelectionChange">
<el-table-column label="任务名称" align="left" prop="task_name" />
<el-table-column label="任务说明" align="left" prop="task_desc" />
<el-table-column label="使用数据集" align="left" prop="data_set_name" />
<el-table-column label="使用数据集" align="left" prop="dataset_name" />
<el-table-column label="运行模型" align="left" prop="model_name" width="120" />
<el-table-column label="模型网络" align="left" prop="modl_net_type" width="120" />
<el-table-column label="创建时间" align="left" prop="crTime" width="120" />
<el-table-column label="操作" fixed="right" align="center" width="200">
<el-table-column label="创建时间" align="left" prop="create_time" width="120" />
<el-table-column label="完成时间" align="left" prop="finish_time" width="120" />
<el-table-column label="操作" fixed="right" align="center" width="200" v-if="1==2">
<template #default="scope">
<el-button text type="primary" size="small" @click="doShowDetail(scope.row)"><i-ep-view />查看报告</el-button>
<el-button text type="primary" size="small" @click="doShowDetail(scope.row)"><i-ep-view />查看报告</el-button>
<el-button text type="primary" v-if="1 == 2" size="small"
@click="doDelete(scope.row)"><i-ep-close-bold />删除</el-button>
</template>

View File

@ -1,11 +0,0 @@
<template>
<div>
555
</div>
</template>
<script setup>
</script>
<style scoped lang='less'>
</style>

View File

@ -0,0 +1,242 @@
<template>
<div class="app-container simulation-report-desc" >
<div style="background-color: #fff;padding:20px;margin-bottom: 60px;" id="print_simulation_report_desc">
<div class="report-name">{{ info.report.report_name }}</div>
<div class="report-info">
<table>
<tr>
<td style="width:100px;" align="right"> 报告创建人:</td>
<td>{{ info.report.user_name }}</td>
</tr>
<tr>
<td align="right"> 报告生成时间:</td>
<td>{{ info.report.create_time }}</td>
</tr>
<tr>
<td align="right"> 报告说明:</td>
<td>{{ info.report.report_desc }}</td>
</tr>
</table>
</div>
<div class="div-line"></div>
<div class="sub-title">推理任务列表</div>
<el-table :data="info.taskList" stripe style="margin-top:10px;">
<el-table-column label="任务名称" align="left" prop="task_name" />
<el-table-column label="模型名称" align="left" prop="model_name" />
<el-table-column label="网络类型" align="left" prop="modl_sub_type" />
<el-table-column label="互联名称" align="left" prop="connection_name" />
<el-table-column label="数据集名称" align="left" prop="dataset_name" />
<el-table-column label="图片数量" align="left" prop="image_count" />
<el-table-column label="设备名称" align="left" prop="device_name" />
<el-table-column label="设备处理器" align="left" prop="hardware_chip" />
</el-table>
<div class="task-lists" v-if="info.tasks && info.tasks.length > 0">
<div v-for="(it, idx) in info.tasks" :key="idx">
<div class="sub-title">我的任务{{ idx + 1 }}的评估报告</div>
<div v-if="info.thresholds" class="info-thresholds">
<span>置信度阈值</span>
<span>{{ info.thresholds.score_threshold }}</span>
<span>nms阈值:</span>
<span>{{ info.thresholds.nms_threshold }}</span>
</div>
<el-table :data="it.classes" stripe style="margin-top:10px;">
<el-table-column label="类别名称" align="left" prop="class_name" />
<el-table-column label="Accuracy(准确度)" align="left" prop="accuracy" />
<el-table-column label="Precision(精准度)" align="left" prop="precision" />
<el-table-column label="Recall(召回率)" align="left" prop="recall" />
<el-table-column label="F1-score" align="left" prop="f1_score" />
<el-table-column label="AP" align="left" prop="ap" />
</el-table>
<el-table :data="it.datas" stripe style="margin-top:20px;" >
<el-table-column label="mAP" align="left" prop="map" />
<el-table-column label="Micro F1" align="left" prop="micro_f1" />
<el-table-column label="Macro F1" align="left" prop="macro_f1" />
<el-table-column label="加权F1-Scroe" align="left" prop="weight_f1" />
<el-table-column label="平均推理时间" align="left" prop="inference_time" />
<el-table-column label="系统延迟时间" align="left" prop="system_delay" />
</el-table>
<el-row class="report-chart1" style="margin-top:20px;">
<el-col :span="12">
<charts :id="'reportChart1-' + idx" width="100%" height="400px"
:render="opt => renderChart1(it, 'roc')"></charts>
</el-col>
<el-col :span="12">
<charts :id="'reportChart2-' + idx" width="100%" height="400px"
:render="opt => renderChart1(it, 'rp')"></charts>
</el-col>
</el-row>
</div>
</div>
</div>
<el-card class="card-footer">
<el-button type="primary" @click="doPrint"></el-button>
<el-button type="primary">导出</el-button>
<el-button type="primary" @click="doDelete"></el-button>
<el-button @click="goBack"></el-button>
</el-card>
</div>
</template>
<script setup>
import ReportApi from '@/api/report'
import charts from './components/charts.vue'
import printJS from 'print-js'
const route = useRoute()
const router = useRouter();
const info = reactive({
report: {},
taskList: [],
thresholds: null,
extra_evaluation_type: '',
tasks: []
})
function goBack(){
router.push({ path: "/simulationEvaluation/reportList"});
}
function doPrint(){
printJS({
printable:'print_simulation_report_desc',
type: 'html',
header:info.report.report_name,
ignoreElements: ['no-print']
});
}
const doDelete = () => {
let id = route.query.id;
ElMessageBox.confirm("确认删除?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(function () {
ReportApi.deleteReport(id).then(d=>{
if(d.data.code==0){
ElMessage.success("删除成功!");
goBack();
}else{
ElMessage.error("删除失败!");
}
});
});
}
function renderChart1(data, type) {
let chartInfo = data.chartsInfo
let opt = {
legend: {
left:'10%',right:'10%',
data: chartInfo.names },
grid: { top: '25%', },
xAxis: [{
type: 'category', // type
data: ['0.0', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', "0.8", "0.9", "1.0"], // x
}],
yAxis: [{
type: 'value',
name: type == 'roc' ? "ROC曲线" : "RP曲线"
}],
tooltip: {
trigger: 'axis'
},
series: (type == "roc" ? chartInfo.rocs : chartInfo.rps).map(it => {
return {
name: it.name,
type: it.type,
data: it.data,
label:{
show:true,
position:'top'
}
}
})
}
return opt;
}
function initTaskChart(it) {
let rocs = [];
let rps = [];
let names = [];
let classes = it.classes || [];
classes.forEach(d => {
rocs.push({
name: d.class_name, data: d.roc, type: 'line'
});
rps.push({
name: d.class_name, data: d.pr, type: 'line'
});
names.push(d.class_name)
});
return {
rocs, rps, names
}
}
function loadData() {
let id = route.query.id;
ReportApi.getReport(id).then(d => {
info.report = d.data.data || {};
info.taskList = info.report.task_list || []
info.thresholds = info.report.report_parameters?.report_parameters?.thresholds || null
info.extra_evaluation_type = info.report.report_parameters?.report_parameters?.extra_evaluation_type || '';
info.tasks = (info.report.report_data?.tasks || []).map(it => {
it.classes.splice(20)
it.datas = [{
inference_time: it.inference_time, macro_f1: it.macro_f1, map: it.map, micro_f1: it.micro_f1,
system_delay: it.system_delay, task_id: it.task_id, weight_f1: it.weight_f1
}];
it.chartsInfo = initTaskChart(it);
return it;
});
});
}
onMounted(loadData);
</script>
<style lang='scss'>
.simulation-report-desc {
font-size: 12px;
.report-name {
font-size: 20px;
text-align: center;
font-weight: bold;
}
.sub-title {
font-size: 14px;
font-weight: bold;
text-align: center;
}
.div-line {
margin: 10px 0px;
height: 2px;
background-color: #aaa;
}
.task-lists {
margin-top: 20px;
.info-thresholds {
font-weight: bold;
}
}
.card-footer{
position: fixed;
width: calc(100% - 215px);
bottom: 0px;
.el-card__body {
padding: 10px;
.el-pagination {
justify-content: end;
}
}
}
}
</style>

View File

@ -0,0 +1,130 @@
<template>
<div class="app-container simulation-his-task-list">
<div class="search-container" style="position: relative;">
<el-button type="primary" @click="doAddReport"
style="position: absolute;left:10px;"><i-ep-plus />新建评估报告</el-button>
<el-form ref="queryFormRef" :model="queryParams" :inline="true" style="flex-grow: 1;text-align: right;">
<el-form-item label="" prop="keywords">
<el-input v-model="queryParams.keywords" placeholder="请输入模型名称" clearable style="width: 250px"
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery"><i-ep-search />搜索</el-button>
<el-button @click="resetQuery">
<i-ep-refresh />
重置</el-button>
</el-form-item>
</el-form>
</div>
<el-card>
<el-table v-loading="loading" :data="info.tableData" stripe>
<el-table-column label="报告名称" align="left" prop="report_name" />
<el-table-column label="任务名称" align="left" prop="task.task_name" />
<el-table-column label="模型名称" align="left" prop="task.model_name" />
<el-table-column label="网络类型" align="left" prop="task.modl_sub_type" />
<el-table-column label="互联名称" align="left" prop="task.connection_name" />
<el-table-column label="数据集名称" align="left" prop="task.dataset_name" />
<el-table-column label="运行设备名称" align="left" prop="task.device_name" />
<el-table-column label="创建时间" align="left" prop="create_time" />
<el-table-column label="操作" fixed="right" align="center" width="200">
<template #default="scope">
<el-button text type="primary" size="small" @click="doShowDetail(scope.row)"><i-ep-view />查看</el-button>
<el-button text type="primary" size="small"
@click="doDelete(scope.row)"><i-ep-close-bold />删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-card class="card-footer">
<pagination v-if="total > 0" v-model:total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="handleQuery" />
</el-card>
</div>
</template>
<script setup>
import ReportApi from '@/api/report'
const queryFormRef = ref(ElForm); //
const router = useRouter();
const loading = ref(false); //
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
keywords: '',
});
const total = ref(0); //
let info = reactive({
tableData: []
})
/** 查询 */
function handleQuery() {
loadData();
}
function resetQuery() {
queryParams = {
pageNum: 1,
pageSize: 10,
keywords: '',
};
loadData();
}
const doDelete = (row) => {
ElMessageBox.confirm("确认删除?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(function () {
ReportApi.deleteReport(row.report_id).then(d=>{
if(d.data.code==0){
ElMessage.success("删除成功!");
}else{
ElMessage.error("删除失败!");
}
loadData();
});
});
}
const doShowDetail = row => {
router.push({ path: "/simulationEvaluation/reportDesc", query: {id:row.report_id } });
}
const loadData = () => {
loading.value = true;
ReportApi.reports(queryParams).then(d => {
loading.value = false;
total.value = d.data.data?.total || 0;
info.tableData = (d.data.data?.report_list || []).map(it=>{
let taskList=it.task_list||[];
it.task={};
if(taskList && taskList.length>0){
it.task=taskList[0]
}
return it;
});
})
}
function doAddReport() {
router.push({ path: "/simulationEvaluation/addReport" });
}
onMounted(loadData);
</script>
<style lang='scss'>
.simulation-his-task-list {
.card-footer {
position: fixed;
width: calc(100% - 215px);
bottom: 0px;
.el-card__body {
padding: 0px;
.el-pagination {
justify-content: end;
}
}
}
}
</style>

View File

@ -1,197 +0,0 @@
<template>
<div class="app-container simulation-his-task-desc">
<el-card class="card-info">
<template #header>
<svg-icon icon-class="pause" style="width:20px;height:20px;" />
推理评估信息</template>
<div class="tb-base-info">
<el-row>
<el-col :span="12">
<span class="sp-title">任务名称:</span>
<span class="sp-text">人员检测测四报告</span>
</el-col>
<el-col :span="12">
<span class="sp-title">任务说明:</span>
<span class="sp-text">
<el-popover placement="top-start" width="50%" trigger="hover"
content="人员检测测四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告">
<template #reference>
人员检测测四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告
</template>
</el-popover>
</span>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<span class="sp-title">互联名称:</span>
<span class="sp-text">人员检测测互联</span>
</el-col>
<el-col :span="12">
<span class="sp-title">互联说明:</span>
<span class="sp-text">
<el-popover placement="top-start" width="50%" trigger="hover"
content="人员检测测四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告">
<template #reference>
人员检测测四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告四报告
</template>
</el-popover>
</span>
</el-col>
</el-row>
</div>
<table style="width:100%" class="tb-base-info">
<tr>
<td class="cl-td">
<span class="sp-title">数据集:</span>
<span class="sp-text">人员识别</span>
</td>
<td class="cl-td">
<span class="sp-title">数据集标签:</span>
<span class="sp-text">人员检测</span>
</td>
</tr>
<tr>
<td class="cl-td">
<span class="sp-title">运行模型:</span>
<span class="sp-text">人员检测模型</span>
</td>
<td class="cl-td">
<span class="sp-title">模型网络:</span>
<span class="sp-text">VIT</span>
</td>
</tr>
<tr>
<td class="cl-td" rowspan="2">
<span class="sp-title">设备列表:</span>
<span class="sp-text">
<el-input v-model="devList" disabled type="textarea"
style="width:calc(100% - 120px);vertical-align: top;" :rows="2" />
</span>
</td>
<td class="cl-td">
<span class="sp-title">推理开始时间:</span>
<span class="sp-text">2024-06-0418:34:32</span>
</td>
</tr>
<tr>
<td class="cl-td">
<span class="sp-title">报告生成时:</span>
<span class="sp-text">2024-06-0418:34:32</span>
</td>
</tr>
</table>
</el-card>
<el-card style="margin-top: 12px;margin-bottom: 100px;height: 450px;">
<template #header>
<svg-icon icon-class="pause" style="width:20px;height:20px;" />
报告图表</template>
<el-row>
<el-col :span="12" style="position: relative;display: flex;justify-content: center;">
<BarChart1/>
</el-col>
<el-col :span="12" style="position: relative;display: flex;justify-content: center;">
<BarChart2/>
</el-col>
</el-row>
</el-card>
<el-card class="card-footer">
<el-button type="primary" @click="doPrint"></el-button>
<el-button type="primary" @click="doExport"></el-button>
<el-button type="primary" @click="doDelete"></el-button>
<el-button type="primary" @click="doBack"></el-button>
</el-card>
</div>
</template>
<script setup>
import BarChart1 from './BarChart1.vue'
import BarChart2 from './BarChart2.vue'
const router = useRouter();
let devList = ref("ST18-9\nRTX4080")
const doBack = () => {
router.push({ path: "/simulationEvaluation/hisTaskList" })
}
const doPrint = () => {
ElMessage.success("正在打印...");
}
const doExport = () => {
ElMessage.success("正在导出...");
}
const doDelete = () => {
ElMessageBox.confirm("确认删除?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(function () {
let idx = tableData.indexOf(row);
if (idx >= 0) {
tableData.splice(idx, 1);
ElMessage.success("删除成功");
setTimeout(() => {
doPrint();
}, 1500);
}
});
}
</script>
<style lang='scss'>
.simulation-his-task-desc {
.el-card__header {
padding: 8px 4px;
display: flex;
align-items: center
}
.card-footer {
position: fixed;
width: calc(100% - 215px);
bottom: 0px;
:deep(.el-card__body) {
padding: 10px;
.el-pagination {
justify-content: end;
}
}
}
.card-info{
.el-card__body{
padding: 10px;
}
}
.tb-base-info {
line-height: 24px;
span {
font-size: 12px;
&.sp-text {
.el-only-child__content {
width: calc(100% - 120px);
text-overflow: ellipsis;
display: inline-block;
overflow: hidden;
white-space: nowrap;
position: relative;
top:10px;
}
}
}
.cl-td{
width:50%;
min-width: 50%;
}
}
}
</style>

View File

@ -1407,6 +1407,11 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@sphinxxxx/color-conversion@^2.2.2":
version "2.2.2"
resolved "https://registry.npmmirror.com/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz#03ecc29279e3c0c832f6185a5bfa3497858ac8ca"
integrity sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==
"@tootallnate/once@1":
version "1.1.2"
resolved "https://registry.npmmirror.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
@ -2312,6 +2317,11 @@ abab@^2.0.3, abab@^2.0.5:
resolved "https://registry.npmmirror.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291"
integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==
ace-builds@^1.31.1:
version "1.36.2"
resolved "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.36.2.tgz#9499bd59e839a335ac4850e74549ca8d849dc554"
integrity sha512-eqqfbGwx/GKjM/EnFu4QtQ+d2NNBu84MGgxoG8R5iyFpcVeQ4p9YlTL+ZzdEJqhdkASqoqOxCSNNGyB6lvMm+A==
acorn-globals@^6.0.0:
version "6.0.0"
resolved "https://registry.npmmirror.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45"
@ -2352,7 +2362,7 @@ agent-base@6:
dependencies:
debug "4"
ajv@^6.12.4:
ajv@^6.12.4, ajv@^6.12.6:
version "6.12.6"
resolved "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@ -5657,6 +5667,11 @@ istanbul-reports@^3.1.3:
html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0"
javascript-natural-sort@^0.7.1:
version "0.7.1"
resolved "https://registry.npmmirror.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59"
integrity sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==
jest-changed-files@^27.5.1:
version "27.5.1"
resolved "https://registry.npmmirror.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5"
@ -6076,6 +6091,11 @@ jiti@^1.19.1, jiti@^1.21.0:
resolved "https://registry.npmmirror.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268"
integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==
jmespath@^0.16.0:
version "0.16.0"
resolved "https://registry.npmmirror.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076"
integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==
js-base64@^2.1.9:
version "2.6.4"
resolved "https://registry.npmmirror.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4"
@ -6154,6 +6174,13 @@ json-buffer@3.0.1:
resolved "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
json-editor-vue3@^1.1.1:
version "1.1.1"
resolved "https://registry.npmmirror.com/json-editor-vue3/-/json-editor-vue3-1.1.1.tgz#fe328c042a9b42980ec3985ceb09fa00ac83a401"
integrity sha512-3qslVNZAY+roVfL10ukuaAw1ia9YpWdLO9PnBL+4SuM5a6R3oWCSQU6dLTTPd/dVtqhIefNn4QmthAioYOBHeA==
dependencies:
jsoneditor "^9.5.6"
json-parse-even-better-errors@^2.3.0:
version "2.3.1"
resolved "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
@ -6169,6 +6196,11 @@ json-schema-traverse@^1.0.0:
resolved "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
json-source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.npmmirror.com/json-source-map/-/json-source-map-0.6.1.tgz#e0b1f6f4ce13a9ad57e2ae165a24d06e62c79a0f"
integrity sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
@ -6186,6 +6218,21 @@ json5@^2.2.3:
resolved "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
jsoneditor@^9.5.6:
version "9.10.5"
resolved "https://registry.npmmirror.com/jsoneditor/-/jsoneditor-9.10.5.tgz#9aeb3a1482850299826f8f292cec22b0f71d975c"
integrity sha512-fVZ0NMt+zm4rqTKBv2x7zPdLeaRyKo1EjJkaR1QjK4gEM1rMwICILYSW1OPxSc1qqyAoDaA/eeNrluKoxOocCA==
dependencies:
ace-builds "^1.31.1"
ajv "^6.12.6"
javascript-natural-sort "^0.7.1"
jmespath "^0.16.0"
json-source-map "^0.6.1"
jsonrepair "3.1.0"
mobius1-selectr "^2.4.13"
picomodal "^3.0.0"
vanilla-picker "^2.12.2"
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
@ -6200,6 +6247,11 @@ jsonparse@^1.2.0:
resolved "https://registry.npmmirror.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==
jsonrepair@3.1.0:
version "3.1.0"
resolved "https://registry.npmmirror.com/jsonrepair/-/jsonrepair-3.1.0.tgz#02488882080930e6a37a7b080bc77546f2e12676"
integrity sha512-idqReg23J0PVRAADmZMc5xQM3xeOX5bTB6OTyMnzq33IXJXmn9iJuWIEvGmrN80rQf4d7uLTMEDwpzujNcI0Rg==
keygrip@~1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226"
@ -6722,6 +6774,11 @@ mlly@^1.4.2, mlly@^1.7.1:
pkg-types "^1.1.1"
ufo "^1.5.3"
mobius1-selectr@^2.4.13:
version "2.4.13"
resolved "https://registry.npmmirror.com/mobius1-selectr/-/mobius1-selectr-2.4.13.tgz#0019dfd9f984840d6e40f70683ab3ec78ce3b5df"
integrity sha512-Mk9qDrvU44UUL0EBhbAA1phfQZ7aMZPjwtL7wkpiBzGh8dETGqfsh50mWoX9EkjDlkONlErWXArHCKfoxVg0Bw==
mousetrap@^1.6.5:
version "1.6.5"
resolved "https://registry.npmmirror.com/mousetrap/-/mousetrap-1.6.5.tgz#8a766d8c272b08393d5f56074e0b5ec183485bf9"
@ -7170,6 +7227,11 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1:
resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
picomodal@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/picomodal/-/picomodal-3.0.0.tgz#facd30f4fbf34a809c1e04ea525f004f399c0b82"
integrity sha512-FoR3TDfuLlqUvcEeK5ifpKSVVns6B4BQvc8SDF6THVMuadya6LLtji0QgUDSStw0ZR2J7I6UGi5V2V23rnPWTw==
pidtree@~0.6.0:
version "0.6.0"
resolved "https://registry.npmmirror.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c"
@ -7360,6 +7422,11 @@ pretty-format@^27.5.1:
ansi-styles "^5.0.0"
react-is "^17.0.1"
print-js@^1.6.0:
version "1.6.0"
resolved "https://registry.npmmirror.com/print-js/-/print-js-1.6.0.tgz#692b046cf31992b46afa6c6d8a9db1c69d431d1f"
integrity sha512-BfnOIzSKbqGRtO4o0rnj/K3681BSd2QUrsIZy/+WdCIugjIswjmx3lDEZpXB2ruGf9d4b3YNINri81+J0FsBWg==
prismjs@^1.23.0:
version "1.29.0"
resolved "https://registry.npmmirror.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12"
@ -9002,6 +9069,13 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
vanilla-picker@^2.12.2:
version "2.12.3"
resolved "https://registry.npmmirror.com/vanilla-picker/-/vanilla-picker-2.12.3.tgz#1cc47b641a2b9c9afc5ac3a9a02febace0f1b17a"
integrity sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==
dependencies:
"@sphinxxxx/color-conversion" "^2.2.2"
vary@^1:
version "1.1.2"
resolved "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"