hunk.code_window:           ng-if="main.state.isFlashing()"
             ng-click="flash.cancelFlash()">
             <span class="glyphicon glyphicon-remove-sign"></span>
           </button>
           <p class="step-footer step-footer-split" ng-if="main.state.getFlashState().speed && main.state.getFlashState().percentage != 100">
             <span ng-bind="main.state.getFlashState().speed.toFixed(2) + ' MB/s'"></span>
  
hunk.labels: keep keep keep keep keep replace keep
hunk.after_edit:         <p class="step-footer step-footer-split" ng-if="main.state.getFlashState().speed != null && main.state.getFlashState().percentage != 100">
  
hunk.file_path: lib/gui/app/pages/main/templates/main.tpl.html
hunk.type: replace
file: /*
   * Copyright 2018 resin.io
   *
   * 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.
   */
  
  'use strict'
  
  const electron = require('electron')
  const EventEmitter = require('events')
  const createInactivityTimer = require('inactivity-timer')
  const debug = require('debug')('etcher:update-lock')
  const analytics = require('./analytics')
  const settings = require('../models/settings')
  
  /* eslint-disable no-magic-numbers, callback-return */
  
  /**
   * Interaction timeout in milliseconds (defaults to 5 minutes)
   * @type {Number}
   * @constant
   */
  const INTERACTION_TIMEOUT_MS = settings.has('interactionTimeout')
    ? parseInt(settings.get('interactionTimeout'), 10)
    : 5 * 60 * 1000
  
  /**
   * Resin Update Lock
   * @class
   */
  class UpdateLock extends EventEmitter {
    /**
     * @summary Resin Update Lock
     * @example
     * new UpdateLock()
     */
    constructor () {
      super()
      this.paused = false
      this.on('inactive', UpdateLock.onInactive)
      this.lockTimer = createInactivityTimer(INTERACTION_TIMEOUT_MS, () => {
        debug('inactive')
        this.emit('inactive')
      })
    }
  
    /**
     * @summary Inactivity event handler, releases the resin update lock on inactivity
     * @private
     * @example
     * this.on('inactive', onInactive)
     */
    static onInactive () {
      if (settings.get('resinUpdateLock')) {
        UpdateLock.check((checkError, isLocked) => {
          debug('inactive-check', Boolean(checkError))
          if (checkError) {
            analytics.logException(checkError)
          }
          if (isLocked) {
            UpdateLock.release((error) => {
              debug('inactive-release', Boolean(error))
              if (error) {
                analytics.logException(error)
              }
            })
          }
        })
      }
    }
  
    /**
     * @summary Acquire the update lock
     * @private
     * @param {Function} callback - callback(error)
     * @example
     * UpdateLock.acquire((error) => {
     *   // ...
     * })
     */
    static acquire (callback) {
      debug('lock')
      if (settings.get('resinUpdateLock')) {
        electron.ipcRenderer.once('resin-update-lock', (event, error) => {
          callback(error)
        })
        electron.ipcRenderer.send('resin-update-lock', 'lock')
      } else {
        callback(new Error('Update lock disabled'))
      }
    }
  
    /**
     * @summary Release the update lock
     * @private
     * @param {Function} callback - callback(error)
     * @example
     * UpdateLock.release((error) => {
     *   // ...
     * })
     */
    static release (callback) {
      debug('unlock')
      if (settings.get('resinUpdateLock')) {
        electron.ipcRenderer.once('resin-update-lock', (event, error) => {
          callback(error)
        })
        electron.ipcRenderer.send('resin-update-lock', 'unlock')
      } else {
        callback(new Error('Update lock disabled'))
      }
    }
  
    /**
     * @summary Check the state of the update lock
     * @private
     * @param {Function} callback - callback(error, isLocked)
     * @example
     * UpdateLock.check((error, isLocked) => {
     *   if (isLocked) {
     *     // ...
     *   }
     * })
     */
    static check (callback) {
      debug('check')
      if (settings.get('resinUpdateLock')) {
        electron.ipcRenderer.once('resin-update-lock', (event, error, isLocked) => {
          callback(error, isLocked)
        })
        electron.ipcRenderer.send('resin-update-lock', 'check')
      } else {
        callback(new Error('Update lock disabled'))
      }
    }
  
    /**
     * @summary Extend the lock timer
     * @example
     * updateLock.extend()
     */
    extend () {
      debug('extend')
  
      if (this.paused) {
        debug('extend:paused')
        return
      }
  
      this.lockTimer.signal()
  
      // When extending, check that we have the lock,
      // and acquire it, if not
      if (settings.get('resinUpdateLock')) {
        UpdateLock.check((checkError, isLocked) => {
          if (checkError) {
            analytics.logException(checkError)
          }
          if (!isLocked) {
            UpdateLock.acquire((error) => {
              if (error) {
                analytics.logException(error)
              }
              debug('extend-acquire', Boolean(error))
            })
          }
        })
      }
    }
  
    /**
     * @summary Clear the lock timer
     * @example
     * updateLock.clearTimer()
     */
    clearTimer () {
      debug('clear')
      this.lockTimer.clear()
    }
  
    /**
     * @summary Clear the lock timer, and pause extension, avoiding triggering until resume()d
     * @example
     * updateLock.pause()
     */
    pause () {
      debug('pause')
      this.paused = true
      this.clearTimer()
    }
  
    /**
     * @summary Un-pause lock extension, and restart the timer
     * @example
     * updateLock.resume()
     */
    resume () {
      debug('resume')
      this.paused = false
      this.extend()
    }
  }
  
  module.exports = new UpdateLock()
  