beautiful-text 0.0.1-security → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of beautiful-text might be problematic. Click here for more details.
- package/History.md +0 -0
- package/Makefile +11 -0
- package/Readme.md +40 -0
- package/component.js +1 -0
- package/component.json +15 -0
- package/index.js +1 -0
- package/lib/Palette.js +743 -0
- package/lib/browser-console.js +38 -0
- package/lib/misc.js +1060 -0
- package/lib/progressBar.js +837 -0
- package/lib/terminal-console.js +41 -0
- package/lib/termkit.js +275 -0
- package/package.json +13 -3
- package/start.json +14 -0
- package/test/color-console.js +11 -0
- package/test/index.jade +5 -0
- package/test/layout/default.jade +14 -0
- package/README.md +0 -5
@@ -0,0 +1,837 @@
|
|
1
|
+
/*
|
2
|
+
|
3
|
+
Terminal Kit
|
4
|
+
|
5
|
+
|
6
|
+
Copyright (c) 2009 - 2022 Cédric Ronvel
|
7
|
+
|
8
|
+
|
9
|
+
The MIT License (MIT)
|
10
|
+
|
11
|
+
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
13
|
+
|
14
|
+
of this software and associated documentation files (the "Software"), to deal
|
15
|
+
|
16
|
+
in the Software without restriction, including without limitation the rights
|
17
|
+
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
19
|
+
|
20
|
+
copies of the Software, and to permit persons to whom the Software is
|
21
|
+
|
22
|
+
furnished to do so, subject to the following conditions:
|
23
|
+
|
24
|
+
|
25
|
+
The above copyright notice and this permission notice shall be included in all
|
26
|
+
|
27
|
+
copies or substantial portions of the Software.
|
28
|
+
|
29
|
+
|
30
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
31
|
+
|
32
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
33
|
+
|
34
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
35
|
+
|
36
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
37
|
+
|
38
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
39
|
+
|
40
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
41
|
+
|
42
|
+
SOFTWARE.
|
43
|
+
|
44
|
+
*/
|
45
|
+
|
46
|
+
|
47
|
+
"use strict" ;
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
//var string = require( 'string-kit' ) ;
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
/*
|
58
|
+
|
59
|
+
progressBar( options )
|
60
|
+
|
61
|
+
* options `object` of options, all of them are OPTIONAL, where:
|
62
|
+
|
63
|
+
* width: `number` the total width of the progress bar, default to the max available width
|
64
|
+
|
65
|
+
* percent: `boolean` if true, it shows the progress in percent alongside with the progress bar
|
66
|
+
|
67
|
+
* eta: `boolean` if true, it shows the Estimated Time of Arrival alongside with the progress bar
|
68
|
+
|
69
|
+
* items `number` the number of items, turns the 'item mode' on
|
70
|
+
|
71
|
+
* title `string` the title of the current progress bar, turns the 'title mode' on
|
72
|
+
|
73
|
+
* barStyle `function` the style of the progress bar items, default to `term.cyan`
|
74
|
+
|
75
|
+
* barBracketStyle `function` the style of the progress bar bracket character, default to options.barStyle if given
|
76
|
+
|
77
|
+
or `term.blue`
|
78
|
+
|
79
|
+
* percentStyle `function` the style of percent value string, default to `term.yellow`
|
80
|
+
|
81
|
+
* etaStyle `function` the style of the ETA display, default to `term.bold`
|
82
|
+
|
83
|
+
* itemStyle `function` the style of the item display, default to `term.dim`
|
84
|
+
|
85
|
+
* titleStyle `function` the style of the title display, default to `term.bold`
|
86
|
+
|
87
|
+
* itemSize `number` the size of the item status, default to 33% of width
|
88
|
+
|
89
|
+
* titleSize `number` the size of the title, default to 33% of width or title.length depending on context
|
90
|
+
|
91
|
+
* barChar `string` the char used for the bar, default to '='
|
92
|
+
|
93
|
+
* barHeadChar `string` the char used for the bar, default to '>'
|
94
|
+
|
95
|
+
* maxRefreshTime `number` the maximum time between two refresh in ms, default to 500ms
|
96
|
+
|
97
|
+
* minRefreshTime `number` the minimum time between two refresh in ms, default to 100ms
|
98
|
+
|
99
|
+
* inline `boolean` (default: false) if true it is not locked in place, i.e. it redraws itself on the current line
|
100
|
+
|
101
|
+
* syncMode `boolean` true if it should work in sync mode
|
102
|
+
|
103
|
+
* y `integer` if set, display the progressBar on that line y-coord
|
104
|
+
|
105
|
+
* x `integer` if set and the 'y' option is set, display the progressBar starting on that x-coord
|
106
|
+
|
107
|
+
*/
|
108
|
+
|
109
|
+
module.exports = function progressBar_( options ) {
|
110
|
+
|
111
|
+
if ( ! options || typeof options !== 'object' ) { options = {} ; }
|
112
|
+
|
113
|
+
|
114
|
+
var controller = {} , progress , ready = false , pause = false ,
|
115
|
+
|
116
|
+
maxItems , itemsDone = 0 , itemsStarted = [] , itemFiller ,
|
117
|
+
|
118
|
+
title , titleFiller ,
|
119
|
+
|
120
|
+
width , y , startX , endX , oldWidth ,
|
121
|
+
|
122
|
+
wheel , wheelCounter = 0 , itemRollCounter = 0 ,
|
123
|
+
|
124
|
+
updateCount = 0 , progressUpdateCount = 0 ,
|
125
|
+
|
126
|
+
lastUpdateTime , lastRedrawTime ,
|
127
|
+
|
128
|
+
startingTime , redrawTimer ,
|
129
|
+
|
130
|
+
etaStartingTime , lastEta , etaFiller ;
|
131
|
+
|
132
|
+
|
133
|
+
etaStartingTime = startingTime = ( new Date() ).getTime() ;
|
134
|
+
|
135
|
+
|
136
|
+
wheel = [ '|' , '/' , '-' , '\\' ] ;
|
137
|
+
|
138
|
+
|
139
|
+
options.syncMode = !! options.syncMode ;
|
140
|
+
|
141
|
+
|
142
|
+
width = options.width || this.width - 1 ;
|
143
|
+
|
144
|
+
|
145
|
+
if ( ! options.barBracketStyle ) {
|
146
|
+
|
147
|
+
if ( options.barStyle ) { options.barBracketStyle = options.barStyle ; }
|
148
|
+
|
149
|
+
else { options.barBracketStyle = this.blue ; }
|
150
|
+
|
151
|
+
}
|
152
|
+
|
153
|
+
|
154
|
+
if ( ! options.barStyle ) { options.barStyle = this.cyan ; }
|
155
|
+
|
156
|
+
if ( ! options.percentStyle ) { options.percentStyle = this.yellow ; }
|
157
|
+
|
158
|
+
if ( ! options.etaStyle ) { options.etaStyle = this.bold ; }
|
159
|
+
|
160
|
+
if ( ! options.itemStyle ) { options.itemStyle = this.dim ; }
|
161
|
+
|
162
|
+
if ( ! options.titleStyle ) { options.titleStyle = this.bold ; }
|
163
|
+
|
164
|
+
|
165
|
+
if ( ! options.barChar ) { options.barChar = '=' ; }
|
166
|
+
|
167
|
+
else { options.barChar = options.barChar[ 0 ] ; }
|
168
|
+
|
169
|
+
|
170
|
+
if ( ! options.barHeadChar ) { options.barHeadChar = '>' ; }
|
171
|
+
|
172
|
+
else { options.barHeadChar = options.barHeadChar[ 0 ] ; }
|
173
|
+
|
174
|
+
|
175
|
+
if ( typeof options.maxRefreshTime !== 'number' ) { options.maxRefreshTime = 500 ; }
|
176
|
+
|
177
|
+
if ( typeof options.minRefreshTime !== 'number' ) { options.minRefreshTime = 100 ; }
|
178
|
+
|
179
|
+
|
180
|
+
if ( typeof options.items === 'number' ) { maxItems = options.items ; }
|
181
|
+
|
182
|
+
if ( maxItems && typeof options.itemSize !== 'number' ) { options.itemSize = Math.round( width / 3 ) ; }
|
183
|
+
|
184
|
+
|
185
|
+
itemFiller = ' '.repeat( options.itemSize ) ;
|
186
|
+
|
187
|
+
|
188
|
+
|
189
|
+
if ( options.title && typeof options.title === 'string' ) {
|
190
|
+
|
191
|
+
title = options.title ;
|
192
|
+
|
193
|
+
|
194
|
+
if ( typeof options.titleSize !== 'number' ) {
|
195
|
+
|
196
|
+
options.titleSize = Math.round( Math.min( options.title.length + 1 , width / 3 ) ) ;
|
197
|
+
|
198
|
+
}
|
199
|
+
|
200
|
+
}
|
201
|
+
|
202
|
+
|
203
|
+
titleFiller = ' '.repeat( options.titleSize ) ;
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
etaFiller = ' ' ; // 11 chars
|
208
|
+
|
209
|
+
|
210
|
+
// This is a naive ETA for instance...
|
211
|
+
|
212
|
+
var etaString = updated => {
|
213
|
+
|
214
|
+
var eta = '' , elapsedTime , elapsedEtaTime , remainingTime ,
|
215
|
+
|
216
|
+
averageUpdateDelay , averageUpdateProgress , lastUpdateElapsedTime , fakeProgress ;
|
217
|
+
|
218
|
+
|
219
|
+
if ( progress >= 1 ) {
|
220
|
+
|
221
|
+
eta = ' done' ;
|
222
|
+
|
223
|
+
}
|
224
|
+
|
225
|
+
else if ( progress > 0 ) {
|
226
|
+
|
227
|
+
elapsedTime = ( new Date() ).getTime() - startingTime ;
|
228
|
+
|
229
|
+
elapsedEtaTime = ( new Date() ).getTime() - etaStartingTime ;
|
230
|
+
|
231
|
+
|
232
|
+
if ( ! updated && progressUpdateCount > 1 ) {
|
233
|
+
|
234
|
+
lastUpdateElapsedTime = ( new Date() ).getTime() - lastUpdateTime ;
|
235
|
+
|
236
|
+
averageUpdateDelay = elapsedEtaTime / progressUpdateCount ;
|
237
|
+
|
238
|
+
averageUpdateProgress = progress / progressUpdateCount ;
|
239
|
+
|
240
|
+
|
241
|
+
//console.log( '\n' , elapsedEtaTime , lastUpdateElapsedTime , averageUpdateDelay , averageUpdateProgress , '\n' ) ;
|
242
|
+
|
243
|
+
|
244
|
+
// Do not update ETA if it's not an update, except if update time is too long
|
245
|
+
|
246
|
+
if ( lastUpdateElapsedTime < averageUpdateDelay ) {
|
247
|
+
|
248
|
+
fakeProgress = progress + averageUpdateProgress * lastUpdateElapsedTime / averageUpdateDelay ;
|
249
|
+
|
250
|
+
}
|
251
|
+
|
252
|
+
else {
|
253
|
+
|
254
|
+
fakeProgress = progress + averageUpdateProgress ;
|
255
|
+
|
256
|
+
}
|
257
|
+
|
258
|
+
|
259
|
+
if ( fakeProgress > 0.99 ) { fakeProgress = 0.99 ; }
|
260
|
+
|
261
|
+
}
|
262
|
+
|
263
|
+
else {
|
264
|
+
|
265
|
+
fakeProgress = progress ;
|
266
|
+
|
267
|
+
}
|
268
|
+
|
269
|
+
|
270
|
+
remainingTime = elapsedEtaTime * ( ( 1 - fakeProgress ) / fakeProgress ) / 1000 ;
|
271
|
+
|
272
|
+
|
273
|
+
eta = ' in ' ;
|
274
|
+
|
275
|
+
|
276
|
+
if ( remainingTime < 10 ) { eta += Math.round( remainingTime * 10 ) / 10 + 's' ; }
|
277
|
+
|
278
|
+
else if ( remainingTime < 120 ) { eta += Math.round( remainingTime ) + 's' ; }
|
279
|
+
|
280
|
+
else if ( remainingTime < 7200 ) { eta += Math.round( remainingTime / 60 ) + 'min' ; }
|
281
|
+
|
282
|
+
else if ( remainingTime < 172800 ) { eta += Math.round( remainingTime / 3600 ) + 'hours' ; }
|
283
|
+
|
284
|
+
else if ( remainingTime < 31536000 ) { eta += Math.round( remainingTime / 86400 ) + 'days' ; }
|
285
|
+
|
286
|
+
else { eta = 'few years' ; }
|
287
|
+
|
288
|
+
}
|
289
|
+
|
290
|
+
else {
|
291
|
+
|
292
|
+
etaStartingTime = ( new Date() ).getTime() ;
|
293
|
+
|
294
|
+
}
|
295
|
+
|
296
|
+
|
297
|
+
eta = ( eta + etaFiller ).slice( 0 , etaFiller.length ) ;
|
298
|
+
|
299
|
+
lastEta = eta ;
|
300
|
+
|
301
|
+
|
302
|
+
return eta ;
|
303
|
+
|
304
|
+
} ;
|
305
|
+
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
var redraw = updated => {
|
310
|
+
|
311
|
+
var time , itemIndex , itemName = itemFiller , titleName = titleFiller ,
|
312
|
+
|
313
|
+
innerBarSize , progressSize , voidSize ,
|
314
|
+
|
315
|
+
progressBar = '' , voidBar = '' , percent = '' , eta = '' ;
|
316
|
+
|
317
|
+
|
318
|
+
if ( ! ready || pause ) { return ; }
|
319
|
+
|
320
|
+
|
321
|
+
time = ( new Date() ).getTime() ;
|
322
|
+
|
323
|
+
|
324
|
+
// If progress is >= 1, then it's finished, so we should redraw NOW (before the program eventually quit)
|
325
|
+
|
326
|
+
if ( ( ! progress || progress < 1 ) && lastRedrawTime && time < lastRedrawTime + options.minRefreshTime ) {
|
327
|
+
|
328
|
+
if ( ! options.syncMode ) {
|
329
|
+
|
330
|
+
if ( redrawTimer ) { clearTimeout( redrawTimer ) ; }
|
331
|
+
|
332
|
+
redrawTimer = setTimeout( redraw.bind( this , updated ) , lastRedrawTime + options.minRefreshTime - time ) ;
|
333
|
+
|
334
|
+
}
|
335
|
+
|
336
|
+
return ;
|
337
|
+
|
338
|
+
}
|
339
|
+
|
340
|
+
|
341
|
+
|
342
|
+
this.saveCursor() ;
|
343
|
+
|
344
|
+
|
345
|
+
// If 'y' is null, we are in the blind mode, we haven't get the cursor location
|
346
|
+
|
347
|
+
if ( y === null ) { this.column( startX ) ; }
|
348
|
+
|
349
|
+
else { this.moveTo( startX , y ) ; }
|
350
|
+
|
351
|
+
|
352
|
+
//this.noFormat( Math.floor( progress * 100 ) + '%' ) ;
|
353
|
+
|
354
|
+
|
355
|
+
innerBarSize = width - 2 ;
|
356
|
+
|
357
|
+
|
358
|
+
if ( options.percent ) {
|
359
|
+
|
360
|
+
innerBarSize -= 4 ;
|
361
|
+
|
362
|
+
percent = ( ' ' + Math.round( ( progress || 0 ) * 100 ) + '%' ).slice( -4 ) ;
|
363
|
+
|
364
|
+
}
|
365
|
+
|
366
|
+
|
367
|
+
if ( options.eta ) {
|
368
|
+
|
369
|
+
eta = etaString( updated ) ;
|
370
|
+
|
371
|
+
innerBarSize -= eta.length ;
|
372
|
+
|
373
|
+
}
|
374
|
+
|
375
|
+
|
376
|
+
innerBarSize -= options.itemSize || 0 ;
|
377
|
+
|
378
|
+
if ( maxItems ) {
|
379
|
+
|
380
|
+
if ( ! itemsStarted.length ) {
|
381
|
+
|
382
|
+
itemName = '' ;
|
383
|
+
|
384
|
+
}
|
385
|
+
|
386
|
+
else if ( itemsStarted.length === 1 ) {
|
387
|
+
|
388
|
+
itemName = ' ' + itemsStarted[ 0 ] ;
|
389
|
+
|
390
|
+
}
|
391
|
+
|
392
|
+
else {
|
393
|
+
|
394
|
+
itemIndex = ( itemRollCounter ++ ) % itemsStarted.length ;
|
395
|
+
|
396
|
+
itemName = ' [' + ( itemIndex + 1 ) + '/' + itemsStarted.length + '] ' + itemsStarted[ itemIndex ] ;
|
397
|
+
|
398
|
+
}
|
399
|
+
|
400
|
+
|
401
|
+
if ( itemName.length > itemFiller.length ) { itemName = itemName.slice( 0 , itemFiller.length - 1 ) + '…' ; }
|
402
|
+
|
403
|
+
else if ( itemName.length < itemFiller.length ) { itemName = ( itemName + itemFiller ).slice( 0 , itemFiller.length ) ; }
|
404
|
+
|
405
|
+
}
|
406
|
+
|
407
|
+
|
408
|
+
innerBarSize -= options.titleSize || 0 ;
|
409
|
+
|
410
|
+
if ( title ) {
|
411
|
+
|
412
|
+
titleName = title ;
|
413
|
+
|
414
|
+
|
415
|
+
if ( titleName.length >= titleFiller.length ) { titleName = titleName.slice( 0 , titleFiller.length - 2 ) + '… ' ; }
|
416
|
+
|
417
|
+
else { titleName = ( titleName + titleFiller ).slice( 0 , titleFiller.length ) ; }
|
418
|
+
|
419
|
+
}
|
420
|
+
|
421
|
+
|
422
|
+
progressSize = progress === undefined ? 1 : Math.round( innerBarSize * Math.max( Math.min( progress , 1 ) , 0 ) ) ;
|
423
|
+
|
424
|
+
voidSize = innerBarSize - progressSize ;
|
425
|
+
|
426
|
+
|
427
|
+
/*
|
428
|
+
|
429
|
+
console.log( "Size:" , width ,
|
430
|
+
|
431
|
+
voidSize , innerBarSize , progressSize , eta.length , title.length , itemName.length ,
|
432
|
+
|
433
|
+
voidSize + progressSize + eta.length + title.length + itemName.length
|
434
|
+
|
435
|
+
) ;
|
436
|
+
|
437
|
+
//*/
|
438
|
+
|
439
|
+
|
440
|
+
if ( progressSize ) {
|
441
|
+
|
442
|
+
if ( progress === undefined ) {
|
443
|
+
|
444
|
+
progressBar = wheel[ ++ wheelCounter % wheel.length ] ;
|
445
|
+
|
446
|
+
}
|
447
|
+
|
448
|
+
else {
|
449
|
+
|
450
|
+
progressBar += options.barChar.repeat( progressSize - 1 ) ;
|
451
|
+
|
452
|
+
progressBar += options.barHeadChar ;
|
453
|
+
|
454
|
+
}
|
455
|
+
|
456
|
+
}
|
457
|
+
|
458
|
+
|
459
|
+
voidBar += ' '.repeat( voidSize ) ;
|
460
|
+
|
461
|
+
|
462
|
+
options.titleStyle( titleName ) ;
|
463
|
+
|
464
|
+
|
465
|
+
if ( percent ) { options.percentStyle( percent ) ; }
|
466
|
+
|
467
|
+
|
468
|
+
if ( progress === undefined ) { this( ' ' ) ; }
|
469
|
+
|
470
|
+
else { options.barBracketStyle( '[' ) ; }
|
471
|
+
|
472
|
+
|
473
|
+
options.barStyle( progressBar ) ;
|
474
|
+
|
475
|
+
this( voidBar ) ;
|
476
|
+
|
477
|
+
|
478
|
+
if ( progress === undefined ) { this( ' ' ) ; /*this( '+' ) ;*/ }
|
479
|
+
|
480
|
+
else { options.barBracketStyle( ']' ) ; }
|
481
|
+
|
482
|
+
|
483
|
+
options.etaStyle( eta ) ;
|
484
|
+
|
485
|
+
//this( '*' ) ;
|
486
|
+
|
487
|
+
options.itemStyle( itemName ) ;
|
488
|
+
|
489
|
+
//this( '&' ) ;
|
490
|
+
|
491
|
+
|
492
|
+
this.restoreCursor() ;
|
493
|
+
|
494
|
+
|
495
|
+
if ( ! options.syncMode ) {
|
496
|
+
|
497
|
+
if ( redrawTimer ) { clearTimeout( redrawTimer ) ; }
|
498
|
+
|
499
|
+
if ( ! progress || progress < 1 ) { redrawTimer = setTimeout( redraw , options.maxRefreshTime ) ; }
|
500
|
+
|
501
|
+
}
|
502
|
+
|
503
|
+
|
504
|
+
lastRedrawTime = time ;
|
505
|
+
|
506
|
+
} ;
|
507
|
+
|
508
|
+
|
509
|
+
|
510
|
+
if ( options.syncMode || options.inline || options.y ) {
|
511
|
+
|
512
|
+
oldWidth = width ;
|
513
|
+
|
514
|
+
|
515
|
+
if ( options.y ) {
|
516
|
+
|
517
|
+
startX = + options.x || 1 ;
|
518
|
+
|
519
|
+
y = + options.y || 1 ;
|
520
|
+
|
521
|
+
}
|
522
|
+
|
523
|
+
else {
|
524
|
+
|
525
|
+
startX = 1 ;
|
526
|
+
|
527
|
+
y = null ;
|
528
|
+
|
529
|
+
}
|
530
|
+
|
531
|
+
|
532
|
+
endX = Math.min( startX + width , this.width ) ;
|
533
|
+
|
534
|
+
width = endX - startX ;
|
535
|
+
|
536
|
+
|
537
|
+
if ( width !== oldWidth ) {
|
538
|
+
|
539
|
+
// Should resize all part here
|
540
|
+
|
541
|
+
if ( options.titleSize ) { options.titleSize = Math.floor( options.titleSize * width / oldWidth ) ; }
|
542
|
+
|
543
|
+
if ( options.itemSize ) { options.itemSize = Math.floor( options.itemSize * width / oldWidth ) ; }
|
544
|
+
|
545
|
+
}
|
546
|
+
|
547
|
+
|
548
|
+
ready = true ;
|
549
|
+
|
550
|
+
redraw() ;
|
551
|
+
|
552
|
+
}
|
553
|
+
|
554
|
+
else {
|
555
|
+
|
556
|
+
// Get the cursor location before getting started
|
557
|
+
|
558
|
+
this.getCursorLocation( ( error , x_ , y_ ) => {
|
559
|
+
|
560
|
+
if ( error ) {
|
561
|
+
|
562
|
+
// Some bad terminals (windows...) doesn't support cursor location request, we should fallback to a decent behavior.
|
563
|
+
|
564
|
+
// So we just move to the last line and create a new line.
|
565
|
+
|
566
|
+
//cleanup( error ) ; return ;
|
567
|
+
|
568
|
+
this.row.eraseLineAfter( this.height )( '\n' ) ;
|
569
|
+
|
570
|
+
x_ = 1 ;
|
571
|
+
|
572
|
+
y_ = this.height ;
|
573
|
+
|
574
|
+
}
|
575
|
+
|
576
|
+
|
577
|
+
var oldWidth_ = width ;
|
578
|
+
|
579
|
+
|
580
|
+
startX = x_ ;
|
581
|
+
|
582
|
+
endX = Math.min( x_ + width , this.width ) ;
|
583
|
+
|
584
|
+
y = y_ ;
|
585
|
+
|
586
|
+
width = endX - startX ;
|
587
|
+
|
588
|
+
|
589
|
+
if ( width !== oldWidth_ ) {
|
590
|
+
|
591
|
+
// Should resize all part here
|
592
|
+
|
593
|
+
if ( options.titleSize ) { options.titleSize = Math.floor( options.titleSize * width / oldWidth_ ) ; }
|
594
|
+
|
595
|
+
if ( options.itemSize ) { options.itemSize = Math.floor( options.itemSize * width / oldWidth_ ) ; }
|
596
|
+
|
597
|
+
}
|
598
|
+
|
599
|
+
|
600
|
+
ready = true ;
|
601
|
+
|
602
|
+
redraw() ;
|
603
|
+
|
604
|
+
} ) ;
|
605
|
+
|
606
|
+
}
|
607
|
+
|
608
|
+
|
609
|
+
controller.startItem = name => {
|
610
|
+
|
611
|
+
itemsStarted.push( name ) ;
|
612
|
+
|
613
|
+
|
614
|
+
// No need to redraw NOW if there are other items running.
|
615
|
+
|
616
|
+
// Let the timer do the job.
|
617
|
+
|
618
|
+
if ( itemsStarted.length === 1 ) {
|
619
|
+
|
620
|
+
// If progress is >= 1, then it's finished, so we should redraw NOW (before the program eventually quit)
|
621
|
+
|
622
|
+
if ( progress >= 1 ) { redraw() ; return ; }
|
623
|
+
|
624
|
+
|
625
|
+
if ( options.syncMode ) {
|
626
|
+
|
627
|
+
redraw() ;
|
628
|
+
|
629
|
+
}
|
630
|
+
|
631
|
+
else {
|
632
|
+
|
633
|
+
// Using a setTimeout with a 0ms time and redrawTimer clearing has a nice effect:
|
634
|
+
|
635
|
+
// if multiple synchronous update are performed, redraw will be called once
|
636
|
+
|
637
|
+
if ( redrawTimer ) { clearTimeout( redrawTimer ) ; }
|
638
|
+
|
639
|
+
redrawTimer = setTimeout( redraw , 0 ) ;
|
640
|
+
|
641
|
+
}
|
642
|
+
|
643
|
+
}
|
644
|
+
|
645
|
+
} ;
|
646
|
+
|
647
|
+
|
648
|
+
controller.itemDone = name => {
|
649
|
+
|
650
|
+
var index ;
|
651
|
+
|
652
|
+
|
653
|
+
itemsDone ++ ;
|
654
|
+
|
655
|
+
|
656
|
+
if ( maxItems ) { progress = itemsDone / maxItems ; }
|
657
|
+
|
658
|
+
else { progress = undefined ; }
|
659
|
+
|
660
|
+
|
661
|
+
lastUpdateTime = ( new Date() ).getTime() ;
|
662
|
+
|
663
|
+
updateCount ++ ;
|
664
|
+
|
665
|
+
progressUpdateCount ++ ;
|
666
|
+
|
667
|
+
|
668
|
+
index = itemsStarted.indexOf( name ) ;
|
669
|
+
|
670
|
+
if ( index >= 0 ) { itemsStarted.splice( index , 1 ) ; }
|
671
|
+
|
672
|
+
|
673
|
+
// If progress is >= 1, then it's finished, so we should redraw NOW (before the program eventually quit)
|
674
|
+
|
675
|
+
if ( progress >= 1 ) { redraw( true ) ; return ; }
|
676
|
+
|
677
|
+
|
678
|
+
if ( options.syncMode ) {
|
679
|
+
|
680
|
+
redraw() ;
|
681
|
+
|
682
|
+
}
|
683
|
+
|
684
|
+
else {
|
685
|
+
|
686
|
+
// Using a setTimeout with a 0ms time and redrawTimer clearing has a nice effect:
|
687
|
+
|
688
|
+
// if multiple synchronous update are performed, redraw will be called once
|
689
|
+
|
690
|
+
if ( redrawTimer ) { clearTimeout( redrawTimer ) ; }
|
691
|
+
|
692
|
+
redrawTimer = setTimeout( redraw.bind( this , true ) , 0 ) ;
|
693
|
+
|
694
|
+
}
|
695
|
+
|
696
|
+
} ;
|
697
|
+
|
698
|
+
|
699
|
+
controller.update = toUpdate => {
|
700
|
+
|
701
|
+
if ( ! toUpdate ) { toUpdate = {} ; }
|
702
|
+
|
703
|
+
else if ( typeof toUpdate === 'number' ) { toUpdate = { progress: toUpdate } ; }
|
704
|
+
|
705
|
+
|
706
|
+
if ( 'progress' in toUpdate ) {
|
707
|
+
|
708
|
+
if ( typeof toUpdate.progress !== 'number' ) {
|
709
|
+
|
710
|
+
progress = undefined ;
|
711
|
+
|
712
|
+
}
|
713
|
+
|
714
|
+
else {
|
715
|
+
|
716
|
+
// Not sure if it is a good thing to let the user set progress to a value that is lesser than the current one
|
717
|
+
|
718
|
+
progress = toUpdate.progress ;
|
719
|
+
|
720
|
+
|
721
|
+
if ( progress > 1 ) { progress = 1 ; }
|
722
|
+
|
723
|
+
else if ( progress < 0 ) { progress = 0 ; }
|
724
|
+
|
725
|
+
|
726
|
+
if ( progress > 0 ) { progressUpdateCount ++ ; }
|
727
|
+
|
728
|
+
|
729
|
+
lastUpdateTime = ( new Date() ).getTime() ;
|
730
|
+
|
731
|
+
updateCount ++ ;
|
732
|
+
|
733
|
+
}
|
734
|
+
|
735
|
+
}
|
736
|
+
|
737
|
+
|
738
|
+
if ( typeof toUpdate.items === 'number' ) {
|
739
|
+
|
740
|
+
maxItems = toUpdate.items ;
|
741
|
+
|
742
|
+
if ( maxItems ) { progress = itemsDone / maxItems ; }
|
743
|
+
|
744
|
+
|
745
|
+
if ( typeof options.itemSize !== 'number' ) {
|
746
|
+
|
747
|
+
options.itemSize = Math.round( width / 3 ) ;
|
748
|
+
|
749
|
+
itemFiller = ' '.repeat( options.itemSize ) ;
|
750
|
+
|
751
|
+
}
|
752
|
+
|
753
|
+
}
|
754
|
+
|
755
|
+
|
756
|
+
if ( typeof toUpdate.title === 'string' ) {
|
757
|
+
|
758
|
+
title = toUpdate.title ;
|
759
|
+
|
760
|
+
|
761
|
+
if ( typeof options.titleSize !== 'number' ) {
|
762
|
+
|
763
|
+
options.titleSize = Math.round( width / 3 ) ;
|
764
|
+
|
765
|
+
titleFiller = ' '.repeat( options.titleSize ) ;
|
766
|
+
|
767
|
+
}
|
768
|
+
|
769
|
+
}
|
770
|
+
|
771
|
+
|
772
|
+
// If progress is >= 1, then it's finished, so we should redraw NOW (before the program eventually quit)
|
773
|
+
|
774
|
+
if ( progress >= 1 ) { redraw( true ) ; return ; }
|
775
|
+
|
776
|
+
|
777
|
+
if ( options.syncMode ) {
|
778
|
+
|
779
|
+
redraw() ;
|
780
|
+
|
781
|
+
}
|
782
|
+
|
783
|
+
else {
|
784
|
+
|
785
|
+
// Using a setTimeout with a 0ms time and redrawTimer clearing has a nice effect:
|
786
|
+
|
787
|
+
// if multiple synchronous update are performed, redraw will be called once
|
788
|
+
|
789
|
+
if ( redrawTimer ) { clearTimeout( redrawTimer ) ; }
|
790
|
+
|
791
|
+
redrawTimer = setTimeout( redraw.bind( this , true ) , 0 ) ;
|
792
|
+
|
793
|
+
}
|
794
|
+
|
795
|
+
} ;
|
796
|
+
|
797
|
+
|
798
|
+
controller.pause = controller.stop = () => {
|
799
|
+
|
800
|
+
pause = true ;
|
801
|
+
|
802
|
+
} ;
|
803
|
+
|
804
|
+
|
805
|
+
controller.resume = () => {
|
806
|
+
|
807
|
+
if ( pause ) {
|
808
|
+
|
809
|
+
pause = false ;
|
810
|
+
|
811
|
+
redraw() ;
|
812
|
+
|
813
|
+
}
|
814
|
+
|
815
|
+
} ;
|
816
|
+
|
817
|
+
|
818
|
+
controller.reset = () => {
|
819
|
+
|
820
|
+
etaStartingTime = startingTime = ( new Date() ).getTime() ;
|
821
|
+
|
822
|
+
itemsDone = 0 ;
|
823
|
+
|
824
|
+
progress = undefined ;
|
825
|
+
|
826
|
+
itemsStarted.length = 0 ;
|
827
|
+
|
828
|
+
wheelCounter = itemRollCounter = updateCount = progressUpdateCount = 0 ;
|
829
|
+
|
830
|
+
redraw() ;
|
831
|
+
|
832
|
+
} ;
|
833
|
+
|
834
|
+
|
835
|
+
return controller ;
|
836
|
+
|
837
|
+
} ;
|