diff --git a/.eslintrc b/.eslintrc
index 188f9f954c9667b2d0d7729ab1a4f5fb8184014e..4ba53d9675b1d23768bd88ef1c480261032c41f3 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -27,6 +27,8 @@
     "sort-keys": ["error", "asc", {
       "caseSensitive": false,
       "natural": false
-    }]
+    }],
+    "react/jsx-props-no-spreading": "off",
+    "arrow-parens": "off",
   }
 }
diff --git a/__tests__/integration/mirador/plugins/add.test.js b/__tests__/integration/mirador/plugins/add.test.js
index 03889a9586fe3b340397dfd7d6e69b97c04be3b5..5e867d89e0c1592419952e60f85939014b7ccabe 100644
--- a/__tests__/integration/mirador/plugins/add.test.js
+++ b/__tests__/integration/mirador/plugins/add.test.js
@@ -1,4 +1,3 @@
-
 describe('add two plugins to <WorkspaceControlPanelButtons>', () => {
   beforeAll(async () => {
     await page.goto('http://127.0.0.1:4488/__tests__/integration/mirador/plugins/add.html');
diff --git a/__tests__/integration/mirador/plugins/companionWindow.test.js b/__tests__/integration/mirador/plugins/companionWindow.test.js
index 003fd12f84cd5df120d1fca9e897c0307a66d4bd..d93f36e3abdf8c2bdd9645abd0ae94734b7f936d 100644
--- a/__tests__/integration/mirador/plugins/companionWindow.test.js
+++ b/__tests__/integration/mirador/plugins/companionWindow.test.js
@@ -1,4 +1,3 @@
-
 describe('add plugins for companion windows', () => {
   beforeAll(async () => {
     await page.goto('http://127.0.0.1:4488/__tests__/integration/mirador/plugins/companionWindow.html');
diff --git a/__tests__/integration/mirador/plugins/priority.test.js b/__tests__/integration/mirador/plugins/priority.test.js
index 3f069fa72dc1c7699e311664430fc020b80216c6..3ed451fb86ca96bc9af0fb14c9bd3c791e376991 100644
--- a/__tests__/integration/mirador/plugins/priority.test.js
+++ b/__tests__/integration/mirador/plugins/priority.test.js
@@ -1,4 +1,3 @@
-
 describe('try to apply 2 add plugins and 2 wrap plugins to <WorkspaceControlPanelButtons>', () => {
   beforeAll(async () => {
     await page.goto('http://127.0.0.1:4488/__tests__/integration/mirador/plugins/priority.html');
diff --git a/__tests__/integration/mirador/plugins/validate.test.js b/__tests__/integration/mirador/plugins/validate.test.js
index c06d76fc642a35cccd0b885519ee03c4f9f816b1..8eb5ef37209072843f0745ca175b39e13508fbb4 100644
--- a/__tests__/integration/mirador/plugins/validate.test.js
+++ b/__tests__/integration/mirador/plugins/validate.test.js
@@ -1,4 +1,3 @@
-
 describe('pass valid and invalid plugins to <WorkspaceControlPanelButtons>', () => {
   beforeAll(async () => {
     await page.goto('http://127.0.0.1:4488/__tests__/integration/mirador/plugins/validate.html');
diff --git a/__tests__/integration/mirador/plugins/wrap.test.js b/__tests__/integration/mirador/plugins/wrap.test.js
index e9948541b90e38ccd296440a9196c93c9257d0ae..77865efa64a3aa67c3ead55313c4dc96a4982344 100644
--- a/__tests__/integration/mirador/plugins/wrap.test.js
+++ b/__tests__/integration/mirador/plugins/wrap.test.js
@@ -1,4 +1,3 @@
-
 describe('wrap <WorkspaceControlPanelButtons> by a plugin', () => {
   beforeAll(async () => {
     await page.goto('http://127.0.0.1:4488/__tests__/integration/mirador/plugins/wrap.html');
diff --git a/__tests__/src/actions/window.test.js b/__tests__/src/actions/window.test.js
index 6861de26a169631fd6638073b477f5fbc4a6b4bf..42c2ad3d4e8ad38095a53c0cc0d5fce898b8df23 100644
--- a/__tests__/src/actions/window.test.js
+++ b/__tests__/src/actions/window.test.js
@@ -249,7 +249,6 @@ describe('window actions', () => {
     });
   });
 
-
   describe('setWindowThumbnailPosition', () => {
     it('returns the appropriate action type', () => {
       const id = 'abc123';
diff --git a/__tests__/src/components/AnnotationsOverlay.test.js b/__tests__/src/components/AnnotationsOverlay.test.js
index cd5fbddbeb29fe1a6b10f5154b17d14303dcdc55..254dda0c48cd129cff718dd92f899a8289d9e5fb 100644
--- a/__tests__/src/components/AnnotationsOverlay.test.js
+++ b/__tests__/src/components/AnnotationsOverlay.test.js
@@ -15,7 +15,6 @@ jest.mock('react-dom');
 jest.mock('openseadragon');
 jest.mock('../../../src/lib/OpenSeadragonCanvasOverlay');
 
-
 describe('AnnotationsOverlay', () => {
   let wrapper;
   let viewer;
diff --git a/__tests__/src/components/AttributionPanel.test.js b/__tests__/src/components/AttributionPanel.test.js
index cdcf43cd2faf70f72685a1ba47fdaee88750e7eb..b8ed56bf2748547b393873ac0561c6c0cb8580b0 100644
--- a/__tests__/src/components/AttributionPanel.test.js
+++ b/__tests__/src/components/AttributionPanel.test.js
@@ -2,7 +2,7 @@ import React from 'react';
 import { shallow } from 'enzyme';
 import Typography from '@material-ui/core/Typography';
 import Link from '@material-ui/core/Link';
-import Img from 'react-image';
+import { Img } from 'react-image';
 import { AttributionPanel } from '../../../src/components/AttributionPanel';
 import { LabelValueMetadata } from '../../../src/components/LabelValueMetadata';
 
diff --git a/__tests__/src/components/CanvasAnnotations.test.js b/__tests__/src/components/CanvasAnnotations.test.js
index c8e46b16eaec3af3bb3eb7bf735c7cc54987734b..b68f0e367ff857dc0d02c82f1e855aab20a7c4a8 100644
--- a/__tests__/src/components/CanvasAnnotations.test.js
+++ b/__tests__/src/components/CanvasAnnotations.test.js
@@ -41,7 +41,6 @@ describe('CanvasAnnotations', () => {
     },
   ];
 
-
   it('renders a heading with the appropriate context based on index and totalSize', () => {
     wrapper = createWrapper({ annotations });
 
diff --git a/__tests__/src/components/LanguageSettings.test.js b/__tests__/src/components/LanguageSettings.test.js
index 56ef773307a76581be3fb74ca5aa7db522ca673d..88909f66fd5d400235e4b8120e44e2e10fc6bb08 100644
--- a/__tests__/src/components/LanguageSettings.test.js
+++ b/__tests__/src/components/LanguageSettings.test.js
@@ -32,7 +32,6 @@ describe('LanguageSettings', () => {
     },
   ];
 
-
   it('renders a list with a list item for each language passed in props', () => {
     wrapper = createWrapper({ languages });
 
diff --git a/__tests__/src/components/LocalePicker.test.js b/__tests__/src/components/LocalePicker.test.js
index 2b75048d97147b9843f9101fdb40e573509d9a91..e12431caf73355b3fab0000beed1ab54e9f6a7ce 100644
--- a/__tests__/src/components/LocalePicker.test.js
+++ b/__tests__/src/components/LocalePicker.test.js
@@ -40,7 +40,6 @@ describe('LocalePicker', () => {
     expect(wrapper.find(MenuItem).length).toBe(2);
   });
 
-
   it('triggers setLocale prop when clicking a list item', () => {
     const setLocale = jest.fn();
 
diff --git a/__tests__/src/components/ManifestForm.test.js b/__tests__/src/components/ManifestForm.test.js
index 5f5c224ecf3f44d84667db1072507707de24b245..cb4bb113ad7b3688622d055e76af0f6aa23bb549 100644
--- a/__tests__/src/components/ManifestForm.test.js
+++ b/__tests__/src/components/ManifestForm.test.js
@@ -13,7 +13,6 @@ function createWrapper(props) {
   );
 }
 
-
 describe('ManifestForm', () => {
   it('renders', () => {
     const wrapper = createWrapper({ addResourcesOpen: false });
diff --git a/__tests__/src/components/OpenSeadragonViewer.test.js b/__tests__/src/components/OpenSeadragonViewer.test.js
index 18c03a552aecae19163c931456f5255eec8ca221..b242ad3e5332015e2f8092fd587c5fcb24eb4001 100644
--- a/__tests__/src/components/OpenSeadragonViewer.test.js
+++ b/__tests__/src/components/OpenSeadragonViewer.test.js
@@ -10,7 +10,6 @@ const canvases = Utils.parseManifest(fixture).getSequences()[0].getCanvases();
 
 jest.mock('openseadragon');
 
-
 describe('OpenSeadragonViewer', () => {
   let wrapper;
   let updateViewport;
diff --git a/__tests__/src/components/SearchHit.test.js b/__tests__/src/components/SearchHit.test.js
index 5cb4a8226080af7f99ca0e0b400984d7592eef28..2be8074e53fa3e436142168b13a58fc6512ef7a9 100644
--- a/__tests__/src/components/SearchHit.test.js
+++ b/__tests__/src/components/SearchHit.test.js
@@ -3,7 +3,6 @@ import { shallow } from 'enzyme';
 import { SearchHit } from '../../../src/components/SearchHit';
 import { ScrollTo } from '../../../src/components/ScrollTo';
 
-
 /**
  * Helper function to create a shallow wrapper around SearchResults
  */
diff --git a/__tests__/src/components/SearchPanel.test.js b/__tests__/src/components/SearchPanel.test.js
index bdac0b0aebb7f2e047e7a792f3817191482fa618..ce33f8e8816d7a0fabe7a8f42d2ebf564005c9da 100644
--- a/__tests__/src/components/SearchPanel.test.js
+++ b/__tests__/src/components/SearchPanel.test.js
@@ -5,7 +5,6 @@ import CompanionWindow from '../../../src/containers/CompanionWindow';
 import SearchResults from '../../../src/containers/SearchResults';
 import { SearchPanel } from '../../../src/components/SearchPanel';
 
-
 /**
  * Helper function to create a shallow wrapper around SearchPanel
  */
diff --git a/__tests__/src/components/SearchPanelNavigation.test.js b/__tests__/src/components/SearchPanelNavigation.test.js
index 258b4e3478762f532cc3efc08e174221fdd7acd3..bec2c1b63ad8c8e8ea433145f83383be4259b88a 100644
--- a/__tests__/src/components/SearchPanelNavigation.test.js
+++ b/__tests__/src/components/SearchPanelNavigation.test.js
@@ -2,7 +2,6 @@ import React from 'react';
 import { shallow } from 'enzyme';
 import { SearchPanelNavigation } from '../../../src/components/SearchPanelNavigation';
 
-
 /**
  * Helper function to create a shallow wrapper around SearchPanelNavigation
  */
diff --git a/__tests__/src/components/SearchResults.test.js b/__tests__/src/components/SearchResults.test.js
index e8b66cc558f287e33ddcaf2ba1614088c986963a..2ceaaba79604609a468c4c24c22b201fdf4bd970 100644
--- a/__tests__/src/components/SearchResults.test.js
+++ b/__tests__/src/components/SearchResults.test.js
@@ -4,7 +4,6 @@ import Button from '@material-ui/core/Button';
 import { SearchResults } from '../../../src/components/SearchResults';
 import { ScrollTo } from '../../../src/components/ScrollTo';
 
-
 /**
  * Helper function to create a shallow wrapper around SearchResults
  */
diff --git a/__tests__/src/extend/pluginPreprocessing.test.js b/__tests__/src/extend/pluginPreprocessing.test.js
index 5623d140a75af4866af30f62f7f3daf1700ad413..619f16e70061448e73c1dc30bb55cf5d1229db78 100644
--- a/__tests__/src/extend/pluginPreprocessing.test.js
+++ b/__tests__/src/extend/pluginPreprocessing.test.js
@@ -3,7 +3,6 @@ import {
   addPluginReducersToStore,
 } from '../../../src/extend/pluginPreprocessing';
 
-
 describe('filterValidPlugins', () => {
   it('returns empty array if plugin array is empty', () => {
     expect(filterValidPlugins([])).toEqual([]);
diff --git a/__tests__/src/extend/withPlugins.test.js b/__tests__/src/extend/withPlugins.test.js
index 2e3ecf2cdc8de9b6b775ec00684992756b27e17e..108d5e6f622d9c648c4eed24e833742d23b0903d 100644
--- a/__tests__/src/extend/withPlugins.test.js
+++ b/__tests__/src/extend/withPlugins.test.js
@@ -3,7 +3,6 @@ import { mount } from 'enzyme';
 import { withPlugins } from '../../../src/extend/withPlugins';
 import PluginContext from '../../../src/extend/PluginContext';
 
-
 /** Mock target component */
 const Target = props => <div>Hello</div>;
 
diff --git a/__tests__/src/lib/MiradorCanvas.test.js b/__tests__/src/lib/MiradorCanvas.test.js
index e501add183df05b52033abeca3a6e3017daa4e4a..82a529231d57e58360d65200225a01b9d9147e04 100644
--- a/__tests__/src/lib/MiradorCanvas.test.js
+++ b/__tests__/src/lib/MiradorCanvas.test.js
@@ -1,7 +1,6 @@
 import { Utils } from 'manifesto.js/dist-esmodule/Utils';
 import MiradorCanvas from '../../../src/lib/MiradorCanvas';
 import fixture from '../../fixtures/version-2/019.json';
-import v3fixture from '../../fixtures/version-3/001.json';
 import serviceFixture from '../../fixtures/version-2/canvasService.json';
 import otherContentFixture from '../../fixtures/version-2/299843.json';
 import otherContentStringsFixture from '../../fixtures/version-2/BibliographicResource_3000126341277.json';
@@ -9,14 +8,10 @@ import fragmentFixture from '../../fixtures/version-2/hamilton.json';
 
 describe('MiradorCanvas', () => {
   let instance;
-  let v3Instance;
   beforeAll(() => {
     instance = new MiradorCanvas(
       Utils.parseManifest(fixture).getSequences()[0].getCanvases()[0],
     );
-    v3Instance = new MiradorCanvas(
-      Utils.parseManifest(v3fixture).getSequences()[0].getCanvases()[0],
-    );
   });
   describe('annotationListUris', () => {
     describe('when no annotationLists are present', () => {
diff --git a/__tests__/src/reducers/companionWindows.test.js b/__tests__/src/reducers/companionWindows.test.js
index b6a270a2f7383f03530e2c9d1d8cae7b23b286b7..d46632148c2685bd1855e2c58fa81ee139f01e15 100644
--- a/__tests__/src/reducers/companionWindows.test.js
+++ b/__tests__/src/reducers/companionWindows.test.js
@@ -51,7 +51,6 @@ describe('companionWindowsReducer', () => {
     });
   });
 
-
   describe('UPDATE_COMPANION_WINDOW', () => {
     it('updates an existing companion window', () => {
       const action = {
diff --git a/__tests__/src/reducers/errors.test.js b/__tests__/src/reducers/errors.test.js
index 0b38f0baf528fab7bfaf6622adc39d132845a893..f65c3b4af65abc1aa96d36bde53d5fcdb62227e5 100644
--- a/__tests__/src/reducers/errors.test.js
+++ b/__tests__/src/reducers/errors.test.js
@@ -1,4 +1,3 @@
-
 import { errorsReducer } from '../../../src/state/reducers/errors';
 import ActionTypes from '../../../src/state/actions/action-types';
 
diff --git a/__tests__/src/selectors/canvases.test.js b/__tests__/src/selectors/canvases.test.js
index 1d015577a43576095b98da3ca0ab38421765cd9f..50cd4530b77f625412a91b93c766aedddda7ca63 100644
--- a/__tests__/src/selectors/canvases.test.js
+++ b/__tests__/src/selectors/canvases.test.js
@@ -314,7 +314,6 @@ describe('selectNextAuthService', () => {
   });
 });
 
-
 describe('selectCanvasAuthService', () => {
   const resource = {
     service: [
diff --git a/__tests__/src/selectors/manifests.test.js b/__tests__/src/selectors/manifests.test.js
index 5e9b9f14413edc686da00f651be7af0219fcc7fb..a459e3c8ad669e0bcb3d2de0ba7435ddd278504d 100644
--- a/__tests__/src/selectors/manifests.test.js
+++ b/__tests__/src/selectors/manifests.test.js
@@ -405,7 +405,6 @@ describe('getManifestAutocompleteService', () => {
     expect(getManifestAutocompleteService(state, { manifestId: 'x' }).id).toEqual('https://contentsearch.stanford.edu/fg165hz3589/autocomplete');
   });
 
-
   it('is null if no search service is specified', () => {
     const state = { manifests: { x: { json: manifestFixture019 } } };
     expect(getManifestAutocompleteService(state, { manifestId: 'x' })).toBeNull();
diff --git a/__tests__/src/selectors/ranges.test.js b/__tests__/src/selectors/ranges.test.js
index e006278abe1e3a4b28830f35763b826735f15cd9..945864e75428dcfd4839271e0e628441c7b0a897 100644
--- a/__tests__/src/selectors/ranges.test.js
+++ b/__tests__/src/selectors/ranges.test.js
@@ -79,7 +79,6 @@ describe('getVisibleNodeIds', () => {
     ]));
     expect(visibleNodeIdsForPrezi2.length).toBe(2);
 
-
     const prezi3XYWHFragmentState = setIn(prezi3State, ['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c3']);
     const visibleNodeIdsForXYWHFragment = getVisibleNodeIds(prezi3XYWHFragmentState, { windowId: 'w1' });
     expect(visibleNodeIdsForXYWHFragment).toEqual(expect.arrayContaining([
diff --git a/__tests__/src/selectors/searches.test.js b/__tests__/src/selectors/searches.test.js
index 124e42aee1202dbaf66b45cc3aad2934aaf4a05e..ab6fab00b001926967dfc56a96ba967e3d37595a 100644
--- a/__tests__/src/selectors/searches.test.js
+++ b/__tests__/src/selectors/searches.test.js
@@ -287,7 +287,6 @@ describe('getSelectedContentSearchAnnotationIds', () => {
   });
 });
 
-
 describe('getResourceAnnotationForSearchHit', () => {
   const companionWindowId = 'cwid';
   const annoId = 'annoId2';
diff --git a/package.json b/package.json
index 12e3b216deb6037f552f0c8358b108d65caf5205..a9b82e1141bd373f8e4e3748fd8bdacdae53bec7 100644
--- a/package.json
+++ b/package.json
@@ -37,23 +37,23 @@
     "@researchgate/react-intersection-observer": "^1.0.0",
     "classnames": "^2.2.6",
     "clsx": "^1.0.4",
-    "deepmerge": "^3.3.0",
-    "dompurify": "^1.0.11",
-    "i18next": "^17.0.6",
+    "deepmerge": "^4.2.2",
+    "dompurify": "^2.0.11",
+    "i18next": "^19.5.0",
     "icomcom-react": "^1.0.1",
     "immutable": "^4.0.0-rc.12",
-    "intersection-observer": "^0.7.0",
+    "intersection-observer": "^0.10.0",
     "isomorphic-unfetch": "^3.0.0",
-    "jss": "^10.1.1",
+    "jss": "^10.3.0",
     "jss-rtl": "^0.3.0",
     "lodash": "^4.17.11",
-    "manifesto.js": "^4.0.1",
-    "normalize-url": "^4.2.0",
+    "manifesto.js": "^4.1.0",
+    "normalize-url": "^4.5.0",
     "openseadragon": "^2.4.2",
     "prop-types": "^15.6.2",
-    "re-reselect": "^3.4.0",
+    "re-reselect": "^4.0.0",
     "react-aria-live": "^2.0.5",
-    "react-beautiful-dnd": "^11.0.4",
+    "react-beautiful-dnd": "^13.0.0",
     "react-copy-to-clipboard": "^5.0.1",
     "react-dnd": "^10.0.2",
     "react-dnd-html5-backend": "^10.0.2",
@@ -61,8 +61,8 @@
     "react-dnd-touch-backend": "^10.0.2",
     "react-full-screen": "^0.2.4",
     "react-hot-loader": "^4.12.21",
-    "react-i18next": "^10.11.4",
-    "react-image": "^2.1.3",
+    "react-i18next": "^11.7.0",
+    "react-image": "^4.0.1",
     "react-mosaic-component": "^4.0.1",
     "react-redux": "^7.1.0",
     "react-resize-observer": "^1.1.1",
@@ -70,7 +70,7 @@
     "react-sizeme": "^2.6.7",
     "react-virtualized-auto-sizer": "^1.0.2",
     "react-window": "^1.8.5",
-    "redux": "4.0.1",
+    "redux": "4.0.5",
     "redux-devtools-extension": "^2.13.2",
     "redux-saga": "^1.1.3",
     "redux-thunk": "^2.3.0",
@@ -78,54 +78,54 @@
     "uuid": "^8.1.0"
   },
   "devDependencies": {
-    "@babel/cli": "^7.5.0",
-    "@babel/core": "^7.5.0",
-    "@babel/plugin-proposal-class-properties": "^7.7.4",
-    "@babel/plugin-proposal-object-rest-spread": "^7.7.4",
-    "@babel/plugin-transform-regenerator": "^7.7.5",
-    "@babel/plugin-transform-runtime": "^7.7.6",
-    "@babel/preset-env": "^7.5.0",
-    "@babel/preset-react": "^7.0.0",
-    "babel-eslint": "10.0.2",
-    "babel-jest": "^24.8.0",
+    "@babel/cli": "^7.10.3",
+    "@babel/core": "^7.10.3",
+    "@babel/plugin-proposal-class-properties": "^7.10.1",
+    "@babel/plugin-proposal-object-rest-spread": "^7.10.3",
+    "@babel/plugin-transform-regenerator": "^7.10.3",
+    "@babel/plugin-transform-runtime": "^7.10.3",
+    "@babel/preset-env": "^7.10.3",
+    "@babel/preset-react": "^7.10.1",
+    "babel-eslint": "10.1.0",
+    "babel-jest": "^26.0.1",
     "babel-loader": "^8.0.6",
     "babel-plugin-lodash": "^3.3.4",
     "babel-plugin-macros": "^2.8.0",
     "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
     "bundlewatch": "^0.2.5",
-    "chalk": "^2.4.2",
-    "codecov": "^3.5.0",
+    "chalk": "^4.1.0",
+    "codecov": "^3.7.0",
     "core-js": "^3.4.8",
-    "css-loader": "^3.0.0",
+    "css-loader": "^3.6.0",
     "enzyme": "^3.10.0",
     "enzyme-adapter-react-16": "^1.14.0",
     "eslint": "^6.0.0",
-    "eslint-config-airbnb": "^17.1.1",
+    "eslint-config-airbnb": "^18.2.0",
     "eslint-config-react-app": "^3.0.5",
-    "eslint-loader": "^2.2.1",
-    "eslint-plugin-flowtype": "^3.11.1",
+    "eslint-loader": "^4.0.2",
+    "eslint-plugin-flowtype": "^4.7.0",
     "eslint-plugin-import": "^2.18.0",
-    "eslint-plugin-jest": "^22.7.2",
+    "eslint-plugin-jest": "^23.16.0",
     "eslint-plugin-jsx-a11y": "^6.2.3",
     "eslint-plugin-react": "^7.14.2",
     "glob": "^7.1.4",
-    "http-server": "^0.11.1",
-    "jest": "^24.8.0",
+    "http-server": "^0.12.3",
+    "jest": "^26.0.1",
     "jest-fetch-mock": "^3.0.0",
     "jest-puppeteer": "^4.1.1",
     "jsdom": "15.1.1",
-    "puppeteer": "^1.18.1",
+    "puppeteer": "^4.0.0",
     "react": "^16.8.6",
-    "react-dev-utils": "^9.0.1",
+    "react-dev-utils": "^10.2.1",
     "react-dom": "^16.8.6",
     "redux-mock-store": "^1.5.1",
     "redux-saga-test-plan": "^4.0.0-rc.3",
-    "style-loader": "^0.23.1",
+    "style-loader": "^1.2.1",
     "supertest": "^4.0.2",
-    "terser-webpack-plugin": "^1.3.0",
+    "terser-webpack-plugin": "^3.0.6",
     "unfetch": "^4.1.0",
     "url-polyfill": "^1.1.7",
-    "webpack": "^4.35.3",
+    "webpack": "^4.43.0",
     "webpack-cli": "^3.3.5",
     "webpack-dev-server": "^3.11.0"
   },
diff --git a/scripts/i18n-lint.js b/scripts/i18n-lint.js
index e61701bd558b45300f5d1a5694fd71c715fb0d04..6a407f3e32706af68886d7c517821ce5963aac9a 100644
--- a/scripts/i18n-lint.js
+++ b/scripts/i18n-lint.js
@@ -43,7 +43,6 @@ files.forEach((fileName) => {
 
 const completeKeys = normalizedFiles[defaultLocaleFile].slice().sort();
 
-
 Object.keys(normalizedFiles).forEach((fileName) => {
   const unsorted = unsortedKeys(normalizedFiles[fileName]);
   const missing = missingKeys(completeKeys, normalizedFiles[fileName]);
diff --git a/setupJest.js b/setupJest.js
index fc331173c87f54d98df781b0d1c5a0007d4bd82c..cc3e8aca8525e1a5818392b56daf766342cf3661 100644
--- a/setupJest.js
+++ b/setupJest.js
@@ -1,4 +1,3 @@
-
 // Setup Jest to mock fetch
 
 import { JSDOM } from 'jsdom'; // eslint-disable-line import/no-extraneous-dependencies
@@ -6,7 +5,7 @@ import fetch from 'jest-fetch-mock'; // eslint-disable-line import/no-extraneous
 import Enzyme from 'enzyme'; // eslint-disable-line import/no-extraneous-dependencies
 import Adapter from 'enzyme-adapter-react-16'; // eslint-disable-line import/no-extraneous-dependencies
 
-const jsdom = new JSDOM('<!doctype html><html><body><div id="main"></div></body></html>');
+const jsdom = new JSDOM('<!doctype html><html><body><div id="main"></div></body></html>', { url: 'https://localhost' });
 const { window } = jsdom;
 
 jest.setTimeout(10000);
diff --git a/src/components/AppProviders.js b/src/components/AppProviders.js
index 6ce73577360f337c5c5a95cadd23b48a25c4d696..d250761dfdf5e3c093ffa2d32965d4960f4d3ed2 100644
--- a/src/components/AppProviders.js
+++ b/src/components/AppProviders.js
@@ -13,7 +13,6 @@ import { create } from 'jss';
 import rtl from 'jss-rtl';
 import createI18nInstance from '../i18n';
 
-
 /**
  * Allow applications to opt-out of (or provide their own) drag and drop context
  */
diff --git a/src/components/AttributionPanel.js b/src/components/AttributionPanel.js
index 358798f5438917e984d6c3a1c75279c64ab94818..15063c45c4e75f6b2bf4e1f99c641e2d6489a9dc 100644
--- a/src/components/AttributionPanel.js
+++ b/src/components/AttributionPanel.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
 import Typography from '@material-ui/core/Typography';
 import Link from '@material-ui/core/Link';
 import Skeleton from '@material-ui/lab/Skeleton';
-import Img from 'react-image';
+import { Img } from 'react-image';
 import CompanionWindow from '../containers/CompanionWindow';
 import { LabelValueMetadata } from './LabelValueMetadata';
 import ns from '../config/css-ns';
diff --git a/src/components/AuthenticationSender.js b/src/components/AuthenticationSender.js
index f0ff9c39461a3fe6bba41f3a74a6f4496e6d96cd..e277838069e5f7a88ed2d34f0609a4edec046962 100644
--- a/src/components/AuthenticationSender.js
+++ b/src/components/AuthenticationSender.js
@@ -2,7 +2,6 @@ import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import { NewWindow } from './NewWindow';
 
-
 /**
  * Opens a new window for click
  */
diff --git a/src/components/CanvasLayers.js b/src/components/CanvasLayers.js
index 7a7501e7262b6704387e1eb5b4dab7ea40d1ba05..7024334c49909bb7b1f6b92c6d4e9b3264c413ec 100644
--- a/src/components/CanvasLayers.js
+++ b/src/components/CanvasLayers.js
@@ -260,7 +260,6 @@ export class CanvasLayers extends Component {
   }
 }
 
-
 CanvasLayers.propTypes = {
   canvas: PropTypes.shape({
     id: PropTypes.string,
diff --git a/src/components/CompanionWindow.js b/src/components/CompanionWindow.js
index 67523cfdeec84ac57125c4c409cd1fa0b9145235..a37ab7602bbd60382d7660eb04be734377d25382 100644
--- a/src/components/CompanionWindow.js
+++ b/src/components/CompanionWindow.js
@@ -21,7 +21,6 @@ export class CompanionWindow extends Component {
     return {};
   }
 
-
   /** */
   resizeHandles() {
     const { direction, position } = this.props;
@@ -36,7 +35,6 @@ export class CompanionWindow extends Component {
       },
     };
 
-
     const base = {
       bottom: false,
       bottomLeft: false,
@@ -88,7 +86,6 @@ export class CompanionWindow extends Component {
       );
     });
 
-
     return (
       <Paper
         className={[classes.root, position === 'bottom' ? classes.horizontal : classes.vertical, classes[`companionWindow-${position}`], ns(`companion-window-${position}`), paperClassName].join(' ')}
diff --git a/src/components/LabelValueMetadata.js b/src/components/LabelValueMetadata.js
index 4bd30d103b69a3eb834e1bf5daecd89236fabdd2..d89e50352662a769491dd4daef7d590cdf7e006f 100644
--- a/src/components/LabelValueMetadata.js
+++ b/src/components/LabelValueMetadata.js
@@ -4,7 +4,6 @@ import Typography from '@material-ui/core/Typography';
 import SanitizedHtml from '../containers/SanitizedHtml';
 import ns from '../config/css-ns';
 
-
 /**
  * Renders label/value pair metadata in a dl
  * @prop {object} labelValuePair
diff --git a/src/components/LocalePicker.js b/src/components/LocalePicker.js
index a33d586fff7048fe9fde875b79d96c52accb8a47..e2177036c9f25700a5b8f7d7fc969b22814758aa 100644
--- a/src/components/LocalePicker.js
+++ b/src/components/LocalePicker.js
@@ -5,7 +5,6 @@ import FormControl from '@material-ui/core/FormControl';
 import Select from '@material-ui/core/Select';
 import Typography from '@material-ui/core/Typography';
 
-
 /**
  * Provide a locale picker
  */
@@ -51,7 +50,6 @@ export class LocalePicker extends Component {
   }
 }
 
-
 LocalePicker.propTypes = {
   availableLocales: PropTypes.arrayOf(PropTypes.string),
   classes: PropTypes.objectOf(PropTypes.string),
diff --git a/src/components/ManifestListItem.js b/src/components/ManifestListItem.js
index a921d48c6ec77a6d5d1b52a67db316d65e0838d2..ea2c4127947e714cdcd38eae6312602dd0d7f955 100644
--- a/src/components/ManifestListItem.js
+++ b/src/components/ManifestListItem.js
@@ -5,7 +5,7 @@ import ButtonBase from '@material-ui/core/ButtonBase';
 import Grid from '@material-ui/core/Grid';
 import Typography from '@material-ui/core/Typography';
 import Skeleton from '@material-ui/lab/Skeleton';
-import Img from 'react-image';
+import { Img } from 'react-image';
 import ManifestListItemError from '../containers/ManifestListItemError';
 import ns from '../config/css-ns';
 
diff --git a/src/components/ManifestListItemError.js b/src/components/ManifestListItemError.js
index 8b6289510d7ab69bda672f352aff3ee6dd22d316..fd37247bc07e1e9e6ca80fcfd5d79134db2bd4b4 100644
--- a/src/components/ManifestListItemError.js
+++ b/src/components/ManifestListItemError.js
@@ -51,7 +51,6 @@ export class ManifestListItemError extends Component {
   }
 }
 
-
 ManifestListItemError.propTypes = {
   classes: PropTypes.objectOf(PropTypes.string).isRequired,
   manifestId: PropTypes.string.isRequired,
diff --git a/src/components/MinimalWindow.js b/src/components/MinimalWindow.js
index 7db511ac7de2dc555be0b30e0d6ba24e65b2a219..2097bad94161124dc549103625dad4c6362d4e86 100644
--- a/src/components/MinimalWindow.js
+++ b/src/components/MinimalWindow.js
@@ -31,7 +31,8 @@ export class MinimalWindow extends Component {
         elevation={1}
         id={windowId}
         className={
-          cn(classes.window, ns('placeholder-window'))}
+          cn(classes.window, ns('placeholder-window'))
+        }
         aria-label={t('window', { label })}
       >
         <AppBar position="relative" color="default">
diff --git a/src/components/MiradorMenuButton.js b/src/components/MiradorMenuButton.js
index 7793aa790e4cd5e475c6a48f5d8aedc780cc0b2f..83c13b26168a35cc3ca97b2092b973e306b27153 100644
--- a/src/components/MiradorMenuButton.js
+++ b/src/components/MiradorMenuButton.js
@@ -26,8 +26,7 @@ export function MiradorMenuButton(props) {
     <IconButton {...iconButtonProps}>
       {badge
         ? <Badge {...BadgeProps}>{children}</Badge>
-        : children
-      }
+        : children}
     </IconButton>
   );
 
diff --git a/src/components/NestedMenu.js b/src/components/NestedMenu.js
index 9371f76f24699b9b474ba151ecd7928de04b99af..6831c4de37921b00824a9876ff9f9c05ca5652af 100644
--- a/src/components/NestedMenu.js
+++ b/src/components/NestedMenu.js
@@ -46,9 +46,7 @@ export class NestedMenu extends Component {
     return (
       <>
         <MenuItem onClick={this.handleMenuClick} divider={nestedMenuIsOpen} {...otherProps}>
-          {icon
-            && (<ListItemIcon>{icon}</ListItemIcon>)
-          }
+          {icon && (<ListItemIcon>{icon}</ListItemIcon>)}
           <ListItemText primaryTypographyProps={{ variant: 'body1' }}>
             {label}
           </ListItemText>
diff --git a/src/components/NewWindow.js b/src/components/NewWindow.js
index 702fb9d4bc51c76c93358d6a52273b8030e6120a..d5099a95a1bdbaa928df0ebf71524a1fc158f320 100644
--- a/src/components/NewWindow.js
+++ b/src/components/NewWindow.js
@@ -1,7 +1,6 @@
 import { Component } from 'react';
 import PropTypes from 'prop-types';
 
-
 /**
  * Opens a new window for click
  */
diff --git a/src/components/SearchPanelControls.js b/src/components/SearchPanelControls.js
index 89039c1a7dfbf9cc4fbd805af514751aff1a7b30..9a37eef51e310c506a6b050b01acda7fcba99e04 100644
--- a/src/components/SearchPanelControls.js
+++ b/src/components/SearchPanelControls.js
@@ -80,7 +80,6 @@ export class SearchPanelControls extends Component {
     this.setState({ suggestions: json.terms });
   }
 
-
   /** */
   submitSearch(event) {
     const {
diff --git a/src/components/ThumbnailCanvasGrouping.js b/src/components/ThumbnailCanvasGrouping.js
index d30751f39c5c7b4733fd85f40a09772b42856b6a..958e2e5f2a4d10e31a48a932f5b4f878ec06da50 100644
--- a/src/components/ThumbnailCanvasGrouping.js
+++ b/src/components/ThumbnailCanvasGrouping.js
@@ -4,7 +4,6 @@ import classNames from 'classnames';
 import IIIFThumbnail from '../containers/IIIFThumbnail';
 import ns from '../config/css-ns';
 
-
 /** */
 export class ThumbnailCanvasGrouping extends PureComponent {
   /** */
diff --git a/src/components/Window.js b/src/components/Window.js
index f1b4b8bfcf4e630bdc401b31f51c98140792e0c7..62466dd06d74ee869da7f31cbf7d73acd6e39f50 100644
--- a/src/components/Window.js
+++ b/src/components/Window.js
@@ -12,7 +12,6 @@ import ErrorContent from '../containers/ErrorContent';
 import WindowAuthenticationControl from '../containers/WindowAuthenticationControl';
 import { PluginHook } from './PluginHook';
 
-
 /**
  * Represents a Window in the mirador workspace
  * @param {object} window
@@ -85,7 +84,8 @@ export class Window extends Component {
         id={windowId}
         className={
           cn(classes.window, ns('window'),
-            maximized ? classes.maximized : null)}
+            maximized ? classes.maximized : null)
+}
         aria-label={t('window', { label })}
       >
         {this.wrappedTopBar()}
diff --git a/src/components/WindowAuthenticationControl.js b/src/components/WindowAuthenticationControl.js
index 7ea9e787db7a2b8abbb6f584e6f489c8f3d10b9f..32b3cbef3856c4fffdf3adcb6af8c9cb050c6d5b 100644
--- a/src/components/WindowAuthenticationControl.js
+++ b/src/components/WindowAuthenticationControl.js
@@ -103,8 +103,7 @@ export class WindowAuthenticationControl extends Component {
                 { t('continue') }
               </Typography>
               )
-              : confirmButton
-            }
+              : confirmButton}
           </span>
         </Button>
         {
diff --git a/src/components/WindowCanvasNavigationControls.js b/src/components/WindowCanvasNavigationControls.js
index 802b3684ccf8635189dd9114482016673426fea6..39e662db8bdb6631310e56a53c29f72b641db976 100644
--- a/src/components/WindowCanvasNavigationControls.js
+++ b/src/components/WindowCanvasNavigationControls.js
@@ -40,7 +40,8 @@ export class WindowCanvasNavigationControls extends Component {
             classes.canvasNav,
             this.canvasNavControlsAreStacked() ? ns('canvas-nav-stacked') : null,
             this.canvasNavControlsAreStacked() ? classes.canvasNavStacked : null,
-          )}
+          )
+}
         elevation={0}
       >
         <ZoomControls
@@ -57,7 +58,6 @@ export class WindowCanvasNavigationControls extends Component {
   }
 }
 
-
 WindowCanvasNavigationControls.propTypes = {
   classes: PropTypes.objectOf(PropTypes.string),
   size: PropTypes.shape({ width: PropTypes.number }).isRequired,
diff --git a/src/components/WindowSideBarInfoPanel.js b/src/components/WindowSideBarInfoPanel.js
index 805f894c024e9b9f578403729a8d1fe16edbe011..f2530d26152e7fa47dc6a518d971a1f706bbabe3 100644
--- a/src/components/WindowSideBarInfoPanel.js
+++ b/src/components/WindowSideBarInfoPanel.js
@@ -7,7 +7,6 @@ import ManifestInfo from '../containers/ManifestInfo';
 import ManifestRelatedLinks from '../containers/ManifestRelatedLinks';
 import ns from '../config/css-ns';
 
-
 /**
  * WindowSideBarInfoPanel
  */
diff --git a/src/components/WindowTopBar.js b/src/components/WindowTopBar.js
index 940017674495c9d4fd74ccb94214e0eccb8f4381..6bb4cbd62a000c07d36111f73187635390854de3 100644
--- a/src/components/WindowTopBar.js
+++ b/src/components/WindowTopBar.js
@@ -15,7 +15,6 @@ import WindowMaxIcon from './icons/WindowMaxIcon';
 import WindowMinIcon from './icons/WindowMinIcon';
 import ns from '../config/css-ns';
 
-
 /**
  * WindowTopBar
  */
diff --git a/src/components/WindowTopBarPluginMenu.js b/src/components/WindowTopBarPluginMenu.js
index f5704153993cd11f0404661147b86ff8ac50419d..b3e6e4b3c00aa04a6caf668076311e70619e6181 100644
--- a/src/components/WindowTopBarPluginMenu.js
+++ b/src/components/WindowTopBarPluginMenu.js
@@ -99,7 +99,6 @@ WindowTopBarPluginMenu.propTypes = {
   windowId: PropTypes.string.isRequired,
 };
 
-
 WindowTopBarPluginMenu.defaultProps = {
   classes: {},
   menuIcon: <MoreVertIcon />,
diff --git a/src/components/WorkspaceArea.js b/src/components/WorkspaceArea.js
index 3baa66b987f739c8b187e599824379de7a854d1e..83439c3a7875e03239de7323a1cf987d5765694e 100644
--- a/src/components/WorkspaceArea.js
+++ b/src/components/WorkspaceArea.js
@@ -47,7 +47,6 @@ export class WorkspaceArea extends Component {
   }
 }
 
-
 WorkspaceArea.propTypes = {
   classes: PropTypes.objectOf(PropTypes.string).isRequired,
   controlPanelVariant: PropTypes.string,
diff --git a/src/components/WorkspaceExport.js b/src/components/WorkspaceExport.js
index af0f4d701d669fdbed6970254389867aedf7e84d..c752f393cbde46c1d88cfb9dab2c87a80ddcecf5 100644
--- a/src/components/WorkspaceExport.js
+++ b/src/components/WorkspaceExport.js
@@ -44,7 +44,6 @@ export class WorkspaceExport extends Component {
     return JSON.stringify(exportableState, null, 2);
   }
 
-
   /**
    * render
    * @return
diff --git a/src/containers/AccessTokenSender.js b/src/containers/AccessTokenSender.js
index c241349ead656c22613970d6f7ecd68e8e30e702..61a4edcce3c6ed63c55c819d98e87ce96f049598 100644
--- a/src/containers/AccessTokenSender.js
+++ b/src/containers/AccessTokenSender.js
@@ -4,7 +4,6 @@ import { withPlugins } from '../extend/withPlugins';
 import * as actions from '../state/actions';
 import { AccessTokenSender } from '../components/AccessTokenSender';
 
-
 /**
  * mapStateToProps - to hook up connect
  * @memberof App
diff --git a/src/containers/AnnotationsOverlay.js b/src/containers/AnnotationsOverlay.js
index 5cdb684f25ca2bdeef8843e12e873ff19a3794a3..43be6e15931dddb888d88d183ac1805caea27df5 100644
--- a/src/containers/AnnotationsOverlay.js
+++ b/src/containers/AnnotationsOverlay.js
@@ -59,5 +59,4 @@ const enhance = compose(
   withPlugins('AnnotationsOverlay'),
 );
 
-
 export default enhance(AnnotationsOverlay);
diff --git a/src/containers/AppProviders.js b/src/containers/AppProviders.js
index 14d7ae802cea7b6093935176629d022711c0ac1f..226621be110d055cfcd56670824136e0ec36cacf 100644
--- a/src/containers/AppProviders.js
+++ b/src/containers/AppProviders.js
@@ -5,7 +5,6 @@ import * as actions from '../state/actions';
 import { getTheme } from '../state/selectors';
 import { AppProviders } from '../components/AppProviders';
 
-
 /**
  * mapStateToProps - to hook up connect
  * @memberof App
diff --git a/src/containers/AuthenticationSender.js b/src/containers/AuthenticationSender.js
index 3f0db7e2ddcf6ef22a14d8a0925b871fadd1e915..c574259646d4a9461404d9058d14b274936bf1f3 100644
--- a/src/containers/AuthenticationSender.js
+++ b/src/containers/AuthenticationSender.js
@@ -4,7 +4,6 @@ import { withPlugins } from '../extend/withPlugins';
 import * as actions from '../state/actions';
 import { AuthenticationSender } from '../components/AuthenticationSender';
 
-
 /**
  * mapStateToProps - to hook up connect
  * @memberof App
diff --git a/src/containers/ChangeThemeDialog.js b/src/containers/ChangeThemeDialog.js
index 3b09a0f3ed6872c681208ff3d540112436913852..b992922c008b67f2445c23443d197414b4fe32d9 100644
--- a/src/containers/ChangeThemeDialog.js
+++ b/src/containers/ChangeThemeDialog.js
@@ -48,7 +48,6 @@ const styles = theme => ({
   },
 });
 
-
 const enhance = compose(
   withTranslation(),
   withStyles(styles),
diff --git a/src/containers/LanguageSettings.js b/src/containers/LanguageSettings.js
index d335b360519dac2595ef8551de502c4f5f7f1a0c..5cfbce473032c0a72318a73ce58545b556418167 100644
--- a/src/containers/LanguageSettings.js
+++ b/src/containers/LanguageSettings.js
@@ -23,7 +23,6 @@ const mapDispatchToProps = (dispatch, { afterSelect }) => ({
   },
 });
 
-
 export default compose(
   connect(mapStateToProps, mapDispatchToProps),
   withPlugins('LanguageSettings'),
diff --git a/src/containers/OpenSeadragonViewer.js b/src/containers/OpenSeadragonViewer.js
index c733eb33bce2be58a22f31805de13239a1ca870c..25bd53f6f5b91070af23e2c9f642ec9733dc4e05 100644
--- a/src/containers/OpenSeadragonViewer.js
+++ b/src/containers/OpenSeadragonViewer.js
@@ -71,5 +71,4 @@ const enhance = compose(
   withPlugins('OpenSeadragonViewer'),
 );
 
-
 export default enhance(OpenSeadragonViewer);
diff --git a/src/containers/SidebarIndexTableOfContents.js b/src/containers/SidebarIndexTableOfContents.js
index df45c5dc2eea379720d39bdb6a1e7d23b1b36e62..6d0d7d771eaedfa1f278fd613bfd598741d82320 100644
--- a/src/containers/SidebarIndexTableOfContents.js
+++ b/src/containers/SidebarIndexTableOfContents.js
@@ -13,7 +13,6 @@ import {
 } from '../state/selectors';
 import * as actions from '../state/actions';
 
-
 /**
  * mapStateToProps - to hook up connect
  */
diff --git a/src/containers/ThumbnailNavigation.js b/src/containers/ThumbnailNavigation.js
index 623579b5e231e6fa2cb7c747a38a400f80babf12..df0e69e15228cd613c99d8e61eec331a62759d6a 100644
--- a/src/containers/ThumbnailNavigation.js
+++ b/src/containers/ThumbnailNavigation.js
@@ -56,7 +56,6 @@ const styles = theme => ({
   },
 });
 
-
 const enhance = compose(
   withStyles(styles),
   withTranslation(),
diff --git a/src/containers/Window.js b/src/containers/Window.js
index 21a3315697e789cc1687d68f9f70d2ac79ebbf1d..6e4eb5d3ea453fa54b443a224f9736b5c6b39c84 100644
--- a/src/containers/Window.js
+++ b/src/containers/Window.js
@@ -10,7 +10,6 @@ import {
   getWorkspaceType, getWindowDraggability, getWindowViewType, getManifestError,
 } from '../state/selectors';
 
-
 /**
  * mapStateToProps - used to hook up connect to action creators
  * @memberof Window
diff --git a/src/containers/WindowAuthenticationControl.js b/src/containers/WindowAuthenticationControl.js
index f6b42b17598df6993d142bb85a1025a880aae84f..97b8978ae201e4bc7b5ee87a19251741cc4009b3 100644
--- a/src/containers/WindowAuthenticationControl.js
+++ b/src/containers/WindowAuthenticationControl.js
@@ -13,7 +13,6 @@ import {
 } from '../state/selectors';
 import { WindowAuthenticationControl } from '../components/WindowAuthenticationControl';
 
-
 /**
  * mapStateToProps - to hook up connect
  * @memberof App
diff --git a/src/containers/WindowSideBarAnnotationsPanel.js b/src/containers/WindowSideBarAnnotationsPanel.js
index 7c2dca5480c3a7806cd4e6a06aa7de3fe0f7f5dd..64af2caedc2d7bf2977b00037c2296865eefb012 100644
--- a/src/containers/WindowSideBarAnnotationsPanel.js
+++ b/src/containers/WindowSideBarAnnotationsPanel.js
@@ -22,7 +22,6 @@ const mapStateToProps = (state, { windowId }) => ({
   selectedCanvases: getVisibleCanvases(state, { windowId }),
 });
 
-
 /** */
 const styles = theme => ({
   section: {
diff --git a/src/containers/WindowSideBarButtons.js b/src/containers/WindowSideBarButtons.js
index f6adba102a9511fa9822dc5cb968d2c856a9f022..157d5cff8e10c5947f16ca3f1414726ae86123a5 100644
--- a/src/containers/WindowSideBarButtons.js
+++ b/src/containers/WindowSideBarButtons.js
@@ -16,7 +16,6 @@ import {
 } from '../state/selectors';
 import { WindowSideBarButtons } from '../components/WindowSideBarButtons';
 
-
 /**
  * mapDispatchToProps - used to hook up connect to action creators
  * @memberof WindowSideButtons
diff --git a/src/containers/WindowTopBarPluginMenu.js b/src/containers/WindowTopBarPluginMenu.js
index 2f983ea354d06e545c7ed2607ef4ad8969e8db22..946d9d0b5db92798d0ab882cdda9736bca96154c 100644
--- a/src/containers/WindowTopBarPluginMenu.js
+++ b/src/containers/WindowTopBarPluginMenu.js
@@ -15,7 +15,6 @@ const mapStateToProps = state => ({
   containerId: getContainerId(state),
 });
 
-
 /**
  *
  * @param theme
diff --git a/src/containers/WindowTopBarTitle.js b/src/containers/WindowTopBarTitle.js
index e1c65661119c323eabbd78cb9ef1fe2c792bec71..28b9bb903995e95bc0bfe9b2ec746f5ae79baf1f 100644
--- a/src/containers/WindowTopBarTitle.js
+++ b/src/containers/WindowTopBarTitle.js
@@ -14,7 +14,6 @@ const mapStateToProps = (state, { windowId }) => ({
   manifestTitle: getManifestTitle(state, { windowId }),
 });
 
-
 /**
  * @param theme
  */
diff --git a/src/containers/WindowViewer.js b/src/containers/WindowViewer.js
index f724ad9232922003debddaf418d309a737316a7c..b6c396b2ef611abeadf99a46597f47f39a7ea545 100644
--- a/src/containers/WindowViewer.js
+++ b/src/containers/WindowViewer.js
@@ -1,5 +1,4 @@
 import { compose } from 'redux';
-import { connect } from 'react-redux';
 import { withPlugins } from '../extend/withPlugins';
 import { WindowViewer } from '../components/WindowViewer';
 
diff --git a/src/containers/WorkspaceOptionsButton.js b/src/containers/WorkspaceOptionsButton.js
index cf172e5129d6d58034234b8fa1757750387af51d..f17b51310f56018393b23b6593ff87da902f2857 100644
--- a/src/containers/WorkspaceOptionsButton.js
+++ b/src/containers/WorkspaceOptionsButton.js
@@ -17,7 +17,6 @@ const styles = theme => ({
   },
 });
 
-
 const enhance = compose(
   withStyles(styles),
   withTranslation(),
diff --git a/src/extend/withPlugins.js b/src/extend/withPlugins.js
index f7033bac4fe2addafe701172313255074806f80a..478e88723572356fbec6279fb05841b58d8cfb31 100644
--- a/src/extend/withPlugins.js
+++ b/src/extend/withPlugins.js
@@ -3,7 +3,6 @@ import curry from 'lodash/curry';
 import isEmpty from 'lodash/isEmpty';
 import PluginContext from './PluginContext';
 
-
 /** withPlugins should be the innermost HOC */
 function _withPlugins(targetName, TargetComponent) { // eslint-disable-line no-underscore-dangle
   /** */
diff --git a/src/lib/MiradorManifest.js b/src/lib/MiradorManifest.js
index 9a96a00faa48e7641f5b74e1b58ec900b7dff355..da7414ff4dbe017cd75e9a428fee7f7e5ba4e1db 100644
--- a/src/lib/MiradorManifest.js
+++ b/src/lib/MiradorManifest.js
@@ -1,4 +1,3 @@
-
 /**
  * MiradorCanvas - adds additional, testable logic around Manifesto's Manifest
  * https://iiif-commons.github.io/manifesto/classes/_canvas_.manifesto.canvas.html
diff --git a/src/lib/htmlRules.js b/src/lib/htmlRules.js
index f964817aa6274aedab602f6e4f0e1fec5fb50af7..43fd823275b1bf50c98b29f68b4f8ef34353c09a 100644
--- a/src/lib/htmlRules.js
+++ b/src/lib/htmlRules.js
@@ -1,4 +1,3 @@
-
 // Only remove security related tags and attributes. Allow each other.
 const liberal = {};
 
diff --git a/src/state/sagas/iiif.js b/src/state/sagas/iiif.js
index 30e8308bf3d06e061044f551e6c27184e09c0f99..9a8288427e53b2708527b980ba7c41ac326c7270 100644
--- a/src/state/sagas/iiif.js
+++ b/src/state/sagas/iiif.js
@@ -210,7 +210,6 @@ export function* refetchInfoResponses({ serviceId }) {
   yield put({ serviceId, type: ActionTypes.CLEAR_ACCESS_TOKEN_QUEUE });
 }
 
-
 /** */
 export default function* iiifSaga() {
   yield all([
diff --git a/src/state/selectors/annotations.js b/src/state/selectors/annotations.js
index 7fec25ef117cbd398c271ee803481b627ddd619f..d8849b6df12b5d1256aef424ac1b4b4a4b9ee20c 100644
--- a/src/state/selectors/annotations.js
+++ b/src/state/selectors/annotations.js
@@ -31,7 +31,6 @@ const getPresentAnnotationsCanvas = createSelector(
   ),
 );
 
-
 const getAnnotationsOnSelectedCanvases = createSelector(
   [
     getVisibleCanvasIds,
diff --git a/src/state/selectors/companionWindows.js b/src/state/selectors/companionWindows.js
index f6647638f340f6790045f3d159625d86c49dc116..692ee92295682ff930f857846055bbda0370c6ea 100644
--- a/src/state/selectors/companionWindows.js
+++ b/src/state/selectors/companionWindows.js
@@ -2,7 +2,6 @@ import { createSelector } from 'reselect';
 import groupBy from 'lodash/groupBy';
 import { getWindow, getWindows } from './getters';
 
-
 /** */
 export function getCompanionWindows(state) {
   return state.companionWindows;