hunk.code_window:     "@types/node-ipc": "^9.1.2",
       "@types/react-dom": "^16.8.4",
       "@types/request": "^2.48.4",
       "@types/semver": "^7.1.0",
       "@types/sinon": "^9.0.0",
       "@types/tmp": "^0.2.0",
       "@types/webpack-node-externals": "^1.7.0",
       "bluebird": "^3.7.2",
       "bootstrap-sass": "^3.3.6",
       "chai": "^4.2.0",
  
hunk.labels: keep keep keep keep add keep keep keep keep keep
hunk.after_edit:     "@types/terser-webpack-plugin": "^2.2.0",
  
hunk.file_path: package.json
hunk.type: add
file: /*
   * Copyright 2016 balena.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.
   */
  
  import * as sdk from 'etcher-sdk';
  import * as _ from 'lodash';
  
  import { bytesToMegabytes } from '../../../shared/units';
  import { Actions, store } from './store';
  
  /**
   * @summary Reset flash state
   */
  export function resetState() {
  	store.dispatch({
  		type: Actions.RESET_FLASH_STATE,
  		data: {},
  	});
  }
  
  /**
   * @summary Check if currently flashing
   */
  export function isFlashing(): boolean {
  	return store.getState().toJS().isFlashing;
  }
  
  /**
   * @summary Set the flashing flag
   *
   * @description
   * The flag is used to signify that we're going to
   * start a flash process.
   */
  export function setFlashingFlag() {
  	store.dispatch({
  		type: Actions.SET_FLASHING_FLAG,
  		data: {},
  	});
  }
  
  /**
   * @summary Unset the flashing flag
   *
   * @description
   * The flag is used to signify that the write process ended.
   */
  export function unsetFlashingFlag(results: {
  	cancelled?: boolean;
  	sourceChecksum?: string;
  	errorCode?: string | number;
  }) {
  	store.dispatch({
  		type: Actions.UNSET_FLASHING_FLAG,
  		data: results,
  	});
  }
  
  export function setDevicePaths(devicePaths: string[]) {
  	store.dispatch({
  		type: Actions.SET_DEVICE_PATHS,
  		data: devicePaths,
  	});
  }
  
  export function addFailedDevicePath(devicePath: string) {
  	const failedDevicePathsSet = new Set(
  		store.getState().toJS().failedDevicePaths,
  	);
  	failedDevicePathsSet.add(devicePath);
  	store.dispatch({
  		type: Actions.SET_FAILED_DEVICE_PATHS,
  		data: Array.from(failedDevicePathsSet),
  	});
  }
  
  /**
   * @summary Set the flashing state
   */
  export function setProgressState(
  	state: sdk.multiWrite.MultiDestinationProgress,
  ) {
  	// Preserve only one decimal place
  	const PRECISION = 1;
  	const data = {
  		...state,
  		percentage:
  			state.percentage !== undefined && _.isFinite(state.percentage)
  				? Math.floor(state.percentage)
  				: undefined,
  
  		speed: _.attempt(() => {
  			if (_.isFinite(state.speed)) {
  				return _.round(bytesToMegabytes(state.speed), PRECISION);
  			}
  
  			return null;
  		}),
  	};
  
  	store.dispatch({
  		type: Actions.SET_FLASH_STATE,
  		data,
  	});
  }
  
  export function getFlashResults() {
  	return store.getState().toJS().flashResults;
  }
  
  export function getFlashState() {
  	return store.getState().get('flashState').toJS();
  }
  
  export function wasLastFlashCancelled() {
  	return _.get(getFlashResults(), ['cancelled'], false);
  }
  
  export function getLastFlashSourceChecksum(): string {
  	return getFlashResults().sourceChecksum;
  }
  
  export function getLastFlashErrorCode() {
  	return getFlashResults().errorCode;
  }
  
  export function getFlashUuid() {
  	return store.getState().toJS().flashUuid;
  }
  