11cb0ef41Sopenharmony_ci'use strict' 21cb0ef41Sopenharmony_civar Plumbing = require('./plumbing.js') 31cb0ef41Sopenharmony_civar hasUnicode = require('has-unicode') 41cb0ef41Sopenharmony_civar hasColor = require('./has-color.js') 51cb0ef41Sopenharmony_civar onExit = require('signal-exit').onExit 61cb0ef41Sopenharmony_civar defaultThemes = require('./themes') 71cb0ef41Sopenharmony_civar setInterval = require('./set-interval.js') 81cb0ef41Sopenharmony_civar process = require('./process.js') 91cb0ef41Sopenharmony_civar setImmediate = require('./set-immediate') 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_cimodule.exports = Gauge 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cifunction callWith (obj, method) { 141cb0ef41Sopenharmony_ci return function () { 151cb0ef41Sopenharmony_ci return method.call(obj) 161cb0ef41Sopenharmony_ci } 171cb0ef41Sopenharmony_ci} 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_cifunction Gauge (arg1, arg2) { 201cb0ef41Sopenharmony_ci var options, writeTo 211cb0ef41Sopenharmony_ci if (arg1 && arg1.write) { 221cb0ef41Sopenharmony_ci writeTo = arg1 231cb0ef41Sopenharmony_ci options = arg2 || {} 241cb0ef41Sopenharmony_ci } else if (arg2 && arg2.write) { 251cb0ef41Sopenharmony_ci writeTo = arg2 261cb0ef41Sopenharmony_ci options = arg1 || {} 271cb0ef41Sopenharmony_ci } else { 281cb0ef41Sopenharmony_ci writeTo = process.stderr 291cb0ef41Sopenharmony_ci options = arg1 || arg2 || {} 301cb0ef41Sopenharmony_ci } 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci this._status = { 331cb0ef41Sopenharmony_ci spun: 0, 341cb0ef41Sopenharmony_ci section: '', 351cb0ef41Sopenharmony_ci subsection: '', 361cb0ef41Sopenharmony_ci } 371cb0ef41Sopenharmony_ci this._paused = false // are we paused for back pressure? 381cb0ef41Sopenharmony_ci this._disabled = true // are all progress bar updates disabled? 391cb0ef41Sopenharmony_ci this._showing = false // do we WANT the progress bar on screen 401cb0ef41Sopenharmony_ci this._onScreen = false // IS the progress bar on screen 411cb0ef41Sopenharmony_ci this._needsRedraw = false // should we print something at next tick? 421cb0ef41Sopenharmony_ci this._hideCursor = options.hideCursor == null ? true : options.hideCursor 431cb0ef41Sopenharmony_ci this._fixedFramerate = options.fixedFramerate == null 441cb0ef41Sopenharmony_ci ? !(/^v0\.8\./.test(process.version)) 451cb0ef41Sopenharmony_ci : options.fixedFramerate 461cb0ef41Sopenharmony_ci this._lastUpdateAt = null 471cb0ef41Sopenharmony_ci this._updateInterval = options.updateInterval == null ? 50 : options.updateInterval 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci this._themes = options.themes || defaultThemes 501cb0ef41Sopenharmony_ci this._theme = options.theme 511cb0ef41Sopenharmony_ci var theme = this._computeTheme(options.theme) 521cb0ef41Sopenharmony_ci var template = options.template || [ 531cb0ef41Sopenharmony_ci { type: 'progressbar', length: 20 }, 541cb0ef41Sopenharmony_ci { type: 'activityIndicator', kerning: 1, length: 1 }, 551cb0ef41Sopenharmony_ci { type: 'section', kerning: 1, default: '' }, 561cb0ef41Sopenharmony_ci { type: 'subsection', kerning: 1, default: '' }, 571cb0ef41Sopenharmony_ci ] 581cb0ef41Sopenharmony_ci this.setWriteTo(writeTo, options.tty) 591cb0ef41Sopenharmony_ci var PlumbingClass = options.Plumbing || Plumbing 601cb0ef41Sopenharmony_ci this._gauge = new PlumbingClass(theme, template, this.getWidth()) 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci this._$$doRedraw = callWith(this, this._doRedraw) 631cb0ef41Sopenharmony_ci this._$$handleSizeChange = callWith(this, this._handleSizeChange) 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci this._cleanupOnExit = options.cleanupOnExit == null || options.cleanupOnExit 661cb0ef41Sopenharmony_ci this._removeOnExit = null 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci if (options.enabled || (options.enabled == null && this._tty && this._tty.isTTY)) { 691cb0ef41Sopenharmony_ci this.enable() 701cb0ef41Sopenharmony_ci } else { 711cb0ef41Sopenharmony_ci this.disable() 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci} 741cb0ef41Sopenharmony_ciGauge.prototype = {} 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ciGauge.prototype.isEnabled = function () { 771cb0ef41Sopenharmony_ci return !this._disabled 781cb0ef41Sopenharmony_ci} 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ciGauge.prototype.setTemplate = function (template) { 811cb0ef41Sopenharmony_ci this._gauge.setTemplate(template) 821cb0ef41Sopenharmony_ci if (this._showing) { 831cb0ef41Sopenharmony_ci this._requestRedraw() 841cb0ef41Sopenharmony_ci } 851cb0ef41Sopenharmony_ci} 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ciGauge.prototype._computeTheme = function (theme) { 881cb0ef41Sopenharmony_ci if (!theme) { 891cb0ef41Sopenharmony_ci theme = {} 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci if (typeof theme === 'string') { 921cb0ef41Sopenharmony_ci theme = this._themes.getTheme(theme) 931cb0ef41Sopenharmony_ci } else if ( 941cb0ef41Sopenharmony_ci Object.keys(theme).length === 0 || theme.hasUnicode != null || theme.hasColor != null 951cb0ef41Sopenharmony_ci ) { 961cb0ef41Sopenharmony_ci var useUnicode = theme.hasUnicode == null ? hasUnicode() : theme.hasUnicode 971cb0ef41Sopenharmony_ci var useColor = theme.hasColor == null ? hasColor : theme.hasColor 981cb0ef41Sopenharmony_ci theme = this._themes.getDefault({ 991cb0ef41Sopenharmony_ci hasUnicode: useUnicode, 1001cb0ef41Sopenharmony_ci hasColor: useColor, 1011cb0ef41Sopenharmony_ci platform: theme.platform, 1021cb0ef41Sopenharmony_ci }) 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci return theme 1051cb0ef41Sopenharmony_ci} 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ciGauge.prototype.setThemeset = function (themes) { 1081cb0ef41Sopenharmony_ci this._themes = themes 1091cb0ef41Sopenharmony_ci this.setTheme(this._theme) 1101cb0ef41Sopenharmony_ci} 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ciGauge.prototype.setTheme = function (theme) { 1131cb0ef41Sopenharmony_ci this._gauge.setTheme(this._computeTheme(theme)) 1141cb0ef41Sopenharmony_ci if (this._showing) { 1151cb0ef41Sopenharmony_ci this._requestRedraw() 1161cb0ef41Sopenharmony_ci } 1171cb0ef41Sopenharmony_ci this._theme = theme 1181cb0ef41Sopenharmony_ci} 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ciGauge.prototype._requestRedraw = function () { 1211cb0ef41Sopenharmony_ci this._needsRedraw = true 1221cb0ef41Sopenharmony_ci if (!this._fixedFramerate) { 1231cb0ef41Sopenharmony_ci this._doRedraw() 1241cb0ef41Sopenharmony_ci } 1251cb0ef41Sopenharmony_ci} 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ciGauge.prototype.getWidth = function () { 1281cb0ef41Sopenharmony_ci return ((this._tty && this._tty.columns) || 80) - 1 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ciGauge.prototype.setWriteTo = function (writeTo, tty) { 1321cb0ef41Sopenharmony_ci var enabled = !this._disabled 1331cb0ef41Sopenharmony_ci if (enabled) { 1341cb0ef41Sopenharmony_ci this.disable() 1351cb0ef41Sopenharmony_ci } 1361cb0ef41Sopenharmony_ci this._writeTo = writeTo 1371cb0ef41Sopenharmony_ci this._tty = tty || 1381cb0ef41Sopenharmony_ci (writeTo === process.stderr && process.stdout.isTTY && process.stdout) || 1391cb0ef41Sopenharmony_ci (writeTo.isTTY && writeTo) || 1401cb0ef41Sopenharmony_ci this._tty 1411cb0ef41Sopenharmony_ci if (this._gauge) { 1421cb0ef41Sopenharmony_ci this._gauge.setWidth(this.getWidth()) 1431cb0ef41Sopenharmony_ci } 1441cb0ef41Sopenharmony_ci if (enabled) { 1451cb0ef41Sopenharmony_ci this.enable() 1461cb0ef41Sopenharmony_ci } 1471cb0ef41Sopenharmony_ci} 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ciGauge.prototype.enable = function () { 1501cb0ef41Sopenharmony_ci if (!this._disabled) { 1511cb0ef41Sopenharmony_ci return 1521cb0ef41Sopenharmony_ci } 1531cb0ef41Sopenharmony_ci this._disabled = false 1541cb0ef41Sopenharmony_ci if (this._tty) { 1551cb0ef41Sopenharmony_ci this._enableEvents() 1561cb0ef41Sopenharmony_ci } 1571cb0ef41Sopenharmony_ci if (this._showing) { 1581cb0ef41Sopenharmony_ci this.show() 1591cb0ef41Sopenharmony_ci } 1601cb0ef41Sopenharmony_ci} 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ciGauge.prototype.disable = function () { 1631cb0ef41Sopenharmony_ci if (this._disabled) { 1641cb0ef41Sopenharmony_ci return 1651cb0ef41Sopenharmony_ci } 1661cb0ef41Sopenharmony_ci if (this._showing) { 1671cb0ef41Sopenharmony_ci this._lastUpdateAt = null 1681cb0ef41Sopenharmony_ci this._showing = false 1691cb0ef41Sopenharmony_ci this._doRedraw() 1701cb0ef41Sopenharmony_ci this._showing = true 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci this._disabled = true 1731cb0ef41Sopenharmony_ci if (this._tty) { 1741cb0ef41Sopenharmony_ci this._disableEvents() 1751cb0ef41Sopenharmony_ci } 1761cb0ef41Sopenharmony_ci} 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ciGauge.prototype._enableEvents = function () { 1791cb0ef41Sopenharmony_ci if (this._cleanupOnExit) { 1801cb0ef41Sopenharmony_ci this._removeOnExit = onExit(callWith(this, this.disable)) 1811cb0ef41Sopenharmony_ci } 1821cb0ef41Sopenharmony_ci this._tty.on('resize', this._$$handleSizeChange) 1831cb0ef41Sopenharmony_ci if (this._fixedFramerate) { 1841cb0ef41Sopenharmony_ci this.redrawTracker = setInterval(this._$$doRedraw, this._updateInterval) 1851cb0ef41Sopenharmony_ci if (this.redrawTracker.unref) { 1861cb0ef41Sopenharmony_ci this.redrawTracker.unref() 1871cb0ef41Sopenharmony_ci } 1881cb0ef41Sopenharmony_ci } 1891cb0ef41Sopenharmony_ci} 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ciGauge.prototype._disableEvents = function () { 1921cb0ef41Sopenharmony_ci this._tty.removeListener('resize', this._$$handleSizeChange) 1931cb0ef41Sopenharmony_ci if (this._fixedFramerate) { 1941cb0ef41Sopenharmony_ci clearInterval(this.redrawTracker) 1951cb0ef41Sopenharmony_ci } 1961cb0ef41Sopenharmony_ci if (this._removeOnExit) { 1971cb0ef41Sopenharmony_ci this._removeOnExit() 1981cb0ef41Sopenharmony_ci } 1991cb0ef41Sopenharmony_ci} 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ciGauge.prototype.hide = function (cb) { 2021cb0ef41Sopenharmony_ci if (this._disabled) { 2031cb0ef41Sopenharmony_ci return cb && process.nextTick(cb) 2041cb0ef41Sopenharmony_ci } 2051cb0ef41Sopenharmony_ci if (!this._showing) { 2061cb0ef41Sopenharmony_ci return cb && process.nextTick(cb) 2071cb0ef41Sopenharmony_ci } 2081cb0ef41Sopenharmony_ci this._showing = false 2091cb0ef41Sopenharmony_ci this._doRedraw() 2101cb0ef41Sopenharmony_ci cb && setImmediate(cb) 2111cb0ef41Sopenharmony_ci} 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ciGauge.prototype.show = function (section, completed) { 2141cb0ef41Sopenharmony_ci this._showing = true 2151cb0ef41Sopenharmony_ci if (typeof section === 'string') { 2161cb0ef41Sopenharmony_ci this._status.section = section 2171cb0ef41Sopenharmony_ci } else if (typeof section === 'object') { 2181cb0ef41Sopenharmony_ci var sectionKeys = Object.keys(section) 2191cb0ef41Sopenharmony_ci for (var ii = 0; ii < sectionKeys.length; ++ii) { 2201cb0ef41Sopenharmony_ci var key = sectionKeys[ii] 2211cb0ef41Sopenharmony_ci this._status[key] = section[key] 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci } 2241cb0ef41Sopenharmony_ci if (completed != null) { 2251cb0ef41Sopenharmony_ci this._status.completed = completed 2261cb0ef41Sopenharmony_ci } 2271cb0ef41Sopenharmony_ci if (this._disabled) { 2281cb0ef41Sopenharmony_ci return 2291cb0ef41Sopenharmony_ci } 2301cb0ef41Sopenharmony_ci this._requestRedraw() 2311cb0ef41Sopenharmony_ci} 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ciGauge.prototype.pulse = function (subsection) { 2341cb0ef41Sopenharmony_ci this._status.subsection = subsection || '' 2351cb0ef41Sopenharmony_ci this._status.spun++ 2361cb0ef41Sopenharmony_ci if (this._disabled) { 2371cb0ef41Sopenharmony_ci return 2381cb0ef41Sopenharmony_ci } 2391cb0ef41Sopenharmony_ci if (!this._showing) { 2401cb0ef41Sopenharmony_ci return 2411cb0ef41Sopenharmony_ci } 2421cb0ef41Sopenharmony_ci this._requestRedraw() 2431cb0ef41Sopenharmony_ci} 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ciGauge.prototype._handleSizeChange = function () { 2461cb0ef41Sopenharmony_ci this._gauge.setWidth(this._tty.columns - 1) 2471cb0ef41Sopenharmony_ci this._requestRedraw() 2481cb0ef41Sopenharmony_ci} 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ciGauge.prototype._doRedraw = function () { 2511cb0ef41Sopenharmony_ci if (this._disabled || this._paused) { 2521cb0ef41Sopenharmony_ci return 2531cb0ef41Sopenharmony_ci } 2541cb0ef41Sopenharmony_ci if (!this._fixedFramerate) { 2551cb0ef41Sopenharmony_ci var now = Date.now() 2561cb0ef41Sopenharmony_ci if (this._lastUpdateAt && now - this._lastUpdateAt < this._updateInterval) { 2571cb0ef41Sopenharmony_ci return 2581cb0ef41Sopenharmony_ci } 2591cb0ef41Sopenharmony_ci this._lastUpdateAt = now 2601cb0ef41Sopenharmony_ci } 2611cb0ef41Sopenharmony_ci if (!this._showing && this._onScreen) { 2621cb0ef41Sopenharmony_ci this._onScreen = false 2631cb0ef41Sopenharmony_ci var result = this._gauge.hide() 2641cb0ef41Sopenharmony_ci if (this._hideCursor) { 2651cb0ef41Sopenharmony_ci result += this._gauge.showCursor() 2661cb0ef41Sopenharmony_ci } 2671cb0ef41Sopenharmony_ci return this._writeTo.write(result) 2681cb0ef41Sopenharmony_ci } 2691cb0ef41Sopenharmony_ci if (!this._showing && !this._onScreen) { 2701cb0ef41Sopenharmony_ci return 2711cb0ef41Sopenharmony_ci } 2721cb0ef41Sopenharmony_ci if (this._showing && !this._onScreen) { 2731cb0ef41Sopenharmony_ci this._onScreen = true 2741cb0ef41Sopenharmony_ci this._needsRedraw = true 2751cb0ef41Sopenharmony_ci if (this._hideCursor) { 2761cb0ef41Sopenharmony_ci this._writeTo.write(this._gauge.hideCursor()) 2771cb0ef41Sopenharmony_ci } 2781cb0ef41Sopenharmony_ci } 2791cb0ef41Sopenharmony_ci if (!this._needsRedraw) { 2801cb0ef41Sopenharmony_ci return 2811cb0ef41Sopenharmony_ci } 2821cb0ef41Sopenharmony_ci if (!this._writeTo.write(this._gauge.show(this._status))) { 2831cb0ef41Sopenharmony_ci this._paused = true 2841cb0ef41Sopenharmony_ci this._writeTo.on('drain', callWith(this, function () { 2851cb0ef41Sopenharmony_ci this._paused = false 2861cb0ef41Sopenharmony_ci this._doRedraw() 2871cb0ef41Sopenharmony_ci })) 2881cb0ef41Sopenharmony_ci } 2891cb0ef41Sopenharmony_ci} 290