Browse Source

提交数据集预览及数据集标注功能代码。

Signed-off-by: zouap <zouap@pcl.ac.cn>
tags/v1.21.9.1^2
zouap 4 years ago
parent
commit
6fec47adc5
39 changed files with 18418 additions and 45 deletions
  1. +28
    -3
      models/attachment.go
  2. +24
    -0
      models/file_chunk.go
  3. +27
    -0
      modules/labelmsg/label_redis_service.go
  4. +61
    -0
      modules/labelmsg/redismsgsender.go
  5. +1
    -0
      options/locale/locale_en-US.ini
  6. +1
    -0
      options/locale/locale_zh-CN.ini
  7. +7
    -0
      public/self/css/bootstrap.min.css
  8. +4
    -0
      public/self/css/font-awesome.min.css
  9. +6
    -0
      public/self/css/ionicons.min.css
  10. +117
    -0
      public/self/css/jquery.yhhDataTable.css
  11. +4263
    -0
      public/self/css/style.css
  12. +741
    -0
      public/self/dataset_preview.js
  13. BIN
      public/self/fonts/FontAwesome.otf
  14. BIN
      public/self/fonts/fontawesome-webfont.eot
  15. +2671
    -0
      public/self/fonts/fontawesome-webfont.svg
  16. BIN
      public/self/fonts/fontawesome-webfont.ttf
  17. BIN
      public/self/fonts/fontawesome-webfont.woff
  18. BIN
      public/self/fonts/fontawesome-webfont.woff2
  19. +273
    -0
      public/self/func.js
  20. +2938
    -0
      public/self/js/Director/detection.js
  21. +2206
    -0
      public/self/js/Director/labelingSelfDefine.js
  22. +739
    -0
      public/self/js/app.js
  23. +7
    -0
      public/self/js/bootstrap.min.js
  24. +1541
    -0
      public/self/js/jquery.jscrollpane.js
  25. +2
    -0
      public/self/js/jquery.min.js
  26. +221
    -0
      public/self/js/jquery.mousewheel.js
  27. +962
    -0
      public/self/labelTaskPage.js
  28. +874
    -0
      public/self/labeling.html
  29. +2
    -0
      routers/init.go
  30. +46
    -3
      routers/repo/attachment.go
  31. +47
    -2
      routers/repo/dataset.go
  32. +106
    -16
      routers/repo/dir.go
  33. +37
    -0
      routers/repo/label.go
  34. +3
    -0
      routers/routes/routes.go
  35. +5
    -1
      templates/repo/datasets/dataset_list.tmpl
  36. +11
    -0
      templates/repo/datasets/dirs/dir_list.tmpl
  37. +212
    -0
      templates/repo/datasets/dirs/dir_preview.tmpl
  38. +26
    -20
      templates/repo/datasets/dirs/index.tmpl
  39. +209
    -0
      templates/repo/datasets/label/index.tmpl

+ 28
- 3
models/attachment.go View File

@@ -6,11 +6,12 @@ package models

import (
"bytes"
"code.gitea.io/gitea/modules/log"
"fmt"
"io"
"path"

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/obs"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
api "code.gitea.io/gitea/modules/structs"
@@ -253,9 +254,33 @@ func DeleteAttachments(attachments []*Attachment, remove bool) (int, error) {

if remove {
for i, a := range attachments {
if err := storage.Attachments.Delete(a.RelativePath()); err != nil {
return i, err
if a.Type == TypeCloudBrainOne {
if err := storage.Attachments.Delete(a.RelativePath()); err != nil {
return i, err
}
}
if a.Type == TypeCloudBrainTwo {
input := &obs.DeleteObjectInput{}
input.Bucket = setting.Bucket
input.Key = setting.BasePath + path.Join(a.UUID[0:1], a.UUID[1:2], a.UUID, a.Name)
log.Info("delete obs file:" + input.Key)
output, err := storage.ObsCli.DeleteObject(input)
if err == nil {
fmt.Printf("RequestId:%s\n", output.RequestId)
} else if obsError, ok := err.(obs.ObsError); ok {
fmt.Printf("Code:%s\n", obsError.Code)
fmt.Printf("Message:%s\n", obsError.Message)
}
}

//rf := path.Join(a.UUID[0:1], a.UUID[1:2])
/*
files, err := repo.GetDatasetDirs(a.UUID, "")
if err != nil {
log.Info("No files in attachment dirs.")
}
log.Info("files=" + files)
*/
}
}
return int(cnt), nil


+ 24
- 0
models/file_chunk.go View File

@@ -1,6 +1,9 @@
package models

import (
"fmt"

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/xorm"
)
@@ -87,6 +90,27 @@ func InsertFileChunk(fileChunk *FileChunk) (_ *FileChunk, err error) {
return fileChunk, nil
}

func DeleteFileChunkById(uuid string) (*FileChunk, error) {
return deleteFileChunkById(x, uuid)
}

func deleteFileChunkById(e Engine, uuid string) (*FileChunk, error) {
fileChunk := new(FileChunk)
if has, err := e.Where("uuid = ?", uuid).Get(fileChunk); err != nil {
return nil, err
} else if !has {
return nil, ErrFileChunkNotExist{"", uuid}
}

err := deleteFileChunk(e, fileChunk)
log.Info("delete the filechunk,id=" + fmt.Sprint(fileChunk.ID))
if err != nil {
return nil, err
} else {
return fileChunk, nil
}
}

// UpdateFileChunk updates the given file_chunk in database
func UpdateFileChunk(fileChunk *FileChunk) error {
return updateFileChunk(x, fileChunk)


+ 27
- 0
modules/labelmsg/label_redis_service.go View File

@@ -0,0 +1,27 @@
package labelmsg

import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
redigo "github.com/gomodule/redigo/redis"
)

var pool *redigo.Pool

func Init() {
redisBroker := setting.Broker
pool_size := 20
log.Info("start to connect redis.")
pool = redigo.NewPool(func() (redigo.Conn, error) {
c, err := redigo.DialURL(redisBroker)
if err != nil {
return nil, err
}
return c, nil
}, pool_size)

}

func Get() redigo.Conn {
return pool.Get()
}

+ 61
- 0
modules/labelmsg/redismsgsender.go View File

@@ -0,0 +1,61 @@
package labelmsg

import (
"code.gitea.io/gitea/modules/log"
)

// 方法名
const (
LabelTaskName = "LabelRedisQueue"
LabelDatasetDeleteQueue = "LabelDatasetDeleteQueue"
DecompressOBSTaskName = "LabelDecompressOBSQueue"
)

func SendAddAttachToLabelSys(attach string) error {

redisclient := Get()

//记得销毁本次链连接
defer redisclient.Close()

_, err := redisclient.Do("Publish", LabelTaskName, attach)
if err != nil {
log.Critical("redis Publish failed.")
}

log.Info("LabelRedisQueue(%s) success", attach)

return nil
}

func SendDeleteAttachToLabelSys(attach string) error {

redisclient := Get()

//记得销毁本次链连接
defer redisclient.Close()

_, err := redisclient.Do("Publish", LabelDatasetDeleteQueue, attach)
if err != nil {
log.Critical("redis Publish failed.")
}

log.Info("LabelDatasetDeleteQueue(%s) success", attach)

return nil
}

func SendDecompressAttachToLabelOBS(attach string) error {

redisclient := Get()
//记得销毁本次链连接
defer redisclient.Close()

_, err := redisclient.Do("Publish", DecompressOBSTaskName, attach)
if err != nil {
log.Critical("redis Publish failed.")
}

log.Info("LabelDecompressOBSQueue(%s) success", attach)
return nil
}

+ 1
- 0
options/locale/locale_en-US.ini View File

@@ -648,6 +648,7 @@ dir = directory
back = back
copy_url=copy download url
directory=check directory of the datasets
create_label_task=create label task
visibility = visibility
visibility_description = Only the owner or the organization members if they have rights, will be able to see it.
visibility_helper = Make Dataset Private


+ 1
- 0
options/locale/locale_zh-CN.ini View File

@@ -650,6 +650,7 @@ back=返回
copy_url=复制下载链接
copy_md5=复制文件MD5
directory=查看数据集目录结构
create_label_task=创建标注任务
visibility=可见性
visibility_description=只有组织所有人或拥有权利的组织成员才能看到。
visibility_helper=将数据集设为私有


+ 7
- 0
public/self/css/bootstrap.min.css
File diff suppressed because it is too large
View File


+ 4
- 0
public/self/css/font-awesome.min.css
File diff suppressed because it is too large
View File


+ 6
- 0
public/self/css/ionicons.min.css
File diff suppressed because it is too large
View File


+ 117
- 0
public/self/css/jquery.yhhDataTable.css View File

@@ -0,0 +1,117 @@
.yhh-data-table-frame{
color:inherit;font-family:inherit;font-size:14px;font-weight:normal;
border:0;margin:0;padding:0;background-color:#FFFFFF;
}
/*table样式*/
.yhh-data-table-frame>table.yhh-data-table{
width:100%;border-collapse:collapse;border-spacing:0;empty-cells:show;
}
.yhh-data-table-frame>table.yhh-data-table td,
.yhh-data-table-frame>table.yhh-data-table th{
vertical-align:middle;text-align:left;border:1px solid #DDDDDD;
}
.yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a td,
.yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a th{
border:0;
}
.yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a tr{
border-bottom:1px solid #DDDDDD;
}
.yhh-data-table-frame>table.yhh-data-table td{
background-color:#FFFFFF;color:inherit;
}
.yhh-data-table-frame>table.yhh-data-table th,
.yhh-data-table-frame>table.yhh-data-table thead td,
.yhh-data-table-frame>table.yhh-data-table tfoot td{
background-color:#DDDDDD;color:inherit;font-weight:bold;
}
.yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a th,
.yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a thead td,
.yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a tfoot td{
background-color:#FFFFFF;
}
.yhh-data-table-frame>table.yhh-data-table tbody th,
.yhh-data-table-frame>table.yhh-data-table tbody td{
padding:10px 10px;
}
.yhh-data-table-frame>table.yhh-data-table thead th,
.yhh-data-table-frame>table.yhh-data-table thead td,
.yhh-data-table-frame>table.yhh-data-table tfoot th,
.yhh-data-table-frame>table.yhh-data-table tfoot td{
padding:10px 10px;
}
.yhh-data-table-frame>table.yhh-data-table tr.odd td{}
.yhh-data-table-frame>table.yhh-data-table tr.even td{background-color:#F6F6F6;}
.yhh-data-table-frame>table.yhh-data-table tr.hover-row td{
background-color:#F0F8FF;color:#00BFFF;
}
.yhh-data-table-frame>table.yhh-data-table tr.selected-row td{
background-color:#E6E6FA;
}
/*table上下功能行公共样式*/
.yhh-data-table-frame>.data-table-top-box,
.yhh-data-table-frame>.data-table-bottom-box{
position:relative;
}
.yhh-data-table-frame>.data-table-top-box,
.yhh-data-table-frame>.data-table-bottom-box,
.yhh-data-table-frame>.data-table-top-box>.per-length-box,
.yhh-data-table-frame>.data-table-bottom-box>.info-box,
.yhh-data-table-frame>.data-table-bottom-box>.paginate-box{
height:35px;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box,
.yhh-data-table-frame>.data-table-bottom-box>.info-box,
.yhh-data-table-frame>.data-table-bottom-box>.paginate-box{
line-height:35px;position:absolute;
}
/*改变每页显示数目功能样式*/
.yhh-data-table-frame>.data-table-top-box>.per-length-box{
top:0;right:2px;padding-right:50px;z-index:8;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box>.per-length-select{
position:absolute;top:1.5px;right:0;width:50px;margin:0;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box dt.sel-choosen-box,
.yhh-data-table-frame>.data-table-top-box>.per-length-box dd.sel-list{
border:1px solid #DDDDDD;border-radius:0;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box dt.sel-choosen-box{
height:30px;line-height:30px;cursor:pointer;background-color:#F0F8FF;
position:relative;padding-right:13px;padding-left:8px;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box dt.sel-choosen-box.expand{
border-radius:0;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box dd.sel-list.expand{
border-radius:0;border-top:0;margin:0;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box i.sel-icon{
height:30px;line-height:30px;position:absolute;top:0;right:2px;color:#AAAAAA;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box dd.sel-list{
z-index:10;max-height:200px;height:auto;
border-radius:0;border-top:0;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option{
display:block;border-bottom:1px solid #CCCCCC;line-height:normal;
background-color:#FFFFFF;padding:6.5px 0;padding-left:8px;cursor:pointer;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option:hover{
background-color:#DDE4FE;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option:active{
background-color:#DA70D6;
}
.yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option.last-option{
border-bottom:0;
}
/*显示数据信息功能样式*/
.yhh-data-table-frame>.data-table-bottom-box>.info-box{
top:0;left:2px;
}
.yhh-data-table-frame>.data-table-bottom-box>.info-box .info-num{color:#F5A523;padding:0 5px;}
/*翻页按钮功能样式*/
.yhh-data-table-frame>.data-table-bottom-box>.paginate-box{
top:3px;right:0;overflow:hidden;
}

+ 4263
- 0
public/self/css/style.css
File diff suppressed because it is too large
View File


+ 741
- 0
public/self/dataset_preview.js View File

@@ -0,0 +1,741 @@
var img=new Image();

var ip = getIp();



var token = getCookie("_csrf");

canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
// canvas.width = document.getElementById("myCanvas").offsetWidth;
// canvas.height = document.getElementById("myCanvas").offsetWidth/1280*720;

canvas.width = document.getElementById("win_canvas").offsetWidth;
canvas.height = document.getElementById("win_canvas").offsetHeight;




var color_dict = {"car":"#0099CC", "person":"#FF99CC","point":"#00cc00","pointselected":"red"};
var color_person = {"0":"#13c90c","1":"#fc0707","2":"#FF99CC","3":"#fceb07"};

var rects=[];
var masks=[];
var pointShapes =[];

var fileindex =0;
var lastindex=false;
var labeltastresult;

var pageSize = 12;
var tableData;
var tablePageData;
var dataset_id = $('#hide_uuidid').val();
var dbdatasetid = dataset_id;
var textContent;
var labelInfo;

page(0,pageSize);


function getCookie(name)
{
var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
if(arr=document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}

function list(current,pageSize){
$.ajax({
type:"GET",
url:ip + "/gitea-dateset-item-page",
headers: {
authorization:token,
},
dataType:"json",
data:{
'datasetId':dbdatasetid,
'startPage':current,
'pageSize':pageSize},
async:false,
success:function(json){
tablePageData = json;
tableData = json.data;
labeltastresult = tableData;
fileindex=0;
if(lastindex){
fileindex = pageSize - 1;
}
},
error:function(response) {
}
});
}



function getTextContent(uuid,filename){
$.ajax({
type:"GET",
url:ip + "/getgiteatext",
headers: {
authorization:token,
},
dataType:"text",
data:{
'uuid':uuid,
'filename':filename
},
async:false,
success:function(json){
textContent = json;
},
error:function(response) {
}
});
}



/*
function previewDataSetFile(uuid,filename){
console.log('uuid=' + uuid + " filename=" + filename);
loadimg(uuid,filename);
}

function loadimg(uuid,filename){
img.src = ip + "/getgiteaimage?uuid=" + uuid + "&filename=" + filename;
var fname = filename.substring(filename.lastIndexOf('/') + 1);
$("#filename").text(fname);
}
*/

function loadimg(){
var length = labeltastresult[fileindex].pic_image_field.length;
 if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".json" 
     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".xml"
     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".txt"
     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".csv"
     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".md"
     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".py"
     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".sh"){
//文本
canvas.style.display="none";
document.getElementById("textcontent").style.display="block";
getTextContent(dataset_id,labeltastresult[fileindex].pic_image_field);
$('#textcontent').height(canvas.height-40)
$("#textcontent").text(textContent);
}else{
if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".jpeg" 
    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".jpg"
    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".bmp"
    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".gif"
    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".png"){
canvas.style.display="block";
document.getElementById("textcontent").style.display="none";
img.src = ip + "/getgiteaimage?uuid=" + dataset_id + "&filename=" + labeltastresult[fileindex].pic_image_field;
}else{
canvas.style.display="none";
document.getElementById("textcontent").style.display="block";
$('#textcontent').height(canvas.height)
$("#textcontent").text("暂不支持预览");

}
}
var fname = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/') + 1);
$("#filename").text(fname);
}

img.onload = function(){

canvas.width = document.getElementById("win_canvas").offsetWidth;
canvas.height = document.getElementById("win_canvas").offsetHeight-40;
//调整画布大小
// if ((img.width/img.height)<(canvas.width/canvas.height)){
// canvas.width=canvas.height * img.width / img.height;
// }
// else{
// canvas.height=canvas.width * img.height / img.width;
// }
drawimage();
}

function isEmpty(str){
if(typeof str == "undefined" || str == null || str == ""){
return true;
}
return false;
}
function drawimage() {
parse_labelinfo(labeltastresult[fileindex].label_info);
// 清除画布,准备绘制
context.clearRect(0, 0, canvas.width, canvas.heigth);
// modal_context.cleararc
context.drawImage(img,0,0,img.width,img.height,0,0,canvas.width, canvas.height);
for(var i=0; i<rects.length; i++) {
var rect = rects[i];
rectxywh = new Array(4);
rectxywh_tmp = rect.getXYWH();
rectxywh[0] = rectxywh_tmp[0] / canvas.width * canvas.width;
rectxywh[1] = rectxywh_tmp[1] / canvas.height * canvas.height;
rectxywh[2] = rectxywh_tmp[2] / canvas.width * canvas.width;
rectxywh[3] = rectxywh_tmp[3] / canvas.height * canvas.height;
// 绘制矩形

context.lineWidth = 3;
if(rect.type == "person"){
context.strokeStyle = color_person[ i % 4];
}else{
context.strokeStyle=color_dict[rect.type];
}
context.strokeRect(rectxywh[0],rectxywh[1],rectxywh[2],rectxywh[3]);
context.font = "15px Georgia";
context.fillStyle= context.strokeStyle;

context.fillText(rect.type, rectxywh[0],rectxywh[1]-5);
for(var j=0; j<4; j++){
var p_tmp = rect.points[j];
var p = new point(0,0);
p.x = p_tmp.x/ canvas.width * canvas.width;;
p.y = p_tmp.y / canvas.height * canvas.height;
context.fillStyle = color_dict["point"];
context.fillRect(p.x-2,p.y-2,4,4);
}
}
for (var i=0; i<masks.length; i++){
context.strokeStyle="purple"
var mask =masks[i];
context.lineWidth = 2;
for (var j=1; j<mask.points.length; j++){
context.beginPath();
context.moveTo(mask.points[j-1].x, mask.points[j-1].y);
context.lineTo(mask.points[j].x,mask.points[j].y);
context.stroke();
// modal_context.closePath();
}
context.moveTo(mask.points[mask.points.length-1].x,mask.points[mask.points.length-1].y);
context.lineTo(mask.points[0].x,mask.points[0].y);
context.stroke();
context.closePath();
for (var j=0; j<mask.points.length; j++){
var p = mask.points[j]
context.fillStyle = color_dict["point"];
context.fillRect(p.x-2,p.y-2,4,4);
}
}
}
function parse_labelinfo(labelinfo){
rects.length = 0;
masks.length = 0;
pointShapes.length = 0;
if(!isEmpty(labelinfo)){
var label_arr = JSON.parse(labelinfo);
for(var i=0;i<label_arr.length;i++){
if(!isEmpty(label_arr[i].mask)){
cls=label_arr[i].class_name;
var tmpMask = new maskar(getCanvasLocationX(label_arr[i].mask[0]),getCanvasLocationY(label_arr[i].mask[1]),cls);
for(var j = 2; j < label_arr[i].mask.length; j+=2){
tmpMask.points.push(new point(getCanvasLocationX(label_arr[i].mask[j]),getCanvasLocationY(label_arr[i].mask[j+1])));
}
if(!isEmpty(label_arr[i].id)){
tmpMask.id= label_arr[i].id;
}
if(!isEmpty(label_arr[i].blurred)){
tmpMask.blurred = label_arr[i].blurred;
}
if(!isEmpty(label_arr[i].goodIllumination)){
tmpMask.goodIllumination = label_arr[i].goodIllumination;
}
if(!isEmpty(label_arr[i].frontview)){
tmpMask.frontview = label_arr[i].frontview;
}
tmpMask.finish = true;
masks.push(tmpMask);
}else if(!isEmpty(label_arr[i].box)){
x1 = getCanvasLocationX(label_arr[i].box[0]);
y1 = getCanvasLocationY(label_arr[i].box[1]);
x2 = getCanvasLocationX(label_arr[i].box[2]);
y2 = getCanvasLocationY(label_arr[i].box[3]);
cls=label_arr[i].class_name;
score = label_arr[i].score;
rect = new rectar(x1,y1,x2,y2,cls,score);
if(!isEmpty(label_arr[i].id)){
rect.id= label_arr[i].id;
}
if(!isEmpty(label_arr[i].blurred)){
rect.blurred = label_arr[i].blurred;
}
if(!isEmpty(label_arr[i].goodIllumination)){
rect.goodIllumination = label_arr[i].goodIllumination;
}
if(!isEmpty(label_arr[i].frontview)){
rect.frontview = label_arr[i].frontview;
}
rects.push(rect);
}else if(!isEmpty(label_arr[i].keypoints)){
cls=label_arr[i].class_name;
score = label_arr[i].score;
var pointShapeObj = new pointShape(getCanvasLocationX(label_arr[i].keypoints[0]),getCanvasLocationY(label_arr[i].keypoints[1]),cls,score);
pointShapes.push(pointShapeObj);
}
}
}
}

function point(x,y){
this.x = x;
this.y = y;
this.isSelected = false;
};

function pointShape(x,y,type,score=1.0){
this.x = x;
this.y = y;
this.isSelected = false;
this.type = type;
this.score = score;
this.id =""; //标识
this.blurred=false;//模糊不清的; 记不清的; 难以区分的; 模棱两可的
this.goodIllumination = false; //照明
this.frontview = false;//正面图
}

function rectar(x1,y1,x2,y2, type, score=1.0){
// this.x = x;
// this.y = y;
// this.width = width;
// this.height = height;
this.type = type;
this.score = score;
//0--1,
//| |
//2--3
this.points = [new point(x1,y1), new point(x1, y2),new point(x2, y1),new point(x2, y2)];
this.getXYWH = function(){
var x_min=Math.min(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x);
var x_max=Math.max(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x);
var y_min=Math.min(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y);
var y_max=Math.max(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y);
return [x_min,y_min,x_max-x_min,y_max-y_min];
}
this.getX1Y1X2Y2 = function(){
var x_min=Math.min(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x);
var x_max=Math.max(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x);
var y_min=Math.min(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y);
var y_max=Math.max(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y);
return [x_min,y_min,x_max,y_max];
}
this.getdiapid = function(pid){//获取对角点
var twooverlapped,fouroverlapped;
for (var i=0;i<4;i++){
if ((this.points[pid].x!=this.points[i].x)&&(this.points[pid].y!=this.points[i].y)){
return i;
}
if ((this.points[pid].x!=this.points[i].x)||(this.points[pid].y!=this.points[i].y)){
twooverlapped=i;
}
if (i!=pid) fouroverlapped=i;

}
if (twooverlapped)
return twooverlapped;
return fouroverlapped;
}
this.mouseonpoint = false;
this.mouseonrect = false;
this.isSelected = false;
this.id =""; //标识
this.blurred=false;//模糊不清的; 记不清的; 难以区分的; 模棱两可的
this.goodIllumination = true; //照明
this.frontview = true;//正面图
};



function maskar(x0,y0,type){
this.type = type;
this.points = [new point(x0,y0)];
this.finish = false;
this.mouseonpoint = false;
this.mouseonmask = false;
this.isSelected = false;
this.getX1Y1 = function(){return [this.points[0].x,this.points[0].y]}
this.getBound = function(){
mlen = this.points.length;
var minX = 999999999, minY = 999999999, maxX = -1, maxY = -1;
for (var i = 0; i < mlen; i ++){
if(minX > this.points[i].x){
minX = this.points[i].x;
}
if(maxX < this.points[i].x){
maxX = this.points[i].x;
}
if(minY > this.points[i].y){
minY = this.points[i].y;
}
if(maxY < this.points[i].y){
maxY = this.points[i].y;
}
}
return [minX, minY, maxX, maxY];
}
this.id =""; //标识
this.blurred=false;//模糊不清的; 记不清的; 难以区分的; 模棱两可的
this.goodIllumination = true; //照明
this.frontview = true;//正面图
}

function getCanvasLocationX(num){
return Math.round(num * canvas.width/parseInt(img.width));
}

function getCanvasLocationY(num){
return Math.round(num * canvas.height/parseInt(img.height));
}


function page(current,pageSize){
list(current,pageSize);
getLabelInfo(dataset_id);
showlabelflist();
showfilelist();
breadFiles();
loadimg();
setPage(tablePageData,pageSize);
}

function nextPage(){
var current = $('#displayPage1').text();
page(current,pageSize);
}

function prePage(){
var current =$('#displayPage1').text();
if(current > 1){
page(current - 2,pageSize);
}
}

function goPage(){
var goNum = $('#goNum').val();

var pageTotal = $("#totalNum").text();
var pageNum = parseInt(pageTotal/pageSize);
if(pageTotal%pageSize!=0){
pageNum += 1;
}else {
pageNum = pageNum;
}
if (goNum<=0){
alert("请输入大于0的数值");
}
else if(goNum<=pageNum){
page(goNum - 1,pageSize);
}
else{
alert("不能超出总页码!");
}
}

$("#goNum").keydown(function (e) {
if (e.keyCode == 13) {
goPage();
}
});

function setPage(pageData,pageSize){
if (isEmpty(pageData)){
return;
}
var startIndex = pageData.current * pageSize;
if(pageData.total > 0){
startIndex = startIndex + 1;
}
if(startIndex < 10){
$('#startIndex').text(" " + (startIndex));
}else{
$('#startIndex').text(startIndex);
}
var endIndex = pageData.current * pageSize + pageData.data.length;
if(endIndex < 10){
$('#endIndex').text(" " + (endIndex));
}else{
$('#endIndex').text(endIndex);
}
$('#totalNum').text(pageData.total);
$('#displayPage1').text(pageData.current + 1);


if(pageData.current == 0){
$('#prePage').removeAttr("href");
$('#prePage').attr('style','color:#f5f5f6;');
}
else{
$('#prePage').attr("href","javascript:prePage()");
$('#prePage').attr('style','color:#000;');
}

if((pageData.current + 1) * pageSize >= pageData.total){
$('#nextPage').removeAttr("href");
$('#nextPage').attr('style','color:#f5f5f6;')
}
else{
$('#nextPage').attr("href","javascript:nextPage()");
$('#nextPage').attr('style','color:#000;');
}

var pageTotal = pageData.total;
var pageNum = parseInt(pageTotal/pageSize);
if(pageTotal%pageSize!=0){
pageNum += 1;
}else {
pageNum = pageNum;
}
$("#totalPageNum").text(pageNum);
}

function clickfilelist(index){
fileindex=index;
loadimg();
//drawimage();
breadFiles()
showfilelist();
}

function clickNext(){
if(fileindex<tableData.length-1) {
next();
}else{
if((tablePageData.current + 1) * pageSize >= tablePageData.total){
return;
}
nextPage();
}
}


function next(){
if(fileindex<tableData.length-1) {fileindex=fileindex+1;}
loadimg();
//drawimage();
breadFiles()
showfilelist();
}

function clickLast(){
if(fileindex == 0){
prePage();
}else{
last();
}
}

function last(){

if(fileindex>0) {fileindex=fileindex-1;}
loadimg();
//drawimage();
breadFiles();
showfilelist();
}


// function showfilelist(){
// var htmlstr="";
// for (var i=0;i<labeltastresult.length;i++){
// var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1);
// var lablebg=" style=\"cursor:pointer\"";
// if (i==fileindex){lablebg=" style=\"background:#eee;color:#5a5a5a;cursor:pointer;\"";}
// htmlstr = htmlstr+"<tr onclick=\"clickfilelist("+i+");\""+ lablebg+"><td>"+ fname+ "</td></tr>";
// };
// document.getElementById("filelist").innerHTML=htmlstr;
// }


function showfilelist(){
var filename_title = $('a.section:first').text()
filename_title = filename_title.split('.')[0]
var htmlstr = '';
// htmlstr += '<div class="ui list">';
htmlstr += '<div class="item" style="padding:1.2em;border-bottom:0">'
htmlstr += '<i class="caret down icon"></i>'
htmlstr += '<div class="content" style="background:#fff">'
htmlstr += '<div class="header" style="color: rgba(0,0,0,.8);font-size: 12px;font-weight: 600;">'+filename_title+'</div>'
htmlstr += '<div class="list" style="padding:1.2em">'
for (var i=0;i<labeltastresult.length;i++){
var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1);
console.log(labeltastresult[i])
if(labeltastresult[i].pic_image_field.length > 70){
var tmpIndex = labeltastresult[i].pic_image_field.indexOf("/",70);
console.log(tmpIndex)
if(tmpIndex != -1){
fname = labeltastresult[i].pic_image_field.substring(tmpIndex + 1);
}
}
htmlstr += '<div class="item" onclick=\"clickfilelist('+i+');\" style="border-bottom:0;padding-bottom:0.9em;cursor:pointer">'
htmlstr += '<div class="content" style="background:#fff;padding:0;">'
if(i==fileindex){
htmlstr += '<div class="header" style="color: rgba(0,0,0,.8);font-size: 12px;font-weight: 100;color:#0366d6">'+fname+'</div>'
}
else{
htmlstr += '<div class="header" style="color: rgba(0,0,0,.8);font-size: 12px;font-weight: 100;">'+fname+'</div>'
}
htmlstr += '</div>'
htmlstr += '</div>'
};
htmlstr += '</div>'
htmlstr += '</div>'
htmlstr += '</div>'
document.getElementById("filelist").innerHTML=htmlstr;
}


function breadFiles(){

// for (var i=0;i<labeltastresult.length;i++){
// var fname_full_path=""
// if(labeltastresult[i].pic_image_field.length > 70){
// var tmp_index = labeltastresult[i].pic_image_field.indexOf("/",70);
// if(tmp_index != -1){
// fname_full_path = labeltastresult[i].pic_image_field.substring(tmp_index + 1);
// }
// var fname_path = fname_full_path.split('/')
// html_breadFile += '<div class="section">'+fname_full_path+'.zip'+'</div>'
// for(var i=1;i<fname_path.length;i++){
// html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>'
// html_breadFile += '<div class="section">'+fname_path[i]+'</div>'

// }
// }
// else{


// }
// }
var fname_full_path=""
var filename_title = $('a.section:first').text()
filename_title = filename_title.split('.')[0]
var tmp_index = tableData[fileindex].pic_image_field.indexOf("/",70);
if(tmp_index != -1){
fname_full_path = tableData[fileindex].pic_image_field.substring(tmp_index + 1);
}
var fname_path = fname_full_path.split('/')
console.log(fname_path)
// var filename_text = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/')+1)
var html_breadFile = ''
// var source_name = filename_title+'.zip'
// html_breadFile += '<div class="section">'+source_name+'</div>'
// html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>'
html_breadFile += '<div class="section">'+filename_title+'</div>'
html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>'
for (var i=0;i<fname_path.length;i++){
html_breadFile += '<div class="section">'+fname_path[i]+'</div>'
html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>'
}
document.getElementById("breadFile").innerHTML=html_breadFile

}

function showlabelflist(){
if(!isEmpty(labelInfo)){
var resLabelInfo = JSON.parse(labelInfo)
var textInfo = resLabelInfo["type"]
var html_labelFile = ''
for (var i=0;i<textInfo.length;i++){

html_labelFile += `<span style="display:block;width:70%;margin:0.6em 15%;padding-left:1.5em;padding-top:0.4em;padding-bottom:0.4em;font-size:12px;" class="labelInfo">${textInfo[i]}</span>`

}
document.getElementById("labellist").innerHTML=html_labelFile
setColor()
}
else{
return
}

}
function setColor(){
var el_span = document.querySelectorAll("span.labelInfo")
for (var i=0;i<el_span.length;i++){
var colorinfo = ~~(Math.random()*(1<<24))
var colorinfo1 = '#'+(colorinfo).toString(16)
var colorinfo2 = '#'+(colorinfo+100).toString(16)
el_span[i].style.backgroundColor = colorinfo1
el_span[i].style.borderLeft = '6px solid'+ colorinfo2
}

}
function getLabelInfo(uuid){
$.ajax({
type:"GET",
url:ip + "/getlabelinfo",
headers: {
authorization:token,
},
dataType:"text",
data:{
'uuid':uuid
},
async:false,
success:function(json){
labelInfo = json;
},
error:function(response) {
}
});

}

BIN
public/self/fonts/FontAwesome.otf View File


BIN
public/self/fonts/fontawesome-webfont.eot View File


+ 2671
- 0
public/self/fonts/fontawesome-webfont.svg
File diff suppressed because it is too large
View File


BIN
public/self/fonts/fontawesome-webfont.ttf View File


BIN
public/self/fonts/fontawesome-webfont.woff View File


BIN
public/self/fonts/fontawesome-webfont.woff2 View File


+ 273
- 0
public/self/func.js View File

@@ -0,0 +1,273 @@
function getIp(){
//return "http://192.168.62.129:8000";
//return "http://192.168.62.129";
return "http://192.168.62.129:8010";
//return "http://111.231.109.64:8000";
}


function isEmpty(str){
if(typeof str == "undefined" || str == null || str == ""){
return true;
}
return false;
}

function redirect(response){
if("REDIRECT" == response.getResponseHeader("REDIRECT")){ //若HEADER中含有REDIRECT说明后端想重定向,
var win = window;
while(win != win.top){
win = win.top;
}
win.location.href = getIp() +"/login.html";//使用win.location.href去实现重定向到登录页面
}
}

function setCookie(name,value)
{
var Days = 7;
var exp = new Date();
exp.setTime(exp.getTime() + Days*24*60*60*1000);
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
}

//读取cookies
function getCookie(name)
{
var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
if(arr=document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}

function delCookie(name)
{
var exp = new Date();
exp.setTime(exp.getTime() - 1);
var cval=getCookie(name);
if(cval!=null)
document.cookie= name + "="+cval+";expires="+exp.toGMTString();
}

//检查是否都符合 注册 要求
function check_reg()
{
if(check_email(document.getElementById('email')) && check_web(document.getElementById('web')))
{
return true;
}else{
return false;
}
}
//检查密码长度不能少于6
function check_len(thisObj){
if(thisObj.value.length==0)
{
document.getElementById('show_pass').innerHTML="密码不能为空";
return false;
}else{
if (thisObj.value.length<6)
{
document.getElementById('show_pass').innerHTML="密码长度不少于6";
return false;
}
document.getElementById('show_pass').innerHTML="";
return true;
}
}
//检查俩次密码输入是否一致
function check_pass(thisObj){
var psw=document.getElementById('pass');
if(psw.value.length==0)
{
document.getElementById('show_pass').innerHTML="密码不能为空";
return false;
}else{
document.getElementById('show_pass').innerHTML="";
if (thisObj.value!=psw.value)
{
document.getElementById('show_repass').innerHTML="两次密码输入不正确";
return false;
}
document.getElementById('show_repass').innerHTML="";
return true;
}
}
//检查email是否正确
function check_email(thisObj){
var reg=/^([a-zA-Z\d][a-zA-Z0-9_]+@[a-zA-Z\d]+(\.[a-zA-Z\d]+)+)$/gi;
var rzt=thisObj.value.match(reg);
if(thisObj.value.length==0){
document.getElementById('show_e').innerHTML="Email不能为空";
return false;
}else{
if (rzt==null)
{
document.getElementById('show_e').innerHTML="Email地址不正确";
return false;
}
document.getElementById('show_e').innerHTML="";
return true;
}
}
//检查web是否正确
function check_web(thisObj){
//var reg=/^\w+([\.\-]\w)*$/;
//var rzt=thisObj.value.match(reg);
if(thisObj.value.length==0){
document.getElementById('show_web').innerHTML="主页不能为空";
return false;
}else{
/*if (rzt==null)
{
document.getElementById('show_web').innerHTML="主页地址不正确";
return false;
} */
var strRegex = "^((https|http|ftp|rtsp|mms)?://)"
+ "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@
+ "(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184
+ "|" // 允许IP和DOMAIN(域名)
+ "([0-9a-z_!~*'()-]+\.)*" // 域名- www.
+ "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // 二级域名
+ "[a-z]{2,6})" // first level domain- .com or .museum
+ "(:[0-9]{1,4})?" // 端口- :80
+ "((/?)|" // a slash isn't required if there is no file name
+ "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";
var re=new RegExp(strRegex);
if(!re.test(thisObj.value))
{
document.getElementById('show_web').innerHTML="主页地址不正确";
return false;
}
document.getElementById('show_web').innerHTML="";
return true;
}
}

function isRightLatitude(lat){
var latreg = /^(\-|\+)?([0-8]?\d{1}\.\d{0,6}|90\.0{0,6}|[0-8]?\d{1}|90)$/;
if(!latreg.test(lat)){
return false;
//console.log("纬度整数部分为0-90,小数部分为0到6位!");
}
return true;
}

function isRightLongitude(longitude){
var longrg = /^(\-|\+)?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,6})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,6}|180)$/;
if(!longrg.test(longitude)){
return false;
//console.log("经度整数部分为0-180,小数部分为0到6位!");
}
return true;
}

function isRightDateTime_dot(time){
//2020-05-20 14:20:20
if(time.length != 19){
return false;
}
return strDateTime(time);
}

function strDateTime(str)
{
var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/;
var r = str.match(reg);
if(r==null){
return false;
}
var d= new Date(r[1], r[3]-1,r[4],r[5],r[6],r[7]);
return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]&&d.getHours()==r[5]&&d.getMinutes()==r[6]&&d.getSeconds()==r[7]);
}

function isRightDateTime_yyyyMMddHHmmss(time){
//20200520142020
if(time.length != 14){
return false;
}
var year = time.substring(0,4);
var month = time.substring(4,6);
var day = time.substring(6,8);
var hour = time.substring(8,10);
var minute = time.substring(10,12);
var second = time.substring(12,14);
console.log("year=" + year + " month=" + month + "day=" + day);
var d= new Date(year,month-1,day,hour,minute,second);
return (d.getFullYear()==year && (d.getMonth()+1)== month&& d.getDate()== day && d.getHours()==hour && d.getMinutes()==minute && d.getSeconds()==second);
}

function isDateString(strDate){
var strSeparator = "-"; //日期分隔符
var strDateArray;
var intYear;
var intMonth;
var intDay;
var boolLeapYear;
var ErrorMsg = ""; //出错信息
strDateArray = strDate.split(strSeparator);
//没有判断长度,其实2008-8-8也是合理的//strDate.length != 10 ||
if(strDateArray.length != 3) {
ErrorMsg += "日期格式必须为: yyyy-MM-dd";
return ErrorMsg;
}
intYear = parseInt(strDateArray[0],10);
intMonth = parseInt(strDateArray[1],10);
intDay = parseInt(strDateArray[2],10);
if(isNaN(intYear)||isNaN(intMonth)||isNaN(intDay)) {
ErrorMsg += "日期格式错误: 年月日必须为纯数字";
return ErrorMsg;
}
if(intMonth>12 || intMonth<1) {
ErrorMsg += "日期格式错误: 月份必须介于1和12之间";
return ErrorMsg;
}
if((intMonth==1||intMonth==3||intMonth==5||intMonth==7
||intMonth==8||intMonth==10||intMonth==12)
&&(intDay>31||intDay<1)) {
ErrorMsg += "日期格式错误: 大月的天数必须介于1到31之间";
return ErrorMsg;
}
if((intMonth==4||intMonth==6||intMonth==9||intMonth==11)
&&(intDay>30||intDay<1)) {
ErrorMsg += "日期格式错误: 小月的天数必须介于1到31之间";
return ErrorMsg;
}
if(intMonth==2){
if(intDay < 1) {
ErrorMsg += "日期格式错误: 日期必须大于或等于1";
return ErrorMsg;
}
boolLeapYear = false;
if((intYear%100) == 0){
if((intYear%400) == 0)
boolLeapYear = true;
}
else{
if((intYear % 4) == 0)
boolLeapYear = true;
}
if(boolLeapYear){
if(intDay > 29) {
ErrorMsg += "日期格式错误: 闰年的2月份天数不能超过29";
return ErrorMsg;
}
} else {
if(intDay > 28) {
ErrorMsg += "日期格式错误: 非闰年的2月份天数不能超过28";
return ErrorMsg;
}
}
}
return ErrorMsg;
}

+ 2938
- 0
public/self/js/Director/detection.js
File diff suppressed because it is too large
View File


+ 2206
- 0
public/self/js/Director/labelingSelfDefine.js
File diff suppressed because it is too large
View File


+ 739
- 0
public/self/js/app.js View File

@@ -0,0 +1,739 @@
/*!
* Author: Abdullah A Almsaeed
* Date: 4 Jan 2014
* Description:
* This file should be included in all pages
!**/

/*
* Global variables. If you change any of these vars, don't forget
* to change the values in the less files!
*/
var left_side_width = 220; //Sidebar width in pixels

$(function() {
"use strict";

//Enable sidebar toggle
$("[data-toggle='offcanvas']").click(function(e) {
e.preventDefault();

//If window is small enough, enable sidebar push menu
if ($(window).width() <= 992) {
$('.row-offcanvas').toggleClass('active');
$('.left-side').removeClass("collapse-left");
$(".right-side").removeClass("strech");
$('.row-offcanvas').toggleClass("relative");
} else {
//Else, enable content streching
$('.left-side').toggleClass("collapse-left");
$(".right-side").toggleClass("strech");
}
});

//Add hover support for touch devices
$('.btn').bind('touchstart', function() {
$(this).addClass('hover');
}).bind('touchend', function() {
$(this).removeClass('hover');
});

//Activate tooltips
$("[data-toggle='tooltip']").tooltip();

/*
* Add collapse and remove events to boxes
*/
$("[data-widget='collapse']").click(function() {
//Find the box parent
var box = $(this).parents(".box").first();
//Find the body and the footer
var bf = box.find(".box-body, .box-footer");
if (!box.hasClass("collapsed-box")) {
box.addClass("collapsed-box");
//Convert minus into plus
$(this).children(".fa-minus").removeClass("fa-minus").addClass("fa-plus");
bf.slideUp();
} else {
box.removeClass("collapsed-box");
//Convert plus into minus
$(this).children(".fa-plus").removeClass("fa-plus").addClass("fa-minus");
bf.slideDown();
}
});

/*
* ADD SLIMSCROLL TO THE TOP NAV DROPDOWNS
* ---------------------------------------
*/
$(".navbar .menu").slimscroll({
height: "200px",
alwaysVisible: false,
size: "3px"
}).css("width", "100%");

/*
* INITIALIZE BUTTON TOGGLE
* ------------------------
*/
$('.btn-group[data-toggle="btn-toggle"]').each(function() {
var group = $(this);
$(this).find(".btn").click(function(e) {
group.find(".btn.active").removeClass("active");
$(this).addClass("active");
e.preventDefault();
});

});

$("[data-widget='remove']").click(function() {
//Find the box parent
var box = $(this).parents(".box").first();
box.slideUp();
});

/* Sidebar tree view */
$(".sidebar .treeview").tree();

/*
* Make sure that the sidebar is streched full height
* ---------------------------------------------
* We are gonna assign a min-height value every time the
* wrapper gets resized and upon page load. We will use
* Ben Alman's method for detecting the resize event.
*
**/
function _fix() {
//Get window height and the wrapper height
var height = $(window).height() - $("body > .header").height() - ($("body > .footer").outerHeight() || 0);
$(".wrapper").css("min-height", height + "px");
var content = $(".wrapper").height();
//If the wrapper height is greater than the window
if (content > height){

//then set sidebar height to the wrapper
$(".left-side, html, body").css("min-height", content + "px");
$(".pull-height, html, body").css("min-height", content + "px");
}
else {
//Otherwise, set the sidebar to the height of the window
$(".left-side, html, body").css("min-height", height + "px");
$(".pull-height, html, body").css("min-height", content + "px");
}
}
//Fire upon load
_fix();
//Fire when wrapper is resized
$(".wrapper").resize(function() {
_fix();
fix_sidebar();
});

//Fix the fixed layout sidebar scroll bug
fix_sidebar();

/*
* We are gonna initialize all checkbox and radio inputs to
* iCheck plugin in.
* You can find the documentation at http://fronteed.com/iCheck/
*/
// $("input[type='checkbox']:not(.simple), input[type='radio']:not(.simple)").iCheck({
// checkboxClass: 'icheckbox_minimal',
// radioClass: 'iradio_minimal'
// });

});
function fix_sidebar() {
//Make sure the body tag has the .fixed class
if (!$("body").hasClass("fixed")) {
return;
}

//Add slimscroll
$(".sidebar").slimscroll({
height: ($(window).height() - $(".header").height()) + "px",
color: "rgba(0,0,0,0.2)"
});
}


/*
* BOX REFRESH BUTTON
* ------------------
* This is a custom plugin to use with the compenet BOX. It allows you to add
* a refresh button to the box. It converts the box's state to a loading state.
*
* USAGE:
* $("#box-widget").boxRefresh( options );
* */
(function($) {
"use strict";

$.fn.boxRefresh = function(options) {

// Render options
var settings = $.extend({
//Refressh button selector
trigger: ".refresh-btn",
//File source to be loaded (e.g: ajax/src.php)
source: "",
//Callbacks
onLoadStart: function(box) {
}, //Right after the button has been clicked
onLoadDone: function(box) {
} //When the source has been loaded

}, options);

//The overlay
var overlay = $('<div class="overlay"></div><div class="loading-img"></div>');

return this.each(function() {
//if a source is specified
if (settings.source === "") {
if (console) {
console.log("Please specify a source first - boxRefresh()");
}
return;
}
//the box
var box = $(this);
//the button
var rBtn = box.find(settings.trigger).first();

//On trigger click
rBtn.click(function(e) {
e.preventDefault();
//Add loading overlay
start(box);

//Perform ajax call
box.find(".box-body").load(settings.source, function() {
done(box);
});


});

});

function start(box) {
//Add overlay and loading img
box.append(overlay);

settings.onLoadStart.call(box);
}

function done(box) {
//Remove overlay and loading img
box.find(overlay).remove();

settings.onLoadDone.call(box);
}

};

})(jQuery);

/*
* SIDEBAR MENU
* ------------
* This is a custom plugin for the sidebar menu. It provides a tree view.
*
* Usage:
* $(".sidebar).tree();
*
* Note: This plugin does not accept any options. Instead, it only requires a class
* added to the element that contains a sub-menu.
*
* When used with the sidebar, for example, it would look something like this:
* <ul class='sidebar-menu'>
* <li class="treeview active">
* <a href="#>Menu</a>
* <ul class='treeview-menu'>
* <li class='active'><a href=#>Level 1</a></li>
* </ul>
* </li>
* </ul>
*
* Add .active class to <li> elements if you want the menu to be open automatically
* on page load. See above for an example.
*/
(function($) {
"use strict";

$.fn.tree = function() {

return this.each(function() {
var btn = $(this).children("a").first();
var menu = $(this).children(".treeview-menu").first();
var isActive = $(this).hasClass('active');

//initialize already active menus
if (isActive) {
menu.show();
btn.children(".fa-angle-left").first().removeClass("fa-angle-left").addClass("fa-angle-down");
}
//Slide open or close the menu on link click
btn.click(function(e) {
e.preventDefault();
if (isActive) {
//Slide up to close menu
menu.slideUp();
isActive = false;
btn.children(".fa-angle-down").first().removeClass("fa-angle-down").addClass("fa-angle-left");
btn.parent("li").removeClass("active");
} else {
//Slide down to open menu
menu.slideDown();
isActive = true;
btn.children(".fa-angle-left").first().removeClass("fa-angle-left").addClass("fa-angle-down");
btn.parent("li").addClass("active");
}
});

/* Add margins to submenu elements to give it a tree look */
menu.find("li > a").each(function() {
var pad = parseInt($(this).css("margin-left")) + 10;

$(this).css({"margin-left": pad + "px"});
});

});

};


}(jQuery));

/*
* TODO LIST CUSTOM PLUGIN
* -----------------------
* This plugin depends on iCheck plugin for checkbox and radio inputs
*/
(function($) {
"use strict";

$.fn.todolist = function(options) {
// Render options
var settings = $.extend({
//When the user checks the input
onCheck: function(ele) {
},
//When the user unchecks the input
onUncheck: function(ele) {
}
}, options);

return this.each(function() {
$('input', this).on('ifChecked', function(event) {
var ele = $(this).parents("li").first();
ele.toggleClass("done");
settings.onCheck.call(ele);
});

$('input', this).on('ifUnchecked', function(event) {
var ele = $(this).parents("li").first();
ele.toggleClass("done");
settings.onUncheck.call(ele);
});
});
};

}(jQuery));

/* CENTER ELEMENTS */
(function($) {
"use strict";
jQuery.fn.center = function(parent) {
if (parent) {
parent = this.parent();
} else {
parent = window;
}
this.css({
"position": "absolute",
"top": ((($(parent).height() - this.outerHeight()) / 2) + $(parent).scrollTop() + "px"),
"left": ((($(parent).width() - this.outerWidth()) / 2) + $(parent).scrollLeft() + "px")
});
return this;
}
}(jQuery));

/*
* jQuery resize event - v1.1 - 3/14/2010
* http://benalman.com/projects/jquery-resize-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($, h, c) {
var a = $([]), e = $.resize = $.extend($.resize, {}), i, k = "setTimeout", j = "resize", d = j + "-special-event", b = "delay", f = "throttleWindow";
e[b] = 250;
e[f] = true;
$.event.special[j] = {setup: function() {
if (!e[f] && this[k]) {
return false;
}
var l = $(this);
a = a.add(l);
$.data(this, d, {w: l.width(), h: l.height()});
if (a.length === 1) {
g();
}
}, teardown: function() {
if (!e[f] && this[k]) {
return false
}
var l = $(this);
a = a.not(l);
l.removeData(d);
if (!a.length) {
clearTimeout(i);
}
}, add: function(l) {
if (!e[f] && this[k]) {
return false
}
var n;
function m(s, o, p) {
var q = $(this), r = $.data(this, d);
r.w = o !== c ? o : q.width();
r.h = p !== c ? p : q.height();
n.apply(this, arguments)
}
if ($.isFunction(l)) {
n = l;
return m
} else {
n = l.handler;
l.handler = m
}
}};
function g() {
i = h[k](function() {
a.each(function() {
var n = $(this), m = n.width(), l = n.height(), o = $.data(this, d);
if (m !== o.w || l !== o.h) {
n.trigger(j, [o.w = m, o.h = l])
}
});
g()
}, e[b])
}}
)(jQuery, this);

/*!
* SlimScroll https://github.com/rochal/jQuery-slimScroll
* =======================================================
*
* Copyright (c) 2011 Piotr Rochala (http://rocha.la) Dual licensed under the MIT
*/
(function(f) {
jQuery.fn.extend({slimScroll: function(h) {
var a = f.extend({width: "auto", height: "100%", size: "7px", color: "#000", position: "right", distance: "1px", start: "top", opacity: 0.4, alwaysVisible: !0, disableFadeOut: !1, railVisible: !1, railColor: "#333", railOpacity: 0.2, railDraggable: !0, railClass: "slimScrollRail", barClass: "slimScrollBar", wrapperClass: "slimScrollDiv", allowPageScroll: !1, wheelStep: 20, touchScrollStep: 200, borderRadius: "5px", railBorderRadius: "5px"}, h);
this.each(function() {
function r(d) {
if (s) {
d = d ||
window.event;
var c = 0;
d.wheelDelta && (c = -d.wheelDelta / 120);
d.detail && (c = d.detail / 3);
f(d.target || d.srcTarget || d.srcElement).closest("." + a.wrapperClass).is(b.parent()) && m(c, !0);
d.preventDefault && !k && d.preventDefault();
k || (d.returnValue = !1)
}
}
function m(d, f, h) {
k = !1;
var e = d, g = b.outerHeight() - c.outerHeight();
f && (e = parseInt(c.css("top")) + d * parseInt(a.wheelStep) / 100 * c.outerHeight(), e = Math.min(Math.max(e, 0), g), e = 0 < d ? Math.ceil(e) : Math.floor(e), c.css({top: e + "px"}));
l = parseInt(c.css("top")) / (b.outerHeight() - c.outerHeight());
e = l * (b[0].scrollHeight - b.outerHeight());
h && (e = d, d = e / b[0].scrollHeight * b.outerHeight(), d = Math.min(Math.max(d, 0), g), c.css({top: d + "px"}));
b.scrollTop(e);
b.trigger("slimscrolling", ~~e);
v();
p()
}
function C() {
window.addEventListener ? (this.addEventListener("DOMMouseScroll", r, !1), this.addEventListener("mousewheel", r, !1), this.addEventListener("MozMousePixelScroll", r, !1)) : document.attachEvent("onmousewheel", r)
}
function w() {
u = Math.max(b.outerHeight() / b[0].scrollHeight * b.outerHeight(), D);
c.css({height: u + "px"});
var a = u == b.outerHeight() ? "none" : "block";
c.css({display: a})
}
function v() {
w();
clearTimeout(A);
l == ~~l ? (k = a.allowPageScroll, B != l && b.trigger("slimscroll", 0 == ~~l ? "top" : "bottom")) : k = !1;
B = l;
u >= b.outerHeight() ? k = !0 : (c.stop(!0, !0).fadeIn("fast"), a.railVisible && g.stop(!0, !0).fadeIn("fast"))
}
function p() {
a.alwaysVisible || (A = setTimeout(function() {
a.disableFadeOut && s || (x || y) || (c.fadeOut("slow"), g.fadeOut("slow"))
}, 1E3))
}
var s, x, y, A, z, u, l, B, D = 30, k = !1, b = f(this);
if (b.parent().hasClass(a.wrapperClass)) {
var n = b.scrollTop(),
c = b.parent().find("." + a.barClass), g = b.parent().find("." + a.railClass);
w();
if (f.isPlainObject(h)) {
if ("height"in h && "auto" == h.height) {
b.parent().css("height", "auto");
b.css("height", "auto");
var q = b.parent().parent().height();
b.parent().css("height", q);
b.css("height", q)
}
if ("scrollTo"in h)
n = parseInt(a.scrollTo);
else if ("scrollBy"in h)
n += parseInt(a.scrollBy);
else if ("destroy"in h) {
c.remove();
g.remove();
b.unwrap();
return
}
m(n, !1, !0)
}
} else {
a.height = "auto" == a.height ? b.parent().height() : a.height;
n = f("<div></div>").addClass(a.wrapperClass).css({position: "relative",
overflow: "hidden", width: a.width, height: a.height});
b.css({overflow: "hidden", width: a.width, height: a.height});
var g = f("<div></div>").addClass(a.railClass).css({width: a.size, height: "100%", position: "absolute", top: 0, display: a.alwaysVisible && a.railVisible ? "block" : "none", "border-radius": a.railBorderRadius, background: a.railColor, opacity: a.railOpacity, zIndex: 90}), c = f("<div></div>").addClass(a.barClass).css({background: a.color, width: a.size, position: "absolute", top: 0, opacity: a.opacity, display: a.alwaysVisible ?
"block" : "none", "border-radius": a.borderRadius, BorderRadius: a.borderRadius, MozBorderRadius: a.borderRadius, WebkitBorderRadius: a.borderRadius, zIndex: 99}), q = "right" == a.position ? {right: a.distance} : {left: a.distance};
g.css(q);
c.css(q);
b.wrap(n);
b.parent().append(c);
b.parent().append(g);
a.railDraggable && c.bind("mousedown", function(a) {
var b = f(document);
y = !0;
t = parseFloat(c.css("top"));
pageY = a.pageY;
b.bind("mousemove.slimscroll", function(a) {
currTop = t + a.pageY - pageY;
c.css("top", currTop);
m(0, c.position().top, !1)
});
b.bind("mouseup.slimscroll", function(a) {
y = !1;
p();
b.unbind(".slimscroll")
});
return!1
}).bind("selectstart.slimscroll", function(a) {
a.stopPropagation();
a.preventDefault();
return!1
});
g.hover(function() {
v()
}, function() {
p()
});
c.hover(function() {
x = !0
}, function() {
x = !1
});
b.hover(function() {
s = !0;
v();
p()
}, function() {
s = !1;
p()
});
b.bind("touchstart", function(a, b) {
a.originalEvent.touches.length && (z = a.originalEvent.touches[0].pageY)
});
b.bind("touchmove", function(b) {
k || b.originalEvent.preventDefault();
b.originalEvent.touches.length &&
(m((z - b.originalEvent.touches[0].pageY) / a.touchScrollStep, !0), z = b.originalEvent.touches[0].pageY)
});
w();
"bottom" === a.start ? (c.css({top: b.outerHeight() - c.outerHeight()}), m(0, !0)) : "top" !== a.start && (m(f(a.start).position().top, null, !0), a.alwaysVisible || c.hide());
C()
}
});
return this
}});
jQuery.fn.extend({slimscroll: jQuery.fn.slimScroll})
})(jQuery);

/*! iCheck v1.0.1 by Damir Sultanov, http://git.io/arlzeA, MIT Licensed */
(function(h) {
function F(a, b, d) {
var c = a[0], e = /er/.test(d) ? m : /bl/.test(d) ? s : l, f = d == H ? {checked: c[l], disabled: c[s], indeterminate: "true" == a.attr(m) || "false" == a.attr(w)} : c[e];
if (/^(ch|di|in)/.test(d) && !f)
D(a, e);
else if (/^(un|en|de)/.test(d) && f)
t(a, e);
else if (d == H)
for (e in f)
f[e] ? D(a, e, !0) : t(a, e, !0);
else if (!b || "toggle" == d) {
if (!b)
a[p]("ifClicked");
f ? c[n] !== u && t(a, e) : D(a, e)
}
}
function D(a, b, d) {
var c = a[0], e = a.parent(), f = b == l, A = b == m, B = b == s, K = A ? w : f ? E : "enabled", p = k(a, K + x(c[n])), N = k(a, b + x(c[n]));
if (!0 !== c[b]) {
if (!d &&
b == l && c[n] == u && c.name) {
var C = a.closest("form"), r = 'input[name="' + c.name + '"]', r = C.length ? C.find(r) : h(r);
r.each(function() {
this !== c && h(this).data(q) && t(h(this), b)
})
}
A ? (c[b] = !0, c[l] && t(a, l, "force")) : (d || (c[b] = !0), f && c[m] && t(a, m, !1));
L(a, f, b, d)
}
c[s] && k(a, y, !0) && e.find("." + I).css(y, "default");
e[v](N || k(a, b) || "");
B ? e.attr("aria-disabled", "true") : e.attr("aria-checked", A ? "mixed" : "true");
e[z](p || k(a, K) || "")
}
function t(a, b, d) {
var c = a[0], e = a.parent(), f = b == l, h = b == m, q = b == s, p = h ? w : f ? E : "enabled", t = k(a, p + x(c[n])),
u = k(a, b + x(c[n]));
if (!1 !== c[b]) {
if (h || !d || "force" == d)
c[b] = !1;
L(a, f, p, d)
}
!c[s] && k(a, y, !0) && e.find("." + I).css(y, "pointer");
e[z](u || k(a, b) || "");
q ? e.attr("aria-disabled", "false") : e.attr("aria-checked", "false");
e[v](t || k(a, p) || "")
}
function M(a, b) {
if (a.data(q)) {
a.parent().html(a.attr("style", a.data(q).s || ""));
if (b)
a[p](b);
a.off(".i").unwrap();
h(G + '[for="' + a[0].id + '"]').add(a.closest(G)).off(".i")
}
}
function k(a, b, d) {
if (a.data(q))
return a.data(q).o[b + (d ? "" : "Class")]
}
function x(a) {
return a.charAt(0).toUpperCase() +
a.slice(1)
}
function L(a, b, d, c) {
if (!c) {
if (b)
a[p]("ifToggled");
a[p]("ifChanged")[p]("if" + x(d))
}
}
var q = "iCheck", I = q + "-helper", u = "radio", l = "checked", E = "un" + l, s = "disabled", w = "determinate", m = "in" + w, H = "update", n = "type", v = "addClass", z = "removeClass", p = "trigger", G = "label", y = "cursor", J = /ipad|iphone|ipod|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent);
h.fn[q] = function(a, b) {
var d = 'input[type="checkbox"], input[type="' + u + '"]', c = h(), e = function(a) {
a.each(function() {
var a = h(this);
c = a.is(d) ?
c.add(a) : c.add(a.find(d))
})
};
if (/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(a))
return a = a.toLowerCase(), e(this), c.each(function() {
var c = h(this);
"destroy" == a ? M(c, "ifDestroyed") : F(c, !0, a);
h.isFunction(b) && b()
});
if ("object" != typeof a && a)
return this;
var f = h.extend({checkedClass: l, disabledClass: s, indeterminateClass: m, labelHover: !0, aria: !1}, a), k = f.handle, B = f.hoverClass || "hover", x = f.focusClass || "focus", w = f.activeClass || "active", y = !!f.labelHover, C = f.labelHoverClass ||
"hover", r = ("" + f.increaseArea).replace("%", "") | 0;
if ("checkbox" == k || k == u)
d = 'input[type="' + k + '"]';
-50 > r && (r = -50);
e(this);
return c.each(function() {
var a = h(this);
M(a);
var c = this, b = c.id, e = -r + "%", d = 100 + 2 * r + "%", d = {position: "absolute", top: e, left: e, display: "block", width: d, height: d, margin: 0, padding: 0, background: "#fff", border: 0, opacity: 0}, e = J ? {position: "absolute", visibility: "hidden"} : r ? d : {position: "absolute", opacity: 0}, k = "checkbox" == c[n] ? f.checkboxClass || "icheckbox" : f.radioClass || "i" + u, m = h(G + '[for="' + b + '"]').add(a.closest(G)),
A = !!f.aria, E = q + "-" + Math.random().toString(36).replace("0.", ""), g = '<div class="' + k + '" ' + (A ? 'role="' + c[n] + '" ' : "");
m.length && A && m.each(function() {
g += 'aria-labelledby="';
this.id ? g += this.id : (this.id = E, g += E);
g += '"'
});
g = a.wrap(g + "/>")[p]("ifCreated").parent().append(f.insert);
d = h('<ins class="' + I + '"/>').css(d).appendTo(g);
a.data(q, {o: f, s: a.attr("style")}).css(e);
f.inheritClass && g[v](c.className || "");
f.inheritID && b && g.attr("id", q + "-" + b);
"static" == g.css("position") && g.css("position", "relative");
F(a, !0, H);
if (m.length)
m.on("click.i mouseover.i mouseout.i touchbegin.i touchend.i", function(b) {
var d = b[n], e = h(this);
if (!c[s]) {
if ("click" == d) {
if (h(b.target).is("a"))
return;
F(a, !1, !0)
} else
y && (/ut|nd/.test(d) ? (g[z](B), e[z](C)) : (g[v](B), e[v](C)));
if (J)
b.stopPropagation();
else
return!1
}
});
a.on("click.i focus.i blur.i keyup.i keydown.i keypress.i", function(b) {
var d = b[n];
b = b.keyCode;
if ("click" == d)
return!1;
if ("keydown" == d && 32 == b)
return c[n] == u && c[l] || (c[l] ? t(a, l) : D(a, l)), !1;
if ("keyup" == d && c[n] == u)
!c[l] && D(a, l);
else if (/us|ur/.test(d))
g["blur" ==
d ? z : v](x)
});
d.on("click mousedown mouseup mouseover mouseout touchbegin.i touchend.i", function(b) {
var d = b[n], e = /wn|up/.test(d) ? w : B;
if (!c[s]) {
if ("click" == d)
F(a, !1, !0);
else {
if (/wn|er|in/.test(d))
g[v](e);
else
g[z](e + " " + w);
if (m.length && y && e == B)
m[/ut|nd/.test(d) ? z : v](C)
}
if (J)
b.stopPropagation();
else
return!1
}
})
})
}
})(window.jQuery || window.Zepto);

+ 7
- 0
public/self/js/bootstrap.min.js
File diff suppressed because it is too large
View File


+ 1541
- 0
public/self/js/jquery.jscrollpane.js
File diff suppressed because it is too large
View File


+ 2
- 0
public/self/js/jquery.min.js
File diff suppressed because it is too large
View File


+ 221
- 0
public/self/js/jquery.mousewheel.js View File

@@ -0,0 +1,221 @@
/*!
* jQuery Mousewheel 3.1.13
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*/

(function (factory) {
if ( typeof define === 'function' && define.amd ) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS style for Browserify
module.exports = factory;
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {

var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
slice = Array.prototype.slice,
nullLowestDeltaTimeout, lowestDelta;

if ( $.event.fixHooks ) {
for ( var i = toFix.length; i; ) {
$.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
}
}

var special = $.event.special.mousewheel = {
version: '3.1.12',

setup: function() {
if ( this.addEventListener ) {
for ( var i = toBind.length; i; ) {
this.addEventListener( toBind[--i], handler, false );
}
} else {
this.onmousewheel = handler;
}
// Store the line height and page height for this particular element
$.data(this, 'mousewheel-line-height', special.getLineHeight(this));
$.data(this, 'mousewheel-page-height', special.getPageHeight(this));
},

teardown: function() {
if ( this.removeEventListener ) {
for ( var i = toBind.length; i; ) {
this.removeEventListener( toBind[--i], handler, false );
}
} else {
this.onmousewheel = null;
}
// Clean up the data we added to the element
$.removeData(this, 'mousewheel-line-height');
$.removeData(this, 'mousewheel-page-height');
},

getLineHeight: function(elem) {
var $elem = $(elem),
$parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
if (!$parent.length) {
$parent = $('body');
}
return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
},

getPageHeight: function(elem) {
return $(elem).height();
},

settings: {
adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
normalizeOffset: true // calls getBoundingClientRect for each event
}
};

$.fn.extend({
mousewheel: function(fn) {
return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
},

unmousewheel: function(fn) {
return this.unbind('mousewheel', fn);
}
});


function handler(event) {
var orgEvent = event || window.event,
args = slice.call(arguments, 1),
delta = 0,
deltaX = 0,
deltaY = 0,
absDelta = 0,
offsetX = 0,
offsetY = 0;
event = $.event.fix(orgEvent);
event.type = 'mousewheel';

// Old school scrollwheel delta
if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }

// Firefox < 17 horizontal scrolling related to DOMMouseScroll event
if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
deltaX = deltaY * -1;
deltaY = 0;
}

// Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
delta = deltaY === 0 ? deltaX : deltaY;

// New school wheel delta (wheel event)
if ( 'deltaY' in orgEvent ) {
deltaY = orgEvent.deltaY * -1;
delta = deltaY;
}
if ( 'deltaX' in orgEvent ) {
deltaX = orgEvent.deltaX;
if ( deltaY === 0 ) { delta = deltaX * -1; }
}

// No change actually happened, no reason to go any further
if ( deltaY === 0 && deltaX === 0 ) { return; }

// Need to convert lines and pages to pixels if we aren't already in pixels
// There are three delta modes:
// * deltaMode 0 is by pixels, nothing to do
// * deltaMode 1 is by lines
// * deltaMode 2 is by pages
if ( orgEvent.deltaMode === 1 ) {
var lineHeight = $.data(this, 'mousewheel-line-height');
delta *= lineHeight;
deltaY *= lineHeight;
deltaX *= lineHeight;
} else if ( orgEvent.deltaMode === 2 ) {
var pageHeight = $.data(this, 'mousewheel-page-height');
delta *= pageHeight;
deltaY *= pageHeight;
deltaX *= pageHeight;
}

// Store lowest absolute delta to normalize the delta values
absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );

if ( !lowestDelta || absDelta < lowestDelta ) {
lowestDelta = absDelta;

// Adjust older deltas if necessary
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
lowestDelta /= 40;
}
}

// Adjust older deltas if necessary
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
// Divide all the things by 40!
delta /= 40;
deltaX /= 40;
deltaY /= 40;
}

// Get a whole, normalized value for the deltas
delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);

// Normalise offsetX and offsetY properties
if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
var boundingRect = this.getBoundingClientRect();
offsetX = event.clientX - boundingRect.left;
offsetY = event.clientY - boundingRect.top;
}

// Add information to the event object
event.deltaX = deltaX;
event.deltaY = deltaY;
event.deltaFactor = lowestDelta;
event.offsetX = offsetX;
event.offsetY = offsetY;
// Go ahead and set deltaMode to 0 since we converted to pixels
// Although this is a little odd since we overwrite the deltaX/Y
// properties with normalized deltas.
event.deltaMode = 0;

// Add event and delta to the front of the arguments
args.unshift(event, delta, deltaX, deltaY);

// Clearout lowestDelta after sometime to better
// handle multiple device types that give different
// a different lowestDelta
// Ex: trackpad = 3 and mouse wheel = 120
if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);

return ($.event.dispatch || $.event.handle).apply(this, args);
}

function nullLowestDelta() {
lowestDelta = null;
}

function shouldAdjustOldDeltas(orgEvent, absDelta) {
// If this is an older event and the delta is divisable by 120,
// then we are assuming that the browser is treating this as an
// older mouse wheel event and that we should divide the deltas
// by 40 to try and get a more usable deltaFactor.
// Side note, this actually impacts the reported scroll distance
// in older browsers and can cause scrolling to be slower than native.
// Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
}

}));

+ 962
- 0
public/self/labelTaskPage.js View File

@@ -0,0 +1,962 @@
var token;
if(isEmpty(token)){
var meta = $("meta[name=_uid]");
if(!isEmpty(meta)){
token = meta.attr("content");
console.log("token is uid:" + token);
}
}
var authorMeta = $("meta[name=author]");
var userName;
if(!isEmpty(authorMeta)){
userName = authorMeta.attr("content");
console.log("user name=" + userName);
}
var userType;
if(isEmpty(userType)){
userType =1;
}
var ip = getIp();

var pageSize = 10;

var tableData;
var tablePageData;

var preDictTaskData;
var dataSetTaskData;

var userInfoData;
var labelPropertyData;
var repoId = $('#repoId').val();


console.log("repoId=" + repoId);

function setDataSetTask(){
dataset_task_list();
display_createdatasetlabel(0);
//getUser();
//dislpayUser();
getLabelPropertyTask();
displayLabelPropertyTask();
$(".ui.dataset.modal").modal("show");
}

function getLabelPropertyTask(){
$.ajax({
type:"GET",
url:ip + "/api/label-property-task-all/",
headers: {
authorization:token,
},
dataType:"json",
async:false,
success:function(json){
labelPropertyData = json;
console.log(json);
},
error:function(response) {
redirect(response);
}
});
}

function displayLabelPropertyTask(){
var html="<option value=\"\" selected=\"\">请选择</option>";
for (var i=0;i<labelPropertyData.length;i++){
var row = "<option value=\""+labelPropertyData[i].id+
"\">"+labelPropertyData[i].task_name +
"</option>";
html=html+row;
}
console.log(html);
document.getElementById('labelpropertytask_dataset').innerHTML=html;
document.getElementById('labelpropertytask_auto').innerHTML=html;
}

function dataset_task_list(){
$.ajax({
type:"GET",
url:ip + "/gitea-dataset/",
headers: {
authorization:token,
},
dataType:"json",
data:{
'repoId':repoId,
'dateset_type':'[1]'
},
async:false,
success:function(json){
dataSetTaskData = json;
console.log(json);
// return json.token;
},
error:function(response) {
redirect(response);
}
});
}

function countLabel(){
$.ajax({
type:"GET",
url:ip + "/gitea/label-count/",
headers: {
authorization:token,
},
dataType:"json",
async:false,
success:function(json){
alert("请等待几分钟,服务端正在加紧统计。");
},
error:function(response) {
redirect(response);
}
});
}

function display_createdatasetlabel(sindex=-1){
var html="";
for (var i=0;i<dataSetTaskData.length;i++){
if (i==sindex){
var row = "<option value=\""+dataSetTaskData[i].id+
"\" selected=\"\">"+dataSetTaskData[i].task_name+
"</option>";
$("#datasetlabeltaskname").attr({value:dataSetTaskData[i].task_name + "-人工标注"});
}else{
var row = "<option value=\""+dataSetTaskData[i].id+
"\">"+dataSetTaskData[i].task_name+
"</option>";
}
html=html+row;
}
console.log(html);
document.getElementById('dataset_list').innerHTML=html;
}


function setPredictTask(){
pre_predict_task_list();
display_createlabel(0);
getUser();
dislpayUser();
getLabelPropertyTask();
displayLabelPropertyTask();
}

function pre_predict_task_list(){
$.ajax({
type:"GET",
url:ip + "/api/pre-predict-taskforLabel/",
headers: {
authorization:token,
},
dataType:"json",
async:false,
success:function(json){
preDictTaskData = json;
console.log(json);
// return json.token;
},
error:function(response) {
redirect(response);
}
});
}

function sele_Change(sele){
var predictTaskName = $('#pre_predict_task_for_label option:selected').text();
console.log("select predictTaskName =" + predictTaskName);
$("#labeltaskname").attr({value:predictTaskName+"-人工标注"});
}

function sele_export_Change(sele){

var isNeedPicture = $('#isNeedPicture option:selected').val();

if(isNeedPicture == 3){
document.getElementById("maxscore_div").style.display="block";
document.getElementById("minscore_div").style.display="block";
$('#maxscore').val("1.0");
$('#minscore').val("0.6");
}else{
document.getElementById("maxscore_div").style.display="none";
document.getElementById("minscore_div").style.display="none";
$('#maxscore').val("");
$('#minscore').val("");
}
}


function dataset_sele_Change(sele){
var dataset_listName = $('#dataset_list option:selected').text();
console.log("select dataset_list =" + dataset_listName);
$("#datasetlabeltaskname").attr({value:dataset_listName+"-人工标注"});
}



function display_createlabel(sindex=-1){
var html="";
for (var i=0;i<preDictTaskData.length;i++){
if (i==sindex){
var row = "<option value=\""+preDictTaskData[i].id+
"\" selected=\"\">"+preDictTaskData[i].task_name+
"</option>";
$("#labeltaskname").attr({value:preDictTaskData[i].task_name + "-人工标注"});
}else{
var row = "<option value=\""+preDictTaskData[i].id+
"\">"+preDictTaskData[i].task_name+
"</option>";
}
html=html+row;
}
console.log(html);
document.getElementById('pre_predict_task_for_label').innerHTML=html;
}

var createsucced;

function submit_datasettask(){
console.log($('#datasetlabeltaskname').val());
var task_name = $('#datasetlabeltaskname').val();
if (isEmpty(task_name) || task_name.length > 32){
alert("人工标注任务名称不能为空或者不能超过32个字符。");
return;
}
var assign_user_id = $('#assign_user option:selected').val();
if(isEmpty(assign_user_id)){
assign_user_id = token;
}
var relate_task_id = $('#dataset_list option:selected').val();
if(isEmpty(relate_task_id)){
alert("数据集对象不能为空。");
return;
}
var labelpropertytaskid = $('#labelpropertytask_dataset option:selected').val();
createsucced = true;
label_task_create(task_name, relate_task_id, 2,assign_user_id,labelpropertytaskid);
if(createsucced){
$(".ui.dataset.modal").modal("hide");
//$("#labelDataModal").modal('hide');
}
page(0,pageSize);
}

function submit_labeltask(){
console.log($('#labeltaskname').val());
var task_name = $('#labeltaskname').val();
if (isEmpty(task_name) || task_name.length > 32){
alert("人工标注任务名称不能为空或者不能超过32个字符。");
return;
}
var relate_task_id = $('#pre_predict_task_for_label option:selected').val();
if(isEmpty(relate_task_id)){
alert("关联的自动标注任务不能为空。");
return;
}
var assign_user_id = $('#label_assign_user option:selected').val();
if(isEmpty(assign_user_id)){
assign_user_id = token;
}
var labelpropertytaskid = $('#labelpropertytask_dataset option:selected').val();
createsucced = true;
label_task_create(task_name, relate_task_id, 1,assign_user_id,labelpropertytaskid);
if(createsucced){
$("#labelModal").modal('hide');
}
page(0,pageSize);
}


function label_task_create(task_name, relate_task_id, taskType,assign_user_id,labelpropertytaskid){
var task_flow_type = $('#task_flow_type option:selected').val();
var relate_other_label_task = [];
if(task_flow_type == 2){
var items = document.getElementsByName("category");
for (i = 0; i < items.length; i++) {
if (items[i].checked) {
relate_other_label_task.push(items[i].value);
}
}
}
relate_other_label_task_jsonstr = JSON.stringify(relate_other_label_task);
console.log("relate_task_id=" + relate_task_id);
$.ajax({
type:"POST",
contentType:'application/json',
url:ip + "/gitea/label-task/",
dataType:"json",
async:false,
headers: {
authorization:token,
},
beforeSend: function (xhr) {
      xhr.withCredentials = true
    },
data:JSON.stringify({'task_name':task_name,
'assign_user_id':assign_user_id,
'task_flow_type':task_flow_type,
'relate_task_id':relate_task_id,//task id
'relate_other_label_task': relate_other_label_task_jsonstr,
"taskType": taskType,
"appid": repoId,
"createUserName":userName,
"labelPropertyTaskId":labelpropertytaskid
}),
success:function(res){
console.log(res);
if(res.code == 0){
alert("人工校验任务创建成功!");
createsucced = true;
}
else{
alert("创建人工标注任务失败," + res.message);
createsucced = false;
}
},
error:function(response) {
redirect(response);
}
});
}

function list(current,pageSize){
$.ajax({
type:"GET",
url:ip + "/gitea/label-task-page/",
headers: {
authorization:token,
},
dataType:"json",
data:{'startPage':current,
'pageSize':pageSize},
async:false,
success:function(json){
tablePageData = json;
tableData = json.data;
//console.log(json);
},
error:function(response) {
redirect(response);
}
});
}

var otherUserLabelTaskData;

function flow_type_sele_Change(sele){
var task_flow_type = $('#task_flow_type option:selected').val();
if(task_flow_type == 2){
var datasetid = $('#dataset_list option:selected').val();
getOtherUserLabelTaskByDataSetId(datasetid);
var html = "<p>请选择该数据集要审核的标注任务</p>";
for(var i = 0; i < otherUserLabelTaskData.length; i++){
html += "<p><input type=\"checkbox\" name=\"category\" value=\"" + otherUserLabelTaskData[i].id + "\"/>" + otherUserLabelTaskData[i].task_name + "(标注人:" + otherUserLabelTaskData[i].assign_user + ")" + "</p>";
}
document.getElementById('related_task_list').innerHTML=html;
}else{
document.getElementById('related_task_list').innerHTML= "";
}
}

function getOtherUserLabelTaskByDataSetId(datasetid){
$.ajax({
type:"GET",
url:ip + "/gitea/label-related-task/" + datasetid + "/",
headers: {
authorization:token,
},
dataType:"json",
async:false,
success:function(json){
otherUserLabelTaskData = json;
console.log(json);
},
error:function(response) {
redirect(response);
}
});
}

function dislpayUser(){
var html="<option value=\"\" selected=\"\">请选择</option>";
for (var i=0;i<userInfoData.length;i++){
var row = "<option value=\""+userInfoData[i].id+
"\">"+userInfoData[i].username+
"</option>";
html=html+row;
}
console.log(html);
document.getElementById('assign_user').innerHTML=html;
document.getElementById('label_assign_user').innerHTML=html;
}


function getUser(){
$.ajax({
type:"GET",
url:ip + "/api/queryAllUser/",
headers: {
authorization:token,
},
dataType:"json",
async:false,
success:function(json){
userInfoData = json;
console.log(json);
},
error:function(response) {
redirect(response);
}
});
}


function delete_labeltask(){
var stop = del();
if (stop){
return;
}
var Check = $("table[id='label_task_list'] input[type=checkbox]:checked");//在table中找input下类型为checkbox属性为选中状态的数据
      Check.each(function () {//遍历
            var row = $(this).parent("td").parent("tr");//获取选中行
            var id = row.find("[id='labeltask_id']").html();//获取name='Sid'的值
            delete_labeltask_byid(id);
        });
page(0,pageSize);
}

function del(){
if($("table[id='label_task_list'] input[type=checkbox]").is(":checked")) {
if (confirm("确实要删除吗?")) {
// alert("已经删除!");
return false;
} else {
// alert("已经取消了删除操作");
return true;
}
}else if($("table[id='label_task_list']").find("input").length=="0"){
alert("暂无可删的数据!");
return true;
}else{
alert("请先选择需要删除的选项!");
return true;
}
}

function delete_labeltask_byid(label_task_id){
$.ajax({
type:"DELETE",
url:ip + "/gitea/label-task/",
headers: {
authorization:token,
},
dataType:"json",
async:false,
data:{'label_task_id': label_task_id},
success:function(json){
console.log(json);
},
error:function(response) {
redirect(response);
}
});
}

function getTaskTypeDesc(task_type){
if(task_type == 1){
return "自动标注结果";
}else if(task_type == 2){
return "原始数据集-图片";
}else if(task_type == 3){
return "原始数据集-CT影像";
}else if(task_type == 4){
return "原始数据集-视频";
}
return "其它";
}

function getLabelDesc(task_flow_type){
if(task_flow_type == 2){
return "审核";
}else{
return "人工"
}
}

function getTaskSataus(task_status,task_status_desc){
if(task_status == 0){
return "标注中:" + task_status_desc;
}else if(task_status == 1){
return "审核中:" + task_status_desc;
}
}

function getVerify(task_status,id,task_type){
console.log("task_status=" + task_status + " userType=" + userType);
if(task_status == 0 && (userType == 1 || userType == 0) ){
return "<a onclick=\"startToVerify(\'"+id+"\',\'" + task_type +"\');\" class=\"btn btn-xs btn-success\">转审核</a>&nbsp;&nbsp;&nbsp;";
}else if(task_status == 1 && userType == 2){
return "<a onclick=\"goVerify(\'"+id+"\',\'" + task_type +"\');\" class=\"btn btn-xs btn-success\">进入审核</a>&nbsp;&nbsp;&nbsp;" + "<a onclick=\"startToLabel(\'"+id+"\',\'" + task_type +"\');\" class=\"btn btn-xs btn-success\">转标注</a>&nbsp;&nbsp;&nbsp;";
}else{
return "";
}
}

function getLabel(task_status,id,task_type,task_flow_type){
if(task_status == 0 && (userType == 1 || userType == 0)){
return "<a onclick=\"personLabel(\'" + id + "\'," + task_type + ")\"><b>" + getLabelDesc(task_flow_type) + "标注</b></a><br>";
}else{
return "";
}
}


function display_list(){

var html="<tr>\
<th></th>\
<th id=\"labeltask_head\"></th>\
<th>标注任务名称</th>\
<th>关联的任务名称</th>\
<th>数据类型</th>\
<th>标注人员</th>\
<th>审核人员</th>\
<th>任务开始时间</th>\
<th>任务状态</th>\
<th>总标注数量</th>\
<th>操作</th>\
</tr>";
for (var i=0;i<tableData.length;i++){
var row = "<tr>\
<td><input type=\"checkbox\" class=\"flat-grey list-child\"/></td>\
<td id=\"labeltask_id\">"+tableData[i].id+"</td>\
<td>"+tableData[i].task_name+"</td>\
<td>"+tableData[i].relate_task_name+"</td>\
<td>"+ getTaskTypeDesc(tableData[i].task_type) +"</td>\
<td>"+tableData[i].assign_user+"</td>\
<td>"+tableData[i].verify_user+"</td>\
<td>"+tableData[i].task_add_time+"</td>\
<td>"+getTaskSataus(tableData[i].task_status,tableData[i].task_status_desc)+"</td>\
<td>"+tableData[i].total_label+"</td>\
<td>" +
getLabel(tableData[i].task_status,tableData[i].id,tableData[i].task_type,tableData[i].task_flow_type) + "<a onclick=\"setTaskId(\'"+tableData[i].id+"\');\"><b>导出标注</b></a>"
+
"</td>\
</tr>";

html=html+row;
}
//console.log(html);
document.getElementById('label_task_list').innerHTML=html;

$('#label_task_list tr').find('td:eq(1)').hide();
$('#label_task_list tr').find('th:eq(1)').hide();
}


function startToLabel(taskid, task_type){//从审核转回标注,标注人不变。
$.ajax({
type:"PATCH",
url:ip + "/gitea/label-task-status/",
dataType:"json",
async:false,
headers: {
authorization:token,
},
data:{
"label_task_id" : taskid,
"verify_user_id" : 0,
"task_status" : 0
},
success:function(res){
console.log(res);
},
error:function(response) {
redirect(response);
}
});
var current =$('#displayPage1').text();
page(current - 1,pageSize);
}

function startToVerify(taskid, task_type){
$("#hide_labeltasktoverifyid").val(taskid);
$.ajax({
type:"GET",
url:ip + "/api/queryVerifyUser/",
headers: {
authorization:token,
},
dataType:"json",
async:false,
success:function(json){
console.log(json);
var html="<option value=\"\" selected=\"\">请选择</option>";
for (var i=0;i<json.length; i++){
var row = "<option value=\""+json[i].id+"\">" + json[i].username + "</option>";
html=html+row;
}
document.getElementById('label_verify_user').innerHTML=html;
},
error:function(response) {
redirect(response);
}
});
$("#startToVerify").modal('show');
}

function submit_labeltask_toverify(){
var label_task_id = $('#hide_labeltasktoverifyid').val();
console.log("label_task_id=" +label_task_id);
var verify_user_id = $('#label_verify_user option:selected').val();
//修改状态
$.ajax({
type:"PATCH",
url:ip + "/gitea/label-task-status/",
dataType:"json",
async:false,
headers: {
authorization:token,
},
data:{
"label_task_id" : label_task_id,
"verify_user_id" : verify_user_id,
"task_status" : 1
},
success:function(res){
console.log(res);
},
error:function(response) {
redirect(response);
}
});
$("#startToVerify").modal('hide');
var current =$('#displayPage1').text();
page(current - 1,pageSize);
}
function goVerify(taskid, task_type){
sessionStorage.setItem('label_task',taskid);
sessionStorage.setItem('label_task_status',1);//审核
console.log("task_type=" + task_type);
if(task_type == 2 || task_type == 1 || task_type == 4){
window.location.href="labeling.html";
}else if(task_type == 3){
window.location.href="labelingDcm.html";
}
}


function personLabel(taskid, task_type){
sessionStorage.setItem('label_task',taskid);
sessionStorage.setItem('token',token);
sessionStorage.setItem('userType',1);
var pathname = window.location.pathname;
var search = window.location.search
var url_name = pathname + search
sessionStorage.setItem('return_url',url_name);
console.log("task_type=" + task_type);
if(task_type == 2 || task_type == 1 || task_type == 4){
window.open("/self/labeling.html","标注");
//window.location.href="/self/labeling.html";
}else if(task_type == 3){
window.location.href="labelingDcm.html";
}
}

function setMultiTaskId(){
var Check = $("table[id='label_task_list'] input[type=checkbox]:checked");//在table中找input下类型为checkbox属性为选中状态的数据
if(Check.length == 0){
alert("请选择一个或者多个标注数据进行导出。");
return;
}
var taskList = [];
  Check.each(function () {//遍历
      var row = $(this).parent("td").parent("tr");//获取选中行
      var id = row.find("[id='labeltask_id']").html();//获取name='Sid'的值
taskList.push(id);
      //$('#hide_labeltaskid').val(id);
  });
setTaskId(JSON.stringify(taskList));
}



function setTaskId(labeltaskid){
$('#hide_labeltaskid').val(labeltaskid);
console.log("go here1");
bar.style.width='1%';
document.getElementById('text-progress').innerHTML="0%";
document.getElementById("predtask_id").removeAttribute("disabled");
console.log("go here2");
$(".ui.export.modal").modal("show");
}

function isBeetween(score_threshhold){
if(isEmpty(score_threshhold)){
return true;
}
var regPos = /^\d+(\.\d+)?$/; //非负浮点数
if(!regPos.test(score_threshhold)){
return false;
}else{
if(score_threshhold >1 || score_threshhold < 0){
return false;
}
}
return true;
}


function downloadFile(){

var labeltaskid = $('#hide_labeltaskid').val();
var isNeedPicture = $('#isNeedPicture option:selected').val();
var maxscore = $('#maxscore').val();
var minscore = $('#minscore').val();
var exportFormat = $('#exportFormat option:selected').val();
if(isNeedPicture == 3){
if(!isBeetween(maxscore)){
alert("标注得分最大值应该填写0--1.0之间的数值。");
return;
}
if(!isBeetween(minscore)){
alert("标注得分最小值应该填写0--1.0之间的数值。");
return;
}
if(!isEmpty(maxscore) && !isEmpty(minscore)){
if(minscore>maxscore){
alert("标注得分最小值应该小于标注得分最大值。");
return;
}
}
}
document.getElementById("predtask_id").setAttribute("disabled", true);
var taskreturnid = "";
$.ajax({
type:"GET",
url:ip + "/gitea-label-task-export/",
headers: {
authorization:token,
},
dataType:"json",
data:{
"label_task_id" : labeltaskid,
"needPicture" : isNeedPicture,
"exportFormat":exportFormat,
"maxscore":maxscore,
"minscore":minscore
},
async:false,
success:function(json){
taskreturnid = json.message;
console.log(json);
},
error:function(response) {
redirect(response);
}
});
console.log("taskreturnid=" +taskreturnid);
if(!isEmpty(taskreturnid)){
setIntervalToDo(taskreturnid);
}
}


var timeId=[];
var count;
var progress;

function setIntervalToDo(taskreturnid){
count=0;
var tmpTimeId = self.setInterval("clock('" + taskreturnid +"')",1000);//5秒刷新
timeId.push(tmpTimeId);
console.log("开始刷新。timeId=" + tmpTimeId);
}

function clock(taskreturnid){
count++;
if(count > 600 ){
for(var i = 0;i < timeId.length; i++){
console.log("清除定时器1。exportTimeId=" + timeId[i]);
window.clearInterval(timeId[i]);
}
timeId = [];
$(".ui.export.modal").modal("hide");
return;
}
$.ajax({
type:"GET",
url:ip + "/api/query-download-progress/",
headers: {
authorization:token,
},
dataType:"json",
data:{'taskId': taskreturnid},
async:false,
success:function(json){
progress = json;
console.log(json);
},
error:function(response) {
progress = null;
console.log('query return null.');
redirect(response);
}
});
if(!isEmpty(progress)){
if(progress.progress >= 100){

var iSpeed = progress.progress;
bar.style.width=iSpeed+'%';
document.getElementById('text-progress').innerHTML=iSpeed+'%' + ",开始下载文件。"
for(var i = 0;i < timeId.length; i++){
console.log("清除定时器2。exportTimeId=" + timeId[i]);
window.clearInterval(timeId[i]);
}
timeId = [];
var url = ip + "/api/label-file-download/";
var $iframe = $('<iframe />');
var $form = $('<form method="get" target="_self"/>');
$form.attr('action', url); //设置get的url地址

$form.append('<input type="hidden" name="taskId" value="' + taskreturnid + '" />');
$iframe.append($form);
$(document.body).append($iframe);
$form[0].submit();//提交表单
$iframe.remove();//移除框架
$(".ui.export.modal").modal("hide");
}else{
//更新进度
var iSpeed = progress.progress;
bar.style.width=iSpeed+'%';
document.getElementById('text-progress').innerHTML=iSpeed+'%'
}
}else{
count = 600;
}
}


function page(current,pageSize){
list(current,pageSize);
display_list();
setPage(tablePageData,pageSize);
sessionStorage.setItem('label_task_page',current);
}

function nextPage(){
var current = $('#displayPage1').text();
console.log("current=" + current);
page(current,pageSize);
}

function prePage(){
var current =$('#displayPage1').text();
console.log("current=" + current);
if(current > 1){
console.log("current=" + (current - 2));
page(current - 2,pageSize);
}
}


function goPage(){
var goNum = $('#goNum').val();

var pageTotal = $("#totalNum").text();
var pageNum = parseInt(pageTotal/pageSize);
if(pageTotal%pageSize!=0){
pageNum += 1;
}else {
pageNum = pageNum;
}
if (goNum<=0){
alert("请输入大于0的数值");
}
else if(goNum<=pageNum){
page(goNum - 1,pageSize);
}
else{
alert("不能超出总页码!");
}
}

$("#goNum").keydown(function (e) {
if (e.keyCode == 13) {
goPage();
}
});



function setPage(pageData,pageSize){
if (isEmpty(pageData)){
return;
}
var startIndex = pageData.current * pageSize;
if(pageData.total > 0){
startIndex = startIndex + 1;
}
$('#startIndex').text(startIndex);
$('#endIndex').text(pageData.current * pageSize + pageData.data.length);
$('#totalNum').text(pageData.total);
$('#displayPage1').text(pageData.current + 1);

console.log("set prePage status, pageData.current=" + pageData.current);

if(pageData.current == 0){
console.log("set prePage disabled.");
$('#prePage').removeAttr("href");
$('#prePage').attr('style','color:#f5f5f6;');
}
else{
$('#prePage').attr("href","javascript:prePage()");
$('#prePage').attr('style','color:#000;');
}

if((pageData.current + 1) * pageSize >= pageData.total){
console.log("set nextPage disabled.");
$('#nextPage').removeAttr("href");
}
else{
$('#nextPage').attr("href","javascript:nextPage()");
}

var pageTotal = pageData.total;
var pageNum = parseInt(pageTotal/pageSize);
if(pageTotal%pageSize!=0){
pageNum += 1;
}else {
pageNum = pageNum;
}
$("#totalPageNum").text(pageNum);
}
var tmpCurrent = sessionStorage.getItem("label_task_page");
if(isEmpty(tmpCurrent)){
tmpCurrent = 0;
}
page(tmpCurrent,pageSize);


+ 874
- 0
public/self/labeling.html View File

@@ -0,0 +1,874 @@
<!-- <!DOCTYPE html> -->
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>PCL数据标注平台V2.0</title>
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
<meta name="description" content="Developed By M Abdur Rokib Promy">
<meta name="keywords" content="Admin, Bootstrap 3, Template, Theme, Responsive">
<!-- bootstrap 3.0.2 -->
<link href="/self/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<!-- font Awesome -->
<link href="/self/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<!-- Ionicons -->
<link href="/self/css/ionicons.min.css" rel="stylesheet" type="text/css" />
<!-- google font -->
<!-- Theme style -->
<link href="/self/css/style.css" rel="stylesheet" type="text/css" />

<link href="/self/css/jquery.yhhDataTable.css" rel="stylesheet" type="text/css" />

<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<![endif]-->
<script>
window.config={
AppSubUrl:'',
StaticUrlPrefix: '',
csrf: '',
}
</script>
<style>

html body{ height: 100%;margin: 0;padding: 0;}
.containers{
height: 100%;
}
.table-define td{border-bottom: 1px solid #222324;padding-top: 5px !important;padding-bottom:5px !important;border-top: 0px !important;padding-left: 20px !important;vertical-align: middle !important;}
.btn:hover{background: transparent;}
.display_area_content { } /* this class is used to clear the display area content */
.force_small_font { font-size:small !important; }
.draw_tool{padding:0;color:#fff}
.draw_li {padding: 0.2em;border: 0.5px solid rgba(34,35,36,0.2);border-bottom: 0;border-radius: 3px;cursor: pointer;}

ul.region_shape { font-size:xx-large; list-style-type:none; overflow:hidden; padding:0.4em 0; margin:0; }
/*ul.region_shape li { float:left; padding:0 0.2em; fill:#ffffff; stroke:#000000; }*/
ul.region_shape li { float:right; padding:0 0.2em; fill:#ffffff; stroke:#000000; }
ul.region_shape li:hover { cursor:pointer; fill:#ffffff; stroke:#ff0000; }
ul.region_shape .selected { fill:#ffffff; stroke:#ff0000; }

/*.toolbar { display:inline-block; margin-left:1rem; }*/
.toolbar { display:inline-block; margin-right:1rem; }
.toolbar svg { fill:white; margin: 0.2rem 0.1rem; height:1.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none;}
.toolbar svg:hover { fill:yellow; cursor:pointer; }
.toolbar svg:active { fill:white; }
.toolbar ul { display:inline-block; padding:0.2rem; margin:0; }
/*.toolbar li { display:inline; float:left; padding:0rem 0.3rem; border:1px solid white;} *//* main menu items */
.toolbar li { display:inline; float:right; padding:0rem 0.3rem; border:1px solid white;}
.toolbar li:hover { color:red; cursor:pointer; }

/* Top panel : #navbar, #toolbar */
.top_panel { font-size:0.9rem; display:block; background-color:#212121; color:#ffffff; z-index:1001; margin-bottom:1rem;}

/* Navigation menu bar that appear at the top */
.menubar { display:inline-block; height:1.8rem; } /* height needed to avoid extra bottom border */
.menubar a:link { color:#eeeeee; text-decoration:none; }
.menubar a:visited { color:#eeeeee; text-decoration:none; }
.menubar ul { display:block; padding:0; margin:0; }
/*.menubar li { display:inline; float:left; padding:0.45rem 1rem; }*/
.menubar li { display:inline; float:right; padding:0.45rem 1rem; }
.menubar li:hover { background-color:#616161; cursor:default; }

.menubar li ul { display:none; background-color:#212121; border:1px solid #616161; min-width:10rem; position:absolute; z-index:100; margin:0.4rem -1rem;}
.menubar li ul li { display:block; float:none; color:#eeeeee; margin:0; padding:0.6rem 1rem; }
.menubar li ul li:hover { cursor:pointer; }
.menubar li ul li.submenu_divider { margin:0 0.4rem; padding:0; height:1px; border-bottom:1px solid #424242; }
.menubar li:hover ul { display:block; }

/* toolbar containing small icons for tools */
.toolbar { display:inline-block; margin-right:1rem; }
/*.toolbar { display:inline-block; margin-left:1rem; }*/
.toolbar svg { fill:white; margin: 0.2rem 0.1rem; height:1.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none;}
.toolbar svg:hover { fill:yellow; cursor:pointer; }
.toolbar svg:active { fill:white; }
.toolbar ul { display:inline-block; padding:0.2rem; margin:0; }
/*.toolbar li { display:inline; float:left; padding:0rem 0.3rem; border:1px solid white;} *//* main menu items */
.toolbar li { display:inline; float:right; padding:0rem 0.3rem; border:1px solid white;}
.toolbar li:hover { color:red; cursor:pointer; }

/* Middle panel: containing #image_panel, #leftsidebar */
/*.middle_panel { display:table; table-layout:fixed; width:100%; z-index:1; padding:0;}*/
.middle_panel { display:table; table-layout:fixed; right:0px,width:100%; z-index:1; padding:0;}
/*#leftsidebar { display:none; z-index:10; vertical-align:top;}*/
#leftsidebar { display:none; z-index:10; vertical-align:top;}
/*#rightsidebar { z-index:-10; vertical-align:left;}*/
/*#display_area { display:table-cell; width:100%; z-index:1; margin:0; padding-left:1em; vertical-align:top; }*/
#display_area { display:table-cell; width:100%; z-index:1; margin:0; padding-right:1em; vertical-align:top; }
/* layers of canvas */
/*#image_panel { position:relative; outline:none; }
#image_panel img { visibility:hidden; opacity:0; position:absolute; top:0px; left:0px; width:100%; height:100%; outline:none; }*/
#image_panel { position:relative; outline:none; }
#image_panel img { visibility:hidden; opacity:0; position:absolute; top:0px; right:0px; width:100%; height:100%; outline:none; }
#image_panel canvas { position:absolute; top:0px; left:0px; outline:none;}
#image_panel .visible { visibility:visible !important; opacity:1 !important; }
#image_panel label>img { visibility:visible; opacity:1; position:relative; width:auto; height:4em; outline:none; }



#leftsidebar_collapse_panel { display:none; position:relative; z-index:10; vertical-align:top; }
/*#leftsidebar_show_button { font-size:large; margin-left:0.1rem; }*/
#leftsidebar_show_button { font-size:large; margin-right:0.1rem; }
#leftsidebar_show_button:hover { color:red; cursor: pointer; }

/* Left sidebar accordion */
button.leftsidebar_accordion { font-size:large; background-color:#f2f2f2; cursor:pointer; padding:0.5em 0.5em; width:100%; text-align:left; border:0; outline:none; }
button.leftsidebar_accordion:focus { outline: none; }
button.leftsidebar_accordion.active, button.leftsidebar_accordion:hover { background-color: #e6e6e6; }
button.leftsidebar_accordion:after { content:'\02795'; color:#4d4d4d; float:right; }
button.leftsidebar_accordion.active:after { content: '\2796'; }
.leftsidebar_accordion_panel { display:none; padding:0 0.5em; font-size:small; border-right:0px solid #f2f2f2; border-bottom:0px solid #f2f2f2; }
.leftsidebar_accordion_panel.show { display:block; }

/* Keyboard shortcut panel */
.leftsidebar_accordion_panel table { border-collapse:collapse; }
.leftsidebar_accordion_panel td { border:1px solid #f2f2f2; padding:0.2rem 0.4rem; }

/* buttons */
/*.button_panel { display:inline-block; width:100%; margin:0.2rem 0; }*/
.button_panel { display:inline-block; width:100%; margin:0.2rem 0; }
.button_panel .text_button, .text_button { color: #0000ff; padding: 0.2rem 0.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; }
.button_panel .flush_right { float:right; }
.button_panel .text_button:hover, .text_button:hover { cursor:pointer; }
.button_panel .text_button:active, .text_button:active { color: #000000; }
.button_panel .active { border-bottom:1px solid black; }
.button_panel .button { display:inline-block; padding:0.35rem 0.5rem; margin:0 0.05rem; cursor:pointer; background-color:#cccccc; border-radius:0.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; }
.button_panel .button:hover { background-color:black; color:white; }

/* Attributes properties: name, description, type, ... */
#attribute_properties { display:table; right:200;width:100%; border-collapse:collapse; margin:1rem 0; border:1px solid #cccccc; }
/*#attribute_properties { display:table; border-collapse:collapse; margin:1rem 0; border:1px solid #cccccc; }*/
#attribute_properties .property { display:table-row;}
#attribute_properties .property span { display:table-cell; padding: 0.2rem 0.4rem; }
#attribute_properties .property span input { width: 100%; border:1px solid #cccccc; margin: 0;}
#attribute_properties .property span input:focus { border:1px solid black; }
#attribute_properties .property span select { width: 100%; border:1px solid #cccccc; margin: 0;}

/* Attributes options: options for attribute type={checkbox,radio,...} */
#attribute_options { display:table; width:100%; border-collapse:collapse; margin:1rem 0; border:1px solid #cccccc; table-layout:fixed; }
#attribute_options .new_option_id_entry { display:inline-block; padding:1rem 0.2rem; }
#attribute_options .new_option_id_entry input {border:none; border-bottom:1px solid #cccccc; margin: 0; font-size: 1.3rem;}
#attribute_options .property { display:table-row;}
#attribute_options .property span { display:table-cell; padding: 0.2rem 0.2rem; font-weight:bold; }
/*#attribute_options .property input { display:table-cell; width:100%; border:none; border-bottom:1px solid #cccccc; margin: 0; font-size: 0.8rem;}*/
#attribute_options .property input { display:table-cell; width:100%; border:none; border-bottom:1px solid #cccccc; margin: 0; font-size: 1.3rem;}
#attribute_options .property input:focus { border-bottom:1px solid #000000; background-color:#f2f2f2; color:#000000; }
#attribute_options .property span input[type=checkbox] { vertical-align:middle; }
#attribute_options .property span input[type=radio] { vertical-align:middle; }


#user_input_panel { position:fixed; display:none; width:100%; height:100%; top:0; left:50; right:0; bottom:0; background-color: rgba(0,0,0,0.6); z-index:1002; }
/*#user_input_panel .content { position:fixed; background-color:white; top:50%; left:50%; transform:translate(-50%,-50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); padding:2rem 4rem;}*/
#user_input_panel .content { position:fixed; background-color:white; top:50%; left:50%; transform:translate(-50%,-50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); padding:2rem 4rem;}
#user_input_panel .content .title { font-size:large; font-weight:bold; }
#user_input_panel .content .user_inputs { display:table; width:100%; border-collapse:collapse;}
#user_input_panel .content .user_inputs .row { display:table-row; }
#user_input_panel .content .user_inputs .cell { display:table-cell; padding:1rem 0.5rem; vertical-align:middle; border:1px solid #f2f2f2; }
#user_input_panel .content .user_confirm { display:table; width:100%; text-align:center; margin:2rem 0;}
#user_input_panel .content .user_confirm .ok { display:table-cell; width:48%; }
#user_input_panel .content .user_confirm .cancel { display:table-cell; width:48%; }
#user_input_panel .content .warning { color:red; }

/* Attribute editor */
#annotation_editor_panel { position:fixed; display:none; width:100%; right:0; bottom:0; background-color:white; border-top:2px solid #cccccc; padding:0.2em 1em; overflow:auto; z-index:1001; box-shadow: 0 0 1em #cccccc;}
/*#annotation_editor { display:table; margin-bottom:3em; border-collapse:collapse; font-size:inherit; position: absolute; top:500px;left:800px; background-color:white; }*/
#annotation_editor { display:table; margin-bottom:3em; border-collapse:collapse; font-size:inherit; background-color:white; z-index:10024;}
#annotation_editor .row { display:table-row; }
#annotation_editor .highlight .col { background-color:#e6e6e6;}

#annotation_editor .col { display:table-cell; padding:0.4em 0.6em; border:1px solid #000000; vertical-align:middle; font-size:inherit; }
#annotation_editor .header { font-weight:bold; white-space:nowrap}
#annotation_editor .id { font-weight:bold; }
#annotation_editor .col input[type=checkbox] { vertical-align:middle; }
#annotation_editor .col input[type=radio] { vertical-align:middle; font-size:inherit; }
#annotation_editor .col label { vertical-align:middle; font-size:inherit; }
#annotation_editor .col textarea { border:0.1em solid #cccccc; padding:0; margin:0; font-size:inherit; background-color:#ffffff;height:20px;width: 80px}
#annotation_editor .col textarea:focus { border:0.1em dashed #cccccc; }
#annotation_editor .col span { display:block; }
#annotation_editor .col horizontal_container { display:inline-block; }

#annotation_editor .col .img_options { display:inline; }
#annotation_editor .col .img_options .imrow { display:block; }
#annotation_editor .col .img_options span { display:inline-block; margin: 0.2rem 0.4rem;}
#annotation_editor .col .img_options span img { height:4em; }
#annotation_editor .col .img_options p { margin:0; padding:0; font-size:inherit; }
#annotation_editor .col .img_options input[type=radio] { display:none; }
#annotation_editor .col .img_options input[type=radio] + label { display:block; cursor:pointer; text-align:center;}
#annotation_editor .col .img_options input[type=radio]:checked + label { border: 0.1em solid black; background-color:#cccccc; cursor:default; font-size:inherit; }

/* Region shape selection panel inside leftsidebar */
ul.region_shape { font-size:xx-large; list-style-type:none; overflow:hidden; padding:0.4em 0; margin:0; }
ul.region_shape li { float:left; padding:0 0.2em; fill:#ffffff; stroke:#000000; }
/*ul.region_shape li { float:right; padding:0 0.2em; fill:#ffffff; stroke:#000000; }*/
ul.region_shape li:hover { cursor:pointer; fill:#ffffff; stroke:#ff0000; }
ul.region_shape .selected { fill:#ffffff; stroke:#ff0000; }

/* cursor coordinates inside region shape selection panel in leftsidebar */
#region_info { font-size:0.8em; margin-bottom:0.4em; }

/*#message_panel { display:block; width:100%; position:fixed; bottom:300px; z-index:9999; text-align:center; }*/
#message_panel { display:block; width:100%; position:fixed; bottom:30px; right:0;z-index:9999; text-align:center; }
#message_panel .content { display:inline; margin:auto; background-color:#000000; color:#ffff00; font-size:small; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:2rem; padding: 0.5rem 2rem;}

.text_panel { display:none; margin:auto; font-size:medium; line-height:1.3em; margin: 0; max-width:700px; }
/*.text_panel li { margin:1em 0; text-align:left; }
.text_panel p { text-align:left; }*/
.text_panel li { margin:1em 0; text-align:right; }
.text_panel p { text-align:right; }

.svg_button:hover { cursor:pointer; }

/* Loading spinbar */
.loading_spinbox { display:inline-block; border:0.4em solid #cccccc; border-radius:50%; border-top:0.4em solid black; border-bottom:0.4em solid black;-webkit-animation:spin 2s linear infinite; animation:spin 2s linear infinite; }
@-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } }
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }

#invisible_file_input { width:0.1px; height:0.1px; opacity:0; overflow:hidden; position:absolute; z-index:-1; }

.display_none { display:none !important; }
.display_block { display:block !important; }

.display_area_content { } /* this class is used to clear the display area content */
.narrow_page_content li { font-size:0.9rem; margin: 0.4rem 0; }
.narrow_page_content { width:60%; }

.force_small_font { font-size:small !important; }
.key { font-family:monospace; padding:1px 6px; background:linear-gradient(to bottom,#f0f0f0,#fcfcfc);; border:1px solid #e0e0e0; white-space:nowrap; color:#303030; border-bottom-width:2px; border-radius:3px; font-size:1.2em; }

#progress{
width: 100%;
height: 20px;
background: rgb(255, 255, 255);
}
#bar{
width: 1%;
height: 20px;
margin-top: 1px;
background: green;
}

</style>
</head>
<body>
<svg style="display:none;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="via_logo">
<!-- Logo designed by Abhishek Dutta <adutta@robots.ox.ac.uk>, May 2018 -->
<title>VGG Image Annotator Logo</title>
<rect width="400" height="160" x="0" y="0" fill="#212121"></rect>

<text x="56" y="130" font-family="Serif" font-size="100" fill="white">V</text>
<text x="180" y="130" font-family="Serif" font-size="100" fill="white">I</text>
<text x="270" y="130" font-family="Serif" font-size="100" fill="white">A</text>

<rect width="80" height="100" x="52" y="40" stroke="yellow" fill="none" stroke-width="2"></rect>
<text x="72" y="30" font-family="'Comic Sans MS', cursive, sans-serif" font-size="18" fill="yellow">VGG</text>

<rect width="50" height="100" x="175" y="45" stroke="yellow" fill="none" stroke-width="2"></rect>
<text x="175" y="35" font-family="'Comic Sans MS', cursive, sans-serif" font-size="18" fill="yellow">Image</text>

<rect width="80" height="100" x="265" y="40" stroke="yellow" fill="none" stroke-width="2"></rect>
<text x="265" y="30" font-family="'Comic Sans MS', cursive, sans-serif" font-size="18" fill="yellow">Annotator</text>
</symbol>
<symbol id="shape_rectangle">
<rect width="20" height="12" x="6" y="10" stroke-width="2"></rect>
</symbol>
<symbol id="shape_circle">
<title>Circular region shape</title>
<circle r="10" cx="16" cy="16" stroke-width="2"></circle>
</symbol>
<symbol id="shape_ellipse">
<title>Elliptical region shape</title>
<ellipse rx="12" ry="8" cx="16" cy="16" stroke-width="2"></ellipse>
</symbol>
<symbol id="shape_polygon">
<path d="M 15.25,2.2372 3.625,11.6122 6,29.9872 l 20.75,-9.625 2.375,-14.75 z" stroke-width="2"></path>
</symbol>
<symbol id="shape_point">
<circle r="3" cx="16" cy="16" stroke-width="2"></circle>
</symbol>
<symbol id="shape_polyline">
<title>Polyline region shape</title>
<path d="M 2,12 10,24 18,12 24,18" stroke-width="2"></path>
<circle r="1" cx="2" cy="12" stroke-width="2"></circle>
<circle r="1" cx="10" cy="24" stroke-width="2"></circle>
<circle r="1" cx="18" cy="12" stroke-width="2"></circle>
<circle r="1" cx="24" cy="18" stroke-width="2"></circle>
</symbol>

<!-- Material icons downloaded from https://material.io/icons -->
<symbol id="icon_settings">
<path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"></path>
</symbol>
<symbol id="icon_save">
<path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"></path>
</symbol>
<symbol id="icon_open">
<path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z"></path>
</symbol>
<symbol id="icon_gridon">
<path d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 20H4v-4h4v4zm0-6H4v-4h4v4zm0-6H4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4z"></path>
</symbol>
<symbol id="icon_gridoff">
<path d="M8 4v1.45l2 2V4h4v4h-3.45l2 2H14v1.45l2 2V10h4v4h-3.45l2 2H20v1.45l2 2V4c0-1.1-.9-2-2-2H4.55l2 2H8zm8 0h4v4h-4V4zM1.27 1.27L0 2.55l2 2V20c0 1.1.9 2 2 2h15.46l2 2 1.27-1.27L1.27 1.27zM10 12.55L11.45 14H10v-1.45zm-6-6L5.45 8H4V6.55zM8 20H4v-4h4v4zm0-6H4v-4h3.45l.55.55V14zm6 6h-4v-4h3.45l.55.54V20zm2 0v-1.46L17.46 20H16z"></path>
</symbol>
<symbol id="icon_next">
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path>
</symbol>
<symbol id="icon_prev">
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path>
</symbol>
<symbol id="icon_list">
<path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"></path>
</symbol>
<symbol id="icon_zoomin">
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
<path d="M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z"/>
</symbol>
<symbol id="icon_zoomout">
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z"></path>
</symbol>
<symbol id="icon_copy">
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"></path>
</symbol>
<symbol id="icon_paste">
<path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path>
</symbol>
<symbol id="icon_pasten">
<path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path>
<text x="8" y="18">n</text>
</symbol>
<symbol id="icon_pasteundo">
<path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path>
<text x="8" y="18">x</text>
</symbol>
<symbol id="icon_selectall">
<path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z"></path>
</symbol>
<symbol id="icon_close">
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path>
</symbol>
<symbol id="icon_insertcomment">
<path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"></path>
</symbol>
<symbol id="icon_checkbox">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"></path>
</symbol>
<symbol id="icon_fileupload">
<path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"></path>
</symbol>
<symbol id="icon_filedownload">
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path>
</symbol>

</defs>
</svg>

<!-- header logo: style can be found in header.less -->
<!-- <header class="header" >
<div class="logo">
人工标注
</div>
<nav class="navbar navbar-static-top" role="navigation">
<span style="font-size:28px" id="title_id">通用图片标注</span>
</nav>
</header> -->
<div style="height:100vh;display:flex;flex-flow:column nowrap;overflow:hidden;position: relative;">
<header class="header">
<div class="row" style="background-color: #020004;">
<div class="col-lg-1">
<a id="return_url" href="" style="margin: 8px;display: inline-block;"><i class="fa fa-home fa-fw" style="color: #E1E3E6;font-size: 24px;"></i></a>
</div>
<div class="col-lg-9">
<div class="row">
<div class="col-lg-6" style=" padding-left: 0;">
<!-- <button type="button" class="btn" style="background:#3291F8;margin:8px 12px 8px 0;color: #fff;border-radius: 0;padding: 4px 12px;font-size: 12px;">返回任务</button>
<button type="button" class="btn" style="margin: 8px 12px;background:#74818D;color: #fff;border-radius: 0;padding: 4px 12px;font-size: 12px;">跳过</button>
<button type="button" class="btn" style="margin: 8px 12px;background:#FF6200;color: #fff;border-radius: 0;padding: 4px 12px;font-size: 12px;">提交</button> -->
</div>
<div class="col-lg-1" style="text-align: center;;line-height: 42px;color: #fff;">
<span id="float_text"> dog.1000.jpg</span>
</div>
</div>
</div>
<div class="col-lg-2"></div>
</div>
</header>
<div class="box1" style="float:left;position: absolute;z-index: 9999;left: 0.4em;top: 3.5em;">
<ul class="draw_tool" style="font-size: 18px;background-color: rgba(12,13,13,0.3);color: rgba(225,227,230,0.8);">
<li id="region_shape_rect" class="selected draw_li" onclick="createRectLabel()" title="新建矩形标注(W)"><i class="fa fa-square-o"></i></li>
<li id="region_shape_polygon" class="draw_li" onclick="createMaskLabel()" title="新建多边形标注"><i class="fa fa-first-order" aria-hidden="true"></i> </li>
<li id="region_shape_point" class="draw_li" onclick="createPointLabel()" title="新建点标注"><i class="fa fa-circle-o"></i></li>
<li id="delete_shape" class="draw_li" onclick="deleterect()" title="删除选中的标注(D)"><i class="fa fa-times-circle-o" aria-hidden="true"></i></li>
<li id="delete_all_shape" class="draw_li" onclick="deleteAllRect()" title="删除所有的标注框"><i class="fa fa-times" aria-hidden="true"></i></li>
<li id="save_shape" class="draw_li" onclick="save()" title="保存标注(S)"><i class="fa fa-floppy-o" aria-hidden="true"></i></li>
<!-- <li id="previous_shape" onclick="last()" title="上一张(Q)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_prev"></use></svg></li>
<li id="next_shape" onclick="next()" title="下一张(E)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_next"></use></svg></li> -->
<li id="copy_shape" class="draw_li" onclick="copyOneBox()" title="复制单个选中的标注(C)"><i class="fa fa-file-o" aria-hidden="true"></i></li>
<li id="copy_shape" class="draw_li" onclick="copy()" title="复制所有的标注"><i class="fa fa-clone" aria-hidden="true"></i></li>
<li id="paste_shape" class="draw_li" onclick="paste()" title="粘贴复制的标注(V)"><i class="fa fa-clipboard" aria-hidden="true"></i></li>
<li id="arrow-left" class="draw_li" onclick="moveLeftOnePx()" title="标注左移一个像素"><i class="fa fa-arrow-left" aria-hidden="true"></i> </li>
<li id="arrow-right" class="draw_li" onclick="moveRightOnePx()" title="标注右移一个像素"><i class="fa fa-arrow-right" aria-hidden="true"></i> </li>
<li id="arrow-up" class="draw_li" onclick="moveUpOnePx()" title="标注上移一个像素"><i class="fa fa-arrow-up" aria-hidden="true"></i></li>
<li id="arrow-down" class="draw_li" onclick="moveDownOnePx()" title="标注下移一个像素"><i class="fa fa-arrow-down" aria-hidden="true"></i></li>
<li id="setting" class="draw_li" onclick="updateSetting()" title="设置" href="#labeldefine"><i class="fa fa-cog" aria-hidden="true"></i> </li>
<li id="skip" class="draw_li" onclick="skipLast()" title="跳转至上次标注的地方"><i class="fa fa-eraser" aria-hidden="true"></i></li>
<!-- <li class="draw_li" onclick="setAutoModel()" title="自动标注" href="#autoLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-cube" aria-hidden="true"></i></li> -->
<li class="draw_li" onclick="undo()" title="撤销上次标注(Z)" ><i class="fa fa-reply-all" aria-hidden="true"></i></li>
<li style="padding: 0.2em;border: 0.5px solid rgba(34,35,36,0.2);border-radius: 3px;cursor: pointer;" title="清空指定文件的标注" href="#deleteLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-eraser" aria-hidden="true"></i></li>
</ul>
</div>
<div class="containers" style="flex: 1;">
<!-- <aside class="left-side sidebar-offcanvas" ></aside> -->
<div class="row" style="height: 100%;">

<!-- left-side -->
<!-- <div class="col-lg-1" style="background-color: #020004;height: 100%;border-top: 1px solid #222324;padding: 0;">
<div style="line-height: 3em;text-align: center;font-size: 16px;">
<span style="color: #fff;float: left;padding-left: 1.5em;">动物-狗</span>
<a style="float: right;padding-right: 1em;"><i class="fa fa-cog" style="color: #74818D;font-size: 18px;cursor: pointer;"></i></a>
</div>
<div style="clear: both;">
<input type="text" placeholder="搜索标签" style="width: 80%;margin: 0 10%;background-color: transparent;border-radius: 6px;border: 0.5px solid #43474B;outline: none;color: #74818D;padding: 0.1em;">
</div>
</div> -->

<!-- canvas -->
<div class="col-lg-10" id="showPic" style="background-color: #222324;height: 100%;padding: 0;padding-left: 4em;">

<!-- <nav class="navbar navbar-default" role="navigation" id="tool0" style="margin-bottom: 0;">
<div class="leftsidebar_accordion_panel show">
<ul class="region_shape" style="padding: 0;">
<li id="region_shape_rect" class="selected" onclick="createRectLabel()" title="新建矩形标注(W)"><svg height="28" viewbox="0 0 28 28"><use xlink:href="#shape_rectangle"></use></svg></li>
<li id="region_shape_polygon" onclick="createMaskLabel()" title="新建多边形标注"><svg height="28" viewbox="0 0 28 28"><use xlink:href="#shape_polygon"></use></svg></li>
<li id="region_shape_point" onclick="createPointLabel()" title="新建点标注"><svg height="28" viewbox="0 0 28 28"><use xlink:href="#shape_point"></use></svg></li>
<li id="delete_shape" onclick="deleterect()" title="删除选中的标注(D)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_close"></use></svg></li>
<li id="save_shape" onclick="save()" title="保存标注(S)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_save"></use></svg></li>
<li id="previous_shape" onclick="last()" title="上一张(Q)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_prev"></use></svg></li>
<li id="next_shape" onclick="next()" title="下一张(E)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_next"></use></svg></li>
<li id="copy_shape" onclick="copy()" title="复制所有的标注"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_copy"></use></svg></li>
<li id="paste_shape" onclick="paste()" title="粘贴复制的标注(V)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_pasten"></use></svg></li>
<li id="copy_shape" style="font-size: 20px;" onclick="copyOneBox()" title="复制单个选中的标注(C)"><i class="fa fa-files-o" style="vertical-align: bottom;" aria-hidden="true"></i></li>
<li id="arrow-left" style="font-size: 26px" onclick="moveLeftOnePx()" title="标注左移一个像素"><i class="fa fa-long-arrow-left" aria-hidden="true" ></i></li>
<li id="arrow-right" style="font-size: 26px" onclick="moveRightOnePx()" title="标注右移一个像素"><i class="fa fa-long-arrow-right" aria-hidden="true"></i></li>
<li id="arrow-up" style="font-size: 26px" onclick="moveUpOnePx()" title="标注上移一个像素"><i class="fa fa-long-arrow-up" aria-hidden="true"></i></li>
<li id="arrow-down" style="font-size: 26px" onclick="moveDownOnePx()" title="标注下移一个像素"><i class="fa fa-long-arrow-down" aria-hidden="true"></i></li>
<li id="delete_all_shape" style="font-size: 22px;" onclick="deleteAllRect()" title="删除所有的标注框"><i class="fa fa-window-close-o" style="vertical-align: middle;" aria-hidden="true" ></i></li>
<li id="setting" onclick="updateSetting()" title="设置" href="#labeldefine"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_settings"></use></svg></li>
<li id="skip" style="font-size: 22px" onclick="skipLast()" title="跳转至上次标注的地方"><i class="fa fa-share" aria-hidden="true"></i></li>
<li style="font-size: 22px" onclick="setAutoModel()" title="自动标注" href="#autoLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-tag" aria-hidden="true"></i></li>
<li style="font-size: 22px" onclick="undo()" title="撤销上次标注(Z)" ><i class="fa fa-undo" aria-hidden="true"></i></li>
<li style="font-size: 22px" title="清空指定文件的标注" href="#deleteLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-eraser" aria-hidden="true"></i></li>
</ul>
</div>
<div id=labeldefine>
</div>
</nav> -->
<div id="labelwin" width="100%" >
<input type="hidden" class="form-control" id="postmessage" >
<div id = "show_region" style="z-index: 50000;position: absolute;width: 0px;height: 0px"></div>
<canvas id="myCanvas" style="border:1px solid #5a5a5a;"></canvas>
<div id="float_text"></div>
</div>
</div>




<!-- right side -->
<div class="col-lg-2" style="background-color: #020004;height: 100%;border-top: 1px solid #222324;padding: 0;">
<div style="line-height: 3em;text-align: center;font-size: 14px;">
<span id="task_info" style="color: #fff;float: left;padding-left: 1.5em;">train数据集标注任务</span>
<!-- <a style="float: right;padding-right: 2em;"><i class="fa fa-cog" style="color: #74818D;font-size: 18px;cursor: pointer;"></i></a> -->
</div>
<div class="progress" style="clear: both;margin: 0 2em 0 1em;height: 0.5em;">
<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;background-color: #389E0D;">
<span class="sr-only">60% Complete</span>
</div>
</div>
<div style="margin: 1em 1.5em;font-size: 10px;">
<span style="color: #7092BE;margin-right: 1em;">任务标注进度</span><span id="task_progress" style="color:#7092BE;"></span>
</div>
<div class="panel" style="margin-bottom: 1em;">
<div id = "labelStatus"></div>
</div>

<div id="nav" style="height:100%">
<ul style="display: flex;padding: 0;margin: 0;color:#7092BE;">
<li id="0" class="active">文件列表</li>
<li id="1">标签列表</li>
</ul>
<div class="tabpannel" style="height: 100%;">
<!-- <h4 class="ui top attached header">
文件列表
</h4> -->
<!-- <table class="ui single line table" id="filelist" style="table-layout:fixed;word-break: break-all;word-wrap: break-word;">
</table> -->
<div class="panel-body no-padding" id="filepanel" style="height: 100%;">
<div style="display: flex;padding: 0.3em 0;border-bottom: 1px solid #222324 ;">
<span style="flex: 3;padding-left: 20px;color: #7092BE;">文件名</span>
<div class="btn-group" style="flex:1">
<button type="button" class="btn-default dropdown-toggle"
data-toggle="dropdown" style="background: transparent;padding: 0;border: 0;vertical-align: top;line-height: 1;color: #7092BE;">
...
</button>
<ul class="dropdown-menu" role="menu" style="left:-90px;background: #020004;border: 1px solid #222324;border-radius: 0;width:2em;min-width: 8em;color: #fff;">
<li value="1" onclick="showOrder($(this).attr('value'))" style="font-size: 8px;color: #fff;padding: 0.3em 0 0.3em 2em;width: 100%;text-align: start;border-bottom: 0.5px solid #222324;">按文件名排序</li>
<li value="2" onclick="showOrder($(this).attr('value'))" style="font-size: 8px;color: #fff;padding: 0.3em 0 0.3em 2em;width: 100%;text-align: start;">未标注</li>
</ul>
</div>
</div>
<table class="table table-condensed table-define" id="filelist" style="table-layout:fixed;overflow:auto;word-break: break-all;word-wrap: break-word;color:#7092BE;font-size: 10px;">
</table>
</div>
<div class="panel-body" id="filepanel" style='position: absolute;bottom: 0;padding: 0.9em 0;width: 100%;border-top: 1px #ccc solid; color: #7092BE;'>
<div style="width: 80%; margin: 0 10%;">
<a id="prePage" href="" style="margin-right: 0.2em;"><i class="fa fa-angle-left"></i></a>
<span id="startIndex">0</span>-<span id="endIndex">0</span>/<span id="totalNum">0</span>
<span style="margin-left: 0.2em;">第</span><span id="displayPage1">1</span><span style="margin-right: 0.2em;">页</span>
<span>跳到</span><input type="text" id="goNum" style="width: 2em;border-radius: 4px;padding: 0 0.4em;margin: 0 0.4em;height: 1.2em;border: 1px solid;" maxlength="5" oninput="value=value.replace(/[^\d]/g,'')"><span>页</span>
<a style="margin-left: 0.4em;" id="nextPage" href=""><i class="fa fa-angle-right"></i></a>
</div>
</div>
</div>
<div class="hide1 tabpannel">
<div class="panel-body no-padding" id="labelpanel">
<table class="table table-condensed table-define" style="color: #fff;" >
<tbody id="boxlabels">
</tbody>
</table>
</div><!-- /.panel-body -->
<div class="panel-body no-padding" id="labelcountpanel" style="display: none;">
<table class="table table-condensed" id="labelcounttable">
</table>
</div><!-- /.panel-body -->
</div>

</div>
</div>
</div>



<div class="panel" id="set_attributes" class="force_small_font display_area_content" style="display:none;">
<button class="close" onclick="close_attribute()" style=" padding: .3em 0.8em;"> × </button>
<div id="user_input_panel"></div>
<div id="message_panel">
<div id="message_panel_content" class="content"></div>
</div>
<div id="leftsidebar_collapse_panel">
<span class="text_button" onclick="leftsidebar_toggle()" title="Show left sidebar">&rtrif;</span>
</div>
<div id="leftsidebar">
<div class="leftsidebar_accordion_panel show" id="attributes_editor_panel">
<div class="button_panel" style="padding:1rem 0;">
<h4 class="modal-title">设置</h4>
</div>
<div id="attributes_update_panel">
<div class="button_panel">
<input style="width:50%" type="text" placeholder="attribute name" id="user_input_attribute_id" value="">
<span id="button_add_new_attribute" class="button" onclick="add_new_attribute_from_user_input()" title="Add new attribute">&plus;</span>
</div>
<div class="button_panel" style="margin:0.1rem 0;width:70%;" >
<table class="table table-hover" id="attributes_name_list">
</table>
</div>
<div id="atttibute_child" >
<div id="type_car" style="display: none;">
<span class= "btn btn-xs btn-success" style="margin-left:5px" onclick="show_tpye_attribute();">点击此处快速添加常用车辆类别</span>
</div>
<div id="type_color" style="display: none;">
<span class= "btn btn-xs btn-success" style="margin-left:5px" onclick="show_color_attribute();">点击此处快速添加常用颜色</span>
</div>
<div id="attribute_properties"> </div>
<div id="attribute_options"></div>
<p style="text-align:center"></p>
</div>
</div>
<div>
<button type="button" class="btn btn-default" onclick="save_attribute()" id="save" style=" margin:0.5rem 0.3rem "> 保存属性值</button>
<button type="button" class="btn btn-default" onclick="export_attribute()" id="export" style=" margin:0.5rem 0.3rem;float:right"> 导出属性值</button>
<button type="button" class="btn btn-default" onclick="import_attribute()" id="import" style=" margin:0.5rem 0.3rem;float:right"> 导入属性值</button>
</div>

</div>
</div> <!-- Dialog setAttribute -->
<div style="width: 100%;" id="vertical_space"></div>
</div><!-- /.panel -->


<div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="autoLabel" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button>
<h4 class="modal-title">自动标注</h4>
</div>
<div class="modal-body">
<form role="form">
<div class="form-group">
<label for="exampleInputPassword1">自动标注任务使用的模型</label>
<select class="form-control" name="预检模型" id="predict_model" onchange="model_sele_Change(this)">
<option value="" >请选择</option>
<!--<option value="1" selected="">Faster RCNN</option> -->
</select>
</div>
<div id="tracking_startid_div" class="form-group" style="display:none">
<label for="exampleInputEmail1">追踪起始图片ID</label>
<input type="" class="form-control" id="tracking_startid" placeholder="追踪起始图片ID">
</div>
<div id="tracking_endid_div" class="form-group" style="display:none">
<label for="exampleInputEmail1">追踪结束图片ID</label>
<input type="" class="form-control" id="tracking_endid" placeholder="追踪结束图片ID">
</div>
<div id="label_id_div" class="form-group">
<label for="exampleInputEmail1">标注框ID</label>
<input type="" class="form-control" id="label_id" placeholder="标注框ID">
</div>
<div id="labelOption_div" class="form-group">
<label for="exampleInputEmail1">标注信息选项</label>
<select class="form-control" name="labelOption" id="labelOption">
<option value="4">请选择</option>
<!--<option value="0" selected="">合并已有的标注信息</option>
<option value="1">删除已有的标注信息</option>
<option value="2">识别车的颜色及车的类型</option> -->
</select>
</div>
<div id="progress">
<div id="bar"></div>
</div>
<div><h5 id="text-progress">0%</h3></div>
<button id="predtask_id" type="button" onclick="submit_predtask();">提交</button>
</form>
</div>
</div>
</div>
</div>
<div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="deleteLabel" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button>
<h4 class="modal-title">清空指定文件的标注</h4>
</div>
<div class="modal-body">
<form role="form">
<div id="delete_startid_div" class="form-group">
<label for="exampleInputEmail1">起始文件ID(对应文件列表中第几条)</label>
<input type="" class="form-control" id="delete_startid" placeholder="起始文件ID">
</div>
<div id="delete_endid_div" class="form-group">
<label for="exampleInputEmail1">结束文件ID(对应文件列表中第几条)</label>
<input type="" class="form-control" id="delete_endid" placeholder="结束文件ID">
</div>
<button id="predtask_id" type="button" onclick="submit_deletelabel();">提交</button>
</form>
</div>
</div>
</div>
</div>


<div aria-hidden="true" aria-labelledby="myModalLabelc" role="dialog" tabindex="-1" id="datasetModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button>
<h4 class="modal-title">导入标注属性</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label id = "labelInfo" for="exampleInputFile">请输入符合格式Json字符串<font color=red>*</font> </label>
<div>
<textarea id="jsoninput" rows="8" cols="70"> </textarea>
</div>
</div>
<button id="btnSubmit" type="button" onclick="submit_import_property();">提交</button>
</div>
</div>
</div>
</div>
</div>




<script>
// back to label table
var back_url = sessionStorage.getItem('return_url')
document.getElementById('return_url').setAttribute('href',back_url);


var ulObj = document.getElementById('nav').getElementsByTagName('ul')[0];
var divObj = document.getElementsByClassName('tabpannel');
var liObj = document.getElementById('nav').getElementsByTagName('li')
ulObj.onclick = function(event){
var ev = window.event || event;
var item = ev.srcElement || ev.target;

var id = item.getAttribute("id")
for (var i=0; i<divObj.length;i++){
if(i == id){
divObj[i].style.display = 'block'
liObj[i].classList.add('active')
}
else{
divObj[i].style.display = 'none'
liObj[i].classList.remove('active')
}
}
}
</script>
<script>
var box = document.getElementsByClassName("box1")[0]; //获取元素
var x, y; //鼠标相对与div左边,上边的偏移
var isDrop = false; //移动状态的判断鼠标按下才能移动
box.onmousedown = function(e) {
var e = e || window.event; //要用event这个对象来获取鼠标的位置
x = e.clientX - box.offsetLeft;
y = e.clientY - box.offsetTop;
isDrop = true; //设为true表示可以移动
}

document.onmousemove = function(e) {
//是否为可移动状态                    
if(isDrop) {    
var e = e || window.event;   
var moveX = e.clientX - x; //得到距离左边移动距离   
var moveY = e.clientY - y; //得到距离上边移动距离
//可移动最大距离
var maxX = document.documentElement.clientWidth - box.offsetWidth;
var maxY = document.documentElement.clientHeight - box.offsetHeight;

//范围限定 当移动的距离最小时取最大 移动的距离最大时取最小
//范围限定方法一
/*if(moveX < 0) {
moveX = 0
} else if(moveX > maxX) {
moveX = maxX;
}

if(moveY < 0) {
moveY = 0;
} else if(moveY > maxY) {
moveY = maxY;
} */
//范围限定方法二 
moveX=Math.min(maxX, Math.max(0,moveX));
moveY=Math.min(maxY, Math.max(0,moveY));
box.style.left = moveX + "px";  
box.style.top = moveY + "px";          
} else {
return;          
}

}

document.onmouseup = function() {
isDrop = false; //设置为false不可移动
}
</script>
<script src="/self/func.js" type="text/javascript"></script>
<!-- jQuery 2.0.2 -->
<!-- -->
<script src="/self/js/jquery.min.js" type="text/javascript"></script>
<script src="/self/js/jquery.mousewheel.js"></script>
<script src="/self/js/jquery.jscrollpane.js"></script>

<!-- Bootstrap -->
<script src="/self/js/bootstrap.min.js" type="text/javascript"></script>
<script src="/self/js/app.js" type="text/javascript" ></script>
<script src="/self/js/Director/labelingSelfDefine.js" type="text/javascript"></script>
<script src="/self/js/Director/detection.js" type="text/javascript" ></script>
<!-- <script src="../js/labelx.js"></script> -->

</body>
</html>


+ 2
- 0
routers/init.go View File

@@ -22,6 +22,7 @@ import (
code_indexer "code.gitea.io/gitea/modules/indexer/code"
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
stats_indexer "code.gitea.io/gitea/modules/indexer/stats"
"code.gitea.io/gitea/modules/labelmsg"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/external"
@@ -63,6 +64,7 @@ func NewServices() {
_ = cache.NewContext()
notification.NewContext()
decompression.NewContext()
labelmsg.Init()
}

// In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology


+ 46
- 3
routers/repo/attachment.go View File

@@ -17,6 +17,7 @@ import (

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/labelmsg"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/minio_ext"
"code.gitea.io/gitea/modules/setting"
@@ -131,7 +132,19 @@ func DeleteAttachment(ctx *context.Context) {
ctx.Error(403)
return
}
err = models.DeleteAttachment(attach, false)

err = models.DeleteAttachment(attach, true)
if err != nil {
ctx.Error(500, fmt.Sprintf("DeleteAttachment: %v", err))
return
}

attachjson, _ := json.Marshal(attach)
labelmsg.SendDeleteAttachToLabelSys(string(attachjson))

DeleteAllUnzipFile(attach, "")

_, err = models.DeleteFileChunkById(attach.UUID)
if err != nil {
ctx.Error(500, fmt.Sprintf("DeleteAttachment: %v", err))
return
@@ -416,6 +429,21 @@ func UpdateAttachmentDecompressState(ctx *context.Context) {
log.Error("UpdateAttachment(%s) failed:%s", uuid, err.Error())
return
}
log.Info("start to send msg to labelsystem ")

dataset, _ := models.GetDatasetByID(attach.DatasetID)

var labelMap map[string]string
labelMap = make(map[string]string)
labelMap["UUID"] = uuid
labelMap["Type"] = fmt.Sprint(attach.Type)
labelMap["UploaderID"] = fmt.Sprint(attach.UploaderID)
labelMap["RepoID"] = fmt.Sprint(dataset.RepoID)
labelMap["AttachName"] = attach.Name
attachjson, _ := json.Marshal(labelMap)
labelmsg.SendAddAttachToLabelSys(string(attachjson))

log.Info("end to send msg to labelsystem ")

ctx.JSON(200, map[string]string{
"result_code": "0",
@@ -738,8 +766,8 @@ func CompleteMultipart(ctx *context.Context) {
}

if attachment.DatasetID != 0 {
if typeCloudBrain == models.TypeCloudBrainOne {
if strings.HasSuffix(attachment.Name, ".zip") {
if strings.HasSuffix(attachment.Name, ".zip") {
if typeCloudBrain == models.TypeCloudBrainOne {
err = worker.SendDecompressTask(contexExt.Background(), uuid)
if err != nil {
log.Error("SendDecompressTask(%s) failed:%s", uuid, err.Error())
@@ -751,6 +779,21 @@ func CompleteMultipart(ctx *context.Context) {
}
}
}
if typeCloudBrain == models.TypeCloudBrainTwo {
attachjson, _ := json.Marshal(attachment)
labelmsg.SendDecompressAttachToLabelOBS(string(attachjson))
}
} else {
dataset, _ := models.GetDatasetByID(attachment.DatasetID)
var labelMap map[string]string
labelMap = make(map[string]string)
labelMap["UUID"] = uuid
labelMap["Type"] = fmt.Sprint(attachment.Type)
labelMap["UploaderID"] = fmt.Sprint(attachment.UploaderID)
labelMap["RepoID"] = fmt.Sprint(dataset.RepoID)
labelMap["AttachName"] = attachment.Name
attachjson, _ := json.Marshal(labelMap)
labelmsg.SendAddAttachToLabelSys(string(attachjson))
}
}



+ 47
- 2
routers/repo/dataset.go View File

@@ -1,13 +1,14 @@
package repo

import (
"sort"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"sort"
)

const (
@@ -60,19 +61,62 @@ func newFilterPrivateAttachments(ctx *context.Context, list []*models.Attachment
}
}

func QueryDataSet(ctx *context.Context) []*models.Attachment {
repo := ctx.Repo.Repository

dataset, err := models.GetDatasetByRepo(repo)
if err != nil {
log.Error("zou not found dataset 1")
ctx.NotFound("GetDatasetByRepo", err)
return nil
}

if ctx.Query("type") == "" {
log.Error("zou not found type 2")
ctx.NotFound("type error", nil)
return nil
}
err = models.GetDatasetAttachments(ctx.QueryInt("type"), dataset)
if err != nil {
ctx.ServerError("GetDatasetAttachments", err)
return nil
}
attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo)

ctx.Data["SortType"] = ctx.Query("sort")
switch ctx.Query("sort") {
case "newest":
sort.Slice(attachments, func(i, j int) bool {
return attachments[i].CreatedUnix > attachments[j].CreatedUnix
})
case "oldest":
sort.Slice(attachments, func(i, j int) bool {
return attachments[i].CreatedUnix < attachments[j].CreatedUnix
})
default:
ctx.Data["SortType"] = "newest"
sort.Slice(attachments, func(i, j int) bool {
return attachments[i].CreatedUnix > attachments[j].CreatedUnix
})
}
return attachments
}

func DatasetIndex(ctx *context.Context) {
log.Info("dataset index 1")
MustEnableDataset(ctx)

repo := ctx.Repo.Repository

dataset, err := models.GetDatasetByRepo(repo)
if err != nil {
log.Error("query dataset, not found repo.")
ctx.NotFound("GetDatasetByRepo", err)
return
}

if ctx.Query("type") == "" {
log.Error("not found param type")
log.Error("query dataset, not found param type")
ctx.NotFound("type error", nil)
return
}
@@ -81,6 +125,7 @@ func DatasetIndex(ctx *context.Context) {
ctx.ServerError("GetDatasetAttachments", err)
return
}

attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo)

ctx.Data["SortType"] = ctx.Query("sort")


+ 106
- 16
routers/repo/dir.go View File

@@ -3,15 +3,19 @@ package repo
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"path"
"strings"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/obs"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
)

const (
@@ -32,6 +36,87 @@ type RespGetDirs struct {
FileInfos string `json:"fileInfos"`
}

func DeleteAllUnzipFile(attachment *models.Attachment, parentDir string) {
uuid := attachment.UUID
dirArray := strings.Split(parentDir, "/")

if !strings.HasSuffix(attachment.Name, ".zip") {
log.Error("The file is not zip file, can not query the dir")
return
} else if attachment.DecompressState != models.DecompressStateDone {
log.Error("The file has not been decompressed completely now")
return
}

dirArray = append([]string{attachment.Name}, dirArray...)
if parentDir == "" {
dirArray = []string{attachment.Name}
}
if attachment.Type == models.TypeCloudBrainOne {
dirs, err := GetDatasetDirs(uuid, parentDir)
if err != nil {
log.Error("getDatasetDirs failed:", err.Error())
return
}

var fileInfos []FileInfo
err = json.Unmarshal([]byte(dirs), &fileInfos)
if err != nil {
log.Error("json.Unmarshal failed:", err.Error())
return
}

for _, fileInfo := range fileInfos {
log.Info("fileName=" + fileInfo.FileName)
log.Info("parentDir=" + fileInfo.ParenDir)
if fileInfo.IsDir {
DeleteAllUnzipFile(attachment, fileInfo.FileName)
} else {
absolutepath := path.Join(attachment.RelativePath()+attachment.UUID, fileInfo.ParenDir)
log.Info("absolutepath=" + absolutepath)
storage.Attachments.Delete(absolutepath)
}
}
}
if attachment.Type == models.TypeCloudBrainTwo {

input := &obs.ListObjectsInput{}
input.Bucket = setting.Bucket
// 设置每页100个对象
input.MaxKeys = 100
input.Prefix = setting.BasePath + attachment.RelativePath() + attachment.UUID
index := 1
log.Info("prefix=" + input.Prefix)
for {
output, err := storage.ObsCli.ListObjects(input)
if err == nil {
fmt.Printf("Page:%d\n", index)
index++
for _, val := range output.Contents {
log.Info("delete obs file:" + val.Key)
delObj := &obs.DeleteObjectInput{}
delObj.Bucket = setting.Bucket
delObj.Key = val.Key
storage.ObsCli.DeleteObject(delObj)
}
if output.IsTruncated {
input.Marker = output.NextMarker
} else {
break
}
} else {
if obsError, ok := err.(obs.ObsError); ok {
fmt.Printf("Code:%s\n", obsError.Code)
fmt.Printf("Message:%s\n", obsError.Message)
}
break
}
}

}

}

func DirIndex(ctx *context.Context) {
uuid := ctx.Params("uuid")
parentDir := ctx.Query("parentDir")
@@ -58,30 +143,35 @@ func DirIndex(ctx *context.Context) {
dirArray = []string{attachment.Name}
}

dirs, err := getDatasetDirs(uuid, parentDir)
if err != nil {
log.Error("getDatasetDirs failed:", err.Error())
ctx.ServerError("getDatasetDirs failed:", err)
return
}

var fileInfos []FileInfo
err = json.Unmarshal([]byte(dirs), &fileInfos)
if err != nil {
log.Error("json.Unmarshal failed:", err.Error())
ctx.ServerError("json.Unmarshal failed:", err)
return
}
/*
dirs, err := GetDatasetDirs(uuid, parentDir)
if err != nil {
log.Error("getDatasetDirs failed:", err.Error())
ctx.ServerError("getDatasetDirs failed:", err)
return
}
*/

//var fileInfos []FileInfo

/*
err = json.Unmarshal([]byte(dirs), &fileInfos)
if err != nil {
log.Error("json.Unmarshal failed:", err.Error())
ctx.ServerError("json.Unmarshal failed:", err)
return
}
*/

ctx.Data["Path"] = dirArray
ctx.Data["Dirs"] = fileInfos
ctx.Data["Dirs"] = true
ctx.Data["Uuid"] = uuid
ctx.Data["PageIsDataset"] = true

ctx.HTML(200, tplDirIndex)
}

func getDatasetDirs(uuid string, parentDir string) (string, error) {
func GetDatasetDirs(uuid string, parentDir string) (string, error) {
var req string
dataActualPath := setting.Attachment.Minio.RealPath +
setting.Attachment.Minio.Bucket + "/" +


+ 37
- 0
routers/repo/label.go View File

@@ -0,0 +1,37 @@
package repo

import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
)

const (
tplLabelIndex base.TplName = "repo/datasets/label/index"
)

func LabelIndex(ctx *context.Context) {

log.Info("Go Here LabelIndex.")
uuid := ctx.Params("uuid")
attach, err := models.GetAttachmentByUUID(uuid)
if err != nil {
log.Info("query attach error")
} else {
dataset, err := models.GetDatasetByID(attach.DatasetID)
if err != nil {
log.Info("query dataset error")
} else {
ctx.Data["repoId"] = dataset.RepoID
}
}

attachments := QueryDataSet(ctx)

ctx.Data["uuid"] = uuid
ctx.Data["Attachments"] = attachments

ctx.HTML(200, tplLabelIndex)

}

+ 3
- 0
routers/routes/routes.go View File

@@ -926,6 +926,9 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/dirs", func() {
m.Get("/:uuid", reqRepoDatasetReader, repo.DirIndex)
})
m.Group("/label", func() {
m.Get("/:uuid", reqRepoDatasetReader, repo.LabelIndex)
})
}, context.RepoRef())

m.Group("/cloudbrain", func() {


+ 5
- 1
templates/repo/datasets/dataset_list.tmpl View File

@@ -23,7 +23,11 @@
</div>

<div class="wide column one" style="{{if ne .DecompressState 1}}visibility: hidden;{{end}}">
<a class="ui text center" href="datasets/dirs/{{.UUID}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{svg "octicon-file-directory" 16}}</a>
<a class="ui text center" href="datasets/dirs/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{svg "octicon-file-directory" 16}}</a>
</div>
<div class="wide column one" style="{{if ne .DecompressState 1}}visibility: hidden;{{end}}">
<a class="ui text center" href="datasets/label/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.create_label_task"}}'><i class="fa fa-pencil-square-o" aria-hidden="true"></i></a>
</div>

{{if $.Permission.CanWrite $.UnitTypeDatasets}}


+ 11
- 0
templates/repo/datasets/dirs/dir_list.tmpl View File

@@ -24,4 +24,15 @@
</tbody>
</table>

<table id="dataset-files-table" class="ui single line table">
</table>
<script src="{{StaticUrlPrefix}}/self/test.js"></script>


<script type="text/javascript">
displayDir({{$.Uuid}})
</script>


{{end}}

+ 212
- 0
templates/repo/datasets/dirs/dir_preview.tmpl View File

@@ -0,0 +1,212 @@
{{if .Dirs}}

<style>
/* ul{
display: flex;;
position: absolute;
list-style: none;
transform: translate(-50%,-50%);
}
li{
position: relative;
padding: 20px;
color: #000;
line-height: 1;
transition: 0.2s all linear;
cursor: pointer;
}
li::before{
content: "";
position: absolute;

} */
ul,li{
list-style: none;
}
div#nav{
border: 1px solid #ccc;
}
div#nav ul{
border-bottom: 1px solid #ccc;
}
div#nav li{
position: relative;
display: inline-block;
line-height: 3em;
text-align: center;
width: 50%;
cursor: pointer;
transition: 0.2s all linear;
}
div.hide{
display: none;
}
div#nav li.active{
color: rgba(0,0,0,.85);
font-weight: 700;
opacity: 1;
border-bottom: 2px solid rgba(0,0,0,.85);
transition: 0.2s all linear;
}
/* div#nav li::before{
content: "";
position: absolute;
top: 0;
left: 100%;
width: 0;
height: 100%;
border-bottom: 2px solid #f000;
transition: 0.2s all linear;

}
.active ~ li::before{
left: 0;
}
.active::before{
width: 100%;
left: 0;
top: 0;
}
.hover::before{
width: 50%;
} */
</style>
<div id="uuid_div" style="display: none">
<input type="" value="{{$.Uuid}}" id="hide_uuidid" style="display:none;">
</div>
<div id="myCanvas_div" style="width:100%;height:100% ; position: relative;">
<!-- <div style="display:inline-block; width:6%;height: 100%; position: relative; vertical-align: middle;">
<img src="/img/left_new_new.png" onclick="clickLast()" style="margin-left: 15px" />
</div> -->

<div style="display:inline-block; width:71%; height: 100%; position: relative;border: 1px solid #ccc;border-radius: 6px;">
<!-- <div style="text-align:center">
<a>
文件名:
<span id="filename"></span>
</a>
</div> -->

<div id="win_canvas" style="width:100%;height:42em">
<canvas id="myCanvas" style="display:none;">
</canvas>
<code id="textcontent" style="display:none;overflow: auto;">这是一个测试。</code>
<div style="padding:0.2em 0;position: absolute;border-top: 1px solid #ccc;width: 100%;bottom:0;font-size: 1em;padding: 0.5em 1em;">
<div id="breadFile" class="ui small breadcrumb">
<!-- <div class="section">Home</div>
<div class="divider"> / </div>
<div class="active section">Search</div> -->
</div>
</div>


</div>

<div style="font-size: 1.5rem; opacity: 0.7; position: absolute;left: 0.5rem;top: 20rem;cursor: pointer;" onclick="clickLast()"><i class="chevron circle left icon" ></i></div>
<div style="font-size: 1.5rem; opacity: 0.7; position: absolute;right: 0.5rem;top: 20rem;cursor: pointer;" onclick="clickNext()"><i class="chevron circle right icon" ></i></div>
</div>

<!-- <div style="display:inline-block; width:6%;height: 100%; position: relative; vertical-align: middle;">
<img src="/img/right_new_new.png" onclick="clickNext()" style="margin-left: 15px"/>
</div> -->
<div id="nav" style="display:inline-block; width:25%;height: 100%; position: relative;vertical-align: top; background: #ffffff;margin-left: 20px;border-radius: 6px;">
<ul style="display: flex;padding: 0;margin: 0;">
<li id="0" class="active">文件列表</li>

<li id="1">标签列表</li>
</ul>
<div class="tabpannel">
<!-- <h4 class="ui top attached header">
文件列表
</h4> -->
<!-- <table class="ui single line table" id="filelist" style="table-layout:fixed;word-break: break-all;word-wrap: break-word;">
</table> -->
<div class="ui list" id="filelist"></div>


<div class="panel-body" id="filepanel" style='position: absolute;bottom: 0;padding: 0.9em 0;width: 100%;border-top: 1px #ccc solid;'>
<div style="width: 90%; margin: 0 auto;">
<a id="prePage" href="" style="margin-right: 0.2em;color: #000;"><i class="angle left icon"></i></a>
<span id="startIndex">0</span>-<span id="endIndex">0</span>/<span id="totalNum">0</span>
<span style="margin-left: 0.2em;">第</span><span id="displayPage1">1</span><span style="margin-right: 0.2em;">页</span>
<span>跳到</span><input type="text" id="goNum" style="width: 2em;border-radius: 4px;padding: 0 0.4em;margin: 0 0.4em;height: 1.2em;border: 1px solid;" maxlength="5" oninput="value=value.replace(/[^\d]/g,'')"><span>页</span>

<a style="margin-left: 0.4em;color: #000;" id="nextPage" href=""><i class="angle right icon"></i></a>
<!-- 第<span id="startIndex">0</span>至<span id="endIndex">0</span>条,&nbsp;共<span id="totalNum">0</span>条.&nbsp;&nbsp;
<span >
<span >
&nbsp;当前页:<span id="displayPage1">1</span>&nbsp;
</span>
<a id="nextPage" href="">下一页</a>
<span>
&nbsp;共<span id="totalPageNum"></span>页&nbsp;
</span>
</span>
<span>&nbsp;跳转至:<input type="text" id="goNum" style="width: 50px;border-radius: 6px" maxlength="5" oninput="value=value.replace(/[^\d]/g,'')"><a id="goHref" href="javascript:goPage()">&nbsp;GO</a></span> -->
</div>
</div>
</div>
<div class="hide tabpannel">
<div style="margin-top: 1em;" id="labellist">

</div>

</div>
<!-- <div class="ui pointing secondary menu">
<a class="item " data-tab="first">First</a>
<a class="item active" data-tab="second">Second</a>
</div>

<div class="ui bottom attached tab segment active" data-tab="first">
First
</div>
<div class="ui bottom attached tab segment" data-tab="second">
Second
</div>
-->

</div>
</div>
<script>
var ulObj = document.getElementById('nav').getElementsByTagName('ul')[0];
var divObj = document.getElementsByClassName('tabpannel');
var liObj = document.getElementById('nav').getElementsByTagName('li')
ulObj.onclick = function(event){
var ev = window.event || event;
var item = ev.srcElement || ev.target;

var id = item.getAttribute("id")
for (var i=0; i<divObj.length;i++){
if(i == id){
divObj[i].style.display = 'block'
liObj[i].classList.add('active')
}
else{
divObj[i].style.display = 'none'
liObj[i].classList.remove('active')
}
}
}
</script>
<script src="{{StaticUrlPrefix}}/self/dataset_preview.js"></script>
{{end}}

+ 26
- 20
templates/repo/datasets/dirs/index.tmpl View File

@@ -1,29 +1,35 @@
{{template "base/head" .}}
<div class="repository dataset dir-list view">
{{template "repo/header" .}}
<form class="ui container">
<div class="ui stackable grid {{if .Error}}hide{{end}}" id="dir-content">
<div class="row">
<div class="column sixteen wide">
<p>
{{ range $index, $item := .Path }}<a href='{{$.Link}}/?parentDir={{if gt $index 0}}{{DatasetPathJoin $.Path $index "/"}}{{else}}{{end}}'>{{ $item }}</a><span class="directory-seperator">/</span>{{ end }}
</p>
<div style="background:#fff">
{{template "base/head" .}}
<div class="repository dataset dir-list view">
{{template "repo/header" .}}
<div>
<form class="ui container">
<div class="ui stackable grid {{if .Error}}hide{{end}}" id="dir-content">
<div class="row">
<div class="column sixteen wide">
<div class="ui breadcrumb">
{{ range $index, $item := .Path }}<a class="section" href='{{$.Link}}/?parentDir={{if gt $index 0}}{{DatasetPathJoin $.Path $index "/"}}{{else}}{{end}}'>{{ $item }}</a><div class="divider"> / </div>{{ end }}
</div>
</div>
</div>
</div>
</div>
</div>

<div class="ui grid">
<div class="row">
<div class="ui sixteen wide column">
<div class="dir list">
{{template "repo/datasets/dirs/dir_list" .}}
<div class="ui grid">
<div class="row" style="padding-top: 0.5rem;padding-bottom: 0;">
<div class="ui sixteen wide column">
<div class="dir list">
{{template "repo/datasets/dirs/dir_preview" .}}
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</form>
</div>
</div>




{{template "base/footer" .}}

+ 209
- 0
templates/repo/datasets/label/index.tmpl View File

@@ -0,0 +1,209 @@
{{template "base/head" .}}

<style>
#progress{
width: 100%;
height: 20px;
background: rgb(255, 255, 255);
}
#bar{
width: 1%;
height: 20px;
margin-top: 1px;
background: green;
}
</style>

<div class="repository dataset dir-list view">
{{template "repo/header" .}}
<input type="hidden" id="repoId" value="{{.repoId}}">
<div class="ui container">
<div class="header">
<h3 class="modal-title">人工标注任务列表</h3>
</div>
<div class="ui container">
<div class="ui container">
<table class="ui celled table" id="label_task_list"></table>

<div class="ui container" style="height: 30px;">
<div style="float:right">
显示<span id="startIndex">0</span>到<span id="endIndex">0</span>条,共<span id="totalNum">0</span>条。&nbsp;&nbsp;
<span >
<a id="prePage" href=""><b>上一页</b></a>
<span >
&nbsp;当前页:<span id="displayPage1">1</span>&nbsp;
</span>
<a id="nextPage" href=""><b>下一页</b></a>
<span>
&nbsp;共<span id="totalPageNum"></span>页&nbsp;
</span>
<span>&nbsp;跳转到:<input type="text" id="goNum" style="width: 50px;border-radius:6px" maxlength="5" oninput="value=value.replace(/[^\d]/g,'')"><a id="goHref" href="javascript:goPage()">&nbsp;GO</a></span>
</span>
</div>
</div>

<div class="ui container" style="height: 30px;">
<!-- <button type="button" onclick="setPredictTask();" class="ui blue button" style="float:left">新建自动标注结果图片标注</button> -->
<button type="button" onclick="setDataSetTask();" class="ui blue button" style="float:left">新建数据集图片标注</button>
<button type="button" onclick="setMultiTaskId();" class="ui blue button" style="float:right;margin-left:20px;">导出标注数据</button>
<button type="button" onclick="countLabel();" class="ui blue button" style="float:right;margin-left:20px;">统计所有标注数量</button>
<button type="button" onclick="delete_labeltask();" class="ui blue button" style="float:right">删除人工标注</button>
</div>


<!-- 增加新建数据集人工标注-->
<div id="labelDataModal" class="ui dataset modal">
<i class="close icon"></i>
<div class="header">
<h4 class="modal-title">新建数据集图片标注</h4>
</div>
<div class="content">
<div class="ui form">
<div class="field">
<label for="exampleInputPassword1">选择数据集对象<font color=red>*</font></label>
<select name="pre_predict_task" id="dataset_list" onchange="dataset_sele_Change(this)">
<option value="" selected="">请选择</option>
</select>
</div>

<div class="field" >
<label for="exampleInputEmail1">人工标注任务名称<font color=red>*</font></label>
<input type="text" id="datasetlabeltaskname" placeholder="标注任务名称,不超过32个字符">
</div>
<div class="field" style="display:none">
<label for="exampleInputEmail2">任务指派给</label>
<select name="任务指派给" id="assign_user">
<option value="">请选择</option>
</select>
</div>
<div class="field" >
<label for="exampleInputEmail2">模式</label>
<select name="模式" id="task_flow_type" onchange="flow_type_sele_Change(this)">
<option value="1" select="true"> 标注工作模式</option>
<!-- <option value="2"> 标注审核模式</option>
<option value="3"> 主动分类学习模式</option> -->
</select>
</div>
<div class="field" style="display:none">
<label id = "labelInfo" for="exampleInputFile">标注类别(也可以直接在标注界面上进行设置)</label>
<select name="labelpropertytask" id="labelpropertytask_dataset" >
<option value="" selected="">请选择</option>
</select>
</div>
<button type="button" onclick="submit_datasettask();">提交</button>
</div>
</div>
</div> <!-- /.box-body -->

<div id="labelModal" class="ui predict modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button>
<h4 class="modal-title">新建自动标注结果人工标注</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="exampleInputPassword1">关联的自动标注任务<font color=red>*</font></label>
<select class="form-control" name="pre_predict_task" id="pre_predict_task_for_label" onchange="sele_Change(this)">
<option value="" selected="">请选择</option>
</select>
<!-- <input type="" class="form-control" id="prepredtaskid" placeholder="预检任务"> -->
</div>
<div class="form-group" >
<label for="exampleInputEmail2">任务指派给</label>
<select class="form-control" name="任务指派给" id="label_assign_user">
<option value=""> 请选择</option>
</select>
</div>
<div class="form-group">
<label for="exampleInputEmail1">人工标注任务名称<font color=red>*</font></label>
<input type="" class="form-control" id="labeltaskname" placeholder="校验标注任务名称,不超过32个字符" maxlength="32">
</div>
<div class="form-group">
<label id = "labelInfo" for="exampleInputFile">标注类别属性,请输入符合格式Json字符串 </label>
<select class="form-control" name="labelpropertytask" id="labelpropertytask_auto">
<option value="" selected="">请选择</option>
</select>
</div>
<button type="button" onclick="submit_labeltask();">提交</button>
</div>
</div>
</div>
</div> <!-- /.box-body -->
<div id="labeltaskexport" class="ui export modal">
<i class="close icon"></i>
<div class="header">
<h4 class="modal-title">导出标注数据</h4>
</div>
<div class="content">
<div class="ui form">
<input type="" value="" id="hide_labeltaskid" style="display:none;">
<div class="field">
<label for="exampleInputPassword1">是否带图片导出<font color=red>*</font></label>
<select class="form-control" name="是否带图片导出" id="isNeedPicture" onchange="sele_export_Change(this)">
<option value="1" selected="">不带图片导出</option>
<option value="2">带图片导出</option>
<option value="3">导出所有标注抠图</option>
</select>
</div>
<div class="field">
<label for="exampleInputPassword1">选择标注导出格式<font color=red>*</font></label>
<select class="form-control" id="exportFormat">
<option value="1" selected="">COCO</option>
<option value="2">VOC</option>
</select>
</div>
<div class="field" id="maxscore_div" style="display:none;">
<label for="exampleInputEmail1">标注得分最大值(0--1.0),目标检测得分大于此值时,不导出</label>
<input type="" class="form-control" id="maxscore" placeholder="标注得分最大值(0--1.0),当目标检测得分大于此值时,不导出。" maxlength="10">
</div>
<div class="field" id="minscore_div" style="display:none;">
<label for="exampleInputEmail1">标注得分最小值(0--0.99),目标检测得分小于此值时,不导出</label>
<input type="" class="form-control" id="minscore" placeholder="标注得分最小值(0--0.99),当目标检测得分小于此值时,不导出。" maxlength="10">
</div>
<div class="field" id="progress">
<div id="bar"></div>
</div>
<div class="field"><h5 id="text-progress">0%</h3></div>
<div class="field">
<button id="predtask_id" type="button" class="btn btn-default" onclick="downloadFile();">提交</button>
</div>
</div>
</div>
</div>
</div><!-- /.box-body -->
</div>
<!-- </div> -->
</div><!-- /.box -->
</div>



<script src="/self/labelTaskPage.js"></script>

{{template "base/footer" .}}

Loading…
Cancel
Save