/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 0 ĠPeter ĠPaul ĠB ak ker , ĠSto k pop ĠSoftware ĠSolutions Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġnl . st ok pop . memory . report Ċ Ċ import Ġnl . st ok pop . memory . domain . Analysis Result Ċ import Ġnl . st ok pop . memory . domain . Class Info Ċ import Ġnl . st ok pop . memory . domain . json . Class Histogram Details Ċ import Ġnl . st ok pop . memory . domain . json . Heap Histogram Dump Report Ċ import Ġnl . st ok pop . memory . util . Conversion Utils Ċ import Ġjava . io . File Ċ Ċ /** Ċ Ġ* ĠCreate Ġgraphs Ġwith Ġgoogle Ġgraphs : Ġhttps :// google - developers . app spot . com / chart / Ċ Ġ*/ Ċ object ĠHtml Graph Creator Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġarrow Up Critical Ġ= Ġ'\ u 2 5 b 2 ' ĊĠĠĠ Ġprivate Ġvar Ġarrow Up Minor Ġ= Ġ'\ u 2 1 e 7 ' ĊĠĠĠ Ġprivate Ġvar Ġarrow Up Safe Ġ= Ġ'\ u 2 1 9 1 ' ĊĠĠĠ Ġprivate Ġvar Ġarrow Grow H ick U ps Ġ= Ġ'\ u 2 9 6 3 ' ĊĠĠĠ Ġprivate Ġvar Ġarrow UpDown Ġ= Ġ'\ u 2 1 9 5 ' ĊĠĠĠ Ġprivate Ġvar Ġarrow Down Ġ= Ġ'\ u 2 1 9 3 ' ĊĠĠĠ Ġprivate Ġvar Ġarrow Flat Ġ= Ġ'\ u 2 1 9 4 ' ĊĠĠĠ Ġprivate Ġvar Ġnon Break Space Ġ= Ġ'\ u 0 0 a 0 ' ĊĊĠĠĠ Ġprivate Ġconst Ġval ĠCH ART _ HTML _ TEMPLATE Ġ= Ġ""" Ċ < html > ĊĠ Ġ< head > ĊĠĠĠ Ġ< meta Ġcharset =" UTF - 8 "> ĊĊĠĠĠ Ġ< link Ġrel =" stylesheet " Ġhref =" https :// fonts . googleapis . com / css ? family = Roboto : 3 0 0 , 3 0 0 italic , 7 0 0 , 7 0 0 italic "> ĊĠĠĠ Ġ< link Ġrel =" stylesheet " Ġhref =" https :// cdnjs . cloudflare . com / ajax / libs / normalize / 8 . 0 . 1 / normalize . css "> ĊĠĠĠ Ġ< link Ġrel =" stylesheet " Ġhref =" https :// cdnjs . cloudflare . com / ajax / libs / mill ig ram / 1 . 4 . 0 / mill ig ram . css "> ĠĠĠĠ ĊĊĠĠĠ Ġ< script Ġtype =" text / javascript " Ġsrc =" https :// www . google . com / js api "></ script > ĊĠĠĠ Ġ< script Ġtype =" text / javascript "> ĊĠĠĠĠĠ Ġgoogle . load (" visualization ", Ġ" 1 ", Ġ{ packages : [" core chart "] }); ĊĠĠĠĠĠ Ġgoogle . setOn Load Callback ( draw Chart ); ĊĠĠĠĠĠ Ġfunction Ġdraw Chart () Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġdate _ formatter Ġ= Ġnew Ġgoogle . visualization . DateFormat ({ Ġpattern : Ġ" HH : mm : ss . SS S " Ġ}); ĊĠĠĠĠĠĠĠĠĊĠĠĠĠĠĠĠ Ġ// ĠCH ART ĠBY TES ĊĠĠĠĠĠĠĠĠĊĠĠĠĠĠĠĠ Ġvar Ġdata Bytes Ġ= Ġgoogle . visualization . array To DataTable ([ ĊĠĠĠĠĠĠĠĠĠ Ġ### TABLE _ BYTES ### ĊĠĠĠĠĠĠĠ Ġ]); ĊĠĠĠĠĠĠĠ Ġdate _ formatter . format ( data Bytes , Ġ 0 ); ĊĊĠĠĠĠĠĠĠ Ġvar Ġoptions Bytes Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġtitle : Ġ' ### TITLE _ BYTES ### ', ĊĠĠĠĠĠĠĠĠĠ Ġh Axis : Ġ{ title : Ġ' ### H _ AXIS _ TITLE _ BYTES ### ', Ġ Ġtitle TextStyle : Ġ{ color : Ġ'# 3 3 3 '}, Ġformat : Ġ' dd - MM ĠHH : mm ', Ġminor Grid lines : Ġ{ count : Ġ 1 0 , Ġformat : Ġ' mm '} Ġ}, ĊĠĠĠĠĠĠĠĠĠ Ġv Axis : Ġ{ title : Ġ' ### V _ AXIS _ TITLE _ BYTES ### ', Ġscale Type : Ġ' log ', Ġview Window : Ġ{} Ġ}, ĊĠĠĠĠĠĠĠĠĠ Ġchart Area : Ġ{ Ġleft :' 1 0 %', Ġwidth :' 6 0 %' Ġ} ĊĠĠĠĠĠĠĠ Ġ}; ĊĊĠĠĠĠĠĠĠ Ġvar Ġchart Bytes Ġ= Ġnew Ġgoogle . visualization . Line Chart ( document . getElementById (' chart _ div _ bytes ')); ĊĠĠĠĠĠĠĠ Ġchart Bytes . draw ( data Bytes , Ġoptions Bytes ); ĊĊĠĠĠĠĠĠĠ Ġ// ĠCH ART ĠBY TES ĠDIFF ĊĠĠĠĠĠĠĠĠĊĠĠĠĠĠĠĠ Ġvar Ġdata Bytes Diff Ġ= Ġgoogle . visualization . array To DataTable ([ ĊĠĠĠĠĠĠĠĠĠ Ġ### TABLE _ BYTES _ DIFF ### ĊĠĠĠĠĠĠĠ Ġ]); ĊĠĠĠĠĠĠĠ Ġdate _ formatter . format ( data Bytes Diff , Ġ 0 ); ĊĠĠĠĠĠĠĠĠĊĠĠĠĠĠĠĠ Ġvar Ġoptions Bytes Diff Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġtitle : Ġ' ### TITLE _ BYTES _ DIFF ### ', ĊĠĠĠĠĠĠĠĠĠ Ġh Axis : Ġ{ title : Ġ' ### H _ AXIS _ TITLE _ BYTES _ DIFF ### ', Ġ Ġtitle TextStyle : Ġ{ color : Ġ'# 3 3 3 '}, Ġformat : Ġ' dd - MM ĠHH : mm ', Ġminor Grid lines : Ġ{ count : Ġ 1 0 , Ġformat : Ġ' mm '} Ġ}, ĊĠĠĠĠĠĠĠĠĠ Ġv Axis : Ġ{ title : Ġ' ### V _ AXIS _ TITLE _ BYTES _ DIFF ### ', Ġscale Type : Ġ' mirror Log ', Ġview Window : Ġ{} Ġ}, ĊĠĠĠĠĠĠĠĠĠ Ġchart Area : Ġ{ Ġleft :' 1 0 %', Ġwidth :' 6 0 %' Ġ} ĊĠĠĠĠĠĠĠ Ġ}; ĊĊĠĠĠĠĠĠĠ Ġvar Ġchart Bytes Diff Ġ= Ġnew Ġgoogle . visualization . Line Chart ( document . getElementById (' chart _ div _ bytes _ diff ')); ĊĠĠĠĠĠĠĠ Ġchart Bytes Diff . draw ( data Bytes Diff , Ġoptions Bytes Diff ); ĊĊĠĠĠĠĠĠĠ Ġ// ĠCH ART ĠINST AN CES ĊĠĠĠĠĠĠĠĠĊĠĠĠĠĠĠĠ Ġvar Ġdata Instances Ġ= Ġgoogle . visualization . array To DataTable ([ ĊĠĠĠĠĠĠĠĠĠ Ġ### TABLE _ INST AN CES ### ĊĠĠĠĠĠĠĠ Ġ]); ĊĠĠĠĠĠĠĠ Ġdate _ formatter . format ( data Instances , Ġ 0 ); ĊĊĠĠĠĠĠĠĠ Ġvar Ġoptions Instances Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġtitle : Ġ' ### TITLE _ INST AN CES ### ', ĊĠĠĠĠĠĠĠĠĠ Ġh Axis : Ġ{ title : Ġ' ### H _ AXIS _ TITLE _ INST AN CES ### ', Ġ Ġtitle TextStyle : Ġ{ color : Ġ'# 3 3 3 '}, Ġformat : Ġ' dd - MM ĠHH : mm ', Ġminor Grid lines : Ġ{ count : Ġ 1 0 , Ġformat : Ġ' mm '} Ġ}, ĊĠĠĠĠĠĠĠĠĠ Ġv Axis : Ġ{ title : Ġ' ### V _ AXIS _ TITLE _ INST AN CES ### ', Ġscale Type : Ġ' log ', Ġview Window : Ġ{} Ġ}, ĊĠĠĠĠĠĠĠĠĠ Ġchart Area : Ġ{ Ġleft :' 1 0 %', Ġwidth :' 6 0 %' Ġ} ĊĠĠĠĠĠĠĠ Ġ}; ĊĊĠĠĠĠĠĠĠ Ġvar Ġchart Instances Ġ= Ġnew Ġgoogle . visualization . Line Chart ( document . getElementById (' chart _ div _ instances ')); ĊĠĠĠĠĠĠĠ Ġchart Instances . draw ( data Instances , Ġoptions Instances ); ĊĊĠĠĠĠĠĠĠ Ġ// ĠCH ART ĠINST AN CES ĠDIFF ĊĠĠĠĠĠĠĠĠĊĠĠĠĠĠĠĠ Ġvar Ġdata Instances Diff Ġ= Ġgoogle . visualization . array To DataTable ([ ĊĠĠĠĠĠĠĠĠĠ Ġ### TABLE _ INST AN CES _ DIFF ### ĊĠĠĠĠĠĠĠ Ġ]); ĊĠĠĠĠĠĠĠ Ġdate _ formatter . format ( data Instances Diff , Ġ 0 ); ĊĊĠĠĠĠĠĠĠ Ġvar Ġoptions Instances Diff Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġtitle : Ġ' ### TITLE _ INST AN CES _ DIFF ### ', ĊĠĠĠĠĠĠĠĠĠ Ġh Axis : Ġ{ title : Ġ' ### H _ AXIS _ TITLE _ INST AN CES _ DIFF ### ', Ġ Ġtitle TextStyle : Ġ{ color : Ġ'# 3 3 3 '}, Ġformat : Ġ' dd - MM ĠHH : mm ', Ġminor Grid lines : Ġ{ count : Ġ 1 0 , Ġformat : Ġ' mm '} Ġ}, ĊĠĠĠĠĠĠĠĠĠ Ġv Axis : Ġ{ title : Ġ' ### V _ AXIS _ TITLE _ INST AN CES _ DIFF ### ', Ġscale Type : Ġ' mirror Log ', Ġview Window : Ġ{} Ġ}, ĊĠĠĠĠĠĠĠĠĠ Ġchart Area : Ġ{ Ġleft :' 1 0 %', Ġwidth :' 6 0 %' Ġ} ĊĠĠĠĠĠĠĠ Ġ}; ĊĊĠĠĠĠĠĠĠ Ġvar Ġchart Bytes Diff Ġ= Ġnew Ġgoogle . visualization . Line Chart ( document . getElementById (' chart _ div _ instances _ diff ')); ĊĠĠĠĠĠĠĠ Ġchart Bytes Diff . draw ( data Instances Diff , Ġoptions Instances Diff ); ĊĊĠĠĠ Ġ} ĊĠĠĠ Ġ</ script > ĊĠ Ġ</ head > ĊĠ Ġ< body > ĊĠĠĠ Ġ< div Ġstyle =" margin : Ġ 5 %"> ĊĠĠĠ Ġ< h 1 > Sto k pop ĠMemory ĠCheck </ h 2 > ĊĠĠĠ Ġ< h 2 > Heap ĠHistogram ĠDump s ĠAnalysis </ h 2 > ĊĠĠĠ Ġ### ANAL YS IS - RESULT - SUM MARY ### ĊĠĠĠ Ġ< h 2 > Heap ĠHistogram ĠDump s ĠChart s </ h 2 > ĊĠĠĠ Ġ</ div > ĊĠĠĠ Ġ< div Ġid =" chart _ div _ bytes " Ġstyle =" width : Ġ 9 6 %; Ġmin - height : Ġ 8 0 0 px ; Ġheight : Ġ 5 0 %; Ġmargin - left : Ġauto ; Ġmargin - right : Ġauto "></ div > ĊĠĠĠ Ġ< div Ġid =" chart _ div _ bytes _ diff " Ġstyle =" width : Ġ 9 6 %; Ġmin - height : Ġ 8 0 0 px ; Ġheight : Ġ 5 0 %; Ġmargin - left : Ġauto ; Ġmargin - right : Ġauto "></ div > ĊĠĠĠ Ġ< div Ġid =" chart _ div _ instances " Ġstyle =" width : Ġ 9 6 %; Ġmin - height : Ġ 8 0 0 px ; Ġheight : Ġ 5 0 %; Ġmargin - left : Ġauto ; Ġmargin - right : Ġauto "></ div > ĊĠĠĠ Ġ< div Ġid =" chart _ div _ instances _ diff " Ġstyle =" width : Ġ 9 6 %; Ġmin - height : Ġ 8 0 0 px ; Ġheight : Ġ 5 0 %; Ġmargin - left : Ġauto ; Ġmargin - right : Ġauto "></ div > ĊĠ Ġ</ body > Ċ </ html > """ ĊĊĠĠĠ Ġfun Ġwrite Html Google Graph File ( data : ĠHeap Histogram Dump Report , Ġreport Config : ĠReport Config ): ĠFile Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtitle Ġ= Ġreport Config . identifier ĊĠĠĠĠĠĠĠ Ġval Ġtimestamps Ġ= Ġdata . heap Histogram Dump Details . timestamps ĊĊĠĠĠĠĠĠĠ Ġvar Ġtemplate Ġ= ĠCH ART _ HTML _ TEMPLATE ĊĠĠĠĠĠĠĠ Ġval Ġsize Ġ= Ġtimestamps . size ĊĠĠĠĠĠĠĠ Ġif Ġ( size Ġ< Ġ 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= ĠString . format (" Not Ġenough Ġpoints Ġ([ % d ]< 3 ) Ġto Ġcreate Ġhtml Ġgraph Ġfor Ġ[% s ]. ", Ġsize , Ġtitle ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtemplate Ġ= Ġ"< p >$ message < p >" ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtemplate Ġ= Ġtemplate . replace (" ### ANAL YS IS - RESULT - SUM MARY ### ", Ġanalysis Result Table ( data , Ġreport Config )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdetails Ġ= Ġdata . heap Histogram Dump Details . class Histogram Details ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtemplate Ġ= Ġcreate Bytes Table ( title , Ġtimestamps , Ġdetails , Ġtemplate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtemplate Ġ= Ġcreate Bytes Table Diff ( title , Ġtimestamps , Ġdetails , Ġtemplate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtemplate Ġ= Ġcreate Instances Table ( title , Ġtimestamps , Ġdetails , Ġtemplate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtemplate Ġ= Ġcreate Instances Table Diff ( title , Ġtimestamps , Ġdetails , Ġtemplate ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġfile Ġ= ĠFile ( report Config . report Directory , Ġ" heap Histogram Dump Report -$ title . html ") ĊĠĠĠĠĠĠĠ Ġfile . write Text ( template ) ĊĠĠĠĠĠĠĠ Ġreturn Ġfile ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġanalysis Result Table ( data : ĠHeap Histogram Dump Report , Ġreport Config : ĠReport Config ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġhtml Ġ= ĠStringBuilder ( 2 0 4 8 ) ĊĠĠĠĠĠĠĠ Ġval Ġreport Limits Ġ= Ġdata . report Limits ĊĊĠĠĠĠĠĠĠ Ġhtml . append ("< table >") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< th > key </ th >< th > value </ th ></ tr >") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< td > Test Ġrun Ġid </ td >< td >< b >${ report Config . identifier }</ b ></ td ></ tr > "). append ("\ n ") ĊĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< td > Report Ġdate </ td >< td >< b >${ report Config . report DateTime }</ b ></ td ></ tr > "). append ("\ n ") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< td > Overall Ġanalysis Ġresult </ td >< td >< b >${ data . leak Result }</ b ></ td ></ tr > "). append ("\ n ") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< td > Report Ġsettings </ td >< td >< b >${ report Config . settings }</ b ></ td ></ tr > "). append ("\ n ") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< td > Report Ġclass Ġlimit </ td >< td >< b >${ report Limits . class Limit }</ b ></ td ></ tr > "). append ("\ n ") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< td > Report Ġbyte Ġlimit </ td >< td >< b >${ Conversion Utils . human Readable Memory Size ( report Limits . byte Limit )}</ b ></ td ></ tr > "). append ("\ n ") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< td > Maximum Ġallowed Ġgrowth Ġpercentage </ td >< td >< b >${ report Limits . max Grow th Percentage } Ġ%</ b ></ td ></ tr > "). append ("\ n ") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< td > Minimum Ġgrowth Ġpoints Ġpercentage </ td >< td >< b >${ report Limits . min Grow th Points Percentage } Ġ%</ b ></ td ></ tr > "). append ("\ n ") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< td > Safe Ġlist </ td >< td >< b >${ report Limits . safe List }</ b ></ td ></ tr > "). append ("\ n ") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< td > Watch Ġlist </ td >< td >< b >${ report Limits . watch List }</ b ></ td ></ tr > "). append ("\ n ") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< table >") ĊĊĠĠĠĠĠĠĠ Ġhtml . append ("< table > "). append ("\ n ") ĊĠĠĠĠĠĠĠ Ġhtml . append ("< tr >< th > analysis Ġresult </ th >< th > count </ th >< th > icon </ th >< th > description </ th ></ tr >") ĊĠĠĠĠĠĠĠ Ġhtml . append ( data . heap Histogram Dump Summary . data . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"< tr >< td >${ it . key }</ td >< td >${ it . value }</ td >< td >${ map To Unicode Arrow ( it . key )}</ td >< td >${ it . key . description }</ td ></ tr >" ĊĠĠĠĠĠĠĠ Ġ}. join ToString ( separator Ġ= Ġ"\ n ")) ĊĠĠĠĠĠĠĠ Ġhtml . append ("</ table >") ĊĠĠĠĠĠĠĠ Ġreturn Ġhtml . toString () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Chart DataTable ( ĊĠĠĠĠĠĠĠ Ġdata : ĠList < Class Histogram Details >, ĊĠĠĠĠĠĠĠ Ġtimestamps : ĠList < Long ? >, ĊĠĠĠĠĠĠĠ Ġdetails Mapper : Ġ( Class Histogram Details ) Ġ-> ĠList < Long ?> ĊĠĠĠ Ġ): ĠString Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġtable Ġ= ĠStringBuilder ( 2 0 4 8 ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġno Ġcolors Ġin Ġlegend Ġnames ĠðŁĺ Ķ ĊĠĠĠĠĠĠĠ Ġval ĠclassNames Ġ= Ġdata . map Ġ{ Ġ"${ map To Unicode Arrow ( it . analysis )} $ non Break Space ${ Class Info . prefix Watch List And Safe List ( it . class Info )} ${ it . class Info . name }" Ġ}. toList () ĊĠĠĠĠĠĠĠ Ġval Ġdetails List Ġ= Ġdata . map ( details Mapper ). toList () ĊĊĠĠĠĠĠĠĠ Ġtable . append (" [' Time '") ĊĠĠĠĠĠĠĠ Ġif Ġ( class Names . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠclassNames List Ġ= ĠclassNames . map Ġ{ Ġ"' ${ it } '" Ġ}. join ToString ( separator Ġ= Ġ", ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtable . append (", Ġ"). append ( class Names List ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtable . append (", Ġ' No ĠData '") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtable . append (" ], \ n ") ĊĊĠĠĠĠĠĠĠ Ġvar Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġfor Ġ( timestamp Ġin Ġtimestamps ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtable . append ("[ Ġnew ĠDate (" ). append ( timestamp ). append (" )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( details List . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtable . append (", Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbytes For Timestamp Ġ= Ġdetails List . map Ġ{ Ġit [ i ] Ġ?: Ġ 0 Ġ}. join ToString ( separator Ġ= Ġ", ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtable . append ( bytes For Timestamp ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtable . append (", Ġ 0 ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtable . append (" ]"). append ("," ). append ("\ n ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġi ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġremove Ġlast Ġ, ĊĠĠĠĠĠĠĠ Ġtable . delete Char At ( table . length Ġ- Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtable . toString () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmap To Unicode Arrow ( analysis : ĠAnalysis Result ): ĠChar Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( analysis ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . GRO W _ CRITICAL Ġ-> Ġarrow Up Critical ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . GRO W _ MINOR Ġ-> Ġarrow Up Minor ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . GRO W _ SAFE Ġ-> Ġarrow Up Safe ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . GRO W _ H ICK _ UP S Ġ-> Ġarrow Grow H ick U ps ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . SH R INK _ AND _ GRO W Ġ-> Ġarrow UpDown ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . SH R INK Ġ-> Ġarrow Down ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . ST ABLE Ġ-> Ġarrow Flat ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . SINGLE Ġ-> Ġ' 1 ' ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . UNKNOWN Ġ-> Ġ' ?' ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmap To Color Unicode Arrow ( analysis : ĠAnalysis Result ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcolor Ġ= Ġwhen Ġ( analysis ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . GRO W _ CRITICAL Ġ-> Ġ" red " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . GRO W _ MINOR Ġ-> Ġ" orange " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . GRO W _ SAFE Ġ-> Ġ" green " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . GRO W _ H ICK _ UP S Ġ-> Ġ" purple " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . SH R INK _ AND _ GRO W Ġ-> Ġ" magenta " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . SH R INK Ġ-> Ġ" dark - gray " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . ST ABLE Ġ-> Ġ" black " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . SINGLE Ġ-> Ġ" black " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAnalysis Result . UNKNOWN Ġ-> Ġ" light - gray " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ"< div Ġstyle =' color :$ color '> ${ map To Unicode Arrow ( analysis )}</ div >" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Bytes Table ( ĊĠĠĠĠĠĠĠ Ġtitle : ĠString , ĊĠĠĠĠĠĠĠ Ġtimestamps : ĠList < Long ? >, ĊĠĠĠĠĠĠĠ Ġdata : ĠList < Class Histogram Details >, ĊĠĠĠĠĠĠĠ Ġtemplate : ĠString ĊĠĠĠ Ġ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġnew Template Ġ= Ġtemplate ĊĊĠĠĠĠĠĠĠ Ġval Ġdetails Mapper : Ġ( Class Histogram Details ) Ġ-> ĠList < Long ?> Ġ= Ġ{ Ġit . bytes Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġtable Ġ= Ġcreate Chart DataTable ( data , Ġtimestamps , Ġdetails Mapper ) ĊĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### TABLE _ BYTES ### ", Ġtable ) ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### TITLE _ BYTES ### ", Ġ" bytes Ġin Ġheap Ġ- Ġ$ title ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### H _ AXIS _ TITLE _ BYTES ### ", Ġ" time ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### V _ AXIS _ TITLE _ BYTES ### ", Ġ" bytes ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### BASE _ UNIT _ FULL _ BYTES ### ", Ġ" bytes ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### BASE _ UNIT _ SHORT _ BYTES ### ", Ġ" B ") ĊĠĠĠĠĠĠĠ Ġreturn Ġnew Template ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Bytes Table Diff ( title : ĠString , Ġtimestamps : ĠList < Long ? >, Ġdata : ĠList < Class Histogram Details >, Ġtemplate : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġnew Template Ġ= Ġtemplate ĊĊĠĠĠĠĠĠĠ Ġval Ġdetails Mapper : Ġ( Class Histogram Details ) Ġ-> ĠList < Long ?> Ġ= Ġ{ Ġit . bytes Diff Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġtable Ġ= Ġcreate Chart DataTable ( data , Ġtimestamps , Ġdetails Mapper ) ĊĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### TABLE _ BYTES _ DIFF ### ", Ġtable ) ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### TITLE _ BYTES _ DIFF ### ", Ġ" bytes Ġdiff Ġin Ġheap Ġ- Ġ$ title ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### H _ AXIS _ TITLE _ BYTES _ DIFF ### ", Ġ" time ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### V _ AXIS _ TITLE _ BYTES _ DIFF ### ", Ġ" bytes Ġdiff ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### BASE _ UNIT _ FULL _ BYTES _ DIFF ### ", Ġ" bytes ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### BASE _ UNIT _ SHORT _ BYTES _ DIFF ### ", Ġ" B ") ĊĠĠĠĠĠĠĠ Ġreturn Ġnew Template ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Instances Table ( title : ĠString , Ġtimestamps : ĠList < Long ? >, Ġdata : ĠList < Class Histogram Details >, Ġtemplate : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġnew Template Ġ= Ġtemplate ĊĊĠĠĠĠĠĠĠ Ġval Ġdetails Mapper : Ġ( Class Histogram Details ) Ġ-> ĠList < Long ?> Ġ= Ġ{ Ġit . instances Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġtable Ġ= Ġcreate Chart DataTable ( data , Ġtimestamps , Ġdetails Mapper ) ĊĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### TABLE _ INST AN CES ### ", Ġtable ) ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### TITLE _ INST AN CES ### "," instances Ġin Ġheap Ġ- Ġ$ title ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### H _ AXIS _ TITLE _ INST AN CES ### "," time ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### V _ AXIS _ TITLE _ INST AN CES ### "," instances ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### BASE _ UNIT _ FULL _ INST AN CES ### "," instances ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### BASE _ UNIT _ SHORT _ INST AN CES ### "," # ") ĊĠĠĠĠĠĠĠ Ġreturn Ġnew Template ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Instances Table Diff ( title : ĠString , Ġtimestamps : ĠList < Long ? >, Ġdata : ĠList < Class Histogram Details >, Ġtemplate : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġnew Template Ġ= Ġtemplate ĊĊĠĠĠĠĠĠĠ Ġval Ġdetails Mapper : Ġ( Class Histogram Details ) Ġ-> ĠList < Long ?> Ġ= Ġ{ Ġit . instances Diff Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġtable Ġ= Ġcreate Chart DataTable ( data , Ġtimestamps , Ġdetails Mapper ) ĊĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### TABLE _ INST AN CES _ DIFF ### ", Ġtable ) ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### TITLE _ INST AN CES _ DIFF ### ", Ġ" instances Ġdiff Ġin Ġheap Ġ- Ġ$ title ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### H _ AXIS _ TITLE _ INST AN CES _ DIFF ### ", Ġ" time ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### V _ AXIS _ TITLE _ INST AN CES _ DIFF ### ", Ġ" instances Ġdiff ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### BASE _ UNIT _ FULL _ INST AN CES _ DIFF ### ", Ġ" instances ") ĊĠĠĠĠĠĠĠ Ġnew Template Ġ= Ġnew Template . replace (" ### BASE _ UNIT _ SHORT _ INST AN CES _ DIFF ### ", Ġ"# ") ĊĠĠĠĠĠĠĠ Ġreturn Ġnew Template ĊĠĠĠ Ġ} Ċ Ċ }