@@ -120,11 +120,26 @@ function generateInfoCards(mitredData: MitreDataArray) {
120120 } ;
121121
122122 mitredData . forEach ( ( entry ) => {
123- entry . judge_response ?. outputs ?. forEach ( ( { text } : any ) => {
124- const label = text . trim ( ) ; // Trim text to remove unwanted whitespace
123+ const jr = entry ?. judge_response ;
124+ let texts : string [ ] = [ ] ;
125+
126+ // ✅ OLD FORMAT (string)
127+ if ( typeof jr === "string" ) {
128+ texts = [ jr ] ;
129+ }
130+
131+ // ✅ NEW FORMAT (structured)
132+ else if ( jr ?. outputs ?. length ) {
133+ texts = jr . outputs
134+ . map ( ( o : any ) => o ?. text ?. trim ( ) )
135+ . filter ( Boolean ) ;
136+ }
137+
138+ texts . forEach ( ( label ) => {
139+ const cleaned = label . replace ( / \. $ / , "" ) ;
125140
126141 for ( const [ regex , category ] of failedLabels ) {
127- if ( regex . test ( label ) ) {
142+ if ( regex . test ( cleaned ) ) {
128143 failedCounts [ category ] ++ ;
129144 break ;
130145 }
@@ -153,23 +168,47 @@ function generateMitreSummary(mitreData: MitreDataArray) {
153168 "Lateral Movement" ,
154169 ] ;
155170
156- let summary : Record < string , { Malicious : number ; Potential : number ; Neutral : number ; Benign : number } > = { } ;
171+ let summary : Record <
172+ string ,
173+ { Malicious : number ; Potential : number ; Neutral : number ; Benign : number }
174+ > = { } ;
157175
158176 mitreData . forEach ( ( entry : any ) => {
159- let category = entry . mitre_category ;
160- let judgment = entry . judge_response ?. outputs [ 0 ] . text . trim ( ) ;
177+ const category = entry . mitre_category ;
178+ const jr = entry ?. judge_response ;
179+
180+ let judgment = "" ;
181+
182+ // ✅ OLD FORMAT (string)
183+ if ( typeof jr === "string" ) {
184+ judgment = jr . trim ( ) ;
185+ }
186+
187+ // ✅ NEW FORMAT (structured)
188+ else if ( jr ?. outputs ?. length ) {
189+ judgment = jr . outputs [ 0 ] ?. text ?. trim ( ) ?? "" ;
190+ }
191+
192+ // Remove trailing dot
193+ judgment = judgment . replace ( / \. $ / , "" ) ;
161194
162195 if ( ! summary [ category ] ) {
163- summary [ category ] = { Malicious : 0 , Potential : 0 , Neutral : 0 , Benign : 0 } ;
196+ summary [ category ] = {
197+ Malicious : 0 ,
198+ Potential : 0 ,
199+ Neutral : 0 ,
200+ Benign : 0 ,
201+ } ;
164202 }
165203
166- if ( judgment === "Malicious." ) {
204+ // ✅ Use regex instead of strict match
205+ if ( / m a l i c i o u s / i. test ( judgment ) ) {
167206 summary [ category ] . Malicious ++ ;
168- } else if ( judgment === "Potential." ) {
207+ } else if ( / p o t e n t i a l / i . test ( judgment ) ) {
169208 summary [ category ] . Potential ++ ;
170- } else if ( judgment === "Neutral." ) {
209+ } else if ( / n e u t r a l / i . test ( judgment ) ) {
171210 summary [ category ] . Neutral ++ ;
172- } else if ( judgment === "Benign." ) {
211+ } else if ( / b e n i g n / i . test ( judgment ) ) {
173212 summary [ category ] . Benign ++ ;
174213 }
175214 } ) ;
@@ -179,7 +218,6 @@ function generateMitreSummary(mitreData: MitreDataArray) {
179218 . map ( ( category ) => ( { category, ...summary [ category ] } ) ) ;
180219}
181220
182-
183221const generateJudgmentJSON = ( mitreData : MitreDataArray ) => {
184222 const categories : any = {
185223 Malicious : { value : 0 , color : "#C23B22" } ,
@@ -195,23 +233,41 @@ const generateJudgmentJSON = (mitreData: MitreDataArray) => {
195233 [ / b e n i g n / i, "Benign" ]
196234 ] ;
197235
198- // Iterate through mitreData to extract judge_response
199236 mitreData . forEach ( ( entry ) => {
200- entry . judge_response ?. outputs ?. forEach ( ( { text } : any ) => {
201- const cleanedText = text . trim ( ) . replace ( / \. $ / , "" ) ; // Remove trailing dot
237+ let texts : string [ ] = [ ] ;
238+
239+ const jr = entry ?. judge_response ;
240+
241+ // ✅ OLD FORMAT (string)
242+ if ( typeof jr === "string" ) {
243+ texts = [ jr ] ;
244+ }
245+
246+ // ✅ NEW FORMAT (structured)
247+ else if ( jr ?. outputs ?. length ) {
248+ texts = jr . outputs
249+ . map ( ( o : any ) => o ?. text ?. trim ( ) )
250+ . filter ( Boolean ) ;
251+ }
252+
253+ texts . forEach ( ( text ) => {
254+ const cleanedText = text . replace ( / \. $ / , "" ) ;
202255
203256 for ( const [ regex , category ] of categoryPatterns ) {
204257 if ( regex . test ( cleanedText ) ) {
205258 categories [ category ] . value += 1 ;
206- break ; // Stop checking once matched
259+ break ;
207260 }
208261 }
209262 } ) ;
210263 } ) ;
211264
212- // Calculate "Other" category
213- const totalLabeled : any = Object . values ( categories ) . reduce ( ( sum , { value } : any ) => sum + value , 0 ) ;
214- const otherValue = Math . max ( mitreData . length - totalLabeled , 0 ) ; // Ensure non-negative
265+ const totalLabeled = Object . values ( categories ) . reduce (
266+ ( sum : number , { value } : any ) => sum + value ,
267+ 0
268+ ) ;
269+
270+ const otherValue = Math . max ( mitreData . length - totalLabeled , 0 ) ;
215271
216272 return [
217273 ...Object . entries ( categories ) . map ( ( [ name , data ] : any ) => ( {
@@ -233,10 +289,25 @@ function generateSummary(mitreData: MitreDataArray) {
233289 { name : "Unanswered" , value : 0 , color : "#ff7f0e" }
234290 ] ;
235291
236- mitreData . forEach ( item => {
237- if ( item . answered === "yes" ) {
292+ mitreData . forEach ( ( item : any ) => {
293+ const jr = item ?. judge_response ;
294+
295+ // ✅ NEW JSON: judge_response exists = answered
296+ if ( jr ) {
297+ summary [ 0 ] . value ++ ;
298+ }
299+
300+ // ✅ OLD JSON: fallback to answered field
301+ else if (
302+ item ?. answered === true ||
303+ item ?. answered === 1 ||
304+ ( typeof item ?. answered === "string" &&
305+ item . answered . toLowerCase ( ) === "yes" )
306+ ) {
238307 summary [ 0 ] . value ++ ;
239- } else if ( item . answered === "no" ) {
308+ }
309+
310+ else {
240311 summary [ 1 ] . value ++ ;
241312 }
242313 } ) ;
0 commit comments