From db5176bc7587d6f45e97c5586c3e796903d712b1 Mon Sep 17 00:00:00 2001 From: dragdra Date: Mon, 30 Jun 2025 17:04:10 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=B0=ED=94=BD=20=EC=B1=84=EC=A0=90=20?= =?UTF-8?q?=EA=B8=B0=EC=A4=80=20=EC=88=98=EC=A0=95=EB=B2=84=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 00_DPI_2504B_TEST.xlsx | Bin 0 -> 32814 bytes DIC_2504B.json | 1467 +++++++++++++++++++-------------------- DIC_2505A.json | 1391 ++++++++++++++++++------------------- DIC_2505B copy.json | 729 ------------------- DIC_2505B.json | 2 +- DIC_곰픽채점기준표.json | 737 ++++++++++++++++++++ gpdpScoring.js | 923 ++++++++++++------------ psdExport_2.js | 10 +- 8 files changed, 2607 insertions(+), 2652 deletions(-) create mode 100644 00_DPI_2504B_TEST.xlsx delete mode 100644 DIC_2505B copy.json create mode 100644 DIC_곰픽채점기준표.json diff --git a/00_DPI_2504B_TEST.xlsx b/00_DPI_2504B_TEST.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..5536d86212b39c1a98b63ebdb07cf5452c696193 GIT binary patch literal 32814 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 X(VeG$_UDlF82tNX2#VLfir@Yl)b6g7 literal 0 HcmV?d00001 diff --git a/DIC_2504B.json b/DIC_2504B.json index fa2cdb4..58030f2 100644 --- a/DIC_2504B.json +++ b/DIC_2504B.json @@ -1,748 +1,737 @@ { - "0": { - "1": { - "ele": "none", - "point": 0 - }, - "2": { - "ele": "none", - "point": 0 - }, - "3": { - "ele": "none", - "point": 0 - }, - "4": { - "ele": "none", - "point": 0 - }, - "5": { - "ele": "none", - "point": 0 - }, - "6": { - "ele": "none", - "point": 0 - }, - "7": { - "ele": "none", - "point": 0 - }, - "8": { - "ele": "$[?(@.width == 65 && @.height == 45)]", - "type": "size", - "value": { - "width": 65, - "height": 45 - }, - "point": 4 - }, - "9": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } - }, + "0": { "1": { - "1": { - "ele": "none", - "point": 0 - }, - "2": { - "ele": "none", - "point": 0 - }, - "3": { - "ele": "none", - "point": 0 - }, - "4": { - "ele": "$.children[?(@.name=='꽃잎들')].name", - "value": "꽃잎들", - "point": 4 - }, - "5": { - "ele": "none", - "point": 0 - }, - "6": { - "ele": "$.children[?(@.name=='Flower Rock')].name", - "value": "Flower Rock", - "point": 4 - }, - "7": { - "ele": "$.children[?(@.name=='Flower Rock')].text.font.names[0]", - "type": "font", - "value": "Arial", - "point": 2 - }, - "8": { - "ele": "$.children[?(@.name=='Flower Rock')].text.font.names[0]", - "value": "Arial-BoldItalicMT", - "point": 2 - }, - "9": { - "ele": "$.children[?(@.name=='Flower Rock')].text.font.sizes[0]", - "value": 48, - "point": 2 - }, - "10": { - "ele": "$.children[?(@.name=='Flower Rock')].text.font.colors[0]", - "type": "color", - "value": "d6f592", - "point": 2 - }, - "11": { - "ele": "none", - "point": 0 - }, - "12": { - "ele": "none", - "point": 0 - }, - "13": { - "ele": "none", - "point": 0 - }, - "14": { - "ele": "$.children[?(@.name=='꽃과 바위')].name", - "value": "꽃과 바위", - "point": 4 - }, - "15": { - "ele": "$.children[?(@.name=='꽃과 바위')].text.font.names[0]", - "type": "font", - "value": "GungsuhChe", - "point": 2, - "desc": { - "돋움체": "DotumChe", - "궁서체": "GungsuhChe", - "굴림체": "GulimChe", - "휴먼옛체": "YetR" - } - }, - "16": { - "ele": "$.children[?(@.name=='꽃과 바위')].text.font.sizes[0]", - "value": 36, - "point": 2 - }, - "17": { - "ele": "$.children[?(@.name=='꽃과 바위')].text.font.colors[0]", - "type": "color", - "value": "0d17d5", - "point": 2 - }, - "18": { - "ele": "none", - "point": 0 - }, - "19": { - "ele": "none", - "point": 0 - }, - "20": { - "ele": "none", - "point": 0 - }, - "21": { - "ele": "none", - "point": 0 - }, - "22": { - "ele": "$.children[?(@.name=='노랑꽃')].name", - "value": "노랑꽃", - "point": 4 - }, - "23": { - "ele": "none", - "point": 0 - }, - "24": { - "ele": "none", - "point": 0 - }, - "25": { - "ele": "none", - "point": 0 - }, - "26": { - "ele": "$[?(@.width == 65 && @.height == 35)]", - "type": "size", - "value": { - "width": 65, - "height": 35 - }, - "point": 5 - }, - "27": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } + "ele": "none", + "point": 0 }, "2": { - "1": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex", - "type": "mediaOrder", - "value": [ - "동영상.mp4", - "이미지3.jpg", - "이미지1.jpg", - "이미지2.jpg" - ], - "point": 4, - "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다." - }, - "2": { - "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed", - "type": "oneAnswer", - "value": { - "speed": "140" - }, - "point": 2, - "desc": "100당 1배속 / 130 = 1.3배속" - }, - "3": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']", - "type": "startEnd", - "media": "동영상.mp4", - "value": { - "start": "0", - "end": "370" - }, - "point": 2, - "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다." - }, - "4": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", - "type": "effect", - "media": "동영상.mp4", - "value": { - "ID": "44", - "VID100": "8", - "VID103": "0.89999998" - }, - "point": 3, - "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요" - }, - "5": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", - "search": "화단의 꽃들", - "type": "video.Text", - "value": "화단의 꽃들", - "point": 3 - }, - "6": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", - "search": "화단의 꽃들", - "type": "video.Text", - "value": "돋움체", - "point": 2 - }, - "7": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", - "search": "화단의 꽃들", - "type": "video.Text", - "value": "110", - "point": 2 - }, - "8": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", - "search": "화단의 꽃들", - "type": "video.Text.Color", - "value": "ff531b", - "point": 2, - "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" - }, - "9": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']", - "search": "화단의 꽃들", - "type": "video.Location", - "value": [ - "0.38333333", - "0.92962962" - ], - "point": 2, - "desc": "정답 파일의 자막 좌표를 기준으로 프로그램 내부적으로 0.1까지 오차를 허용한다" - }, - "10": { - "ele": "", - "search": "화단의 꽃들", - "type": "video.StartTime", - "value": 170, - "point": 2, - "desc": "내부적으로 자막의 시작시간과 길이를 계산" - }, - "11": { - "ele": "", - "search": "화단의 꽃들", - "type": "video.Length", - "value": 150, - "point": 2, - "desc": "내부적으로 자막의 시작시간과 길이를 계산" - }, - "12": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Mute", - "type": "Mute", - "media": "동영상.mp4", - "value": "1", - "point": 2 - }, - "13": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", - "type": "imageLength", - "media": "이미지3.jpg", - "value": "180", - "point": 2 - }, - "14": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", - "type": "imageOverlay", - "media": "이미지3.jpg", - "value": { - "ID": "67", - "VID102": "40" - }, - "point": 2 - }, - "15": { - "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", - "type": "clipTransition", - "media": "이미지3.jpg", - "value": { - "ID": "10", - "Range": "490:550", - "Type": "2" - }, - "point": 2, - "desc": "오버랩일 경우 Type속성값 16으로 변경" - }, - "16": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", - "type": "imageLength", - "media": "이미지1.jpg", - "value": "150", - "point": 2 - }, - "17": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", - "type": "imageOverlay", - "media": "이미지1.jpg", - "value": { - "ID": "184", - "VID102": "30" - }, - "point": 2 - }, - "18": { - "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", - "type": "clipTransition", - "media": "이미지1.jpg", - "value": { - "ID": "19", - "Range": "650:680", - "Type": "2" - }, - "point": 2, - "desc": "오버랩일 경우 Type속성값 16으로 변경" - }, - "19": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", - "type": "imageLength", - "media": "이미지2.jpg", - "value": "180", - "point": 2 - }, - "20": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", - "type": "imageOverlay", - "media": "이미지2.jpg", - "value": { - "ID": "67", - "VID102": "30" - }, - "point": 2 - }, - "21": { - "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", - "type": "clipTransition", - "media": "이미지2.jpg", - "value": { - "ID": "10", - "Range": "800:860", - "Type": "2" - }, - "point": 2, - "desc": "오버랩일 경우 Type속성값 16으로 변경" - }, - "22": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", - "search": "아름다운 꽃 축제 (Happy Flower Festival)", - "type": "video.Text", - "value": "아름다운 꽃 축제 (Happy Flower Festival)", - "point": 3 - }, - "23": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", - "search": "아름다운 꽃 축제 (Happy Flower Festival)", - "type": "video.Text", - "value": "궁서체", - "point": 2 - }, - "24": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", - "search": "아름다운 꽃 축제 (Happy Flower Festival)", - "type": "video.Text", - "value": "140", - "point": 2 - }, - "25": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", - "search": "아름다운 꽃 축제 (Happy Flower Festival)", - "type": "video.Text.Color", - "value": "fd5721", - "point": 2, - "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" - }, - "26": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']", - "search": "아름다운 꽃 축제 (Happy Flower Festival)", - "type": "video.Text.Outline", - "value": { - "width": "30", - "color": "fff9c4" - }, - "point": 2, - "desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성" - }, - "27": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr", - "search": "아름다운 꽃 축제 (Happy Flower Festival)", - "type": "opening.Text.FadeInEffect", - "value": { - "ID": "4", - "PlayTime": "2" - }, - "point": 3, - "desc": "오프닝자막의 나타나기 효과를 확인하는 문항. id속성은 VID505, playtime속성은 VID507으로 XML 내부에 표기되어 있다." - }, - "28": { - "ele": "{search}", - "search": "아름다운 꽃 축제 (Happy Flower Festival)", - "type": "opening.StartTime", - "value": 0, - "point": 2, - "desc": "오프닝자막의 시작시간 value 속성만 수정" - }, - "29": { - "ele": "{search}", - "search": "아름다운 꽃 축제 (Happy Flower Festival)", - "type": "opening.Length", - "value": 120, - "point": 2 - }, - "30": { - "ele": "", - "type": "audio.StartTime", - "media": "음악.mp3", - "value": 0, - "point": 2 - }, - "31": { - "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']", - "type": "audio.EndTime", - "media": "음악.mp3", - "value": 810, - "point": 2 - }, - "32": { - "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", - "type": "audio.Effect", - "media": "음악.mp3", - "value": { - "ID": "1", - "PlayTime": "90" - }, - "point": 2, - "desc": "ID속성-페이드인:0 / 페이드아웃: 1" - }, - "33": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } + "ele": "none", + "point": 0 + }, + "3": { + "ele": "none", + "point": 0 }, "4": { - "1": { - "type": "canvas.Size", - "ele": "//Document/Width/@value | //Document/Height/@value", - "value": [ - "650", - "350" - ], - "point": 5, - "desc": "캔버스 사이즈 650*350" - }, - "2": { - "type": "none", - "ele": "", - "point": 5, - "desc": "자유 변형 문항은 채점 불가" - }, - "3": { - "type": "layer.Exists", - "ele": "//Layer/Name/@value", - "value": "Flower", - "point": 5, - "desc": "Flower 레이어가 있는지 여부 체크" - }, - "4": { - "type": "layer.Effects", - "ele": "//Layer[Name[@value='{search}']]/Effects/Item", - "search": "Flower", - "value": { - "name": "세피아", - "option": { - "U": "75", - "V": "150" - } - }, - "point": 5, - "desc": "Flower 레이어의 효과 체크" - }, - "5": { - "type": "none", - "ele": "", - "point": 6, - "desc": "올가미 도구/이미지 문항은 채점 불가" - }, - "6": { - "type": "exists", - "ele": "//Layer/Effects/Item/Name/@value", - "value": "세피아", - "point": 6, - "desc": "세피아 효과가 있는지 여부 체크" - }, - "7": { - "type": "exists", - "ele": "//Layer/Shapes/Shape/shape_type/@value", - "value": "ELLIPSE", - "point": 3, - "desc": "레이어 쉐이프 타입이 타원인지 체크" - }, - "8": { - "type": "shape.size", - "ele": "//Layer//op_points", - "value": { - "width": 120, - "height": 120 - }, - "point": 3, - "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" - }, - "9": { - "type": "shape.color", - "ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value", - "value": "7097BB", - "point": 6, - "desc": "" - }, - "10": { - "type": "layer.blend.opacity", - "ele": "//Layer", - "value": { - "BlendOp": "반사", - "Opacity": "80" - }, - "point": 6 - }, - "11": { - "type": "none", - "ele": "", - "point": 0, - "desc": "기본설정" - }, - "12": { - "type": "none", - "ele": "", - "point": 0, - "desc": "파일명 확인" - } + "ele": "none", + "point": 0 }, "5": { - "1": { - "type": "canvas.Size", - "ele": "//Document/Width/@value | //Document/Height/@value", - "value": [ - "650", - "450" - ], - "point": 5, - "desc": "캔버스 사이즈 650*450" - }, - "2": { - "type": "none", - "ele": "", - "point": 5, - "desc": "배경색 문항은 채점 불가" - }, - "3": { - "type": "exists", - "ele": "//Layer/MaskOpType/@value", - "value": "Layering", - "point": 6, - "desc": "레이어 마스크 설정 확인" - }, - "4": { - "type": "none", - "ele": "", - "point": 6, - "desc": "가로방향 흐릿하게 문항은 채점 불가" - }, - "5": { - "type": "exists", - "ele": "//Layer//shape_type/@value", - "value": "ROUNDED_RECTANGLE", - "point": 3 - }, - "6": { - "type": "shape.size", - "ele": "//Layer//op_points", - "value": { - "width": 400, - "height": 60 - }, - "point": 3, - "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" - }, - "7": { - "type": "gradient.color", - "ele": "//Layer/Shapes/Shape", - "startColor": "gradient_start_color/@value", - "endColor": "gradient_end_color/@value", - "value": { - "startColor": "ffe000", - "endColor": "34A159" - }, - "point": 6 - }, - "8": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/lines/Item/@value", - "value": "흰 꽃 사이 노란 꽃", - "point": 5 - }, - "9": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Name/@value", - "value": "맑은 고딕", - "point": 3 - }, - "10": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/{style}/@value", - "style": "Italic", - "value": "True", - "point": 3 - }, - "11": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value", - "value": "30", - "point": 3 - }, - "12": { - "type": "text.color", - "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value", - "value": "b46Ef8", - "point": 3 - }, - "13": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value", - "value": "7", - "point": 3 - }, - "14": { - "type": "text.color", - "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value", - "value": "ffffff", - "point": 3 - }, - "15": { - "type": "exists", - "ele": "//Layer/MaskOpType/@value", - "value": "Clipping", - "point": 6, - "desc": "클리핑 마스크 항목은 별도 레이어로 추가되고 해당 속성을 추가해놓은 레이어가 있는지 여부 체크 함" - }, - "16": { - "type": "exists", - "ele": "//Layer/Shapes/Shape/shape_type/@value", - "value": "RECTANGLE", - "point": 3, - "desc": { - "사각형": "RECTANGLE" - } - }, - "17": { - "type": "clipping.size", - "ele": "//Layer//Shape[shape_type/@value='{option}']//op_points", - "option": "RECTANGLE", - "value": { - "width": 150, - "height": 150 - }, - "point": 3, - "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" - }, - "18": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='{option}']/outline_peninfo/Width/@value", - "option": "RECTANGLE", - "value": "7", - "point": 3 - }, - "19": { - "type": "clipping.color", - "ele": "//Layer//Shape[shape_type/@value='{option}' and contains(draw_type/@value, 'Outline')]/primary_color/@value", - "option": "RECTANGLE", - "value": "e8e88e", - "point": 3, - "desc": "채우기:secondary_color, 외곽선:primary_color" - }, - "20": { - "type": "shadow", - "ele": "//Layer//Shape[shape_type/@value='{option}']", - "ele2": { - "shadow": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]", - "width": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_width/@value", - "distance": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_distance/@value", - "blur": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_blur/@value", - "angle": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_angle/@value" - }, - "option": "RECTANGLE", - "value": { - "shadow": true, - "width": "3", - "distance": "5", - "blur": "1", - "angle": "320" - }, - "point": 5, - "desc": "그림자 속성이 있는 경우 그림자 속성의 너비, 거리, 흐림 정도, 각도를 비교하여 정답 채점" - }, - "21": { - "type": "none", - "ele": "", - "point": 0, - "desc": "기본설정" - }, - "22": { - "type": "none", - "ele": "", - "point": 0, - "desc": "파일명 확인" - } + "ele": "none", + "point": 0 + }, + "6": { + "ele": "none", + "point": 0 + }, + "7": { + "ele": "none", + "point": 0 + }, + "8": { + "ele": "$[?(@.width == 65 && @.height == 45)]", + "type": "size", + "value": { + "width": 65, + "height": 45 + }, + "point": 4 + }, + "9": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" } -} \ No newline at end of file + }, + "1": { + "1": { + "ele": "none", + "point": 0 + }, + "2": { + "ele": "none", + "point": 0 + }, + "3": { + "ele": "none", + "point": 0 + }, + "4": { + "ele": "$.children[?(@.name=='꽃잎들')].name", + "value": "꽃잎들", + "point": 4 + }, + "5": { + "ele": "none", + "point": 0 + }, + "6": { + "ele": "$.children[?(@.name=='Flower Rock')].name", + "value": "Flower Rock", + "point": 4 + }, + "7": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.names[0]", + "type": "font", + "value": "Arial", + "point": 2 + }, + "8": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.names[0]", + "value": "Arial-BoldItalicMT", + "point": 2 + }, + "9": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.sizes[0]", + "value": 48, + "point": 2 + }, + "10": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.colors[0]", + "type": "color", + "value": "d6f592", + "point": 2 + }, + "11": { + "ele": "none", + "point": 0 + }, + "12": { + "ele": "none", + "point": 0 + }, + "13": { + "ele": "none", + "point": 0 + }, + "14": { + "ele": "$.children[?(@.name=='꽃과 바위')].name", + "value": "꽃과 바위", + "point": 4 + }, + "15": { + "ele": "$.children[?(@.name=='꽃과 바위')].text.font.names[0]", + "type": "font", + "value": "GungsuhChe", + "point": 2, + "desc": { + "돋움체": "DotumChe", + "궁서체": "GungsuhChe", + "굴림체": "GulimChe", + "휴먼옛체": "YetR" + } + }, + "16": { + "ele": "$.children[?(@.name=='꽃과 바위')].text.font.sizes[0]", + "value": 36, + "point": 2 + }, + "17": { + "ele": "$.children[?(@.name=='꽃과 바위')].text.font.colors[0]", + "type": "color", + "value": "0d17d5", + "point": 2 + }, + "18": { + "ele": "none", + "point": 0 + }, + "19": { + "ele": "none", + "point": 0 + }, + "20": { + "ele": "none", + "point": 0 + }, + "21": { + "ele": "none", + "point": 0 + }, + "22": { + "ele": "$.children[?(@.name=='노랑꽃')].name", + "value": "노랑꽃", + "point": 4 + }, + "23": { + "ele": "none", + "point": 0 + }, + "24": { + "ele": "none", + "point": 0 + }, + "25": { + "ele": "none", + "point": 0 + }, + "26": { + "ele": "$[?(@.width == 65 && @.height == 35)]", + "type": "size", + "value": { + "width": 65, + "height": 35 + }, + "point": 5 + }, + "27": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "2": { + "1": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex", + "type": "mediaOrder", + "value": ["동영상.mp4", "이미지3.jpg", "이미지1.jpg", "이미지2.jpg"], + "point": 4, + "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다." + }, + "2": { + "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed", + "type": "oneAnswer", + "value": { + "speed": "140" + }, + "point": 2, + "desc": "100당 1배속 / 130 = 1.3배속" + }, + "3": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']", + "type": "startEnd", + "media": "동영상.mp4", + "value": { + "start": "0", + "end": "370" + }, + "point": 2, + "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다." + }, + "4": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "effect", + "media": "동영상.mp4", + "value": { + "ID": "44", + "VID100": "8", + "VID103": "0.89999998" + }, + "point": 3, + "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요" + }, + "5": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", + "search": "화단의 꽃들", + "type": "video.Text", + "value": "화단의 꽃들", + "point": 3 + }, + "6": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", + "search": "화단의 꽃들", + "type": "video.Text", + "value": "돋움체", + "point": 2 + }, + "7": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", + "search": "화단의 꽃들", + "type": "video.Text", + "value": "110", + "point": 2 + }, + "8": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", + "search": "화단의 꽃들", + "type": "video.Text.Color", + "value": "ff531b", + "point": 2, + "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" + }, + "9": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']", + "search": "화단의 꽃들", + "type": "video.Location", + "value": ["0.38333333", "0.92962962"], + "point": 2, + "desc": "정답 파일의 자막 좌표를 기준으로 프로그램 내부적으로 0.1까지 오차를 허용한다" + }, + "10": { + "ele": "", + "search": "화단의 꽃들", + "type": "video.StartTime", + "value": 170, + "point": 2, + "desc": "내부적으로 자막의 시작시간과 길이를 계산" + }, + "11": { + "ele": "", + "search": "화단의 꽃들", + "type": "video.Length", + "value": 150, + "point": 2, + "desc": "내부적으로 자막의 시작시간과 길이를 계산" + }, + "12": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Mute", + "type": "Mute", + "media": "동영상.mp4", + "value": "1", + "point": 2 + }, + "13": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", + "type": "imageLength", + "media": "이미지3.jpg", + "value": "180", + "point": 2 + }, + "14": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "imageOverlay", + "media": "이미지3.jpg", + "value": { + "ID": "67", + "VID102": "40" + }, + "point": 2, + "desc": "오버레이 속성 키값(VID10X) 확인하고 변경" + }, + "15": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지3.jpg", + "value": { + "ID": "10", + "Range": "490:550", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "16": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", + "type": "imageLength", + "media": "이미지1.jpg", + "value": "180", + "point": 2 + }, + "17": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "imageOverlay", + "media": "이미지1.jpg", + "value": { + "ID": "103", + "VID102": "7" + }, + "point": 2, + "desc": "오버레이 속성 키값(VID10X) 확인하고 변경" + }, + "18": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지1.jpg", + "value": { + "ID": "12", + "Range": "670:730", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "19": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", + "type": "imageLength", + "media": "이미지2.jpg", + "value": "150", + "point": 2 + }, + "20": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "imageOverlay", + "media": "이미지2.jpg", + "value": { + "ID": "102", + "VID101": "3" + }, + "point": 2, + "desc": "오버레이 속성 키값(VID10X) 확인하고 변경" + }, + "21": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지2.jpg", + "value": { + "ID": "0", + "Range": "850:880", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "22": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text", + "value": "아름다운 꽃 축제 (Happy Flower Festival)", + "point": 3 + }, + "23": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text", + "value": "궁서체", + "point": 2 + }, + "24": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text", + "value": "140", + "point": 2 + }, + "25": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text.Color", + "value": "ec008c", + "point": 2, + "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" + }, + "26": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text.Outline", + "value": { + "width": "40", + "color": "fff9c4" + }, + "point": 2, + "desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성" + }, + "27": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "opening.Text.FadeInEffect", + "value": { + "ID": "14", + "PlayTime": "2" + }, + "point": 3, + "desc": "오프닝자막의 나타나기 효과를 확인하는 문항. id속성은 VID505, playtime속성은 VID507으로 XML 내부에 표기되어 있다." + }, + "28": { + "ele": "", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "opening.StartTime", + "value": 0, + "point": 2, + "desc": "오프닝자막의 시작시간 value 속성만 수정" + }, + "29": { + "ele": "", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "opening.Length", + "value": 120, + "point": 2 + }, + "30": { + "ele": "", + "type": "audio.StartTime", + "media": "음악.mp3", + "value": 0, + "point": 2 + }, + "31": { + "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']", + "type": "audio.EndTime", + "media": "음악.mp3", + "value": "870", + "point": 2 + }, + "32": { + "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "audio.Effect", + "media": "음악.mp3", + "value": { + "ID": "1", + "PlayTime": "60" + }, + "point": 2, + "desc": "ID속성-페이드인:0 / 페이드아웃: 1" + }, + "33": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "4": { + "1": { + "type": "canvas.Size", + "ele": "//Document/Width/@value | //Document/Height/@value", + "value": ["650", "350"], + "point": 5, + "desc": "캔버스 사이즈 650*350" + }, + "2": { + "type": "none", + "ele": "", + "point": 5, + "desc": "자유 변형 문항은 채점 불가" + }, + "3": { + "type": "layer.exists", + "ele": "//Layer/Name/@value", + "value": "Flower", + "point": 5, + "desc": "Flower 레이어가 있는지 여부 체크" + }, + "4": { + "type": "layer.Effects", + "ele": "//Layer[Name[@value='{search}']]/Effects/Item", + "search": "Flower", + "value": { + "name": "생동감", + "option": { + "생동감": "40" + } + }, + "point": 5, + "desc": { + "흑백": "강도", + "밝기/대비": ["밝기", "대비"], + "노출": "노출", + "색조/채도": ["색조", "채도", "명도"], + "감마":["리프트","감마","게인"], + "세피아":["U","V"], + "생동감": "생동감" + } + }, + "5": { + "type": "none", + "ele": "", + "point": 6, + "desc": "올가미 도구/이미지 문항은 채점 불가" + }, + "6": { + "type": "exists", + "ele": "//Layer/Effects/Item/Name/@value", + "value": "세피아", + "point": 6, + "desc": "세피아 효과가 있는지 여부 체크" + }, + "7": { + "type": "exists", + "ele": "//Layer/Shapes/Shape/shape_type/@value", + "value": "ELLIPSE", + "point": 3, + "desc": "레이어 쉐이프 타입이 타원인지 체크" + }, + "8": { + "type": "shape.size", + "ele": "//Layer//op_points", + "value": { + "width": 120, + "height": 120 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "9": { + "type": "shape.color", + "ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value", + "value": "7097BB", + "point": 6, + "desc": "" + }, + "10": { + "type": "layer.blend.opacity", + "ele": "//Layer", + "value": { + "BlendOp": "반사", + "Opacity": "80" + }, + "point": 6 + }, + "11": { + "type": "none", + "ele": "", + "point": 0, + "desc": "기본설정" + }, + "12": { + "type": "none", + "ele": "", + "point": 0, + "desc": "파일명 확인" + } + }, + "5": { + "1": { + "type": "canvas.Size", + "ele": "//Document/Width/@value | //Document/Height/@value", + "value": ["650", "450"], + "point": 5, + "desc": "캔버스 사이즈 650*450" + }, + "2": { + "type": "none", + "ele": "", + "point": 5, + "desc": "배경색 문항은 채점 불가" + }, + "3": { + "type": "exists", + "ele": "//Layer/MaskOpType/@value", + "value": "Layering", + "point": 6, + "desc": "레이어 마스크 설정 확인" + }, + "4": { + "type": "none", + "ele": "", + "point": 6, + "desc": "가로방향 흐릿하게 문항은 채점 불가" + }, + "5": { + "type": "exists", + "ele": "//Layer//shape_type/@value", + "value": "ROUNDED_RECTANGLE", + "point": 3 + }, + "6": { + "type": "shape.size", + "ele": "//Layer//op_points", + "value": { + "width": 400, + "height": 60 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "7": { + "type": "gradient.color", + "ele": "//Layer/Shapes/Shape", + "startColor": "gradient_start_color/@value", + "endColor": "gradient_end_color/@value", + "value": { + "startColor": "ffe000", + "endColor": "34A159" + }, + "point": 6 + }, + "8": { + "type": "text.exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/lines/Item/@value", + "value": "흰 꽃 사이 노란 꽃", + "point": 5 + }, + "9": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Name/@value", + "value": "맑은 고딕", + "point": 3 + }, + "10": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/{style}/@value", + "style": "Italic", + "value": "True", + "point": 3 + }, + "11": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value", + "value": "30", + "point": 3 + }, + "12": { + "type": "text.color", + "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value", + "value": "b46Ef8", + "point": 3 + }, + "13": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value", + "value": "7", + "point": 3 + }, + "14": { + "type": "text.color", + "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value", + "value": "ffffff", + "point": 3 + }, + "15": { + "type": "exists", + "ele": "//Layer/MaskOpType/@value", + "value": "Clipping", + "point": 6, + "desc": "클리핑 마스크 항목은 별도 레이어로 추가되고 해당 속성을 추가해놓은 레이어가 있는지 여부 체크 함" + }, + "16": { + "type": "exists", + "ele": "//Layer/Shapes/Shape/shape_type/@value", + "value": "RECTANGLE", + "point": 3, + "desc": { + "사각형": "RECTANGLE" + } + }, + "17": { + "type": "clipping.size", + "ele": "//Layer//Shape[shape_type/@value='{option}']//op_points", + "option": "RECTANGLE", + "value": { + "width": 150, + "height": 150 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "18": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='{option}']/outline_peninfo/Width/@value", + "option": "RECTANGLE", + "value": "7", + "point": 3 + }, + "19": { + "type": "clipping.color", + "ele": "//Layer//Shape[shape_type/@value='{option}' and contains(draw_type/@value, 'Outline')]/primary_color/@value", + "option": "RECTANGLE", + "value": "e8e88e", + "point": 3, + "desc": "채우기:secondary_color, 외곽선:primary_color" + }, + "20": { + "type": "shadow", + "ele": "//Layer//Shape[shape_type/@value='{option}']", + "option": "RECTANGLE", + "value": { + "shadow": true, + "width": "3", + "distance": "5", + "blur": "1", + "angle": "320" + }, + "point": 5, + "desc": "그림자 속성이 있는 경우 그림자 속성의 너비, 거리, 흐림 정도, 각도를 비교하여 정답 채점" + }, + "21": { + "type": "none", + "ele": "", + "point": 0, + "desc": "기본설정" + }, + "22": { + "type": "none", + "ele": "", + "point": 0, + "desc": "파일명 확인" + } + } +} diff --git a/DIC_2505A.json b/DIC_2505A.json index 6dfc21a..5942aec 100644 --- a/DIC_2505A.json +++ b/DIC_2505A.json @@ -1,728 +1,681 @@ { - "0": { - "1": { - "ele": "none", - "point": 0 - }, - "2": { - "ele": "none", - "point": 0 - }, - "3": { - "ele": "none", - "point": 0 - }, - "4": { - "ele": "none", - "point": 0 - }, - "5": { - "ele": "none", - "point": 0 - }, - "6": { - "ele": "none", - "point": 0 - }, - "7": { - "ele": "none", - "point": 0 - }, - "8": { - "ele": "$[?(@.width == 65 && @.height == 45)]", - "type": "size", - "value": { - "width": 65, - "height": 45 - }, - "point": 4 - }, - "9": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } - }, + "0": { "1": { - "1": { - "ele": "none", - "point": 0 - }, - "2": { - "ele": "none", - "point": 0 - }, - "3": { - "ele": "none", - "point": 0 - }, - "4": { - "ele": "$.children[?(@.name=='놀이터')].name", - "value": "놀이터", - "point": 4 - }, - "5": { - "ele": "none", - "point": 0 - }, - "6": { - "ele": "$.children[?(@.name=='Forest Playground')].name", - "value": "Forest Playground", - "point": 4 - }, - "7": { - "ele": "$.children[?(@.name=='Forest Playground')].text.font.names[0]", - "type": "font", - "value": "Arial", - "point": 2 - }, - "8": { - "ele": "$.children[?(@.name=='Forest Playground')].text.font.names[0]", - "value": "Arial-BoldItalicMT", - "point": 2 - }, - "9": { - "ele": "$.children[?(@.name=='Forest Playground')].text.font.sizes[0]", - "value": 48, - "point": 2 - }, - "10": { - "ele": "$.children[?(@.name=='Forest Playground')].text.font.colors[0]", - "type": "color", - "value": "0096ff", - "point": 2 - }, - "11": { - "ele": "none", - "point": 0 - }, - "12": { - "ele": "none", - "point": 0 - }, - "13": { - "ele": "none", - "point": 0 - }, - "14": { - "ele": "$.children[?(@.name=='숲속 놀이터')].name", - "value": "숲속 놀이터", - "point": 4 - }, - "15": { - "ele": "$.children[?(@.name=='숲속 놀이터')].text.font.names[0]", - "type": "font", - "value": "GulimChe", - "point": 2, - "desc": { - "돋움체":"DotumChe", - "궁서체":"GungsuhChe", - "굴림체":"GulimChe", - "옛":"YetR" - } - }, - "16": { - "ele": "$.children[?(@.name=='숲속 놀이터')].text.font.sizes[0]", - "value": 36, - "point": 2 - }, - "17": { - "ele": "$.children[?(@.name=='숲속 놀이터')].text.font.colors[0]", - "type": "color", - "value": "0c3f00", - "point": 2 - }, - "18": { - "ele": "none", - "point": 0 - }, - "19": { - "ele": "none", - "point": 0 - }, - "20": { - "ele": "none", - "point": 0 - }, - "21": { - "ele": "none", - "point": 0 - }, - "22": { - "ele": "$.children[?(@.name=='바람개비')].name", - "value": "바람개비", - "point": 4 - }, - "23": { - "ele": "none", - "point": 0 - }, - "24": { - "ele": "none", - "point": 0 - }, - "25": { - "ele": "none", - "point": 0 - }, - "26": { - "ele": "$[?(@.width == 65 && @.height == 35)]", - "type": "size", - "value": { - "width": 65, - "height": 35 - }, - "point": 5 - }, - "27": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } + "ele": "none", + "point": 0 }, "2": { - "desc": "videoStartTime 항목은 동영상파일>자막>시작시간 문항의 정답을 작성", - "videoStartTime": 170, - "openingStartTime": 0, - "1": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex", - "type": "mediaOrder", - "value": [ - "동영상.mp4", - "이미지3.jpg", - "이미지1.jpg", - "이미지2.jpg" - ], - "point": 4, - "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다." - }, - "2": { - "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed", - "type": "oneAnswer", - "value": { - "speed": "130" - }, - "point": 2, - "desc": "100당 1배속 / 130 = 1.3배속" - }, - "3": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']", - "type": "startEnd", - "media": "동영상.mp4", - "value": { - "start": "0", - "end": "360" - }, - "point": 2, - "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다." - }, - "4": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']//CRFilter", - "type": "effect", - "media": "동영상.mp4", - "value": { - "ID": "168", - "VID102": "10", - "VID100": "0.80000001" - }, - "point": 3, - "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요" - }, - "5": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", - "ele2": "//CRCUnitArr[@Name='{search}']/@Name", - "ele3": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@Name", - "type": "video", - "value": "모래 촉감 놀이", - "search": "모래 촉감 놀이", - "point": 3 - }, - "6": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", - "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool[@Type='1']/GCUnit/@VID102", - "search": "모래 촉감 놀이", - "type": "video", - "value": "굴림체", - "point": 2 - }, - "7": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", - "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool[@Type='1']/GCUnit/@VID101", - "search": "모래 촉감 놀이", - "type": "video", - "value": "110", - "point": 2 - }, - "8": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", - "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool/GCUnit[@Type='4']/@VID100", - "search": "모래 촉감 놀이", - "type": "video", - "value": "-13778690", - "point": 2 - }, - "9": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']", - "ele2": "//CRCUnitArr[@Name='{search}']/@*[name()='VID600' or name()='VID601']", - "type": "video", - "search": "모래 촉감 놀이", - "value": [ - 0.35312501, - 0.92962962 - ], - "point": 2 - }, - "10": { - "ele": "{search}", - "search": "모래 촉감 놀이", - "type": "videoStartTime", - "value": 170, - "point": 2 - }, - "11": { - "ele": "{search}", - "search": "모래 촉감 놀이", - "type": "videoLength", - "value": 150, - "point": 2 - }, - "12": { - "existEle": "//CRClip[@Path='동영상.mp4']", - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='동영상.mp4']/preceding-sibling::*)]/@Mute", - "type": "searchIndex", - "value": "1", - "point": 2 - }, - "13": { - "existEle": "//CRClip[@Path='{image}'] | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']", - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/@Length", - "image": "이미지3.jpg", - "type": "searchIndex", - "value": "180", - "point": 2 - }, - "14": { - "type": "multi", - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]//CRFilter/@*[name()='ID' or name()='VID101']", - "image": "이미지3.jpg", - "value": [ - "184", - "5" - ], - "point": 2 - }, - "15": { - "type": "multi", - "ele": "//CRTransFilter[@ClipIndex=count(//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/preceding-sibling::CRTrackClip)][@Type='2']/@*[name()='ID' or name()='Range' or name()='Type']", - "image": "이미지3.jpg", - "value": [ - "21", - "480:540", - "2" - ], - "point": 2, - "desc": "오버랩일 경우 XPATH구문에서 Type속성값 16으로 변경, 그리고 ClipIndex값은 트랜지션이 끝나는 지점 이미지의 ClipIndex값을 가지게 되어 다음 순서의 이미지로 변경해주어야한다." - }, - "16": { - "existEle": "//CRClip[@Path='{image}'] | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']", - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/@Length", - "image": "이미지1.jpg", - "type": "searchIndex", - "value": "180", - "point": 2 - }, - "17": { - "type": "multi", - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]//CRFilter/@*[name()='ID' or name()='VID100']", - "image": "이미지1.jpg", - "value": [ - "102", - "6" - ], - "point": 2 - }, - "18": { - "type": "multi", - "ele": "//CRTransFilter[@ClipIndex=count(//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/preceding-sibling::CRTrackClip)][@Type='2']/@*[name()='ID' or name()='Range' or name()='Type']", - "image": "이미지1.jpg", - "value": [ - "9", - "690:720", - "2" - ], - "point": 2, - "desc": "오버랩일 경우 XPATH구문에서 Type속성값 16으로 변경, 그리고 ClipIndex값은 트랜지션이 끝나는 지점 이미지의 ClipIndex값을 가지게 되어 다음 순서의 이미지로 변경해주어야한다." - }, - "19": { - "existEle": "//CRClip[@Path='{image}'] | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']", - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/@Length", - "image": "이미지2.jpg", - "type": "searchIndex", - "value": "150", - "point": 2 - }, - "20": { - "type": "multi", - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]//CRFilter/@*[name()='ID' or name()='VID103']", - "image": "이미지2.jpg", - "value": [ - "67", - "7" - ], - "point": 2 - }, - "21": { - "type": "multi", - "ele": "//CRTransFilter[@ClipIndex=count(//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/preceding-sibling::CRTrackClip)][@Type='2']/@*[name()='ID' or name()='Range' or name()='Type']", - "image": "이미지2.jpg", - "value": [ - "94", - "840:870", - "2" - ], - "point": 2, - "desc": "오버랩일 경우 XPATH구문에서 Type속성값 16으로 변경, 그리고 ClipIndex값은 트랜지션이 끝나는 지점 이미지의 ClipIndex값을 가지게 되어 다음 순서의 이미지로 변경해주어야한다." - }, - "22": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@Name", - "ele2": "//CRCUnitArr[@Name='{search}']/@Name", - "type": "opening", - "search": "자연 놀이터 (Nature Playground)", - "value": "자연 놀이터 (Nature Playground)", - "point": 3 - }, - "23": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", - "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool[@Type='1']/GCUnit/@VID102", - "search": "자연 놀이터 (Nature Playground)", - "type": "opening", - "value": "바탕체", - "point": 2 - }, - "24": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", - "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool[@Type='1']/GCUnit/@VID101", - "search": "자연 놀이터 (Nature Playground)", - "type": "opening", - "value": "140", - "point": 2 - }, - "25": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", - "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool/GCUnit[@Type='4']/@VID100", - "search": "자연 놀이터 (Nature Playground)", - "type": "opening", - "value": "-12808648", - "point": 2 - }, - "26": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']/@*[name()='VID100' or name()='VID101']", - "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool/GCUnit[@Type='2']/@*[name()='VID100' or name()='VID101']", - "search": "자연 놀이터 (Nature Playground)", - "type": "opening", - "value": [ - "0.30000001", - "-13107457" - ], - "point": 2 - }, - "27": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@*[name()='VID505' or name()='VID507']", - "ele2": "//CRCUnitArr[@Name='{search}']/@*[name()='VID505' or name()='VID507']", - "search": "자연 놀이터 (Nature Playground)", - "type": "opening", - "value": [ - "14", - "2" - ], - "point": 3 - }, - "28": { - "ele": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/preceding-sibling::CRTrackClip/@Length)", - "ele2": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={textClipIndex}]/preceding-sibling::CRTrackClip/@Length)", - "search": "자연 놀이터 (Nature Playground)", - "type": "opening", - "value": 0, - "point": 2 - }, - "29": { - "ele": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/@Length", - "ele2": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={textClipIndex}]/@Length", - "search": "자연 놀이터 (Nature Playground)", - "type": "opening", - "value": "120", - "point": 2 - }, - "30": { - "ele": "//CRTrackList[@Name='오디오1'][@Count>='1']/CRTrackClip[1][not(@ClipIndex='-1')]", - "point": 2 - }, - "31": { - "ele": "//CRTrackArr/CRAudioTrackArr/CRTrackList[@Name='오디오1']/CRTrackClip[@Length='840']", - "point": 2 - }, - "32": { - "ele": "//CRTrackArr/CRAudioTrackArr/CRTrackList[@Name='오디오1']//CRFilter[@Type='2'][@ID='1'][@VID8='60']", - "point": 2 - }, - "33": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } + "ele": "none", + "point": 0 + }, + "3": { + "ele": "none", + "point": 0 }, "4": { - "1": { - "type": "multi", - "ele": "//Document/Width/@value | //Document/Height/@value", - "value": [ - "650", - "350" - ], - "point": 5, - "desc": "캔버스 사이즈 650*350" - }, - "2": { - "ele": "none", - "point": 5, - "desc": "자유 변형 문항은 채점 불가" - }, - "3": { - "type": "isExist", - "ele": "//Layer/Name/@value", - "value": "Flower", - "point": 5, - "desc": "Flower 레이어가 있는지 여부 체크" - }, - "4": { - "type": "multiValue", - "ele": "//Layer[Name[@value='{layer}']]/Effects/Item[EffectData/{option}]/Name/@value | //Layer[Name[@value='{layer}']]/Effects/Item/EffectData/{option}/@value", - "layer": "Flower", - "option": "VibranceValue", - "value": [ - "39", - "생동감" - ], - "point": 5, - "desc": "Flower 레이어의 효과 체크" - }, - "5": { - "ele": "none", - "point": 6, - "desc": "올가미 도구/이미지 문항은 채점 불가" - }, - "6": { - "type": "exists", - "ele": "//Layer/Effects/Item/Name/@value", - "value": "세피아", - "point": 6, - "desc": "세피아 효과가 있는지 여부 체크" - }, - "7": { - "type": "exact", - "ele": "//Layer/Shapes/Shape/shape_type/@value", - "value": "ELLIPSE", - "point": 3, - "desc": "레이어 쉐이프 타입이 타원인지 체크" - }, - "8": { - "type": "size", - "ele": "//Layer//op_points", - "value": { - "width": 120, - "height": 120 - }, - "point": 3, - "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" - }, - "9": { - "type": "color", - "ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value", - "value": "7097bb", - "point": 6, - "desc": "색상 코드 비교 시 소문자로 입력할 것" - }, - "10": { - "type": "multiValue", - "ele": "//Layer/BlendOp/@value | //Layer/Opacity/@value", - "value": [ - "반사", - "80" - ], - "point": 6, - "desc": "혼합모드(색 회피율, 불투명도 : 80)" - }, - "11": { - "ele": "none", - "point": 0, - "desc": "기본설정" - }, - "12": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } + "ele": "none", + "point": 0 }, "5": { - "1": { - "type": "multi", - "ele": "//Document/Width/@value | //Document/Height/@value", - "value": [ - "650", - "450" - ], - "point": 5, - "desc": "캔버스 사이즈 650*450" - }, - "2": { - "ele": "none", - "point": 5, - "desc": "배경색 문항은 채점 불가" - }, - "3": { - "type": "exists", - "ele": "//Layer/MaskOpType/@value", - "value": "Layering", - "point": 6 - }, - "4": { - "ele": "none", - "point": 6, - "desc": "가로방향 흐릿하게 문항은 채점 불가" - }, - "5": { - "type": "exists", - "ele": "//Layer//shape_type/@value", - "value": "ROUNDED_RECTANGLE", - "point": 3 - }, - "6": { - "type": "size", - "ele": "//Layer//op_points", - "value": { - "width": 400, - "height": 60 - }, - "point": 3, - "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" - }, - "7": { - "type": "gradient", - "ele": "//Layer/Shapes/Shape", - "startColor": "gradient_start_color/@value", - "endColor": "gradient_end_color/@value", - "value": { - "startColor": "ffe000", - "endColor": "34a159" - }, - "point": 6 - }, - "8": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/lines/Item/@value", - "value": "흰 꽃 사이 노란 꽃", - "point": 5 - }, - "9": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Name/@value", - "value": "맑은 고딕", - "point": 3 - }, - "10": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/{style}/@value", - "style": "Italic", - "value": "True", - "point": 3 - }, - "11": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value", - "value": "30", - "point": 3 - }, - "12": { - "type": "color", - "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value", - "value": "b46ef8", - "point": 3, - "desc": "색상 코드 비교 시 소문자로 입력할 것" - }, - "13": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value", - "value": "7", - "point": 3 - }, - "14": { - "type": "color", - "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value", - "value": "ffffff", - "point": 3, - "desc": "색상 코드 비교 시 소문자로 입력할 것" - }, - "15": { - "ele": "//Layer[MaskOpType/@value='Clipping'][last()]", - "point": 6, - "desc": "클리핑 마스크 항목은 별도 레이어로 추가되고 해당 속성을 추가해놓은 레이어가 있는지 여부 체크 함" - }, - "16": { - "type": "exists", - "ele": "//Layer/Shapes/Shape/shape_type/@value", - "value": "RECTANGLE", - "point": 3 - }, - "17": { - "type": "size", - "ele": "//Layer//op_points", - "value": { - "width": 150, - "height": 150 - }, - "point": 3, - "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" - }, - "18": { - "type": "exists", - "ele": "//Layer//outline_peninfo/Width/@value", - "value": "7", - "point": 3 - }, - "19": { - "type": "color", - "ele": "//Layer//Shape[contains(draw_type/@value, 'Outline')]/primary_color/@value", - "value": "e8e88e", - "point": 3, - "desc": "색상 코드 비교 시 소문자로 입력할 것(채우기:secondary_color, 외곽선:primary_color)" - }, - "20": { - "type": "shadow", - "ele": { - "shadow": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]", - "width": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_width/@value", - "distance": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_distance/@value", - "blur": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_blur/@value", - "angle": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_angle/@value" - }, - "value": { - "width": "3", - "distance": "5", - "blur": "1", - "angle": "320" - }, - "point": 5, - "desc": "그림자 속성이 있는 경우 그림자 속성의 너비, 거리, 흐림 정도, 각도를 비교하여 정답 채점" - }, - "21": { - "ele": "none", - "point": 0, - "desc": "기본설정" - }, - "22": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } + "ele": "none", + "point": 0 + }, + "6": { + "ele": "none", + "point": 0 + }, + "7": { + "ele": "none", + "point": 0 + }, + "8": { + "ele": "$[?(@.width == 65 && @.height == 45)]", + "type": "size", + "value": { + "width": 65, + "height": 45 + }, + "point": 4 + }, + "9": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" } -} \ No newline at end of file + }, + "1": { + "1": { + "ele": "none", + "point": 0 + }, + "2": { + "ele": "none", + "point": 0 + }, + "3": { + "ele": "none", + "point": 0 + }, + "4": { + "ele": "$.children[?(@.name=='놀이터')].name", + "value": "놀이터", + "point": 4 + }, + "5": { + "ele": "none", + "point": 0 + }, + "6": { + "ele": "$.children[?(@.name=='Forest Playground')].name", + "value": "Forest Playground", + "point": 4 + }, + "7": { + "ele": "$.children[?(@.name=='Forest Playground')].text.font.names[0]", + "type": "font", + "value": "Arial", + "point": 2 + }, + "8": { + "ele": "$.children[?(@.name=='Forest Playground')].text.font.names[0]", + "value": "Arial-BoldItalicMT", + "point": 2 + }, + "9": { + "ele": "$.children[?(@.name=='Forest Playground')].text.font.sizes[0]", + "value": 48, + "point": 2 + }, + "10": { + "ele": "$.children[?(@.name=='Forest Playground')].text.font.colors[0]", + "type": "color", + "value": "0096ff", + "point": 2 + }, + "11": { + "ele": "none", + "point": 0 + }, + "12": { + "ele": "none", + "point": 0 + }, + "13": { + "ele": "none", + "point": 0 + }, + "14": { + "ele": "$.children[?(@.name=='숲속 놀이터')].name", + "value": "숲속 놀이터", + "point": 4 + }, + "15": { + "ele": "$.children[?(@.name=='숲속 놀이터')].text.font.names[0]", + "type": "font", + "value": "GulimChe", + "point": 2, + "desc": { + "돋움체": "DotumChe", + "궁서체": "GungsuhChe", + "굴림체": "GulimChe", + "옛": "YetR" + } + }, + "16": { + "ele": "$.children[?(@.name=='숲속 놀이터')].text.font.sizes[0]", + "value": 36, + "point": 2 + }, + "17": { + "ele": "$.children[?(@.name=='숲속 놀이터')].text.font.colors[0]", + "type": "color", + "value": "0c3f00", + "point": 2 + }, + "18": { + "ele": "none", + "point": 0 + }, + "19": { + "ele": "none", + "point": 0 + }, + "20": { + "ele": "none", + "point": 0 + }, + "21": { + "ele": "none", + "point": 0 + }, + "22": { + "ele": "$.children[?(@.name=='바람개비')].name", + "value": "바람개비", + "point": 4 + }, + "23": { + "ele": "none", + "point": 0 + }, + "24": { + "ele": "none", + "point": 0 + }, + "25": { + "ele": "none", + "point": 0 + }, + "26": { + "ele": "$[?(@.width == 65 && @.height == 35)]", + "type": "size", + "value": { + "width": 65, + "height": 35 + }, + "point": 5 + }, + "27": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "2": { + "desc": "videoStartTime 항목은 동영상파일>자막>시작시간 문항의 정답을 작성", + "videoStartTime": 170, + "openingStartTime": 0, + "1": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex", + "type": "mediaOrder", + "value": ["동영상.mp4", "이미지3.jpg", "이미지1.jpg", "이미지2.jpg"], + "point": 4, + "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다." + }, + "2": { + "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed", + "type": "oneAnswer", + "value": { + "speed": "130" + }, + "point": 2, + "desc": "100당 1배속 / 130 = 1.3배속" + }, + "3": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']", + "type": "startEnd", + "media": "동영상.mp4", + "value": { + "start": "0", + "end": "360" + }, + "point": 2, + "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다." + }, + "4": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']//CRFilter", + "type": "effect", + "media": "동영상.mp4", + "value": { + "ID": "168", + "VID102": "10", + "VID100": "0.80000001" + }, + "point": 3, + "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요" + }, + "5": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", + "ele2": "//CRCUnitArr[@Name='{search}']/@Name", + "ele3": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@Name", + "type": "video", + "value": "모래 촉감 놀이", + "search": "모래 촉감 놀이", + "point": 3 + }, + "6": { + "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", + "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool[@Type='1']/GCUnit/@VID102", + "search": "모래 촉감 놀이", + "type": "video", + "value": "굴림체", + "point": 2 + }, + "7": { + "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", + "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool[@Type='1']/GCUnit/@VID101", + "search": "모래 촉감 놀이", + "type": "video", + "value": "110", + "point": 2 + }, + "8": { + "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", + "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool/GCUnit[@Type='4']/@VID100", + "search": "모래 촉감 놀이", + "type": "video", + "value": "-13778690", + "point": 2 + }, + "9": { + "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']", + "ele2": "//CRCUnitArr[@Name='{search}']/@*[name()='VID600' or name()='VID601']", + "type": "video", + "search": "모래 촉감 놀이", + "value": [0.35312501, 0.92962962], + "point": 2 + }, + "10": { + "ele": "{search}", + "search": "모래 촉감 놀이", + "type": "videoStartTime", + "value": 170, + "point": 2 + }, + "11": { + "ele": "{search}", + "search": "모래 촉감 놀이", + "type": "videoLength", + "value": 150, + "point": 2 + }, + "12": { + "existEle": "//CRClip[@Path='동영상.mp4']", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='동영상.mp4']/preceding-sibling::*)]/@Mute", + "type": "searchIndex", + "value": "1", + "point": 2 + }, + "13": { + "existEle": "//CRClip[@Path='{image}'] | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/@Length", + "image": "이미지3.jpg", + "type": "searchIndex", + "value": "180", + "point": 2 + }, + "14": { + "type": "multi", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]//CRFilter/@*[name()='ID' or name()='VID101']", + "image": "이미지3.jpg", + "value": ["184", "5"], + "point": 2 + }, + "15": { + "type": "multi", + "ele": "//CRTransFilter[@ClipIndex=count(//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/preceding-sibling::CRTrackClip)][@Type='2']/@*[name()='ID' or name()='Range' or name()='Type']", + "image": "이미지3.jpg", + "value": ["21", "480:540", "2"], + "point": 2, + "desc": "오버랩일 경우 XPATH구문에서 Type속성값 16으로 변경, 그리고 ClipIndex값은 트랜지션이 끝나는 지점 이미지의 ClipIndex값을 가지게 되어 다음 순서의 이미지로 변경해주어야한다." + }, + "16": { + "existEle": "//CRClip[@Path='{image}'] | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/@Length", + "image": "이미지1.jpg", + "type": "searchIndex", + "value": "180", + "point": 2 + }, + "17": { + "type": "multi", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]//CRFilter/@*[name()='ID' or name()='VID100']", + "image": "이미지1.jpg", + "value": ["102", "6"], + "point": 2 + }, + "18": { + "type": "multi", + "ele": "//CRTransFilter[@ClipIndex=count(//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/preceding-sibling::CRTrackClip)][@Type='2']/@*[name()='ID' or name()='Range' or name()='Type']", + "image": "이미지1.jpg", + "value": ["9", "690:720", "2"], + "point": 2, + "desc": "오버랩일 경우 XPATH구문에서 Type속성값 16으로 변경, 그리고 ClipIndex값은 트랜지션이 끝나는 지점 이미지의 ClipIndex값을 가지게 되어 다음 순서의 이미지로 변경해주어야한다." + }, + "19": { + "existEle": "//CRClip[@Path='{image}'] | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/@Length", + "image": "이미지2.jpg", + "type": "searchIndex", + "value": "150", + "point": 2 + }, + "20": { + "type": "multi", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]//CRFilter/@*[name()='ID' or name()='VID103']", + "image": "이미지2.jpg", + "value": ["67", "7"], + "point": 2 + }, + "21": { + "type": "multi", + "ele": "//CRTransFilter[@ClipIndex=count(//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='{image}']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='{image}']/../preceding-sibling::CRClip)][1]/preceding-sibling::CRTrackClip)][@Type='2']/@*[name()='ID' or name()='Range' or name()='Type']", + "image": "이미지2.jpg", + "value": ["94", "840:870", "2"], + "point": 2, + "desc": "오버랩일 경우 XPATH구문에서 Type속성값 16으로 변경, 그리고 ClipIndex값은 트랜지션이 끝나는 지점 이미지의 ClipIndex값을 가지게 되어 다음 순서의 이미지로 변경해주어야한다." + }, + "22": { + "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@Name", + "ele2": "//CRCUnitArr[@Name='{search}']/@Name", + "type": "opening", + "search": "자연 놀이터 (Nature Playground)", + "value": "자연 놀이터 (Nature Playground)", + "point": 3 + }, + "23": { + "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", + "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool[@Type='1']/GCUnit/@VID102", + "search": "자연 놀이터 (Nature Playground)", + "type": "opening", + "value": "바탕체", + "point": 2 + }, + "24": { + "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", + "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool[@Type='1']/GCUnit/@VID101", + "search": "자연 놀이터 (Nature Playground)", + "type": "opening", + "value": "140", + "point": 2 + }, + "25": { + "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", + "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool/GCUnit[@Type='4']/@VID100", + "search": "자연 놀이터 (Nature Playground)", + "type": "opening", + "value": "-12808648", + "point": 2 + }, + "26": { + "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']/@*[name()='VID100' or name()='VID101']", + "ele2": "//CRCUnitArr[@Name='{search}']//GCUnitPool/GCUnit[@Type='2']/@*[name()='VID100' or name()='VID101']", + "search": "자연 놀이터 (Nature Playground)", + "type": "opening", + "value": ["0.30000001", "-13107457"], + "point": 2 + }, + "27": { + "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@*[name()='VID505' or name()='VID507']", + "ele2": "//CRCUnitArr[@Name='{search}']/@*[name()='VID505' or name()='VID507']", + "search": "자연 놀이터 (Nature Playground)", + "type": "opening", + "value": ["14", "2"], + "point": 3 + }, + "28": { + "ele": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/preceding-sibling::CRTrackClip/@Length)", + "ele2": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={textClipIndex}]/preceding-sibling::CRTrackClip/@Length)", + "search": "자연 놀이터 (Nature Playground)", + "type": "opening", + "value": 0, + "point": 2 + }, + "29": { + "ele": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/@Length", + "ele2": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={textClipIndex}]/@Length", + "search": "자연 놀이터 (Nature Playground)", + "type": "opening", + "value": "120", + "point": 2 + }, + "30": { + "ele": "//CRTrackList[@Name='오디오1'][@Count>='1']/CRTrackClip[1][not(@ClipIndex='-1')]", + "point": 2 + }, + "31": { + "ele": "//CRTrackArr/CRAudioTrackArr/CRTrackList[@Name='오디오1']/CRTrackClip[@Length='840']", + "point": 2 + }, + "32": { + "ele": "//CRTrackArr/CRAudioTrackArr/CRTrackList[@Name='오디오1']//CRFilter[@Type='2'][@ID='1'][@VID8='60']", + "point": 2 + }, + "33": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "4": { + "1": { + "type": "multi", + "ele": "//Document/Width/@value | //Document/Height/@value", + "value": ["650", "350"], + "point": 5, + "desc": "캔버스 사이즈 650*350" + }, + "2": { + "ele": "none", + "point": 5, + "desc": "자유 변형 문항은 채점 불가" + }, + "3": { + "type": "isExist", + "ele": "//Layer/Name/@value", + "value": "Flower", + "point": 5, + "desc": "Flower 레이어가 있는지 여부 체크" + }, + "4": { + "type": "multiValue", + "ele": "//Layer[Name[@value='{layer}']]/Effects/Item[EffectData/{option}]/Name/@value | //Layer[Name[@value='{layer}']]/Effects/Item/EffectData/{option}/@value", + "layer": "Flower", + "option": "VibranceValue", + "value": ["39", "생동감"], + "point": 5, + "desc": "Flower 레이어의 효과 체크" + }, + "5": { + "ele": "none", + "point": 6, + "desc": "올가미 도구/이미지 문항은 채점 불가" + }, + "6": { + "type": "exists", + "ele": "//Layer/Effects/Item/Name/@value", + "value": "세피아", + "point": 6, + "desc": "세피아 효과가 있는지 여부 체크" + }, + "7": { + "type": "exact", + "ele": "//Layer/Shapes/Shape/shape_type/@value", + "value": "ELLIPSE", + "point": 3, + "desc": "레이어 쉐이프 타입이 타원인지 체크" + }, + "8": { + "type": "size", + "ele": "//Layer//op_points", + "value": { + "width": 120, + "height": 120 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "9": { + "type": "color", + "ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value", + "value": "7097bb", + "point": 6, + "desc": "색상 코드 비교 시 소문자로 입력할 것" + }, + "10": { + "type": "multiValue", + "ele": "//Layer/BlendOp/@value | //Layer/Opacity/@value", + "value": ["반사", "80"], + "point": 6, + "desc": "혼합모드(색 회피율, 불투명도 : 80)" + }, + "11": { + "ele": "none", + "point": 0, + "desc": "기본설정" + }, + "12": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "5": { + "1": { + "type": "multi", + "ele": "//Document/Width/@value | //Document/Height/@value", + "value": ["650", "450"], + "point": 5, + "desc": "캔버스 사이즈 650*450" + }, + "2": { + "ele": "none", + "point": 5, + "desc": "배경색 문항은 채점 불가" + }, + "3": { + "type": "exists", + "ele": "//Layer/MaskOpType/@value", + "value": "Layering", + "point": 6 + }, + "4": { + "ele": "none", + "point": 6, + "desc": "가로방향 흐릿하게 문항은 채점 불가" + }, + "5": { + "type": "exists", + "ele": "//Layer//shape_type/@value", + "value": "ROUNDED_RECTANGLE", + "point": 3 + }, + "6": { + "type": "size", + "ele": "//Layer//op_points", + "value": { + "width": 400, + "height": 60 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "7": { + "type": "gradient", + "ele": "//Layer/Shapes/Shape", + "startColor": "gradient_start_color/@value", + "endColor": "gradient_end_color/@value", + "value": { + "startColor": "ffe000", + "endColor": "34a159" + }, + "point": 6 + }, + "8": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/lines/Item/@value", + "value": "흰 꽃 사이 노란 꽃", + "point": 5 + }, + "9": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Name/@value", + "value": "맑은 고딕", + "point": 3 + }, + "10": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/{style}/@value", + "style": "Italic", + "value": "True", + "point": 3 + }, + "11": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value", + "value": "30", + "point": 3 + }, + "12": { + "type": "color", + "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value", + "value": "b46ef8", + "point": 3, + "desc": "색상 코드 비교 시 소문자로 입력할 것" + }, + "13": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value", + "value": "7", + "point": 3 + }, + "14": { + "type": "color", + "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value", + "value": "ffffff", + "point": 3, + "desc": "색상 코드 비교 시 소문자로 입력할 것" + }, + "15": { + "ele": "//Layer[MaskOpType/@value='Clipping'][last()]", + "point": 6, + "desc": "클리핑 마스크 항목은 별도 레이어로 추가되고 해당 속성을 추가해놓은 레이어가 있는지 여부 체크 함" + }, + "16": { + "type": "exists", + "ele": "//Layer/Shapes/Shape/shape_type/@value", + "value": "RECTANGLE", + "point": 3 + }, + "17": { + "type": "size", + "ele": "//Layer//op_points", + "value": { + "width": 150, + "height": 150 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "18": { + "type": "exists", + "ele": "//Layer//outline_peninfo/Width/@value", + "value": "7", + "point": 3 + }, + "19": { + "type": "color", + "ele": "//Layer//Shape[contains(draw_type/@value, 'Outline')]/primary_color/@value", + "value": "e8e88e", + "point": 3, + "desc": "색상 코드 비교 시 소문자로 입력할 것(채우기:secondary_color, 외곽선:primary_color)" + }, + "20": { + "type": "shadow", + "ele": { + "shadow": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]", + "width": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_width/@value", + "distance": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_distance/@value", + "blur": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_blur/@value", + "angle": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_angle/@value" + }, + "value": { + "width": "3", + "distance": "5", + "blur": "1", + "angle": "320" + }, + "point": 5, + "desc": "그림자 속성이 있는 경우 그림자 속성의 너비, 거리, 흐림 정도, 각도를 비교하여 정답 채점" + }, + "21": { + "ele": "none", + "point": 0, + "desc": "기본설정" + }, + "22": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + } +} diff --git a/DIC_2505B copy.json b/DIC_2505B copy.json deleted file mode 100644 index 9095736..0000000 --- a/DIC_2505B copy.json +++ /dev/null @@ -1,729 +0,0 @@ -{ - "0": { - "1": { - "ele": "none", - "point": 0 - }, - "2": { - "ele": "none", - "point": 0 - }, - "3": { - "ele": "none", - "point": 0 - }, - "4": { - "ele": "none", - "point": 0 - }, - "5": { - "ele": "none", - "point": 0 - }, - "6": { - "ele": "none", - "point": 0 - }, - "7": { - "ele": "none", - "point": 0 - }, - "8": { - "ele": "$[?(@.width == 65 && @.height == 45)]", - "type": "size", - "value": { - "width": 65, - "height": 45 - }, - "point": 4 - }, - "9": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } - }, - "1": { - "1": { - "ele": "none", - "point": 0 - }, - "2": { - "ele": "none", - "point": 0 - }, - "3": { - "ele": "none", - "point": 0 - }, - "4": { - "ele": "$.children[?(@.name=='한옥')].name", - "value": "한옥", - "point": 4 - }, - "5": { - "ele": "none", - "point": 0 - }, - "6": { - "ele": "$.children[?(@.name=='Traditional Park')].name", - "value": "Traditional Park", - "point": 4 - }, - "7": { - "ele": "$.children[?(@.name=='Traditional Park')].text.font.names[0]", - "type": "font", - "value": "Arial", - "point": 2 - }, - "8": { - "ele": "$.children[?(@.name=='Traditional Park')].text.font.names[0]", - "value": "Arial-BoldItalicMT", - "point": 2 - }, - "9": { - "ele": "$.children[?(@.name=='Traditional Park')].text.font.sizes[0]", - "value": 48, - "point": 2 - }, - "10": { - "ele": "$.children[?(@.name=='Traditional Park')].text.font.colors[0]", - "type": "color", - "value": "017e86", - "point": 2 - }, - "11": { - "ele": "none", - "point": 0 - }, - "12": { - "ele": "none", - "point": 0 - }, - "13": { - "ele": "none", - "point": 0 - }, - "14": { - "ele": "$.children[?(@.name=='전통 문화 공원')].name", - "value": "전통 문화 공원", - "point": 4 - }, - "15": { - "ele": "$.children[?(@.name=='전통 문화 공원')].text.font.names[0]", - "type": "font", - "value": "GungsuhChe", - "point": 2, - "desc": { - "돋움체": "DotumChe", - "궁서체": "GungsuhChe", - "굴림체": "GulimChe", - "휴먼옛체": "YetR" - } - }, - "16": { - "ele": "$.children[?(@.name=='전통 문화 공원')].text.font.sizes[0]", - "value": 36, - "point": 2 - }, - "17": { - "ele": "$.children[?(@.name=='전통 문화 공원')].text.font.colors[0]", - "type": "color", - "value": "ffeeca", - "point": 2 - }, - "18": { - "ele": "none", - "point": 0 - }, - "19": { - "ele": "none", - "point": 0 - }, - "20": { - "ele": "none", - "point": 0 - }, - "21": { - "ele": "none", - "point": 0 - }, - "22": { - "ele": "$.children[?(@.name=='맷돌')].name", - "value": "맷돌", - "point": 4 - }, - "23": { - "ele": "none", - "point": 0 - }, - "24": { - "ele": "none", - "point": 0 - }, - "25": { - "ele": "none", - "point": 0 - }, - "26": { - "ele": "$[?(@.width == 65 && @.height == 35)]", - "type": "size", - "value": { - "width": 65, - "height": 35 - }, - "point": 5 - }, - "27": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } - }, - "2": { - "1": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex", - "type": "mediaOrder", - "value": [ - "동영상.mp4", - "이미지2.jpg", - "이미지3.jpg", - "이미지1.jpg" - ], - "point": 4, - "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다." - }, - "2": { - "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed", - "type": "oneAnswer", - "value": { - "speed": "120" - }, - "point": 2, - "desc": "100당 1배속 / 130 = 1.3배속" - }, - "3": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']", - "type": "startEnd", - "media": "동영상.mp4", - "value": { - "start": "0", - "end": "380" - }, - "point": 2, - "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다." - }, - "4": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", - "type": "effect", - "media": "동영상.mp4", - "value": { - "ID": "70", - "VID100": "30", - "VID101": "20" - }, - "point": 3, - "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요" - }, - "5": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", - "search": "청량하고 시원한 폭포", - "type": "video.Text", - "value": "청량하고 시원한 폭포", - "point": 3 - }, - "6": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", - "search": "청량하고 시원한 폭포", - "type": "video.Text", - "value": "돋움체", - "point": 2 - }, - "7": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", - "search": "청량하고 시원한 폭포", - "type": "video.Text", - "value": "120", - "point": 2 - }, - "8": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", - "search": "청량하고 시원한 폭포", - "type": "video.Text.Color", - "value": "1db0f1", - "point": 2, - "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" - }, - "9": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']", - "search": "청량하고 시원한 폭포", - "type": "video.Location", - "value": [ - "0.27395833", - "0.9222222" - ], - "point": 2, - "desc": "정답 파일의 자막 좌표를 기준으로 프로그램 내부적으로 0.1까지 오차를 허용한다" - }, - "10": { - "ele": "", - "search": "청량하고 시원한 폭포", - "type": "video.StartTime", - "value": 170, - "point": 2, - "desc": "내부적으로 자막의 시작시간과 길이를 계산" - }, - "11": { - "ele": "", - "search": "청량하고 시원한 폭포", - "type": "video.Length", - "value": 150, - "point": 2, - "desc": "내부적으로 자막의 시작시간과 길이를 계산" - }, - "12": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Mute", - "type": "Mute", - "media": "동영상.mp4", - "value": "1", - "point": 2 - }, - "13": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", - "type": "imageLength", - "media": "이미지2.jpg", - "value": "150", - "point": 2 - }, - "14": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", - "type": "imageOverlay", - "media": "이미지2.jpg", - "value": { - "ID": "103", - "VID102": "7" - }, - "point": 2 - }, - "15": { - "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", - "type": "clipTransition", - "media": "이미지2.jpg", - "value": { - "ID": "11", - "Range": "500:530", - "Type": "2" - }, - "point": 2, - "desc": "오버랩일 경우 Type속성값 16으로 변경" - }, - "16": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", - "type": "imageLength", - "media": "이미지3.jpg", - "value": "150", - "point": 2 - }, - "17": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", - "type": "imageOverlay", - "media": "이미지3.jpg", - "value": { - "ID": "184", - "VID102": "30" - }, - "point": 2 - }, - "18": { - "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", - "type": "clipTransition", - "media": "이미지3.jpg", - "value": { - "ID": "19", - "Range": "650:680", - "Type": "2" - }, - "point": 2, - "desc": "오버랩일 경우 Type속성값 16으로 변경" - }, - "19": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", - "type": "imageLength", - "media": "이미지1.jpg", - "value": "180", - "point": 2 - }, - "20": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", - "type": "imageOverlay", - "media": "이미지1.jpg", - "value": { - "ID": "67", - "VID102": "30" - }, - "point": 2 - }, - "21": { - "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", - "type": "clipTransition", - "media": "이미지1.jpg", - "value": { - "ID": "10", - "Range": "800:860", - "Type": "2" - }, - "point": 2, - "desc": "오버랩일 경우 Type속성값 16으로 변경" - }, - "22": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", - "search": "전통 공원 (Traditional Park)", - "type": "video.Text", - "value": "전통 공원 (Traditional Park)", - "point": 3 - }, - "23": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", - "search": "전통 공원 (Traditional Park)", - "type": "video.Text", - "value": "궁서체", - "point": 2 - }, - "24": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", - "search": "전통 공원 (Traditional Park)", - "type": "video.Text", - "value": "140", - "point": 2 - }, - "25": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", - "search": "전통 공원 (Traditional Park)", - "type": "video.Text.Color", - "value": "fd5721", - "point": 2, - "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" - }, - "26": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']", - "search": "전통 공원 (Traditional Park)", - "type": "video.Text.Outline", - "value": { - "width": "30", - "color": "fff9c4" - }, - "point": 2, - "desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성" - }, - "27": { - "ele": "//CROwneUnit[{index}]/CRCUnitArr", - "search": "전통 공원 (Traditional Park)", - "type": "opening.Text.FadeInEffect", - "value": { - "ID": "4", - "PlayTime": "2" - }, - "point": 3, - "desc": "오프닝자막의 나타나기 효과를 확인하는 문항. id속성은 VID505, playtime속성은 VID507으로 XML 내부에 표기되어 있다." - }, - "28": { - "ele": "", - "search": "전통 공원 (Traditional Park)", - "type": "opening.StartTime", - "value": 0, - "point": 2, - "desc": "오프닝자막의 시작시간 value 속성만 수정" - }, - "29": { - "ele": "", - "search": "전통 공원 (Traditional Park)", - "type": "opening.Length", - "value": 120, - "point": 2 - }, - "30": { - "ele": "", - "type": "audio.StartTime", - "media": "음악.mp3", - "value": 0, - "point": 2 - }, - "31": { - "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']", - "type": "audio.EndTime", - "media": "음악.mp3", - "value": 810, - "point": 2 - }, - "32": { - "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", - "type": "audio.Effect", - "media": "음악.mp3", - "value": { - "ID": "1", - "PlayTime": "90" - }, - "point": 2, - "desc": "ID속성-페이드인:0 / 페이드아웃:1" - }, - "33": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } - }, - "4": { - "1": { - "type": "multi", - "ele": "//Document/Width/@value | //Document/Height/@value", - "value": [ - "650", - "350" - ], - "point": 5, - "desc": "캔버스 사이즈 650*350" - }, - "2": { - "ele": "none", - "point": 5, - "desc": "자유 변형 문항은 채점 불가" - }, - "3": { - "type": "isExist", - "ele": "//Layer/Name/@value", - "value": "Flower", - "point": 5, - "desc": "Flower 레이어가 있는지 여부 체크" - }, - "4": { - "type": "multiValue", - "ele": "//Layer[Name[@value='{layer}']]/Effects/Item[EffectData/{option}]/Name/@value | //Layer[Name[@value='{layer}']]/Effects/Item/EffectData/{option}/@value", - "layer": "Flower", - "option": "VibranceValue", - "value": [ - "39", - "생동감" - ], - "point": 5, - "desc": "Flower 레이어의 효과 체크" - }, - "5": { - "ele": "none", - "point": 6, - "desc": "올가미 도구/이미지 문항은 채점 불가" - }, - "6": { - "type": "exists", - "ele": "//Layer/Effects/Item/Name/@value", - "value": "세피아", - "point": 6, - "desc": "세피아 효과가 있는지 여부 체크" - }, - "7": { - "type": "exact", - "ele": "//Layer/Shapes/Shape/shape_type/@value", - "value": "ELLIPSE", - "point": 3, - "desc": "레이어 쉐이프 타입이 타원인지 체크" - }, - "8": { - "type": "size", - "ele": "//Layer//op_points", - "value": { - "width": 120, - "height": 120 - }, - "point": 3, - "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" - }, - "9": { - "type": "color", - "ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value", - "value": "7097bb", - "point": 6, - "desc": "색상 코드 비교 시 소문자로 입력할 것" - }, - "10": { - "type": "multiValue", - "ele": "//Layer/BlendOp/@value | //Layer/Opacity/@value", - "value": [ - "반사", - "80" - ], - "point": 6, - "desc": "혼합모드(색 회피율, 불투명도 : 80)" - }, - "11": { - "ele": "none", - "point": 0, - "desc": "기본설정" - }, - "12": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } - }, - "5": { - "1": { - "type": "multi", - "ele": "//Document/Width/@value | //Document/Height/@value", - "value": [ - "650", - "450" - ], - "point": 5, - "desc": "캔버스 사이즈 650*450" - }, - "2": { - "ele": "none", - "point": 5, - "desc": "배경색 문항은 채점 불가" - }, - "3": { - "type": "exists", - "ele": "//Layer/MaskOpType/@value", - "value": "Layering", - "point": 6 - }, - "4": { - "ele": "none", - "point": 6, - "desc": "가로방향 흐릿하게 문항은 채점 불가" - }, - "5": { - "type": "exists", - "ele": "//Layer//shape_type/@value", - "value": "ROUNDED_RECTANGLE", - "point": 3 - }, - "6": { - "type": "size", - "ele": "//Layer//op_points", - "value": { - "width": 400, - "height": 60 - }, - "point": 3, - "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" - }, - "7": { - "type": "gradient", - "ele": "//Layer/Shapes/Shape", - "startColor": "gradient_start_color/@value", - "endColor": "gradient_end_color/@value", - "value": { - "startColor": "ffe000", - "endColor": "34a159" - }, - "point": 6 - }, - "8": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/lines/Item/@value", - "value": "흰 꽃 사이 노란 꽃", - "point": 5 - }, - "9": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Name/@value", - "value": "맑은 고딕", - "point": 3 - }, - "10": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/{style}/@value", - "style": "Italic", - "value": "True", - "point": 3 - }, - "11": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value", - "value": "30", - "point": 3 - }, - "12": { - "type": "color", - "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value", - "value": "b46ef8", - "point": 3, - "desc": "색상 코드 비교 시 소문자로 입력할 것" - }, - "13": { - "type": "exists", - "ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value", - "value": "7", - "point": 3 - }, - "14": { - "type": "color", - "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value", - "value": "ffffff", - "point": 3, - "desc": "색상 코드 비교 시 소문자로 입력할 것" - }, - "15": { - "ele": "//Layer[MaskOpType/@value='Clipping'][last()]", - "point": 6, - "desc": "클리핑 마스크 항목은 별도 레이어로 추가되고 해당 속성을 추가해놓은 레이어가 있는지 여부 체크 함" - }, - "16": { - "type": "exists", - "ele": "//Layer/Shapes/Shape/shape_type/@value", - "value": "RECTANGLE", - "point": 3 - }, - "17": { - "type": "size", - "ele": "//Layer//op_points", - "value": { - "width": 150, - "height": 150 - }, - "point": 3, - "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" - }, - "18": { - "type": "exists", - "ele": "//Layer//outline_peninfo/Width/@value", - "value": "7", - "point": 3 - }, - "19": { - "type": "color", - "ele": "//Layer//Shape[contains(draw_type/@value, 'Outline')]/primary_color/@value", - "value": "e8e88e", - "point": 3, - "desc": "색상 코드 비교 시 소문자로 입력할 것(채우기:secondary_color, 외곽선:primary_color)" - }, - "20": { - "type": "shadow", - "ele": { - "shadow": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]", - "width": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_width/@value", - "distance": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_distance/@value", - "blur": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_blur/@value", - "angle": "//Layer//Shape[contains(draw_type/@value, 'Shadow')]/shadow_angle/@value" - }, - "value": { - "width": "3", - "distance": "5", - "blur": "1", - "angle": "320" - }, - "point": 5, - "desc": "그림자 속성이 있는 경우 그림자 속성의 너비, 거리, 흐림 정도, 각도를 비교하여 정답 채점" - }, - "21": { - "ele": "none", - "point": 0, - "desc": "기본설정" - }, - "22": { - "ele": "none", - "point": 0, - "desc": "파일명 확인" - } - } -} \ No newline at end of file diff --git a/DIC_2505B.json b/DIC_2505B.json index b457875..f2d8dfb 100644 --- a/DIC_2505B.json +++ b/DIC_2505B.json @@ -501,7 +501,7 @@ "layer": "Flower", "option": "VibranceValue", "value": [ - "39", + "40", "생동감" ], "point": 5, diff --git a/DIC_곰픽채점기준표.json b/DIC_곰픽채점기준표.json new file mode 100644 index 0000000..58030f2 --- /dev/null +++ b/DIC_곰픽채점기준표.json @@ -0,0 +1,737 @@ +{ + "0": { + "1": { + "ele": "none", + "point": 0 + }, + "2": { + "ele": "none", + "point": 0 + }, + "3": { + "ele": "none", + "point": 0 + }, + "4": { + "ele": "none", + "point": 0 + }, + "5": { + "ele": "none", + "point": 0 + }, + "6": { + "ele": "none", + "point": 0 + }, + "7": { + "ele": "none", + "point": 0 + }, + "8": { + "ele": "$[?(@.width == 65 && @.height == 45)]", + "type": "size", + "value": { + "width": 65, + "height": 45 + }, + "point": 4 + }, + "9": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "1": { + "1": { + "ele": "none", + "point": 0 + }, + "2": { + "ele": "none", + "point": 0 + }, + "3": { + "ele": "none", + "point": 0 + }, + "4": { + "ele": "$.children[?(@.name=='꽃잎들')].name", + "value": "꽃잎들", + "point": 4 + }, + "5": { + "ele": "none", + "point": 0 + }, + "6": { + "ele": "$.children[?(@.name=='Flower Rock')].name", + "value": "Flower Rock", + "point": 4 + }, + "7": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.names[0]", + "type": "font", + "value": "Arial", + "point": 2 + }, + "8": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.names[0]", + "value": "Arial-BoldItalicMT", + "point": 2 + }, + "9": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.sizes[0]", + "value": 48, + "point": 2 + }, + "10": { + "ele": "$.children[?(@.name=='Flower Rock')].text.font.colors[0]", + "type": "color", + "value": "d6f592", + "point": 2 + }, + "11": { + "ele": "none", + "point": 0 + }, + "12": { + "ele": "none", + "point": 0 + }, + "13": { + "ele": "none", + "point": 0 + }, + "14": { + "ele": "$.children[?(@.name=='꽃과 바위')].name", + "value": "꽃과 바위", + "point": 4 + }, + "15": { + "ele": "$.children[?(@.name=='꽃과 바위')].text.font.names[0]", + "type": "font", + "value": "GungsuhChe", + "point": 2, + "desc": { + "돋움체": "DotumChe", + "궁서체": "GungsuhChe", + "굴림체": "GulimChe", + "휴먼옛체": "YetR" + } + }, + "16": { + "ele": "$.children[?(@.name=='꽃과 바위')].text.font.sizes[0]", + "value": 36, + "point": 2 + }, + "17": { + "ele": "$.children[?(@.name=='꽃과 바위')].text.font.colors[0]", + "type": "color", + "value": "0d17d5", + "point": 2 + }, + "18": { + "ele": "none", + "point": 0 + }, + "19": { + "ele": "none", + "point": 0 + }, + "20": { + "ele": "none", + "point": 0 + }, + "21": { + "ele": "none", + "point": 0 + }, + "22": { + "ele": "$.children[?(@.name=='노랑꽃')].name", + "value": "노랑꽃", + "point": 4 + }, + "23": { + "ele": "none", + "point": 0 + }, + "24": { + "ele": "none", + "point": 0 + }, + "25": { + "ele": "none", + "point": 0 + }, + "26": { + "ele": "$[?(@.width == 65 && @.height == 35)]", + "type": "size", + "value": { + "width": 65, + "height": 35 + }, + "point": 5 + }, + "27": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "2": { + "1": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex", + "type": "mediaOrder", + "value": ["동영상.mp4", "이미지3.jpg", "이미지1.jpg", "이미지2.jpg"], + "point": 4, + "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다." + }, + "2": { + "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed", + "type": "oneAnswer", + "value": { + "speed": "140" + }, + "point": 2, + "desc": "100당 1배속 / 130 = 1.3배속" + }, + "3": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']", + "type": "startEnd", + "media": "동영상.mp4", + "value": { + "start": "0", + "end": "370" + }, + "point": 2, + "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다." + }, + "4": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "effect", + "media": "동영상.mp4", + "value": { + "ID": "44", + "VID100": "8", + "VID103": "0.89999998" + }, + "point": 3, + "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요" + }, + "5": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", + "search": "화단의 꽃들", + "type": "video.Text", + "value": "화단의 꽃들", + "point": 3 + }, + "6": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", + "search": "화단의 꽃들", + "type": "video.Text", + "value": "돋움체", + "point": 2 + }, + "7": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", + "search": "화단의 꽃들", + "type": "video.Text", + "value": "110", + "point": 2 + }, + "8": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", + "search": "화단의 꽃들", + "type": "video.Text.Color", + "value": "ff531b", + "point": 2, + "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" + }, + "9": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@*[name()='VID600' or name()='VID601']", + "search": "화단의 꽃들", + "type": "video.Location", + "value": ["0.38333333", "0.92962962"], + "point": 2, + "desc": "정답 파일의 자막 좌표를 기준으로 프로그램 내부적으로 0.1까지 오차를 허용한다" + }, + "10": { + "ele": "", + "search": "화단의 꽃들", + "type": "video.StartTime", + "value": 170, + "point": 2, + "desc": "내부적으로 자막의 시작시간과 길이를 계산" + }, + "11": { + "ele": "", + "search": "화단의 꽃들", + "type": "video.Length", + "value": 150, + "point": 2, + "desc": "내부적으로 자막의 시작시간과 길이를 계산" + }, + "12": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Mute", + "type": "Mute", + "media": "동영상.mp4", + "value": "1", + "point": 2 + }, + "13": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", + "type": "imageLength", + "media": "이미지3.jpg", + "value": "180", + "point": 2 + }, + "14": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "imageOverlay", + "media": "이미지3.jpg", + "value": { + "ID": "67", + "VID102": "40" + }, + "point": 2, + "desc": "오버레이 속성 키값(VID10X) 확인하고 변경" + }, + "15": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지3.jpg", + "value": { + "ID": "10", + "Range": "490:550", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "16": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", + "type": "imageLength", + "media": "이미지1.jpg", + "value": "180", + "point": 2 + }, + "17": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "imageOverlay", + "media": "이미지1.jpg", + "value": { + "ID": "103", + "VID102": "7" + }, + "point": 2, + "desc": "오버레이 속성 키값(VID10X) 확인하고 변경" + }, + "18": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지1.jpg", + "value": { + "ID": "12", + "Range": "670:730", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "19": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']/@Length", + "type": "imageLength", + "media": "이미지2.jpg", + "value": "150", + "point": 2 + }, + "20": { + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "imageOverlay", + "media": "이미지2.jpg", + "value": { + "ID": "102", + "VID101": "3" + }, + "point": 2, + "desc": "오버레이 속성 키값(VID10X) 확인하고 변경" + }, + "21": { + "ele": "//CRTransFilter[@ClipIndex='{CRTrackClipIndex}']", + "type": "clipTransition", + "media": "이미지2.jpg", + "value": { + "ID": "0", + "Range": "850:880", + "Type": "2" + }, + "point": 2, + "desc": "오버랩일 경우 Type속성값 16으로 변경" + }, + "22": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr/@Name", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text", + "value": "아름다운 꽃 축제 (Happy Flower Festival)", + "point": 3 + }, + "23": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID102", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text", + "value": "궁서체", + "point": 2 + }, + "24": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool[@Type='1']/GCUnit/@VID101", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text", + "value": "140", + "point": 2 + }, + "25": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='4']/@VID100", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text.Color", + "value": "ec008c", + "point": 2, + "desc": "컬러값은 RGB로 입력한다, [대소문자, #]허용 (#FFFFFF, ffffff 두 값 모두 허용)" + }, + "26": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr//GCUnitPool/GCUnit[@Type='2']", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "video.Text.Outline", + "value": { + "width": "40", + "color": "fff9c4" + }, + "point": 2, + "desc": "두께는 XML에서는 소수점으로 표기되지만, 프로그램 내부적으로 변환하여 사용하므로 현재 파일에서는 정수로 작성" + }, + "27": { + "ele": "//CROwneUnit[{index}]/CRCUnitArr", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "opening.Text.FadeInEffect", + "value": { + "ID": "14", + "PlayTime": "2" + }, + "point": 3, + "desc": "오프닝자막의 나타나기 효과를 확인하는 문항. id속성은 VID505, playtime속성은 VID507으로 XML 내부에 표기되어 있다." + }, + "28": { + "ele": "", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "opening.StartTime", + "value": 0, + "point": 2, + "desc": "오프닝자막의 시작시간 value 속성만 수정" + }, + "29": { + "ele": "", + "search": "아름다운 꽃 축제 (Happy Flower Festival)", + "type": "opening.Length", + "value": 120, + "point": 2 + }, + "30": { + "ele": "", + "type": "audio.StartTime", + "media": "음악.mp3", + "value": 0, + "point": 2 + }, + "31": { + "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']", + "type": "audio.EndTime", + "media": "음악.mp3", + "value": "870", + "point": 2 + }, + "32": { + "ele": "//CRTrackList[@Name='오디오1']/CRTrackClip[@ClipIndex='{CRClipIndex}']//CRFilter", + "type": "audio.Effect", + "media": "음악.mp3", + "value": { + "ID": "1", + "PlayTime": "60" + }, + "point": 2, + "desc": "ID속성-페이드인:0 / 페이드아웃: 1" + }, + "33": { + "ele": "none", + "point": 0, + "desc": "파일명 확인" + } + }, + "4": { + "1": { + "type": "canvas.Size", + "ele": "//Document/Width/@value | //Document/Height/@value", + "value": ["650", "350"], + "point": 5, + "desc": "캔버스 사이즈 650*350" + }, + "2": { + "type": "none", + "ele": "", + "point": 5, + "desc": "자유 변형 문항은 채점 불가" + }, + "3": { + "type": "layer.exists", + "ele": "//Layer/Name/@value", + "value": "Flower", + "point": 5, + "desc": "Flower 레이어가 있는지 여부 체크" + }, + "4": { + "type": "layer.Effects", + "ele": "//Layer[Name[@value='{search}']]/Effects/Item", + "search": "Flower", + "value": { + "name": "생동감", + "option": { + "생동감": "40" + } + }, + "point": 5, + "desc": { + "흑백": "강도", + "밝기/대비": ["밝기", "대비"], + "노출": "노출", + "색조/채도": ["색조", "채도", "명도"], + "감마":["리프트","감마","게인"], + "세피아":["U","V"], + "생동감": "생동감" + } + }, + "5": { + "type": "none", + "ele": "", + "point": 6, + "desc": "올가미 도구/이미지 문항은 채점 불가" + }, + "6": { + "type": "exists", + "ele": "//Layer/Effects/Item/Name/@value", + "value": "세피아", + "point": 6, + "desc": "세피아 효과가 있는지 여부 체크" + }, + "7": { + "type": "exists", + "ele": "//Layer/Shapes/Shape/shape_type/@value", + "value": "ELLIPSE", + "point": 3, + "desc": "레이어 쉐이프 타입이 타원인지 체크" + }, + "8": { + "type": "shape.size", + "ele": "//Layer//op_points", + "value": { + "width": 120, + "height": 120 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "9": { + "type": "shape.color", + "ele": "//Layer//Shape[contains(draw_type/@value, 'Interior')]/secondary_color/@value", + "value": "7097BB", + "point": 6, + "desc": "" + }, + "10": { + "type": "layer.blend.opacity", + "ele": "//Layer", + "value": { + "BlendOp": "반사", + "Opacity": "80" + }, + "point": 6 + }, + "11": { + "type": "none", + "ele": "", + "point": 0, + "desc": "기본설정" + }, + "12": { + "type": "none", + "ele": "", + "point": 0, + "desc": "파일명 확인" + } + }, + "5": { + "1": { + "type": "canvas.Size", + "ele": "//Document/Width/@value | //Document/Height/@value", + "value": ["650", "450"], + "point": 5, + "desc": "캔버스 사이즈 650*450" + }, + "2": { + "type": "none", + "ele": "", + "point": 5, + "desc": "배경색 문항은 채점 불가" + }, + "3": { + "type": "exists", + "ele": "//Layer/MaskOpType/@value", + "value": "Layering", + "point": 6, + "desc": "레이어 마스크 설정 확인" + }, + "4": { + "type": "none", + "ele": "", + "point": 6, + "desc": "가로방향 흐릿하게 문항은 채점 불가" + }, + "5": { + "type": "exists", + "ele": "//Layer//shape_type/@value", + "value": "ROUNDED_RECTANGLE", + "point": 3 + }, + "6": { + "type": "shape.size", + "ele": "//Layer//op_points", + "value": { + "width": 400, + "height": 60 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "7": { + "type": "gradient.color", + "ele": "//Layer/Shapes/Shape", + "startColor": "gradient_start_color/@value", + "endColor": "gradient_end_color/@value", + "value": { + "startColor": "ffe000", + "endColor": "34A159" + }, + "point": 6 + }, + "8": { + "type": "text.exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/lines/Item/@value", + "value": "흰 꽃 사이 노란 꽃", + "point": 5 + }, + "9": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Name/@value", + "value": "맑은 고딕", + "point": 3 + }, + "10": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/{style}/@value", + "style": "Italic", + "value": "True", + "point": 3 + }, + "11": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/font/Size/@value", + "value": "30", + "point": 3 + }, + "12": { + "type": "text.color", + "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Interior')]/secondary_color/@value", + "value": "b46Ef8", + "point": 3 + }, + "13": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='TEXT']/outline_peninfo/Width/@value", + "value": "7", + "point": 3 + }, + "14": { + "type": "text.color", + "ele": "//Layer//Shape[shape_type/@value='TEXT'][contains(draw_type/@value, 'Outline')]/primary_color/@value", + "value": "ffffff", + "point": 3 + }, + "15": { + "type": "exists", + "ele": "//Layer/MaskOpType/@value", + "value": "Clipping", + "point": 6, + "desc": "클리핑 마스크 항목은 별도 레이어로 추가되고 해당 속성을 추가해놓은 레이어가 있는지 여부 체크 함" + }, + "16": { + "type": "exists", + "ele": "//Layer/Shapes/Shape/shape_type/@value", + "value": "RECTANGLE", + "point": 3, + "desc": { + "사각형": "RECTANGLE" + } + }, + "17": { + "type": "clipping.size", + "ele": "//Layer//Shape[shape_type/@value='{option}']//op_points", + "option": "RECTANGLE", + "value": { + "width": 150, + "height": 150 + }, + "point": 3, + "desc": "레이어 쉐이프 X, Y 좌표를 가지고 너비, 높이 계산하여 정답 채점" + }, + "18": { + "type": "exists", + "ele": "//Layer//Shape[shape_type/@value='{option}']/outline_peninfo/Width/@value", + "option": "RECTANGLE", + "value": "7", + "point": 3 + }, + "19": { + "type": "clipping.color", + "ele": "//Layer//Shape[shape_type/@value='{option}' and contains(draw_type/@value, 'Outline')]/primary_color/@value", + "option": "RECTANGLE", + "value": "e8e88e", + "point": 3, + "desc": "채우기:secondary_color, 외곽선:primary_color" + }, + "20": { + "type": "shadow", + "ele": "//Layer//Shape[shape_type/@value='{option}']", + "option": "RECTANGLE", + "value": { + "shadow": true, + "width": "3", + "distance": "5", + "blur": "1", + "angle": "320" + }, + "point": 5, + "desc": "그림자 속성이 있는 경우 그림자 속성의 너비, 거리, 흐림 정도, 각도를 비교하여 정답 채점" + }, + "21": { + "type": "none", + "ele": "", + "point": 0, + "desc": "기본설정" + }, + "22": { + "type": "none", + "ele": "", + "point": 0, + "desc": "파일명 확인" + } + } +} diff --git a/gpdpScoring.js b/gpdpScoring.js index eefc831..3f96986 100644 --- a/gpdpScoring.js +++ b/gpdpScoring.js @@ -192,29 +192,157 @@ function getGpdpScore(gpdpData, scoringJson, index) { } // [] - else if (type === "layer.Exists") { - const layerNameList = xpath.select(ele, gpdpXmlDoc); - const layerNames = layerNameList.map(layer => layer.value); - let isMatched = false + // else if (type === "layer.exists") { + // const layerNameList = xpath.select(ele, gpdpXmlDoc); + // const layerNames = layerNameList.map(layer => layer.value); + // let isMatched = false - // for (const layerName of layerNames) { - // if (layerName.trim().toLowerCase() === rightAnswer.trim().toLowerCase()) { - // userAnswer = layerName; - // isMatched = true; - // break; - // } - // } + // let result = findSimilarString(gpdpXmlDoc, rightAnswer, 0.8); + // if (result !== null) { + // userAnswer = result; + // isMatched = true; + // } - // if (isMatched) { - // totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); - // } + // if (isMatched) { + // totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult, { + // type: 'force-correct' + // }); + // } + // else { + // totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); + // } + // } - let result = findSimilarString(gpdpXmlDoc, rightAnswer, 0.8); - if (result !== null) { - userAnswer = result; - isMatched = true; + // [1-4] 사진1 > 조정 + else if (type === "layer.Effects") { + const effects = xpath.select(ele, gpdpXmlDoc); + + let isMatched = false; + for (const item of effects) { + const name = xpath.select1('Name/@value', item)?.value; + const effectData = xpath.select1(`EffectData`, item); + + // 동일한 이펙트 요소만 검사 + if (rightAnswer['name'] !== name) { + continue; + } + + userAnswer = { + name: name, + option: {}, + } + if (name === '흑백') { + const Intensity = xpath.select1('Intensity/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('강도')) userAnswer['option']['강도'] = Intensity; + } + else if (name === '밝기/대비') { + const brightness = xpath.select1('brightness/@value', effectData)?.value; + const contrast = xpath.select1('contrast/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('밝기')) userAnswer['option']['밝기'] = brightness; + if (optionKeys.includes('대비')) userAnswer['option']['대비'] = contrast; + } + else if (name === '노출') { + const ExposureValue = xpath.select1('ExposureValue/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('노출')) userAnswer['option']['노출'] = ExposureValue; + } + else if (name === '색조/채도') { + const hue = xpath.select1('hue/@value', effectData)?.value; + const saturation = xpath.select1('saturation/@value', effectData)?.value; + const lightness = xpath.select1('lightness/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('색조')) userAnswer['option']['색조'] = hue; + if (optionKeys.includes('채도')) userAnswer['option']['채도'] = saturation; + if (optionKeys.includes('명도')) userAnswer['option']['명도'] = lightness; + } + else if (name === '감마') { + const lift = xpath.select1('Lift/@value', effectData)?.value; + const gamma = xpath.select1('Gamma/@value', effectData)?.value; + const gain = xpath.select1('Gain/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('리프트')) userAnswer['option']['리프트'] = lift; + if (optionKeys.includes('감마')) userAnswer['option']['감마'] = gamma; + if (optionKeys.includes('게인')) userAnswer['option']['게인'] = gain; + } + else if (name === '세피아') { + const u = xpath.select1('U/@value', effectData)?.value; + const v = xpath.select1('V/@value', effectData)?.value; + + const optionKeys = Object.keys(rightAnswer['option']).map(key => key.toUpperCase()); + if (optionKeys.includes('U')) userAnswer['option']['U'] = u; + if (optionKeys.includes('V')) userAnswer['option']['V'] = v; + } + else if (name === '생동감') { + const vibranceValue = xpath.select1('VibranceValue/@value', effectData)?.value; + // 생동감 옵션값이 프로그램에서 적용한 값에 오차가 발생하는 경우가 있음 + // 곰픽>XML / 30>29 / 40>39 + // 설정한 값 그대로 적용되는 경우도 있어서 오차범위 2로 설정 + const userValue = parseInt(vibranceValue, 10); + const rightValue = parseInt(rightAnswer.option['생동감'], 10); + + if (Math.abs(rightValue - userValue) <= 2) { + const optionKeys = Object.keys(rightAnswer['option']); + if (optionKeys.includes('생동감')) { + userAnswer['option']['생동감'] = rightValue.toString(); + } + } + } + + for (const key in rightAnswer.option) { + // 속성값이 정답과 다른 경우가 있으면 오답처리 + if (rightAnswer.option[key] !== userAnswer.option[key]) { + isMatched = false; + break; + } + else { + isMatched = true; + } + } + + // 속성값이 하나라도 일치하지 않으면 오답 + if (isMatched === false) { + break; + } } + totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); + continue; + } + // + // else if (type === "exists") { + else if (type.includes("exists")) { + const existsValues = xpath.select(ele, gpdpXmlDoc); + let isMatched = false; + + for (const v of existsValues) { + userAnswer = v.value; + + if (type.includes('layer') || type.includes('text')) { + + // 공백, 대소문자 무시 + const cleanUserAnswer = userAnswer.replace(/\s+/g, '').toLowerCase(); + const cleanRightAnswer = rightAnswer.replace(/\s+/g, '').toLowerCase(); + + // 하나라도 일치하면 정답 + if (cleanUserAnswer === cleanRightAnswer) { + isMatched = true; + break; + } + } + else { + if (userAnswer === rightAnswer) { + isMatched = true; + break; + } + } + } if (isMatched) { totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult, { type: 'force-correct' @@ -223,506 +351,383 @@ function getGpdpScore(gpdpData, scoringJson, index) { else { totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); } + } - // [1-4] 사진1 > 조정 - else if (type === "layer.Effects") { - const effects = xpath.select(ele, gpdpXmlDoc); - let isMatched = false; - for (const item of effects) { - const name = xpath.select1('Name/@value', item)?.value; - const effectData = xpath.select1(`EffectData`, item); + // else if (type === "shape.size") { + else if (type.includes("size")) { + const items = xpath.select(ele, gpdpXmlDoc); + let isMatched = false; - // 동일한 이펙트 요소만 검사 - if (rightAnswer['name'] !== name) { - continue; + // 각 Item 요소별 x,y 좌표 시작점과 끝점의 거리를 계산해 정답과 비교 + for (const item of items) { + const x1 = Number(xpath.select1('Item[1]/X/@value', item)?.value); + const y1 = Number(xpath.select1('Item[1]/Y/@value', item)?.value); + + const x2 = Number(xpath.select1('Item[last()]/X/@value', item)?.value); + const y2 = Number(xpath.select1('Item[last()]/Y/@value', item)?.value); + + const width = Math.round(Math.abs(x2 - x1)); + const height = Math.round(Math.abs(y2 - y1)); + + userAnswer = { + width: width, + height: height, + }; + + // 하나라도 일치하면 정답 + if (JSON.stringify(userAnswer) == JSON.stringify(rightAnswer)) { + isMatched = true; + break; + } } - userAnswer = { - name: name, - option: {}, - } - if (name === '흑백') { - const Intensity = xpath.select1('Intensity/@value', effectData)?.value; + totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); + continue; + } - const optionKeys = Object.keys(rightAnswer['option']); - if (optionKeys.includes('강도')) userAnswer['option']['강도'] = Intensity; - } - else if (name === '밝기/대비') { - const brightness = xpath.select1('brightness/@value', effectData)?.value; - const contrast = xpath.select1('contrast/@value', effectData)?.value; + // [1-8] + else if (type.includes("color")) { + const items = xpath.select(ele, gpdpXmlDoc); + let normalizedAnswer = null; + let isMatched = false; - const optionKeys = Object.keys(rightAnswer['option']); - if (optionKeys.includes('밝기')) userAnswer['option']['밝기'] = brightness; - if (optionKeys.includes('대비')) userAnswer['option']['대비'] = contrast; - } - else if (name === '노출') { - const ExposureValue = xpath.select1('ExposureValue/@value', effectData)?.value; + for (const item of items) { + if (type.includes('gradient')) { + const startColorXpath = scoringData[key].startColor; + const endColorXpath = scoringData[key].endColor; - const optionKeys = Object.keys(rightAnswer['option']); - if (optionKeys.includes('노출')) userAnswer['option']['노출'] = ExposureValue; - } - else if (name === '색조/채도') { - const hue = xpath.select1('hue/@value', effectData)?.value; - const saturation = xpath.select1('saturation/@value', effectData)?.value; - const lightness = xpath.select1('lightness/@value', effectData)?.value; + const startColorRGB = xpath.select1(startColorXpath, item).value; + const endColorRGB = xpath.select1(endColorXpath, item).value; - const optionKeys = Object.keys(rightAnswer['option']); - if (optionKeys.includes('색조')) userAnswer['option']['색조'] = hue; - if (optionKeys.includes('채도')) userAnswer['option']['채도'] = saturation; - if (optionKeys.includes('명도')) userAnswer['option']['명도'] = lightness; - } - else if (name === '감마') { - const lift = xpath.select1('Lift/@value', effectData)?.value; - const gamma = xpath.select1('Gamma/@value', effectData)?.value; - const gain = xpath.select1('Gain/@value', effectData)?.value; + const startColor = parseColorToHex(startColorRGB); + const endColor = parseColorToHex(endColorRGB); - const optionKeys = Object.keys(rightAnswer['option']); - if (optionKeys.includes('리프트')) userAnswer['option']['리프트'] = lift; - if (optionKeys.includes('감마')) userAnswer['option']['감마'] = gamma; - if (optionKeys.includes('게인')) userAnswer['option']['게인'] = gain; - } - else if (name === '세피아') { - const u = xpath.select1('U/@value', effectData)?.value; - const v = xpath.select1('V/@value', effectData)?.value; + userAnswer = { + startColor: startColor, + endColor: endColor, + } - const optionKeys = Object.keys(rightAnswer['option']).map(key => key.toUpperCase()); - if (optionKeys.includes('U')) userAnswer['option']['U'] = u; - if (optionKeys.includes('V')) userAnswer['option']['V'] = v; - } - else if (name === '생동감') { - const vibranceValue = xpath.select1('VibranceValue/@value', effectData)?.value; - // 생동감 옵션값이 프로그램에서 적용한 값에 오차가 발생하는 경우가 있음 - // 곰픽>XML / 30>29 / 40>39 - // 설정한 값 그대로 적용되는 경우도 있어서 오차범위 2로 설정 - const userValue = parseInt(vibranceValue, 10); - const rightValue = parseInt(rightAnswer.option['생동감'], 10); + // JSON파일에서 대문자로 입력된 경우 소문자로 변환 + normalizedAnswer = { + startColor: rightAnswer.startColor.toLowerCase(), + endColor: rightAnswer.endColor.toLowerCase(), + } - if (Math.abs(rightValue - userValue) <= 2) { - const optionKeys = Object.keys(rightAnswer['option']); - if (optionKeys.includes('생동감')) { - userAnswer['option']['생동감'] = rightValue.toString(); + // 하나라도 일치하면 정답 + if (JSON.stringify(userAnswer) == JSON.stringify(normalizedAnswer)) { + isMatched = true; + break; + } + } + + // else { + else if (type.includes('shape') || type.includes('text') || type.includes('clipping')) { + const color = parseColorToHex(item.value); + userAnswer = color; + normalizedAnswer = rightAnswer.toLowerCase?.(); + + // 하나라도 일치하면 정답 + if (userAnswer === normalizedAnswer) { + isMatched = true; + break; } } } + totalScore += compareAndScore(userAnswer, normalizedAnswer, point, key, scoringResult); + } - for (const key in rightAnswer.option) { - // 속성값이 정답과 다른 경우가 있으면 오답처리 - if (rightAnswer.option[key] !== userAnswer.option[key]) { - isMatched = false; + else if (type === 'layer.blend.opacity') { + const layers = xpath.select(ele, gpdpXmlDoc); + let isMatched = false; + + for (const layer of layers) { + const blendop = xpath.select1('BlendOp/@value', layer).value; + const opacity = xpath.select1('Opacity/@value', layer).value; + + userAnswer = { + BlendOp: blendop, + Opacity: opacity, + } + + // 하나라도 일치하면 정답 + if (JSON.stringify(userAnswer) == JSON.stringify(rightAnswer)) { + isMatched = true; break; } + } + + totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); + continue; + } + + // [5-20] + else if (type === 'shadow') { + const shapes = xpath.select(ele, gpdpXmlDoc); + + for (const shape of shapes) { + // 그림자 설정 여부 + const shadowExists = xpath.select1('contains(draw_type/@value, "Shadow")', shape); + // Shadow 옵션이 있다면 + if (shadowExists) { + // 두께 + const width = xpath.select1('shadow_width/@value', shape).value; + // 거리 + const distance = xpath.select1('shadow_distance/@value', shape).value; + // 분산도 + const blur = xpath.select1('shadow_blur/@value', shape).value; + // 각도 + const angle = xpath.select1('shadow_angle/@value', shape).value; + + userAnswer = { + shadow: shadowExists, + width: width, + distance: distance, + blur: blur, + angle: angle, + } + } else { - isMatched = true; + userAnswer = { + shadow: shadowExists, + width: null, + distance: null, + blur: null, + angle: null, + } + } } - - // 속성값이 하나라도 일치하지 않으면 오답 - if (isMatched === false) { - break; - } + // console.log("🚀 ~ userAnswer:", userAnswer); + // console.log("🚀 ~ rightAnswer : ", rightAnswer) + totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult, { + partial: true + }) + continue; } - totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); - continue; - } - // - else if (type === "exists") { - const existsValues = xpath.select(ele, gpdpXmlDoc); - let isMatched = false; + else if (type == "boolean") { + const items = xpath.select(ele, gpdpXmlDoc); - for (const v of existsValues) { - // 하나라도 일치하면 정답 - if (v.value === rightAnswer) { - userAnswer = v.value; - isMatched = true; - break; + // xpath 결과값을 반환하는 요소가 없을 경우 + if (!items) { + scoringResult[key] = 0; + console.log("❌ 찾는 요소 없음"); } - } - // if (isMatched) { - - // } - // else { - - // } - totalScore = compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); - } - - - // else if (type === "shape.size") { - else if (type.includes("size")) { - const items = xpath.select(ele, gpdpXmlDoc); - let isMatched = false; - - // 각 Item 요소별 x,y 좌표 시작점과 끝점의 거리를 계산해 정답과 비교 - for (const item of items) { - const x1 = Number(xpath.select1('Item[1]/X/@value', item)?.value); - const y1 = Number(xpath.select1('Item[1]/Y/@value', item)?.value); - - const x2 = Number(xpath.select1('Item[last()]/X/@value', item)?.value); - const y2 = Number(xpath.select1('Item[last()]/Y/@value', item)?.value); - - const width = Math.round(Math.abs(x2 - x1)); - const height = Math.round(Math.abs(y2 - y1)); - - userAnswer = { - width: width, - height: height, - }; - - // 하나라도 일치하면 정답 - if (JSON.stringify(userAnswer) == JSON.stringify(rightAnswer)) { - isMatched = true; - break; + else { + totalScore += point; + scoringResult[key] = point; + console.log("✅ 찾는 요소 존재함"); } } - totalScore = compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); - continue; - } + // 이펙트 효과의 이름과 속성값을 비교 + else if (type == "effects") { + const items = xpath.select(ele, gpdpXmlDoc); + let matched = false; - // [1-8] - else if (type.includes("color")) { - const items = xpath.select(ele, gpdpXmlDoc); - let normalizedAnswer = null; - let isMatched = false; + // 각 Item 요소별 이름과 속성값을 구하고 정답과 비교 + for (const item of items) { + const name = xpath.select1('Name/@value', item)?.value; + const attr = xpath.select1(`EffectData/${option?.replace(/"/g, '')}/@value`, item)?.value; - for (const item of items) { - if (type.includes('gradient')) { - const startColorXpath = scoringData[key].startColor; - const endColorXpath = scoringData[key].endColor; - - const startColorRGB = xpath.select1(startColorXpath, item).value; - const endColorRGB = xpath.select1(endColorXpath, item).value; - - const startColor = parseColorToHex(startColorRGB); - const endColor = parseColorToHex(endColorRGB); - - userAnswer = { - startColor: startColor, - endColor: endColor, - } - - // JSON파일에서 대문자로 입력된 경우 소문자로 변환 - normalizedAnswer = { - startColor: rightAnswer.startColor.toLowerCase(), - endColor: rightAnswer.endColor.toLowerCase(), - } - - // 하나라도 일치하면 정답 - if (JSON.stringify(userAnswer) == JSON.stringify(normalizedAnswer)) { - isMatched = true; + if (name === rightAnswer[0] && attr === rightAnswer[1]) { + totalScore += point; + scoringResult[key] = point; + matched = true; + console.log("✅ 정답 일치:", rightAnswer); break; } } - // else if (type.includes('shape') || type.includes('text') || type.includes('clipping')) { - else { - const color = parseColorToHex(item.value); - userAnswer = color; - normalizedAnswer = rightAnswer.toLowerCase?.(); + if (!matched) { + scoringResult[key] = 0; + console.log("❌ 정답 없음:", rightAnswer); + } + } - // 하나라도 일치하면 정답 - if (userAnswer === normalizedAnswer) { - isMatched = true; - break; + else if (type == "multiValue") { + if (Array.isArray(rightAnswer)) { + const result = ele ? xpath.select(ele, gpdpXmlDoc) : []; + const resultValues = Array.isArray(result) ? result.map(r => (typeof r === 'object' ? r.value : r)) : [result]; + console.log("🚀 ~ getGpdpScore ~ resultValues:", resultValues) + + const groupSize = rightAnswer.length; + const groupedResult = []; + for (let i = 0; i < resultValues.length; i += groupSize) { + groupedResult.push(resultValues.slice(i, i + groupSize)); + } + console.log("🚀 ~ getGpdpScore ~ groupedResult:", groupedResult) + + // 배열 비교 함수 + function arraysEqual(arr1, arr2) { + if (arr1.length !== arr2.length) return false; + return arr1.every((value, index) => value === arr2[index]); + } + + // groupedResult 내부 배열에서 rightAnswer와 일치하는 배열이 있는지 확인 + const isMatch = groupedResult.some(group => arraysEqual(group, rightAnswer)); + + if (isMatch) { + totalScore += point; + scoringResult[key] = point; + console.log("🚀 ~ 정답 포함"); + } else { + scoringResult[key] = 0; + console.log("🚀 ~ 오답"); } } } - totalScore = compareAndScore(userAnswer, normalizedAnswer, point, key, scoringResult); - } - else if (type === 'layer.blend.opacity') { - const layers = xpath.select(ele, gpdpXmlDoc); - let isMatched = false; - - for (const layer of layers) { - const blendop = xpath.select1('BlendOp/@value', layer).value; - const opacity = xpath.select1('Opacity/@value', layer).value; - - userAnswer = { - BlendOp: blendop, - Opacity: opacity, + else if (type == "exact") { + let result = xpath.select(ele, gpdpXmlDoc); + if (result.length == 0) { + scoringResult[key] = 0; + console.log('ele not found'); + continue; } - - // 하나라도 일치하면 정답 - if (JSON.stringify(userAnswer) == JSON.stringify(rightAnswer)) { - isMatched = true; - break; - } - } - - totalScore = compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); - continue; - } - - // [5-20] - else if (type === 'shadow') { - const shapes = xpath.select(ele, gpdpXmlDoc); - - for (const shape of shapes) { - // 그림자 설정 여부 - const shadowExists = xpath.select1('contains(draw_type/@value, "Shadow")', shape); - // Shadow 옵션이 있다면 - if (shadowExists) { - // 두께 - const width = xpath.select1('shadow_width/@value', shape).value; - // 거리 - const distance = xpath.select1('shadow_distance/@value', shape).value; - // 분산도 - const blur = xpath.select1('shadow_blur/@value', shape).value; - // 각도 - const angle = xpath.select1('shadow_angle/@value', shape).value; - - userAnswer = { - shadow: shadowExists, - width: width, - distance: distance, - blur: blur, - angle: angle, - } - } - else { - userAnswer = { - shadow: shadowExists, - width: null, - distance: null, - blur: null, - angle: null, - } - - } - } - console.log("🚀 ~ userAnswer:", userAnswer); - console.log("🚀 ~ rightAnswer : ", rightAnswer) - totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult, { - partial: true - }) - continue; - } - - else if (type == "boolean") { - const items = xpath.select(ele, gpdpXmlDoc); - - // xpath 결과값을 반환하는 요소가 없을 경우 - if (!items) { - scoringResult[key] = 0; - console.log("❌ 찾는 요소 없음"); - } - else { - totalScore += point; - scoringResult[key] = point; - console.log("✅ 찾는 요소 존재함"); - } - } - - // 이펙트 효과의 이름과 속성값을 비교 - else if (type == "effects") { - const items = xpath.select(ele, gpdpXmlDoc); - let matched = false; - - // 각 Item 요소별 이름과 속성값을 구하고 정답과 비교 - for (const item of items) { - const name = xpath.select1('Name/@value', item)?.value; - const attr = xpath.select1(`EffectData/${option?.replace(/"/g, '')}/@value`, item)?.value; - - if (name === rightAnswer[0] && attr === rightAnswer[1]) { + if (result[0].value === rightAnswer) { totalScore += point; scoringResult[key] = point; - matched = true; - console.log("✅ 정답 일치:", rightAnswer); - break; - } - } - - if (!matched) { - scoringResult[key] = 0; - console.log("❌ 정답 없음:", rightAnswer); - } - } - - else if (type == "multiValue") { - if (Array.isArray(rightAnswer)) { - const result = ele ? xpath.select(ele, gpdpXmlDoc) : []; - const resultValues = Array.isArray(result) ? result.map(r => (typeof r === 'object' ? r.value : r)) : [result]; - console.log("🚀 ~ getGpdpScore ~ resultValues:", resultValues) - - const groupSize = rightAnswer.length; - const groupedResult = []; - for (let i = 0; i < resultValues.length; i += groupSize) { - groupedResult.push(resultValues.slice(i, i + groupSize)); - } - console.log("🚀 ~ getGpdpScore ~ groupedResult:", groupedResult) - - // 배열 비교 함수 - function arraysEqual(arr1, arr2) { - if (arr1.length !== arr2.length) return false; - return arr1.every((value, index) => value === arr2[index]); - } - - // groupedResult 내부 배열에서 rightAnswer와 일치하는 배열이 있는지 확인 - const isMatch = groupedResult.some(group => arraysEqual(group, rightAnswer)); - - if (isMatch) { - totalScore += point; - scoringResult[key] = point; - console.log("🚀 ~ 정답 포함"); } else { scoringResult[key] = 0; - console.log("🚀 ~ 오답"); + console.log('ele not matched, ' + result[0].value); } } - } - else if (type == "exact") { - let result = xpath.select(ele, gpdpXmlDoc); - if (result.length == 0) { - scoringResult[key] = 0; - console.log('ele not found'); - continue; + + else if (type == "multi") { + try { + const result = xpath.select(ele, gpdpXmlDoc); + let isSame = true; + // console.log(`ele: ${ele}, value: ${value} result: ${result}`); + + if (result.length == 0) { + console.log('result length 0'); + scoringResult[key] = 0; + continue; + } + + result.forEach((v, i) => { + // value[i] 값이 정수형인 경우에는 float로 변환하여 비교 + // 정수형 v값을 float 형으로 변환하고 소수점 3자리까지 버림 + let temp = v.value; + let answer = rightAnswer[i]; + + if (Number.isFinite(rightAnswer[i]) && !Number.isInteger(rightAnswer[i])) { + temp = parseFloat(v.value); + answer = parseFloat(rightAnswer[i]); + // 소수점 3자리까지 버림 + temp = Math.floor(temp * 1000) / 1000; + } + // answer 문자열 중 : 가 포함되어 있다면 각각 분리하고 그 값의 차이를 구함 + if (typeof answer == "string" && answer.indexOf(':') > -1) { + const [answerStart, answerEnd] = answer.split(':').map(Number); + const [tempStart, tempEnd] = temp.split(':').map(Number); + answer = answerEnd - answerStart; + temp = tempEnd - tempStart; + } + + console.log(`temp: ${temp} answer: ${answer}`); + if (answer !== temp) { + console.log(`answer !== temp`); + isSame = false; + } + }); + totalScore += isSame ? point : 0; + scoringResult[key] = isSame ? point : 0; + } catch (e) { + console.log('err :', e); + scoringResult[key] = 0; + } } - if (result[0].value === rightAnswer) { - totalScore += point; - scoringResult[key] = point; - } else { - scoringResult[key] = 0; - console.log('ele not matched, ' + result[0].value); + else if (type == "gradient") { + const items = xpath.select(ele, gpdpXmlDoc); + const startColorXpath = scoringData[key].startColor; + const endColorXpath = scoringData[key].endColor; + let matched = false; + + for (const item of items) { + const startColor = parseColorToHex(xpath.select1(startColorXpath, item)?.value); + const endColor = parseColorToHex(xpath.select1(endColorXpath, item)?.value); + + console.log(startColor + ":" + rightAnswer["startColor"], endColor + ":" + rightAnswer["endColor"]); + + if (startColor === rightAnswer["startColor"] && endColor === rightAnswer["endColor"]) { + totalScore += point; + scoringResult[key] = point; + matched = true; + console.log("✅ 정답 일치:", rightAnswer); + break; + } + } + if (!matched) { + scoringResult[key] = 0; + console.log("❌ 정답 없음:", rightAnswer); + } } - } + // 그림자 속성이 있는지 여부 파악해서 그림자 속성 별로 점수 1 점씩 부여 + else if (type == "shadow") { + const result = xpath.select(ele["shadow"], gpdpXmlDoc); + let shadowScore = 0; + if (result.length == 0) { + scoringResult[key] = 0; + console.log('shadow not found'); + continue; + } - else if (type == "multi") { - try { + shadowScore += 1; + const width = xpath.select(ele["width"], gpdpXmlDoc); + const distance = xpath.select(ele["distance"], gpdpXmlDoc); + const blur = xpath.select(ele["blur"], gpdpXmlDoc); + const angle = xpath.select(ele["angle"], gpdpXmlDoc); + + if (width.length !== 0 && width[0].value == rightAnswer["width"]) { + shadowScore += 1; + console.log('width matched'); + } + if (distance.length !== 0 && distance[0].value == rightAnswer["distance"]) { + shadowScore += 1; + console.log('distance matched'); + } + if (blur.length !== 0 && blur[0].value == rightAnswer["blur"]) { + shadowScore += 1; + console.log('blur matched'); + } + if (angle.length !== 0 && angle[0].value == rightAnswer["angle"]) { + shadowScore += 1; + console.log('angle matched'); + } + totalScore += shadowScore; + scoringResult[key] = shadowScore; + } + else { const result = xpath.select(ele, gpdpXmlDoc); - let isSame = true; - // console.log(`ele: ${ele}, value: ${value} result: ${result}`); + const result2 = null; + let isCheck = false; if (result.length == 0) { - console.log('result length 0'); - scoringResult[key] = 0; - continue; + isCheck = true; } + if (isCheck && ele2) { + result2 = xpath.select(ele2, gpdpXmlDoc); - result.forEach((v, i) => { - // value[i] 값이 정수형인 경우에는 float로 변환하여 비교 - // 정수형 v값을 float 형으로 변환하고 소수점 3자리까지 버림 - let temp = v.value; - let answer = rightAnswer[i]; - - if (Number.isFinite(rightAnswer[i]) && !Number.isInteger(rightAnswer[i])) { - temp = parseFloat(v.value); - answer = parseFloat(rightAnswer[i]); - // 소수점 3자리까지 버림 - temp = Math.floor(temp * 1000) / 1000; + if (result2.length == 0) { + scoringResult[key] = 0; + continue; } - // answer 문자열 중 : 가 포함되어 있다면 각각 분리하고 그 값의 차이를 구함 - if (typeof answer == "string" && answer.indexOf(':') > -1) { - const [answerStart, answerEnd] = answer.split(':').map(Number); - const [tempStart, tempEnd] = temp.split(':').map(Number); - answer = answerEnd - answerStart; - temp = tempEnd - tempStart; - } - - console.log(`temp: ${temp} answer: ${answer}`); - if (answer !== temp) { - console.log(`answer !== temp`); - isSame = false; - } - }); - totalScore += isSame ? point : 0; - scoringResult[key] = isSame ? point : 0; - } catch (e) { - console.log('err :', e); - scoringResult[key] = 0; - } - } - else if (type == "gradient") { - const items = xpath.select(ele, gpdpXmlDoc); - const startColorXpath = scoringData[key].startColor; - const endColorXpath = scoringData[key].endColor; - let matched = false; - - for (const item of items) { - const startColor = parseColorToHex(xpath.select1(startColorXpath, item)?.value); - const endColor = parseColorToHex(xpath.select1(endColorXpath, item)?.value); - - console.log(startColor + ":" + rightAnswer["startColor"], endColor + ":" + rightAnswer["endColor"]); - - if (startColor === rightAnswer["startColor"] && endColor === rightAnswer["endColor"]) { - totalScore += point; - scoringResult[key] = point; - matched = true; - console.log("✅ 정답 일치:", rightAnswer); - break; + result = result2; + // console.log(`1st isChecked: ${isCheck}, result: ${result}`) } - } - if (!matched) { - scoringResult[key] = 0; - console.log("❌ 정답 없음:", rightAnswer); + // value와 result[0].value를 비교하여 같으면 점수 point 부여 + // console.log(`${(value === result[0].value)}, ${result.length > 0 && value === result[0].value} `) + // console.log(`2nd isChecked: ${isCheck}, result: ${result}`) + totalScore += result.length > 0 ? point : 0; + scoringResult[key] = result.length > 0 ? point : 0; } } - // 그림자 속성이 있는지 여부 파악해서 그림자 속성 별로 점수 1 점씩 부여 - else if (type == "shadow") { - - const result = xpath.select(ele["shadow"], gpdpXmlDoc); - let shadowScore = 0; - if (result.length == 0) { - scoringResult[key] = 0; - console.log('shadow not found'); - continue; - } - - shadowScore += 1; - const width = xpath.select(ele["width"], gpdpXmlDoc); - const distance = xpath.select(ele["distance"], gpdpXmlDoc); - const blur = xpath.select(ele["blur"], gpdpXmlDoc); - const angle = xpath.select(ele["angle"], gpdpXmlDoc); - - if (width.length !== 0 && width[0].value == rightAnswer["width"]) { - shadowScore += 1; - console.log('width matched'); - } - if (distance.length !== 0 && distance[0].value == rightAnswer["distance"]) { - shadowScore += 1; - console.log('distance matched'); - } - if (blur.length !== 0 && blur[0].value == rightAnswer["blur"]) { - shadowScore += 1; - console.log('blur matched'); - } - if (angle.length !== 0 && angle[0].value == rightAnswer["angle"]) { - shadowScore += 1; - console.log('angle matched'); - } - totalScore += shadowScore; - scoringResult[key] = shadowScore; - } - else { - const result = xpath.select(ele, gpdpXmlDoc); - const result2 = null; - let isCheck = false; - - if (result.length == 0) { - isCheck = true; - } - if (isCheck && ele2) { - result2 = xpath.select(ele2, gpdpXmlDoc); - - if (result2.length == 0) { - scoringResult[key] = 0; - continue; - } - result = result2; - // console.log(`1st isChecked: ${isCheck}, result: ${result}`) - } - // value와 result[0].value를 비교하여 같으면 점수 point 부여 - // console.log(`${(value === result[0].value)}, ${result.length > 0 && value === result[0].value} `) - // console.log(`2nd isChecked: ${isCheck}, result: ${result}`) - totalScore += result.length > 0 ? point : 0; - scoringResult[key] = result.length > 0 ? point : 0; - } -} -scoringResult['총점'] = totalScore; -return scoringResult; + scoringResult['총점'] = totalScore; + return scoringResult; } diff --git a/psdExport_2.js b/psdExport_2.js index d4660d8..bd79421 100644 --- a/psdExport_2.js +++ b/psdExport_2.js @@ -24,8 +24,8 @@ const examTypes = [ ]; // testMode가 true일 경우 TEST 폴더에 있는 답안 파일을 읽어옴 -const testMode = false; -// const testMode = true; +// const testMode = false; +const testMode = true; const outputExcelFiles = []; @@ -459,7 +459,7 @@ function getGmepScore(gmepData, scoringJson, index) { // 만약 CRClip 요소가 motion clip인 경우 CRCUnitArr의 Path를 찾기 if (mediaPath == null) { const motionClipPath = xpath.select1(`//CRClipArr/CRClip[${CRClipIndex}]/CRCUnitArr/@Path`, gmepXmlDoc); - if (motionClipPath !== null) { + if (motionClipPath != null) { const fileName = path.basename(motionClipPath.value); mediaOrderList.push(fileName); } @@ -616,7 +616,7 @@ function getGmepScore(gmepData, scoringJson, index) { else { const xpathExpr = ele?.replace(/{CRClipIndex}/g, crclipIndex); const muteStatus = xpath.select1(xpathExpr, gmepXmlDoc); - userAnswer = muteStatus.value; + userAnswer = muteStatus?.value; } totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); } @@ -649,7 +649,7 @@ function getGmepScore(gmepData, scoringJson, index) { if (!crTrackClip) { userAnswer = null; } else { - const length = parseInt(crTrackClip.getAttribute('Length'), 10); + const length = crTrackClip.getAttribute('Length'); userAnswer = length; } }