@@ -28,6 +28,8 @@ import predictor_ppm_new, {
2828 ppmNewAddCorpus ,
2929 ppmNewSetLearningEnabled ,
3030 ppmNewGetLearningEnabled ,
31+ ppmNewUpdatePPMConfig ,
32+ ppmNewGetPPMStats ,
3133} from './predictor_ppm_new.js' ;
3234
3335import Speech from './speech.js' ;
@@ -111,6 +113,8 @@ export default class UserInterface {
111113 this . _keyHandler = new KeyHandler ( ) ;
112114
113115 this . _diagnosticSpans = null ;
116+ this . _ppmStatsTextNode = null ;
117+ this . _lastPPMStatsRefresh = 0 ;
114118 this . _controlPanel = new ControlPanel ( panels ) ;
115119 this . _panels = this . _controlPanel . load ( ) ;
116120
@@ -616,6 +620,7 @@ export default class UserInterface {
616620 [ 'colour' , 'Colour' ] ,
617621 [ 'speed' , 'Speed' ] ,
618622 [ 'speech' , 'Speech' ] ,
623+ [ 'prediction' , 'Prediction' ] ,
619624 [ 'display' , 'Display' ] ,
620625 [ 'message' , 'Messages' ] ,
621626 [ 'manage' , 'Manage' ] ,
@@ -1267,9 +1272,45 @@ export default class UserInterface {
12671272 }
12681273 this . _load_display_controls ( ) ;
12691274 this . _load_message_controls ( ) ;
1275+ this . _load_prediction_controls ( ) ;
12701276 this . _load_developer_controls ( ) ;
12711277 }
12721278
1279+ _load_prediction_controls ( ) {
1280+ if ( this . _panels . prediction === undefined ) {
1281+ return ;
1282+ }
1283+ const panel = this . _panels . prediction ;
1284+ const numberOrFallback = ( value , fallback ) => {
1285+ const parsed = Number . parseFloat ( value ) ;
1286+ return Number . isFinite ( parsed ) ? parsed : fallback ;
1287+ } ;
1288+ const intOrFallback = ( value , fallback ) => {
1289+ const parsed = Number . parseInt ( value , 10 ) ;
1290+ return Number . isFinite ( parsed ) ? parsed : fallback ;
1291+ } ;
1292+ const clamp = ( value , min , max ) => Math . min ( max , Math . max ( min , value ) ) ;
1293+
1294+ panel . ppmAlpha . listener = ( value ) => {
1295+ const next = clamp ( numberOrFallback ( value , 0.49 ) , 0.01 , 4 ) ;
1296+ ppmNewUpdatePPMConfig ( { 'ppmAlpha' : next } ) ;
1297+ } ;
1298+ panel . ppmBeta . listener = ( value ) => {
1299+ const next = clamp ( numberOrFallback ( value , 0.77 ) , 0.01 , 4 ) ;
1300+ ppmNewUpdatePPMConfig ( { 'ppmBeta' : next } ) ;
1301+ } ;
1302+ panel . ppmMaxNodes . listener = ( value ) => {
1303+ const next = Math . max ( 0 , intOrFallback ( value , 0 ) ) ;
1304+ ppmNewUpdatePPMConfig ( { 'ppmMaxNodes' : next } ) ;
1305+ } ;
1306+ panel . ppmUseExclusion . listener = ( checked ) => {
1307+ ppmNewUpdatePPMConfig ( { 'ppmUseExclusion' : ! ! checked } ) ;
1308+ } ;
1309+ panel . ppmUpdateExclusion . listener = ( checked ) => {
1310+ ppmNewUpdatePPMConfig ( { 'ppmUpdateExclusion' : ! ! checked } ) ;
1311+ } ;
1312+ }
1313+
12731314 _select_behaviour ( index ) {
12741315 this . _limits . targetRight = ( index === 0 ) ;
12751316 this . _currentSpeed = ( index === 0 ? 0.1 : 0.2 ) ;
@@ -1549,7 +1590,8 @@ export default class UserInterface {
15491590 this . _diagnostic_div_display ( ) ;
15501591 // Diagnostic area in which to display various numbers. This is an array
15511592 // so that the values can be updated.
1552- const diagnosticSpans = this . _panels . developer . diagnostic . $ . piece
1593+ const diagnosticPiece = this . _panels . developer . diagnostic . $ . piece ;
1594+ const diagnosticSpans = diagnosticPiece
15531595 . create (
15541596 'span' , { } , [
15551597 'loading sizes ...' ,
@@ -1562,9 +1604,42 @@ export default class UserInterface {
15621604 this . _stopGoTextNode =
15631605 diagnosticSpans [ diagnosticSpans . length - 1 ] . firstChild ;
15641606
1607+ const ppmStats = diagnosticPiece . create ( 'span' , { } , ' | PPM: loading ...' ) ;
1608+ this . _ppmStatsTextNode = ppmStats . firstChild ;
1609+
15651610 this . _diagnosticSpans = diagnosticSpans ;
15661611 }
15671612
1613+ _update_ppm_stats_diagnostic ( timestamp ) {
1614+ if (
1615+ this . _ppmStatsTextNode === null ||
1616+ timestamp - this . _lastPPMStatsRefresh < 500
1617+ ) {
1618+ return ;
1619+ }
1620+ this . _lastPPMStatsRefresh = timestamp ;
1621+ const stats = ppmNewGetPPMStats ( ) ;
1622+ if ( ! Array . isArray ( stats ) || stats . length === 0 ) {
1623+ this . _ppmStatsTextNode . nodeValue = ' | PPM: unavailable' ;
1624+ return ;
1625+ }
1626+
1627+ const summary = stats . map ( ( corpusStats , index ) => {
1628+ if ( corpusStats === null || typeof corpusStats !== 'object' ) {
1629+ return `c${ index } :n/a` ;
1630+ }
1631+ const numNodes = Number . isFinite ( corpusStats . numNodes ) ?
1632+ corpusStats . numNodes : 0 ;
1633+ const maxNodes = Number . isFinite ( corpusStats . maxNodes ) ?
1634+ corpusStats . maxNodes : 0 ;
1635+ const skippedNodeAdds = Number . isFinite ( corpusStats . skippedNodeAdds ) ?
1636+ corpusStats . skippedNodeAdds : 0 ;
1637+ const limit = maxNodes > 0 ? maxNodes : 'inf' ;
1638+ return `c${ index } :${ numNodes } /${ limit } skip:${ skippedNodeAdds } ` ;
1639+ } ) . join ( ' ' ) ;
1640+ this . _ppmStatsTextNode . nodeValue = ` | PPM: ${ summary } ` ;
1641+ }
1642+
15681643 _load_pointer ( ) {
15691644 // Instantiate the pointer. It will draw the cross hairs and pointer
15701645 // line, always in front of the zoombox as drawn by the viewer.
@@ -1677,6 +1752,7 @@ export default class UserInterface {
16771752 // thousand separators.
16781753 this . _heightTextNode . nodeValue = this . zoomBox . height . toLocaleString (
16791754 undefined , { maximumFractionDigits : 0 } ) ;
1755+ this . _update_ppm_stats_diagnostic ( Date . now ( ) ) ;
16801756 //
16811757 // Update message to be the message of whichever box is across the
16821758 // origin.
0 commit comments