From a503248fa53c59edaf2fa534b5edca534b1cf904 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 4 Oct 2018 15:22:07 -0500 Subject: [PATCH 01/91] Updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 85f6bfd..5466217 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "repertory-ui", - "version": "1.0.1", + "version": "1.0.2", "private": true, "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.1", From e310b0c5b617dd5e1fea86e078bd13232a02b1ba Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 9 Oct 2018 19:17:03 -0500 Subject: [PATCH 02/91] Updated releases --- releases.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/releases.json b/releases.json index b7563ef..c2a911f 100644 --- a/releases.json +++ b/releases.json @@ -1,6 +1,10 @@ { "Locations": { "win32": { + "1.0.2": { + "hash": "", + "urls": [] + }, "1.0.1": { "hash": "", "urls": [ @@ -17,6 +21,7 @@ }, "Versions": { "win32": [ + "1.0.2", "1.0.1", "1.0.0" ] From 2dbb791a5f5f4d671cac583429323b762aafb2e7 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Mon, 15 Oct 2018 17:15:25 -0500 Subject: [PATCH 03/91] Use callback during setState() --- src/App.js | 103 +++++++++--------- src/containers/Configuration/Configuration.js | 55 +++++----- src/containers/MountItems/MountItems.js | 83 +++++++------- 3 files changed, 123 insertions(+), 118 deletions(-) diff --git a/src/App.js b/src/App.js index fe29cf7..06fded1 100644 --- a/src/App.js +++ b/src/App.js @@ -101,30 +101,26 @@ class App extends Component { } }; - checkVersionInstalled = (release, version, versionLookup) => { - if (!versionLookup) { - versionLookup = this.state.VersionLookup; - } - - const selectedVersion = versionLookup[this.state.ReleaseTypes[release]][version]; + checkVersionInstalled = () => { this.setState({ AllowDownload: false, - }); + }, ()=> { + const selectedVersion = this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]][this.state.Version]; + if (selectedVersion !== 'unavailable') { + if (ipcRenderer) { + let dependencies = []; + if (this.state.LocationsLookup[selectedVersion] && this.state.LocationsLookup[selectedVersion].dependencies) { + dependencies = this.state.LocationsLookup[selectedVersion].dependencies; + } - if (selectedVersion !== 'unavailable') { - if (ipcRenderer) { - let dependencies = []; - if (this.state.LocationsLookup[selectedVersion] && this.state.LocationsLookup[selectedVersion].dependencies) { - dependencies = this.state.LocationsLookup[selectedVersion].dependencies; + ipcRenderer.send(Constants.IPC_Check_Installed, { + Dependencies: dependencies, + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Version: selectedVersion, + }); } - - ipcRenderer.send(Constants.IPC_Check_Installed, { - Dependencies: dependencies, - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Version: selectedVersion, - }); } - } + }); }; closeErrorDisplay = () => { @@ -176,6 +172,8 @@ class App extends Component { ...this.state.Hyperspace }; + this.saveState(this.state.Release, this.state.Version, sia, hyperspace); + if (storageType === 'Hyperspace') { hyperspace.AutoMount = e.target.checked; this.setState({ @@ -188,7 +186,6 @@ class App extends Component { }); } - this.saveState(this.state.Release, this.state.Version, sia, hyperspace); }; handleConfigClicked = (storageType) => { @@ -212,12 +209,12 @@ class App extends Component { DownloadActive: true, DownloadingDependency: true, DownloadName: fileName, - }); - - ipcRenderer.send(Constants.IPC_Download_File, { - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Filename: fileName, - URL: url, + }, ()=> { + ipcRenderer.send(Constants.IPC_Download_File, { + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Filename: this.state.DownloadName, + URL: url, + }); }); } }; @@ -227,9 +224,6 @@ class App extends Component { ...this.state[storageType], MountLocation: location, }; - this.setState({ - [storageType]: state, - }); const hyperspace = (storageType === 'Hyperspace') ? state : { ...this.state.Hyperspace, }; @@ -238,17 +232,21 @@ class App extends Component { }; this.saveState(this.state.Release, this.state.Version, sia, hyperspace); + this.setState({ + [storageType]: state, + }); }; handleReleaseChanged = (e) => { const val = parseInt(e.target.value, 10); const versionIndex = this.state.VersionLookup[this.state.ReleaseTypes[val]].length - 1; + this.saveState(val, versionIndex, this.state.Sia, this.state.Hyperspace); this.setState({ Release: val, Version: versionIndex + }, ()=> { + this.checkVersionInstalled( ); }); - this.saveState(val, versionIndex, this.state.Sia, this.state.Hyperspace); - this.checkVersionInstalled(val, versionIndex); }; handleReleaseDownload = () => { @@ -259,12 +257,12 @@ class App extends Component { DownloadActive: true, DownloadingRelease: true, DownloadName: fileName, - }); - - ipcRenderer.send(Constants.IPC_Download_File, { - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Filename: fileName, - URL: this.state.LocationsLookup[selectedVersion].urls[0], + }, () => { + ipcRenderer.send(Constants.IPC_Download_File, { + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Filename: this.state.DownloadName, + URL: this.state.LocationsLookup[selectedVersion].urls[0], + }); }); } }; @@ -275,12 +273,12 @@ class App extends Component { DownloadActive: true, DownloadingUpgrade: true, DownloadName: 'UI Upgrade', - }); - - ipcRenderer.send(Constants.IPC_Download_File, { - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Filename: this.props.platform === 'win32' ? 'upgrade.exe' : 'upgrade', - URL: this.state.UpgradeData.urls[0], + }, ()=> { + ipcRenderer.send(Constants.IPC_Download_File, { + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Filename: this.props.platform === 'win32' ? 'upgrade.exe' : 'upgrade', + URL: this.state.UpgradeData.urls[0], + }); }); } else { this.setState({UpgradeDismissed: true}); @@ -289,11 +287,12 @@ class App extends Component { handleVersionChanged = (e) => { const val = parseInt(e.target.value, 10); + this.saveState(this.state.Release, val, this.state.Sia, this.state.Hyperspace); this.setState({ Version: val + }, ()=> { + this.checkVersionInstalled( ); }); - this.saveState(this.state.Release, val, this.state.Sia, this.state.Hyperspace); - this.checkVersionInstalled(this.state.Release, val); }; notifyAutoMountProcessed = () => { @@ -400,8 +399,9 @@ class App extends Component { this.setState({ ExtractActive: false, + }, ()=> { + this.checkVersionInstalled( ); }); - this.checkVersionInstalled(this.state.Release, this.state.Version); }; onGetStateReply = (event, arg) => { @@ -417,9 +417,12 @@ class App extends Component { Release: arg.data.Release, Sia: arg.data.Sia, Version: arg.data.Version, + }, ()=> { + this.grabReleases(); }); + } else { + this.grabReleases(); } - this.grabReleases(); }; onGrabReleasesReply = ()=> { @@ -437,9 +440,9 @@ class App extends Component { Version: version, VersionAvailable: version !== latestVersion, VersionLookup: versionLookup, + }, () => { + this.checkVersionInstalled( ); }); - - this.checkVersionInstalled(this.state.Release, version, versionLookup); }; axios.get(Constants.RELEASES_URL) @@ -500,7 +503,7 @@ class App extends Component { ipcRenderer.send(Constants.IPC_Delete_File, { FilePath: arg.data.Source, }); - this.checkVersionInstalled(this.state.Release, this.state.Version); + this.checkVersionInstalled( ); }; onInstallUpgradeReply = (event, arg) => { diff --git a/src/containers/Configuration/Configuration.js b/src/containers/Configuration/Configuration.js index 5e3e393..e783df7 100644 --- a/src/containers/Configuration/Configuration.js +++ b/src/containers/Configuration/Configuration.js @@ -164,11 +164,12 @@ class Configuration extends Component { if (arg.data.Success) { this.setState({ Template: arg.data.Template, - }); - ipcRenderer.send(Constants.IPC_Get_Config, { - Directory: this.props.directory, - StorageType: this.props.storageType, - Version: this.props.version, + }, ()=> { + ipcRenderer.send(Constants.IPC_Get_Config, { + Directory: this.props.directory, + StorageType: this.props.storageType, + Version: this.props.version, + }); }); } else { this.props.errorHandler(arg.data.Error, () => { @@ -185,32 +186,32 @@ class Configuration extends Component { if (ipcRenderer) { this.setState({ Saving: true, - }); + }, ()=> { + const changedItems = []; + for (const item of this.state.ChangedItems) { + changedItems.push({ + Name: item.label, + Value: item.value, + }); + } - const changedItems = []; - for (const item of this.state.ChangedItems) { - changedItems.push({ - Name: item.label, - Value: item.value, - }); - } - - if (this.state.ChangedObjectLookup) { - for (const key of Object.keys(this.state.ChangedObjectLookup)) { - for (const item of this.state.ChangedObjectLookup[key]) { - changedItems.push({ - Name: key + '.' + item.label, - Value: item.value, - }); + if (this.state.ChangedObjectLookup) { + for (const key of Object.keys(this.state.ChangedObjectLookup)) { + for (const item of this.state.ChangedObjectLookup[key]) { + changedItems.push({ + Name: key + '.' + item.label, + Value: item.value, + }); + } } } - } - ipcRenderer.send(Constants.IPC_Set_Config_Values, { - Directory: this.props.directory, - Items: changedItems, - StorageType: this.props.storageType, - Version: this.props.version, + ipcRenderer.send(Constants.IPC_Set_Config_Values, { + Directory: this.props.directory, + Items: changedItems, + StorageType: this.props.storageType, + Version: this.props.version, + }); }); } }; diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index c2c77ea..f9c08e9 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -69,28 +69,29 @@ class MountItems extends Component { ...this.state[storageType], AllowMount: false, }; - this.setState({ - [storageType]: state, - }); this.props.mountsBusy(true); - if (mount) { - ipcRenderer.send(Constants.IPC_Mount_Drive, { - Directory: this.props.directory, - Location: location, - StorageType: storageType, - Version: this.props.version, - }); - } else { - ipcRenderer.send(Constants.IPC_Unmount_Drive, { - Directory: this.props.directory, - Location: location, - PID: pid, - StorageType: storageType, - Version: this.props.version, - }); - } + this.setState({ + [storageType]: state, + }, ()=> { + if (mount) { + ipcRenderer.send(Constants.IPC_Mount_Drive, { + Directory: this.props.directory, + Location: location, + StorageType: storageType, + Version: this.props.version, + }); + } else { + ipcRenderer.send(Constants.IPC_Unmount_Drive, { + Directory: this.props.directory, + Location: location, + PID: pid, + StorageType: storageType, + Version: this.props.version, + }); + } + }); } }; @@ -111,30 +112,30 @@ class MountItems extends Component { PID: arg.data.PIDS.Hyperspace, }; + this.props.mountsBusy(hs.Mounted || sia.Mounted); + this.setState({ Hyperspace: hs, Sia: sia, + }, () => { + let hsLocation = arg.data.Locations.Hyperspace; + if ((hsLocation.length === 0) && (this.props.platform === 'win32')) { + hsLocation = this.props.hyperspace.MountLocation || arg.data.DriveLetters.Hyperspace[0]; + } + if (hsLocation !== this.props.hyperspace.MountLocation) { + this.props.changed('Hyperspace', hsLocation); + } + + let siaLocation = arg.data.Locations.Sia; + if ((siaLocation.length === 0) && (this.props.platform === 'win32')) { + siaLocation = this.props.sia.MountLocation || arg.data.DriveLetters.Sia[0]; + } + if (siaLocation !== this.props.sia.MountLocation) { + this.props.changed('Sia', siaLocation); + } + + this.performAutoMount(); }); - - this.props.mountsBusy(hs.Mounted || sia.Mounted); - - let hsLocation = arg.data.Locations.Hyperspace; - if ((hsLocation.length === 0) && (this.props.platform === 'win32')) { - hsLocation = this.props.hyperspace.MountLocation || arg.data.DriveLetters.Hyperspace[0]; - } - if (hsLocation !== this.props.hyperspace.MountLocation) { - this.props.changed('Hyperspace', hsLocation); - } - - let siaLocation = arg.data.Locations.Sia; - if ((siaLocation.length === 0) && (this.props.platform === 'win32')) { - siaLocation = this.props.sia.MountLocation || arg.data.DriveLetters.Sia[0]; - } - if (siaLocation !== this.props.sia.MountLocation) { - this.props.changed('Sia', siaLocation); - } - - this.performAutoMount(); } else { this.props.errorHandler(arg.data.Error); } @@ -148,9 +149,9 @@ class MountItems extends Component { }; this.setState({ [arg.data.StorageType]: state, + }, ()=> { + this.detectMounts(); }); - - this.detectMounts(); }; onUnmountDriveReply = (event, arg) => { From 2f24544400afcbfe7450acb6bea564cc993896e3 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 3 Nov 2018 12:29:31 -0500 Subject: [PATCH 04/91] SiaPrime support --- electron.js | 32 +++++++++----- src/App.js | 56 ++++++++++++++++++------- src/containers/MountItems/MountItems.js | 41 ++++++++++++++++++ 3 files changed, 104 insertions(+), 25 deletions(-) diff --git a/electron.js b/electron.js index 1cbcd7b..7bb3c63 100644 --- a/electron.js +++ b/electron.js @@ -21,7 +21,7 @@ let mountedPIDs = []; function createWindow() { // Create the browser window. - const height = process.env.ELECTRON_START_URL ? 324 : 304; + const height = process.env.ELECTRON_START_URL ? 404 : 384; mainWindow = new BrowserWindow({ width: 425, height: height, @@ -191,16 +191,18 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { let driveLetters = { Hyperspace: [], Sia: [], + SiaPrime: [], }; - const grabDriveLetters = (hsLocation, siaLocation) => { + const grabDriveLetters = (hsLocation, siaLocation, siaPrimeLocation) => { for (let i = 'c'.charCodeAt(0); i <= 'z'.charCodeAt(0); i++) { const drive = (String.fromCharCode(i) + ':').toUpperCase(); - if (!(hsLocation.startsWith(drive) || siaLocation.startsWith(drive))) { + if (!(hsLocation.startsWith(drive) || siaLocation.startsWith(drive) || siaPrimeLocation.startsWith(drive))) { try { if (!fs.existsSync(drive)) { driveLetters.Hyperspace.push(drive); driveLetters.Sia.push(drive); + driveLetters.SiaPrime.push(drive); } } catch (e) { } @@ -222,17 +224,21 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { driveLetters.Sia.push(siaLocation); } } + + if (siaPrimeLocation.length > 0) { + if (!driveLetters.SiaPrime.find((driveLetter) => { + return driveLetter === siaPrimeLocation; + })) { + driveLetters.SiaPrime.push(siaPrimeLocation); + } + } }; - const setImage = (hsLocation, siaLocation) => { + const setImage = (hsLocation, siaLocation, siaPrimeLocation) => { if (os.platform() === 'win32') { let image; - if ((siaLocation.length > 0) && (hsLocation.length > 0)) { + if ((siaLocation.length > 0) || (hsLocation.length > 0) || (siaPrimeLocation.length > 0)) { image = nativeImage.createFromPath(path.join(__dirname, '/build/logo_both.png')); - } else if (hsLocation.length > 0) { - image = nativeImage.createFromPath(path.join(__dirname, '/build/logo_hs.png')); - } else if (siaLocation.length > 0) { - image = nativeImage.createFromPath(path.join(__dirname, '/build/logo_sia.png')); } else { image = nativeImage.createFromPath(path.join(__dirname, '/build/logo.png')); } @@ -247,21 +253,25 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { .then((results) => { let hsLocation = results.Hyperspace.Location; let siaLocation = results.Sia.Location; + let siaPrimeLocation = results.SiaPrime.Location; if (os.platform() === 'win32') { hsLocation = hsLocation.toUpperCase(); siaLocation = siaLocation.toUpperCase(); - grabDriveLetters(hsLocation, siaLocation); + siaPrimeLocation = siaPrimeLocation.toUpperCase(); + grabDriveLetters(hsLocation, siaLocation, siaPrimeLocation); } - setImage(hsLocation, siaLocation); + setImage(hsLocation, siaLocation, siaPrimeLocation); standardIPCReply(event, Constants.IPC_Detect_Mounts_Reply, { DriveLetters: driveLetters, Locations: { Hyperspace: hsLocation, Sia: siaLocation, + SiaPrime: siaPrimeLocation, }, PIDS: { Hyperspace: results.Hyperspace.PID, Sia: results.Sia.PID, + SiaPrime: results.SiaPrime.PID, } }); }) diff --git a/src/App.js b/src/App.js index 06fded1..cb6a73b 100644 --- a/src/App.js +++ b/src/App.js @@ -80,6 +80,10 @@ class App extends Component { AutoMount: false, MountLocation: '', }, + SiaPrime: { + AutoMount: false, + MountLocation: '', + }, UpgradeAvailable: false, UpgradeData: {}, UpgradeDismissed: false, @@ -168,11 +172,15 @@ class App extends Component { ...this.state.Sia }; + let siaPrime = { + ...this.state.SiaPrime + }; + let hyperspace = { ...this.state.Hyperspace }; - this.saveState(this.state.Release, this.state.Version, sia, hyperspace); + this.saveState(this.state.Release, this.state.Version, sia, hyperspace, siaPrime); if (storageType === 'Hyperspace') { hyperspace.AutoMount = e.target.checked; @@ -184,6 +192,11 @@ class App extends Component { this.setState({ Sia: sia, }); + } else if (storageType === 'SiaPrime') { + siaPrime.AutoMount = e.target.checked; + this.setState({ + SiaPrime: siaPrime, + }); } }; @@ -230,8 +243,11 @@ class App extends Component { const sia = storageType === 'Sia' ? state : { ...this.state.Sia, }; + const siaPrime = storageType === 'SiaPrime' ? state : { + ...this.state.SiaPrime, + }; - this.saveState(this.state.Release, this.state.Version, sia, hyperspace); + this.saveState(this.state.Release, this.state.Version, sia, hyperspace, siaPrime); this.setState({ [storageType]: state, }); @@ -240,7 +256,7 @@ class App extends Component { handleReleaseChanged = (e) => { const val = parseInt(e.target.value, 10); const versionIndex = this.state.VersionLookup[this.state.ReleaseTypes[val]].length - 1; - this.saveState(val, versionIndex, this.state.Sia, this.state.Hyperspace); + this.saveState(val, versionIndex, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); this.setState({ Release: val, Version: versionIndex @@ -287,7 +303,7 @@ class App extends Component { handleVersionChanged = (e) => { const val = parseInt(e.target.value, 10); - this.saveState(this.state.Release, val, this.state.Sia, this.state.Hyperspace); + this.saveState(this.state.Release, val, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); this.setState({ Version: val }, ()=> { @@ -406,16 +422,26 @@ class App extends Component { onGetStateReply = (event, arg) => { if (arg.data) { - if (arg.data.Hyperspace.AutoMount === undefined) { - arg.data.Hyperspace['AutoMount'] = false; + let hyperspace = arg.data.Hyperspace || this.state.Hyperspace; + if (hyperspace.AutoMount === undefined) { + hyperspace['AutoMount'] = false; } - if (arg.data.Sia.AutoMount === undefined) { - arg.data.Sia['AutoMount'] = false; + + let sia = arg.data.Sia || this.state.Sia; + if (sia.AutoMount === undefined) { + sia['AutoMount'] = false; } + + let siaPrime = arg.data.SiaPrime || this.state.SiaPrime; + if (siaPrime.AutoMount === undefined) { + siaPrime['AutoMount'] = false; + } + this.setState({ - Hyperspace: arg.data.Hyperspace, + Hyperspace: hyperspace, Release: arg.data.Release, - Sia: arg.data.Sia, + Sia: sia, + SiaPrime: siaPrime, Version: arg.data.Version, }, ()=> { this.grabReleases(); @@ -431,7 +457,7 @@ class App extends Component { let version = this.state.Version; if ((version === -1) || !versionLookup[this.state.ReleaseTypes[this.state.Release]][version]) { version = latestVersion; - this.saveState(this.state.Release, version, this.state.Sia, this.state.Hyperspace); + this.saveState(this.state.Release, version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); } this.setState({ @@ -518,7 +544,7 @@ class App extends Component { }); }; - saveState = (release, version, sia, hyperspace)=> { + saveState = (release, version, sia, hyperspace, siaPrime)=> { if (ipcRenderer) { ipcRenderer.send(Constants.IPC_Save_State, { Directory: Constants.DATA_LOCATIONS[this.props.platform], @@ -526,6 +552,7 @@ class App extends Component { Hyperspace: hyperspace, Release: release, Sia: sia, + SiaPrime: siaPrime, Version: version, } }); @@ -637,7 +664,7 @@ class App extends Component { let key = 0; mainContent.push((
+ style={{height: '34%'}}> + style={{height: '28%'}}>
)); diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index f9c08e9..4af83ed 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -36,6 +36,12 @@ class MountItems extends Component { Mounted: false, PID: -1, }, + SiaPrime: { + AllowMount: false, + DriveLetters: [], + Mounted: false, + PID: -1, + }, }; componentWillUnmount = () => { @@ -104,6 +110,13 @@ class MountItems extends Component { Mounted: (arg.data.Locations.Sia.length > 0), PID: arg.data.PIDS.Sia, }; + const siaPrime = { + ...this.state.SiaPrime, + AllowMount: true, + DriveLetters: (arg.data.DriveLetters.SiaPrime), + Mounted: (arg.data.Locations.SiaPrime.length > 0), + PID: arg.data.PIDS.SiaPrime, + }; const hs = { ...this.state.Hyperspace, AllowMount: true, @@ -117,6 +130,7 @@ class MountItems extends Component { this.setState({ Hyperspace: hs, Sia: sia, + SiaPrime: siaPrime, }, () => { let hsLocation = arg.data.Locations.Hyperspace; if ((hsLocation.length === 0) && (this.props.platform === 'win32')) { @@ -134,6 +148,14 @@ class MountItems extends Component { this.props.changed('Sia', siaLocation); } + let siaPrimeLocation = arg.data.Locations.SiaPrime; + if ((siaPrimeLocation.length === 0) && (this.props.platform === 'win32')) { + siaPrimeLocation = this.props.siaprime.MountLocation || arg.data.DriveLetters.SiaPrime[0]; + } + if (siaPrimeLocation !== this.props.siaprime.MountLocation) { + this.props.changed('SiaPrime', siaPrimeLocation); + } + this.performAutoMount(); }); } else { @@ -171,6 +193,11 @@ class MountItems extends Component { (this.props.sia.MountLocation.length > 0)) { this.handleMountUnMount('Sia', true, this.props.sia.MountLocation); } + if (this.props.siaprime.AutoMount && + !this.state.SiaPrime.Mounted && + (this.props.siaprime.MountLocation.length > 0)) { + this.handleMountUnMount('SiaPrime', true, this.props.siaprime.MountLocation); + } } }; @@ -204,6 +231,20 @@ class MountItems extends Component { pid={this.state.Sia.PID} platform={this.props.platform} title={'Sia'}/> +
+ this.props.autoMountChanged('SiaPrime', e)} + changed={(e) => this.handleMountLocationChanged('SiaPrime', e.target.value)} + clicked={this.handleMountUnMount} + configClicked={()=>this.props.configClicked('SiaPrime')} + items={this.state.SiaPrime.DriveLetters} + location={this.props.siaprime.MountLocation} + mounted={this.state.SiaPrime.Mounted} + pid={this.state.SiaPrime.PID} + platform={this.props.platform} + title={'SiaPrime'}/>
); } } From 2059e97e0b0ad87b6b4e4fed5b50873b2e56bfc6 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 3 Nov 2018 12:39:03 -0500 Subject: [PATCH 05/91] Layout changes --- electron.js | 2 +- src/App.js | 2 +- src/containers/MountItems/MountItems.js | 4 ++-- src/index.css | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/electron.js b/electron.js index 7bb3c63..0a7a38b 100644 --- a/electron.js +++ b/electron.js @@ -21,7 +21,7 @@ let mountedPIDs = []; function createWindow() { // Create the browser window. - const height = process.env.ELECTRON_START_URL ? 404 : 384; + const height = process.env.ELECTRON_START_URL ? 394 : 374; mainWindow = new BrowserWindow({ width: 425, height: height, diff --git a/src/App.js b/src/App.js index cb6a73b..6c6dc6b 100644 --- a/src/App.js +++ b/src/App.js @@ -683,7 +683,7 @@ class App extends Component { if (allowMount) { mainContent.push((
+ style={{height: '66%'}}> -
+
-
+
Date: Sat, 3 Nov 2018 12:43:19 -0500 Subject: [PATCH 06/91] SiaPrime changes --- helpers.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/helpers.js b/helpers.js index c88b27e..7857573 100644 --- a/helpers.js +++ b/helpers.js @@ -48,6 +48,11 @@ module.exports.detectRepertoryMounts = (directory, version) => { Location: '', PID: -1, }, + SiaPrime: { + Active: false, + Location: '', + PID: -1, + }, })); }); process.unref(); @@ -166,6 +171,8 @@ module.exports.executeMount = (directory, version, storageType, location, exitCa const args = []; if (storageType.toLowerCase() === 'hyperspace') { args.push('-hs'); + } else if (storageType.toLowerCase() === 'siaprime') { + args.push('-sp'); } if (os.platform() === 'linux') { args.push("-o"); @@ -208,6 +215,8 @@ module.exports.getConfig = (directory, version, storageType) => { args.push('-dc'); if (storageType.toLowerCase() === 'hyperspace') { args.push('-hs'); + } else if (storageType.toLowerCase() === 'siaprime') { + args.push('-sp'); } const process = new spawn(command, args, processOptions); @@ -254,6 +263,8 @@ module.exports.getConfigTemplate = (directory, version, storageType) => { args.push('-gt'); if (storageType.toLowerCase() === 'hyperspace') { args.push('-hs'); + } else if (storageType.toLowerCase() === 'siaprime') { + args.push('-sp'); } const process = new spawn(command, args, processOptions); @@ -417,6 +428,8 @@ module.exports.setConfigValue = (name, value, directory, storageType, version) = args.push(value); if (storageType.toLowerCase() === 'hyperspace') { args.push('-hs'); + } else if (storageType.toLowerCase() === 'siaprime') { + args.push('-sp'); } const process = new spawn(command, args, processOptions); From ddcdfe7e409f4f77cff780ce3f805e1cdd41f819 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 3 Nov 2018 12:43:53 -0500 Subject: [PATCH 07/91] SiaPrime changes --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb5b637..6e62778 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ # Changelog # +## 1.0.2 ## +* SiaPrime support + ## 1.0.1 ## * Added configuration settings for Repertory 1.0.0-alpha.2 and above * Fixed memory leak on component unmount From 486b31fa0ec9872a18520d33fc0142f0e66fc090 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 6 Nov 2018 15:41:51 -0600 Subject: [PATCH 08/91] Auto-restart on unexpected failure --- electron.js | 14 ++++++ src/App.js | 60 +++++++++++++++++++++++-- src/components/MountItem/MountItem.js | 12 +++++ src/containers/MountItems/MountItems.js | 15 ++++++- 4 files changed, 96 insertions(+), 5 deletions(-) diff --git a/electron.js b/electron.js index 0a7a38b..24c3e51 100644 --- a/electron.js +++ b/electron.js @@ -18,6 +18,7 @@ let mainContextWindow; let mainWindow; let mainWindowTray; let mountedPIDs = []; +let expectedUnmount = {}; function createWindow() { // Create the browser window. @@ -260,6 +261,15 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { siaPrimeLocation = siaPrimeLocation.toUpperCase(); grabDriveLetters(hsLocation, siaLocation, siaPrimeLocation); } + if (results.Hyperspace.PID !== -1) { + expectedUnmount['Hyperspace'] = false; + } + if (results.Sia.PID !== -1) { + expectedUnmount['Sia'] = false; + } + if (results.SiaPrime.PID !== -1) { + expectedUnmount['SiaPrime'] = false; + } setImage(hsLocation, siaLocation, siaPrimeLocation); standardIPCReply(event, Constants.IPC_Detect_Mounts_Reply, { DriveLetters: driveLetters, @@ -417,10 +427,13 @@ ipcMain.on(Constants.IPC_Install_Upgrade, (event, data) => { }); ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => { + expectedUnmount[data.StorageType] = false; const dataDirectory = helpers.resolvePath(data.Directory); const errorHandler = (pid, error) => { mountedPIDs.splice(mountedPIDs.indexOf(pid), 1); standardIPCReply(event, Constants.IPC_Unmount_Drive_Reply, { + Expected: expectedUnmount[data.StorageType], + Location: data.Location, PID: -1, StorageType: data.StorageType, }, error || Error(data.StorageType + ' Unmounted')); @@ -473,6 +486,7 @@ ipcMain.on(Constants.IPC_Shutdown, () => { }); ipcMain.on(Constants.IPC_Unmount_Drive, (event, data) => { + expectedUnmount[data.StorageType] = true; helpers .stopProcessByPID(data.PID) .then((pid)=> { diff --git a/src/App.js b/src/App.js index 6c6dc6b..d7339cf 100644 --- a/src/App.js +++ b/src/App.js @@ -62,6 +62,7 @@ class App extends Component { ExtractActive: false, Hyperspace: { AutoMount: false, + AutoRestart: false, MountLocation: '', }, LocationsLookup: {}, @@ -78,10 +79,12 @@ class App extends Component { InstalledVersion: 'none', Sia: { AutoMount: false, + AutoRestart: false, MountLocation: '', }, SiaPrime: { AutoMount: false, + AutoRestart: false, MountLocation: '', }, UpgradeAvailable: false, @@ -180,27 +183,68 @@ class App extends Component { ...this.state.Hyperspace }; - this.saveState(this.state.Release, this.state.Version, sia, hyperspace, siaPrime); - if (storageType === 'Hyperspace') { hyperspace.AutoMount = e.target.checked; this.setState({ Hyperspace: hyperspace, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); }); } else if (storageType === 'Sia') { sia.AutoMount = e.target.checked; this.setState({ Sia: sia, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); }); } else if (storageType === 'SiaPrime') { siaPrime.AutoMount = e.target.checked; this.setState({ SiaPrime: siaPrime, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); }); } }; + handleAutoRestartChanged = (storageType, e) => { + let sia = { + ...this.state.Sia + }; + + let siaPrime = { + ...this.state.SiaPrime + }; + + let hyperspace = { + ...this.state.Hyperspace + }; + + if (storageType === 'Hyperspace') { + hyperspace.AutoRestart = e.target.checked; + this.setState({ + Hyperspace: hyperspace, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + }); + } else if (storageType === 'Sia') { + sia.AutoRestart = e.target.checked; + this.setState({ + Sia: sia, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + }); + } else if (storageType === 'SiaPrime') { + siaPrime.AutoRestart = e.target.checked; + this.setState({ + SiaPrime: siaPrime, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + }); + } + }; + handleConfigClicked = (storageType) => { this.setState({ ConfigStorageType: storageType, @@ -426,16 +470,25 @@ class App extends Component { if (hyperspace.AutoMount === undefined) { hyperspace['AutoMount'] = false; } + if (hyperspace.AutoRestart === undefined) { + hyperspace['AutoRestart'] = false; + } let sia = arg.data.Sia || this.state.Sia; if (sia.AutoMount === undefined) { sia['AutoMount'] = false; } + if (sia.AutoRestart === undefined) { + sia['AutoRestart'] = false; + } let siaPrime = arg.data.SiaPrime || this.state.SiaPrime; if (siaPrime.AutoMount === undefined) { siaPrime['AutoMount'] = false; } + if (siaPrime.AutoRestart === undefined) { + siaPrime['AutoRestart'] = false; + } this.setState({ Hyperspace: hyperspace, @@ -683,10 +736,11 @@ class App extends Component { if (allowMount) { mainContent.push((
+ style={{height: '69%'}}> { ); + const autoRestartControl = ( + + Restart + + ); + return ( {configButton} @@ -90,6 +101,7 @@ export default CSSModules((props) => { {inputControl} {actionsDisplay} {autoMountControl} + {autoRestartControl} ); }, styles, {allowMultiple: true}); \ No newline at end of file diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index dd3525e..10d0a96 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -177,7 +177,12 @@ class MountItems extends Component { }; onUnmountDriveReply = (event, arg) => { - this.detectMounts(); + console.log(arg); + if ((this.props.platform === 'win32') && arg && arg.data && !arg.data.Expected && arg.data.Location && this.props[arg.data.StorageType.toLowerCase()].AutoRestart) { + this.handleMountUnMount(arg.data.StorageType, true, arg.data.Location) + } else { + this.detectMounts(); + } }; performAutoMount = ()=> { @@ -208,6 +213,8 @@ class MountItems extends Component { allowMount={this.state.Hyperspace.AllowMount} autoMount={this.props.hyperspace.AutoMount} autoMountChanged={(e)=>this.props.autoMountChanged('Hyperspace', e)} + autoRestart={this.props.hyperspace.AutoRestart} + autoRestartChanged={(e)=>this.props.autoRestartChanged('Hyperspace', e)} changed={(e) => this.handleMountLocationChanged('Hyperspace', e.target.value)} clicked={this.handleMountUnMount} configClicked={()=>this.props.configClicked('Hyperspace')} @@ -222,6 +229,8 @@ class MountItems extends Component { allowMount={this.state.Sia.AllowMount} autoMount={this.props.sia.AutoMount} autoMountChanged={(e)=>this.props.autoMountChanged('Sia', e)} + autoRestart={this.props.sia.AutoRestart} + autoRestartChanged={(e)=>this.props.autoRestartChanged('Sia', e)} changed={(e) => this.handleMountLocationChanged('Sia', e.target.value)} clicked={this.handleMountUnMount} configClicked={()=>this.props.configClicked('Sia')} @@ -233,9 +242,11 @@ class MountItems extends Component { title={'Sia'}/>
this.props.autoMountChanged('SiaPrime', e)} + autoRestart={this.props.siaprime.AutoRestart} + autoRestartChanged={(e)=>this.props.autoRestartChanged('SiaPrime', e)} changed={(e) => this.handleMountLocationChanged('SiaPrime', e.target.value)} clicked={this.handleMountUnMount} configClicked={()=>this.props.configClicked('SiaPrime')} From d8bfc0e3e95e84f1c53660114524c7c03fac7a6e Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 6 Nov 2018 15:45:24 -0600 Subject: [PATCH 09/91] Layout changes --- src/App.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index d7339cf..a6aedb5 100644 --- a/src/App.js +++ b/src/App.js @@ -736,7 +736,7 @@ class App extends Component { if (allowMount) { mainContent.push((
+ style={{height: '66%'}}> Date: Wed, 7 Nov 2018 14:55:53 -0600 Subject: [PATCH 10/91] SiaPrime changes --- electron.js | 7 +++++++ helpers.js | 4 ++-- src/App.js | 4 ++++ src/components/MountItem/MountItem.js | 12 +++++++----- src/containers/MountItems/MountItems.js | 3 ++- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/electron.js b/electron.js index 24c3e51..0d6cd06 100644 --- a/electron.js +++ b/electron.js @@ -254,6 +254,13 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { .then((results) => { let hsLocation = results.Hyperspace.Location; let siaLocation = results.Sia.Location; + if (!results.SiaPrime) { + results.SiaPrime = { + Active: false, + Location: '', + PID: -1, + }; + } let siaPrimeLocation = results.SiaPrime.Location; if (os.platform() === 'win32') { hsLocation = hsLocation.toUpperCase(); diff --git a/helpers.js b/helpers.js index 7857573..fef1fc3 100644 --- a/helpers.js +++ b/helpers.js @@ -175,8 +175,8 @@ module.exports.executeMount = (directory, version, storageType, location, exitCa args.push('-sp'); } if (os.platform() === 'linux') { - args.push("-o"); - args.push("big_writes"); + args.push('-o'); + args.push('big_writes'); } if (os.platform() === 'win32') { args.push('-hidden'); diff --git a/src/App.js b/src/App.js index a6aedb5..134aa02 100644 --- a/src/App.js +++ b/src/App.js @@ -643,6 +643,9 @@ class App extends Component { const allowConfig = this.state.LocationsLookup[selectedVersion] && this.state.LocationsLookup[selectedVersion].config_support; + const allowSiaPrime = this.state.LocationsLookup[selectedVersion] && + this.state.LocationsLookup[selectedVersion].siaprime_support; + const showDependencies = missingDependencies && !this.state.DownloadActive; @@ -738,6 +741,7 @@ class App extends Component {
{ rowSpan={6}> {e.preventDefault();} : props.configClicked} src={configureImage} style={{padding: 0, border: 0, margin: 0, cursor: 'pointer'}} width={'16px'}/> @@ -32,7 +32,7 @@ export default CSSModules((props) => { inputColumnSpan = 20; inputControl = { - ); } - const buttonDisplay = props.allowMount ? + const buttonDisplay = props.allowMount || props.disabled ? (props.mounted ? 'Unmount' : 'Mount') : {
diff --git a/src/assets/images/release_available.png b/src/assets/images/release_available.png index 07e449388972d66e74641848667e347304e80cdd..4dbba4cd0921295d2af0638f862dcd3dad97cc7c 100644 GIT binary patch literal 71729 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 S7&Su^OSLrgP=$ZqdicK_9Lv4{ literal 79055 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 aZb&f;D?DNz>{o++(wS4{M)@b4Z~q@WO;->A From da06d052d0323699712c498b868818bc8819d5ed Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 8 Nov 2018 16:13:28 -0600 Subject: [PATCH 14/91] Updated docs --- CHANGELOG.md | 1 + README.md | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e62778..45d2ed2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog # ## 1.0.2 ## +* OS X support * SiaPrime support ## 1.0.1 ## diff --git a/README.md b/README.md index 64fcf31..06967d0 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Repertory UI -![alt text](https://image.ibb.co/mnhA1z/repertory_1_0_1.png) +![alt text](https://image.ibb.co/edOg5A/repertory-ui-1-0-2.png) ### GUI for [Repertory](https://bitbucket.org/blockstorage/repertory) ### Repertory allows you to mount Hyperspace or Sia blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows. # Downloads # -* [Repertory UI v1.0.1 Windows 64-bit](https://sia.pixeldrain.com/api/file/Alo1IF1u/download) +* [Repertory UI v1.0.2 Windows 64-bit]() # Supported Platforms # +* OS X * Windows 64-bit # Future Platforms # -* OS X * Linux 64-bit \ No newline at end of file From 1d0f0bbc469e508f695788d3c6bd64379939a3d3 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 9 Nov 2018 11:42:37 -0600 Subject: [PATCH 15/91] [Updated docs] [Launch hidden option] --- CHANGELOG.md | 1 + README.md | 3 ++- electron.js | 39 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45d2ed2..d9714da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog # ## 1.0.2 ## +* Launch hidden (notification icon only) * OS X support * SiaPrime support diff --git a/README.md b/README.md index 06967d0..db8fb91 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # Repertory UI ![alt text](https://image.ibb.co/edOg5A/repertory-ui-1-0-2.png) ### GUI for [Repertory](https://bitbucket.org/blockstorage/repertory) ### -Repertory allows you to mount Hyperspace or Sia blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows. +Repertory allows you to mount Sia, SiaPrime and/or Hyperspace blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows. # Downloads # +* [Repertory UI v1.0.2 OS X]() * [Repertory UI v1.0.2 Windows 64-bit]() # Supported Platforms # * OS X diff --git a/electron.js b/electron.js index d6761cb..ab042e4 100644 --- a/electron.js +++ b/electron.js @@ -19,14 +19,18 @@ let mainWindow; let mainWindowTray; let mountedPIDs = []; let expectedUnmount = {}; +let launchHidden = false; function createWindow() { + loadUiSettings(); + // Create the browser window. const height = process.env.ELECTRON_START_URL ? 394 : 374; mainWindow = new BrowserWindow({ width: 425, height: height, resizable: false, + show: !launchHidden, title: 'Repertory UI', webPreferences: { webSecurity: !process.env.ELECTRON_START_URL @@ -72,7 +76,8 @@ function createWindow() { } else { mainWindow.hide(); } - } + }, + checked: !launchHidden, }, { label: 'Auto-start', type: 'checkbox', click(item) { @@ -86,6 +91,16 @@ function createWindow() { { type: 'separator' }, + { + label: 'Launch Hidden', type: 'checkbox', click(item) { + launchHidden = !!item.checked; + saveUiSettings(); + }, + checked: launchHidden, + }, + { + type: 'separator' + }, { label: 'Exit', click(item) { app.quit(); @@ -93,7 +108,6 @@ function createWindow() { } ]); - mainContextWindow.items[0].checked = true; autoLauncher .isEnabled() .then((enabled) => { @@ -145,6 +159,27 @@ if (!instanceLock) { }); } +const loadUiSettings = () => { + const settingFile = path.join(helpers.resolvePath(Constants.DATA_LOCATIONS[os.platform()]), 'ui.json'); + try { + if (fs.statSync(settingFile).isFile()) { + const settings = JSON.parse(fs.readFileSync(settingFile, 'utf8')); + launchHidden = settings.launch_hidden; + } + } catch (e) { + } +}; + +const saveUiSettings = () => { + const settingFile = path.join(helpers.resolvePath(Constants.DATA_LOCATIONS[os.platform()]), 'ui.json'); + try { + fs.writeFileSync(settingFile, JSON.stringify({ + launch_hidden: launchHidden, + }), 'utf-8'); + } catch (e) { + } +}; + const standardIPCReply = (event, channel, data, error) => { event.sender.send(channel, { data: { From ba74d09eb5b39cd108139f6afc6b58e28c087140 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 9 Nov 2018 16:01:03 -0600 Subject: [PATCH 16/91] Removed icons --- public/favicon_old.ico | Bin 370070 -> 0 bytes public/icon_old.ico | Bin 370070 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 public/favicon_old.ico delete mode 100644 public/icon_old.ico diff --git a/public/favicon_old.ico b/public/favicon_old.ico deleted file mode 100644 index 530403fddc6e4a216a3686b344250e71ea990695..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370070 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 rt2mA7uXD| Date: Thu, 4 Oct 2018 15:22:07 -0500 Subject: [PATCH 17/91] Updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 85f6bfd..5466217 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "repertory-ui", - "version": "1.0.1", + "version": "1.0.2", "private": true, "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.1", From e4ca58e081d2f0d3edf24da842a65172c9837aeb Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 9 Oct 2018 19:17:03 -0500 Subject: [PATCH 18/91] Updated releases --- releases.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/releases.json b/releases.json index b7563ef..c2a911f 100644 --- a/releases.json +++ b/releases.json @@ -1,6 +1,10 @@ { "Locations": { "win32": { + "1.0.2": { + "hash": "", + "urls": [] + }, "1.0.1": { "hash": "", "urls": [ @@ -17,6 +21,7 @@ }, "Versions": { "win32": [ + "1.0.2", "1.0.1", "1.0.0" ] From d8c5c769fd73906cac40b584ca3edd8c763b6d7a Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Mon, 15 Oct 2018 17:15:25 -0500 Subject: [PATCH 19/91] Use callback during setState() --- src/App.js | 103 +++++++++--------- src/containers/Configuration/Configuration.js | 55 +++++----- src/containers/MountItems/MountItems.js | 83 +++++++------- 3 files changed, 123 insertions(+), 118 deletions(-) diff --git a/src/App.js b/src/App.js index fe29cf7..06fded1 100644 --- a/src/App.js +++ b/src/App.js @@ -101,30 +101,26 @@ class App extends Component { } }; - checkVersionInstalled = (release, version, versionLookup) => { - if (!versionLookup) { - versionLookup = this.state.VersionLookup; - } - - const selectedVersion = versionLookup[this.state.ReleaseTypes[release]][version]; + checkVersionInstalled = () => { this.setState({ AllowDownload: false, - }); + }, ()=> { + const selectedVersion = this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]][this.state.Version]; + if (selectedVersion !== 'unavailable') { + if (ipcRenderer) { + let dependencies = []; + if (this.state.LocationsLookup[selectedVersion] && this.state.LocationsLookup[selectedVersion].dependencies) { + dependencies = this.state.LocationsLookup[selectedVersion].dependencies; + } - if (selectedVersion !== 'unavailable') { - if (ipcRenderer) { - let dependencies = []; - if (this.state.LocationsLookup[selectedVersion] && this.state.LocationsLookup[selectedVersion].dependencies) { - dependencies = this.state.LocationsLookup[selectedVersion].dependencies; + ipcRenderer.send(Constants.IPC_Check_Installed, { + Dependencies: dependencies, + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Version: selectedVersion, + }); } - - ipcRenderer.send(Constants.IPC_Check_Installed, { - Dependencies: dependencies, - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Version: selectedVersion, - }); } - } + }); }; closeErrorDisplay = () => { @@ -176,6 +172,8 @@ class App extends Component { ...this.state.Hyperspace }; + this.saveState(this.state.Release, this.state.Version, sia, hyperspace); + if (storageType === 'Hyperspace') { hyperspace.AutoMount = e.target.checked; this.setState({ @@ -188,7 +186,6 @@ class App extends Component { }); } - this.saveState(this.state.Release, this.state.Version, sia, hyperspace); }; handleConfigClicked = (storageType) => { @@ -212,12 +209,12 @@ class App extends Component { DownloadActive: true, DownloadingDependency: true, DownloadName: fileName, - }); - - ipcRenderer.send(Constants.IPC_Download_File, { - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Filename: fileName, - URL: url, + }, ()=> { + ipcRenderer.send(Constants.IPC_Download_File, { + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Filename: this.state.DownloadName, + URL: url, + }); }); } }; @@ -227,9 +224,6 @@ class App extends Component { ...this.state[storageType], MountLocation: location, }; - this.setState({ - [storageType]: state, - }); const hyperspace = (storageType === 'Hyperspace') ? state : { ...this.state.Hyperspace, }; @@ -238,17 +232,21 @@ class App extends Component { }; this.saveState(this.state.Release, this.state.Version, sia, hyperspace); + this.setState({ + [storageType]: state, + }); }; handleReleaseChanged = (e) => { const val = parseInt(e.target.value, 10); const versionIndex = this.state.VersionLookup[this.state.ReleaseTypes[val]].length - 1; + this.saveState(val, versionIndex, this.state.Sia, this.state.Hyperspace); this.setState({ Release: val, Version: versionIndex + }, ()=> { + this.checkVersionInstalled( ); }); - this.saveState(val, versionIndex, this.state.Sia, this.state.Hyperspace); - this.checkVersionInstalled(val, versionIndex); }; handleReleaseDownload = () => { @@ -259,12 +257,12 @@ class App extends Component { DownloadActive: true, DownloadingRelease: true, DownloadName: fileName, - }); - - ipcRenderer.send(Constants.IPC_Download_File, { - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Filename: fileName, - URL: this.state.LocationsLookup[selectedVersion].urls[0], + }, () => { + ipcRenderer.send(Constants.IPC_Download_File, { + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Filename: this.state.DownloadName, + URL: this.state.LocationsLookup[selectedVersion].urls[0], + }); }); } }; @@ -275,12 +273,12 @@ class App extends Component { DownloadActive: true, DownloadingUpgrade: true, DownloadName: 'UI Upgrade', - }); - - ipcRenderer.send(Constants.IPC_Download_File, { - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Filename: this.props.platform === 'win32' ? 'upgrade.exe' : 'upgrade', - URL: this.state.UpgradeData.urls[0], + }, ()=> { + ipcRenderer.send(Constants.IPC_Download_File, { + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Filename: this.props.platform === 'win32' ? 'upgrade.exe' : 'upgrade', + URL: this.state.UpgradeData.urls[0], + }); }); } else { this.setState({UpgradeDismissed: true}); @@ -289,11 +287,12 @@ class App extends Component { handleVersionChanged = (e) => { const val = parseInt(e.target.value, 10); + this.saveState(this.state.Release, val, this.state.Sia, this.state.Hyperspace); this.setState({ Version: val + }, ()=> { + this.checkVersionInstalled( ); }); - this.saveState(this.state.Release, val, this.state.Sia, this.state.Hyperspace); - this.checkVersionInstalled(this.state.Release, val); }; notifyAutoMountProcessed = () => { @@ -400,8 +399,9 @@ class App extends Component { this.setState({ ExtractActive: false, + }, ()=> { + this.checkVersionInstalled( ); }); - this.checkVersionInstalled(this.state.Release, this.state.Version); }; onGetStateReply = (event, arg) => { @@ -417,9 +417,12 @@ class App extends Component { Release: arg.data.Release, Sia: arg.data.Sia, Version: arg.data.Version, + }, ()=> { + this.grabReleases(); }); + } else { + this.grabReleases(); } - this.grabReleases(); }; onGrabReleasesReply = ()=> { @@ -437,9 +440,9 @@ class App extends Component { Version: version, VersionAvailable: version !== latestVersion, VersionLookup: versionLookup, + }, () => { + this.checkVersionInstalled( ); }); - - this.checkVersionInstalled(this.state.Release, version, versionLookup); }; axios.get(Constants.RELEASES_URL) @@ -500,7 +503,7 @@ class App extends Component { ipcRenderer.send(Constants.IPC_Delete_File, { FilePath: arg.data.Source, }); - this.checkVersionInstalled(this.state.Release, this.state.Version); + this.checkVersionInstalled( ); }; onInstallUpgradeReply = (event, arg) => { diff --git a/src/containers/Configuration/Configuration.js b/src/containers/Configuration/Configuration.js index 5e3e393..e783df7 100644 --- a/src/containers/Configuration/Configuration.js +++ b/src/containers/Configuration/Configuration.js @@ -164,11 +164,12 @@ class Configuration extends Component { if (arg.data.Success) { this.setState({ Template: arg.data.Template, - }); - ipcRenderer.send(Constants.IPC_Get_Config, { - Directory: this.props.directory, - StorageType: this.props.storageType, - Version: this.props.version, + }, ()=> { + ipcRenderer.send(Constants.IPC_Get_Config, { + Directory: this.props.directory, + StorageType: this.props.storageType, + Version: this.props.version, + }); }); } else { this.props.errorHandler(arg.data.Error, () => { @@ -185,32 +186,32 @@ class Configuration extends Component { if (ipcRenderer) { this.setState({ Saving: true, - }); + }, ()=> { + const changedItems = []; + for (const item of this.state.ChangedItems) { + changedItems.push({ + Name: item.label, + Value: item.value, + }); + } - const changedItems = []; - for (const item of this.state.ChangedItems) { - changedItems.push({ - Name: item.label, - Value: item.value, - }); - } - - if (this.state.ChangedObjectLookup) { - for (const key of Object.keys(this.state.ChangedObjectLookup)) { - for (const item of this.state.ChangedObjectLookup[key]) { - changedItems.push({ - Name: key + '.' + item.label, - Value: item.value, - }); + if (this.state.ChangedObjectLookup) { + for (const key of Object.keys(this.state.ChangedObjectLookup)) { + for (const item of this.state.ChangedObjectLookup[key]) { + changedItems.push({ + Name: key + '.' + item.label, + Value: item.value, + }); + } } } - } - ipcRenderer.send(Constants.IPC_Set_Config_Values, { - Directory: this.props.directory, - Items: changedItems, - StorageType: this.props.storageType, - Version: this.props.version, + ipcRenderer.send(Constants.IPC_Set_Config_Values, { + Directory: this.props.directory, + Items: changedItems, + StorageType: this.props.storageType, + Version: this.props.version, + }); }); } }; diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index c2c77ea..f9c08e9 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -69,28 +69,29 @@ class MountItems extends Component { ...this.state[storageType], AllowMount: false, }; - this.setState({ - [storageType]: state, - }); this.props.mountsBusy(true); - if (mount) { - ipcRenderer.send(Constants.IPC_Mount_Drive, { - Directory: this.props.directory, - Location: location, - StorageType: storageType, - Version: this.props.version, - }); - } else { - ipcRenderer.send(Constants.IPC_Unmount_Drive, { - Directory: this.props.directory, - Location: location, - PID: pid, - StorageType: storageType, - Version: this.props.version, - }); - } + this.setState({ + [storageType]: state, + }, ()=> { + if (mount) { + ipcRenderer.send(Constants.IPC_Mount_Drive, { + Directory: this.props.directory, + Location: location, + StorageType: storageType, + Version: this.props.version, + }); + } else { + ipcRenderer.send(Constants.IPC_Unmount_Drive, { + Directory: this.props.directory, + Location: location, + PID: pid, + StorageType: storageType, + Version: this.props.version, + }); + } + }); } }; @@ -111,30 +112,30 @@ class MountItems extends Component { PID: arg.data.PIDS.Hyperspace, }; + this.props.mountsBusy(hs.Mounted || sia.Mounted); + this.setState({ Hyperspace: hs, Sia: sia, + }, () => { + let hsLocation = arg.data.Locations.Hyperspace; + if ((hsLocation.length === 0) && (this.props.platform === 'win32')) { + hsLocation = this.props.hyperspace.MountLocation || arg.data.DriveLetters.Hyperspace[0]; + } + if (hsLocation !== this.props.hyperspace.MountLocation) { + this.props.changed('Hyperspace', hsLocation); + } + + let siaLocation = arg.data.Locations.Sia; + if ((siaLocation.length === 0) && (this.props.platform === 'win32')) { + siaLocation = this.props.sia.MountLocation || arg.data.DriveLetters.Sia[0]; + } + if (siaLocation !== this.props.sia.MountLocation) { + this.props.changed('Sia', siaLocation); + } + + this.performAutoMount(); }); - - this.props.mountsBusy(hs.Mounted || sia.Mounted); - - let hsLocation = arg.data.Locations.Hyperspace; - if ((hsLocation.length === 0) && (this.props.platform === 'win32')) { - hsLocation = this.props.hyperspace.MountLocation || arg.data.DriveLetters.Hyperspace[0]; - } - if (hsLocation !== this.props.hyperspace.MountLocation) { - this.props.changed('Hyperspace', hsLocation); - } - - let siaLocation = arg.data.Locations.Sia; - if ((siaLocation.length === 0) && (this.props.platform === 'win32')) { - siaLocation = this.props.sia.MountLocation || arg.data.DriveLetters.Sia[0]; - } - if (siaLocation !== this.props.sia.MountLocation) { - this.props.changed('Sia', siaLocation); - } - - this.performAutoMount(); } else { this.props.errorHandler(arg.data.Error); } @@ -148,9 +149,9 @@ class MountItems extends Component { }; this.setState({ [arg.data.StorageType]: state, + }, ()=> { + this.detectMounts(); }); - - this.detectMounts(); }; onUnmountDriveReply = (event, arg) => { From 21b50d48b5028240325d1afbb1bd4115d50c558c Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 3 Nov 2018 12:29:31 -0500 Subject: [PATCH 20/91] SiaPrime support --- electron.js | 32 +++++++++----- src/App.js | 56 ++++++++++++++++++------- src/containers/MountItems/MountItems.js | 41 ++++++++++++++++++ 3 files changed, 104 insertions(+), 25 deletions(-) diff --git a/electron.js b/electron.js index 1cbcd7b..7bb3c63 100644 --- a/electron.js +++ b/electron.js @@ -21,7 +21,7 @@ let mountedPIDs = []; function createWindow() { // Create the browser window. - const height = process.env.ELECTRON_START_URL ? 324 : 304; + const height = process.env.ELECTRON_START_URL ? 404 : 384; mainWindow = new BrowserWindow({ width: 425, height: height, @@ -191,16 +191,18 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { let driveLetters = { Hyperspace: [], Sia: [], + SiaPrime: [], }; - const grabDriveLetters = (hsLocation, siaLocation) => { + const grabDriveLetters = (hsLocation, siaLocation, siaPrimeLocation) => { for (let i = 'c'.charCodeAt(0); i <= 'z'.charCodeAt(0); i++) { const drive = (String.fromCharCode(i) + ':').toUpperCase(); - if (!(hsLocation.startsWith(drive) || siaLocation.startsWith(drive))) { + if (!(hsLocation.startsWith(drive) || siaLocation.startsWith(drive) || siaPrimeLocation.startsWith(drive))) { try { if (!fs.existsSync(drive)) { driveLetters.Hyperspace.push(drive); driveLetters.Sia.push(drive); + driveLetters.SiaPrime.push(drive); } } catch (e) { } @@ -222,17 +224,21 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { driveLetters.Sia.push(siaLocation); } } + + if (siaPrimeLocation.length > 0) { + if (!driveLetters.SiaPrime.find((driveLetter) => { + return driveLetter === siaPrimeLocation; + })) { + driveLetters.SiaPrime.push(siaPrimeLocation); + } + } }; - const setImage = (hsLocation, siaLocation) => { + const setImage = (hsLocation, siaLocation, siaPrimeLocation) => { if (os.platform() === 'win32') { let image; - if ((siaLocation.length > 0) && (hsLocation.length > 0)) { + if ((siaLocation.length > 0) || (hsLocation.length > 0) || (siaPrimeLocation.length > 0)) { image = nativeImage.createFromPath(path.join(__dirname, '/build/logo_both.png')); - } else if (hsLocation.length > 0) { - image = nativeImage.createFromPath(path.join(__dirname, '/build/logo_hs.png')); - } else if (siaLocation.length > 0) { - image = nativeImage.createFromPath(path.join(__dirname, '/build/logo_sia.png')); } else { image = nativeImage.createFromPath(path.join(__dirname, '/build/logo.png')); } @@ -247,21 +253,25 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { .then((results) => { let hsLocation = results.Hyperspace.Location; let siaLocation = results.Sia.Location; + let siaPrimeLocation = results.SiaPrime.Location; if (os.platform() === 'win32') { hsLocation = hsLocation.toUpperCase(); siaLocation = siaLocation.toUpperCase(); - grabDriveLetters(hsLocation, siaLocation); + siaPrimeLocation = siaPrimeLocation.toUpperCase(); + grabDriveLetters(hsLocation, siaLocation, siaPrimeLocation); } - setImage(hsLocation, siaLocation); + setImage(hsLocation, siaLocation, siaPrimeLocation); standardIPCReply(event, Constants.IPC_Detect_Mounts_Reply, { DriveLetters: driveLetters, Locations: { Hyperspace: hsLocation, Sia: siaLocation, + SiaPrime: siaPrimeLocation, }, PIDS: { Hyperspace: results.Hyperspace.PID, Sia: results.Sia.PID, + SiaPrime: results.SiaPrime.PID, } }); }) diff --git a/src/App.js b/src/App.js index 06fded1..cb6a73b 100644 --- a/src/App.js +++ b/src/App.js @@ -80,6 +80,10 @@ class App extends Component { AutoMount: false, MountLocation: '', }, + SiaPrime: { + AutoMount: false, + MountLocation: '', + }, UpgradeAvailable: false, UpgradeData: {}, UpgradeDismissed: false, @@ -168,11 +172,15 @@ class App extends Component { ...this.state.Sia }; + let siaPrime = { + ...this.state.SiaPrime + }; + let hyperspace = { ...this.state.Hyperspace }; - this.saveState(this.state.Release, this.state.Version, sia, hyperspace); + this.saveState(this.state.Release, this.state.Version, sia, hyperspace, siaPrime); if (storageType === 'Hyperspace') { hyperspace.AutoMount = e.target.checked; @@ -184,6 +192,11 @@ class App extends Component { this.setState({ Sia: sia, }); + } else if (storageType === 'SiaPrime') { + siaPrime.AutoMount = e.target.checked; + this.setState({ + SiaPrime: siaPrime, + }); } }; @@ -230,8 +243,11 @@ class App extends Component { const sia = storageType === 'Sia' ? state : { ...this.state.Sia, }; + const siaPrime = storageType === 'SiaPrime' ? state : { + ...this.state.SiaPrime, + }; - this.saveState(this.state.Release, this.state.Version, sia, hyperspace); + this.saveState(this.state.Release, this.state.Version, sia, hyperspace, siaPrime); this.setState({ [storageType]: state, }); @@ -240,7 +256,7 @@ class App extends Component { handleReleaseChanged = (e) => { const val = parseInt(e.target.value, 10); const versionIndex = this.state.VersionLookup[this.state.ReleaseTypes[val]].length - 1; - this.saveState(val, versionIndex, this.state.Sia, this.state.Hyperspace); + this.saveState(val, versionIndex, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); this.setState({ Release: val, Version: versionIndex @@ -287,7 +303,7 @@ class App extends Component { handleVersionChanged = (e) => { const val = parseInt(e.target.value, 10); - this.saveState(this.state.Release, val, this.state.Sia, this.state.Hyperspace); + this.saveState(this.state.Release, val, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); this.setState({ Version: val }, ()=> { @@ -406,16 +422,26 @@ class App extends Component { onGetStateReply = (event, arg) => { if (arg.data) { - if (arg.data.Hyperspace.AutoMount === undefined) { - arg.data.Hyperspace['AutoMount'] = false; + let hyperspace = arg.data.Hyperspace || this.state.Hyperspace; + if (hyperspace.AutoMount === undefined) { + hyperspace['AutoMount'] = false; } - if (arg.data.Sia.AutoMount === undefined) { - arg.data.Sia['AutoMount'] = false; + + let sia = arg.data.Sia || this.state.Sia; + if (sia.AutoMount === undefined) { + sia['AutoMount'] = false; } + + let siaPrime = arg.data.SiaPrime || this.state.SiaPrime; + if (siaPrime.AutoMount === undefined) { + siaPrime['AutoMount'] = false; + } + this.setState({ - Hyperspace: arg.data.Hyperspace, + Hyperspace: hyperspace, Release: arg.data.Release, - Sia: arg.data.Sia, + Sia: sia, + SiaPrime: siaPrime, Version: arg.data.Version, }, ()=> { this.grabReleases(); @@ -431,7 +457,7 @@ class App extends Component { let version = this.state.Version; if ((version === -1) || !versionLookup[this.state.ReleaseTypes[this.state.Release]][version]) { version = latestVersion; - this.saveState(this.state.Release, version, this.state.Sia, this.state.Hyperspace); + this.saveState(this.state.Release, version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); } this.setState({ @@ -518,7 +544,7 @@ class App extends Component { }); }; - saveState = (release, version, sia, hyperspace)=> { + saveState = (release, version, sia, hyperspace, siaPrime)=> { if (ipcRenderer) { ipcRenderer.send(Constants.IPC_Save_State, { Directory: Constants.DATA_LOCATIONS[this.props.platform], @@ -526,6 +552,7 @@ class App extends Component { Hyperspace: hyperspace, Release: release, Sia: sia, + SiaPrime: siaPrime, Version: version, } }); @@ -637,7 +664,7 @@ class App extends Component { let key = 0; mainContent.push((

+ style={{height: '34%'}}> + style={{height: '28%'}}>
)); diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index f9c08e9..4af83ed 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -36,6 +36,12 @@ class MountItems extends Component { Mounted: false, PID: -1, }, + SiaPrime: { + AllowMount: false, + DriveLetters: [], + Mounted: false, + PID: -1, + }, }; componentWillUnmount = () => { @@ -104,6 +110,13 @@ class MountItems extends Component { Mounted: (arg.data.Locations.Sia.length > 0), PID: arg.data.PIDS.Sia, }; + const siaPrime = { + ...this.state.SiaPrime, + AllowMount: true, + DriveLetters: (arg.data.DriveLetters.SiaPrime), + Mounted: (arg.data.Locations.SiaPrime.length > 0), + PID: arg.data.PIDS.SiaPrime, + }; const hs = { ...this.state.Hyperspace, AllowMount: true, @@ -117,6 +130,7 @@ class MountItems extends Component { this.setState({ Hyperspace: hs, Sia: sia, + SiaPrime: siaPrime, }, () => { let hsLocation = arg.data.Locations.Hyperspace; if ((hsLocation.length === 0) && (this.props.platform === 'win32')) { @@ -134,6 +148,14 @@ class MountItems extends Component { this.props.changed('Sia', siaLocation); } + let siaPrimeLocation = arg.data.Locations.SiaPrime; + if ((siaPrimeLocation.length === 0) && (this.props.platform === 'win32')) { + siaPrimeLocation = this.props.siaprime.MountLocation || arg.data.DriveLetters.SiaPrime[0]; + } + if (siaPrimeLocation !== this.props.siaprime.MountLocation) { + this.props.changed('SiaPrime', siaPrimeLocation); + } + this.performAutoMount(); }); } else { @@ -171,6 +193,11 @@ class MountItems extends Component { (this.props.sia.MountLocation.length > 0)) { this.handleMountUnMount('Sia', true, this.props.sia.MountLocation); } + if (this.props.siaprime.AutoMount && + !this.state.SiaPrime.Mounted && + (this.props.siaprime.MountLocation.length > 0)) { + this.handleMountUnMount('SiaPrime', true, this.props.siaprime.MountLocation); + } } }; @@ -204,6 +231,20 @@ class MountItems extends Component { pid={this.state.Sia.PID} platform={this.props.platform} title={'Sia'}/> +
+ this.props.autoMountChanged('SiaPrime', e)} + changed={(e) => this.handleMountLocationChanged('SiaPrime', e.target.value)} + clicked={this.handleMountUnMount} + configClicked={()=>this.props.configClicked('SiaPrime')} + items={this.state.SiaPrime.DriveLetters} + location={this.props.siaprime.MountLocation} + mounted={this.state.SiaPrime.Mounted} + pid={this.state.SiaPrime.PID} + platform={this.props.platform} + title={'SiaPrime'}/>
); } } From cc8fc6f05c55c5d8ce08074e33bda8d1f34b0e5b Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 3 Nov 2018 12:39:03 -0500 Subject: [PATCH 21/91] Layout changes --- electron.js | 2 +- src/App.js | 2 +- src/containers/MountItems/MountItems.js | 4 ++-- src/index.css | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/electron.js b/electron.js index 7bb3c63..0a7a38b 100644 --- a/electron.js +++ b/electron.js @@ -21,7 +21,7 @@ let mountedPIDs = []; function createWindow() { // Create the browser window. - const height = process.env.ELECTRON_START_URL ? 404 : 384; + const height = process.env.ELECTRON_START_URL ? 394 : 374; mainWindow = new BrowserWindow({ width: 425, height: height, diff --git a/src/App.js b/src/App.js index cb6a73b..6c6dc6b 100644 --- a/src/App.js +++ b/src/App.js @@ -683,7 +683,7 @@ class App extends Component { if (allowMount) { mainContent.push((
+ style={{height: '66%'}}> -
+
-
+
Date: Sat, 3 Nov 2018 12:43:19 -0500 Subject: [PATCH 22/91] SiaPrime changes --- helpers.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/helpers.js b/helpers.js index c88b27e..7857573 100644 --- a/helpers.js +++ b/helpers.js @@ -48,6 +48,11 @@ module.exports.detectRepertoryMounts = (directory, version) => { Location: '', PID: -1, }, + SiaPrime: { + Active: false, + Location: '', + PID: -1, + }, })); }); process.unref(); @@ -166,6 +171,8 @@ module.exports.executeMount = (directory, version, storageType, location, exitCa const args = []; if (storageType.toLowerCase() === 'hyperspace') { args.push('-hs'); + } else if (storageType.toLowerCase() === 'siaprime') { + args.push('-sp'); } if (os.platform() === 'linux') { args.push("-o"); @@ -208,6 +215,8 @@ module.exports.getConfig = (directory, version, storageType) => { args.push('-dc'); if (storageType.toLowerCase() === 'hyperspace') { args.push('-hs'); + } else if (storageType.toLowerCase() === 'siaprime') { + args.push('-sp'); } const process = new spawn(command, args, processOptions); @@ -254,6 +263,8 @@ module.exports.getConfigTemplate = (directory, version, storageType) => { args.push('-gt'); if (storageType.toLowerCase() === 'hyperspace') { args.push('-hs'); + } else if (storageType.toLowerCase() === 'siaprime') { + args.push('-sp'); } const process = new spawn(command, args, processOptions); @@ -417,6 +428,8 @@ module.exports.setConfigValue = (name, value, directory, storageType, version) = args.push(value); if (storageType.toLowerCase() === 'hyperspace') { args.push('-hs'); + } else if (storageType.toLowerCase() === 'siaprime') { + args.push('-sp'); } const process = new spawn(command, args, processOptions); From 9fb07b80bc1ed4736e670aa216c7e51bb32f3513 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 3 Nov 2018 12:43:53 -0500 Subject: [PATCH 23/91] SiaPrime changes --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb5b637..6e62778 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ # Changelog # +## 1.0.2 ## +* SiaPrime support + ## 1.0.1 ## * Added configuration settings for Repertory 1.0.0-alpha.2 and above * Fixed memory leak on component unmount From 7eb1bbe8047a366e71feec469ae444ebb1501201 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 6 Nov 2018 15:41:51 -0600 Subject: [PATCH 24/91] Auto-restart on unexpected failure --- electron.js | 14 ++++++ src/App.js | 60 +++++++++++++++++++++++-- src/components/MountItem/MountItem.js | 12 +++++ src/containers/MountItems/MountItems.js | 15 ++++++- 4 files changed, 96 insertions(+), 5 deletions(-) diff --git a/electron.js b/electron.js index 0a7a38b..24c3e51 100644 --- a/electron.js +++ b/electron.js @@ -18,6 +18,7 @@ let mainContextWindow; let mainWindow; let mainWindowTray; let mountedPIDs = []; +let expectedUnmount = {}; function createWindow() { // Create the browser window. @@ -260,6 +261,15 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { siaPrimeLocation = siaPrimeLocation.toUpperCase(); grabDriveLetters(hsLocation, siaLocation, siaPrimeLocation); } + if (results.Hyperspace.PID !== -1) { + expectedUnmount['Hyperspace'] = false; + } + if (results.Sia.PID !== -1) { + expectedUnmount['Sia'] = false; + } + if (results.SiaPrime.PID !== -1) { + expectedUnmount['SiaPrime'] = false; + } setImage(hsLocation, siaLocation, siaPrimeLocation); standardIPCReply(event, Constants.IPC_Detect_Mounts_Reply, { DriveLetters: driveLetters, @@ -417,10 +427,13 @@ ipcMain.on(Constants.IPC_Install_Upgrade, (event, data) => { }); ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => { + expectedUnmount[data.StorageType] = false; const dataDirectory = helpers.resolvePath(data.Directory); const errorHandler = (pid, error) => { mountedPIDs.splice(mountedPIDs.indexOf(pid), 1); standardIPCReply(event, Constants.IPC_Unmount_Drive_Reply, { + Expected: expectedUnmount[data.StorageType], + Location: data.Location, PID: -1, StorageType: data.StorageType, }, error || Error(data.StorageType + ' Unmounted')); @@ -473,6 +486,7 @@ ipcMain.on(Constants.IPC_Shutdown, () => { }); ipcMain.on(Constants.IPC_Unmount_Drive, (event, data) => { + expectedUnmount[data.StorageType] = true; helpers .stopProcessByPID(data.PID) .then((pid)=> { diff --git a/src/App.js b/src/App.js index 6c6dc6b..d7339cf 100644 --- a/src/App.js +++ b/src/App.js @@ -62,6 +62,7 @@ class App extends Component { ExtractActive: false, Hyperspace: { AutoMount: false, + AutoRestart: false, MountLocation: '', }, LocationsLookup: {}, @@ -78,10 +79,12 @@ class App extends Component { InstalledVersion: 'none', Sia: { AutoMount: false, + AutoRestart: false, MountLocation: '', }, SiaPrime: { AutoMount: false, + AutoRestart: false, MountLocation: '', }, UpgradeAvailable: false, @@ -180,27 +183,68 @@ class App extends Component { ...this.state.Hyperspace }; - this.saveState(this.state.Release, this.state.Version, sia, hyperspace, siaPrime); - if (storageType === 'Hyperspace') { hyperspace.AutoMount = e.target.checked; this.setState({ Hyperspace: hyperspace, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); }); } else if (storageType === 'Sia') { sia.AutoMount = e.target.checked; this.setState({ Sia: sia, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); }); } else if (storageType === 'SiaPrime') { siaPrime.AutoMount = e.target.checked; this.setState({ SiaPrime: siaPrime, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); }); } }; + handleAutoRestartChanged = (storageType, e) => { + let sia = { + ...this.state.Sia + }; + + let siaPrime = { + ...this.state.SiaPrime + }; + + let hyperspace = { + ...this.state.Hyperspace + }; + + if (storageType === 'Hyperspace') { + hyperspace.AutoRestart = e.target.checked; + this.setState({ + Hyperspace: hyperspace, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + }); + } else if (storageType === 'Sia') { + sia.AutoRestart = e.target.checked; + this.setState({ + Sia: sia, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + }); + } else if (storageType === 'SiaPrime') { + siaPrime.AutoRestart = e.target.checked; + this.setState({ + SiaPrime: siaPrime, + }, ()=> { + this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + }); + } + }; + handleConfigClicked = (storageType) => { this.setState({ ConfigStorageType: storageType, @@ -426,16 +470,25 @@ class App extends Component { if (hyperspace.AutoMount === undefined) { hyperspace['AutoMount'] = false; } + if (hyperspace.AutoRestart === undefined) { + hyperspace['AutoRestart'] = false; + } let sia = arg.data.Sia || this.state.Sia; if (sia.AutoMount === undefined) { sia['AutoMount'] = false; } + if (sia.AutoRestart === undefined) { + sia['AutoRestart'] = false; + } let siaPrime = arg.data.SiaPrime || this.state.SiaPrime; if (siaPrime.AutoMount === undefined) { siaPrime['AutoMount'] = false; } + if (siaPrime.AutoRestart === undefined) { + siaPrime['AutoRestart'] = false; + } this.setState({ Hyperspace: hyperspace, @@ -683,10 +736,11 @@ class App extends Component { if (allowMount) { mainContent.push((
+ style={{height: '69%'}}> { ); + const autoRestartControl = ( + + Restart + + ); + return ( {configButton} @@ -90,6 +101,7 @@ export default CSSModules((props) => { {inputControl} {actionsDisplay} {autoMountControl} + {autoRestartControl} ); }, styles, {allowMultiple: true}); \ No newline at end of file diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index dd3525e..10d0a96 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -177,7 +177,12 @@ class MountItems extends Component { }; onUnmountDriveReply = (event, arg) => { - this.detectMounts(); + console.log(arg); + if ((this.props.platform === 'win32') && arg && arg.data && !arg.data.Expected && arg.data.Location && this.props[arg.data.StorageType.toLowerCase()].AutoRestart) { + this.handleMountUnMount(arg.data.StorageType, true, arg.data.Location) + } else { + this.detectMounts(); + } }; performAutoMount = ()=> { @@ -208,6 +213,8 @@ class MountItems extends Component { allowMount={this.state.Hyperspace.AllowMount} autoMount={this.props.hyperspace.AutoMount} autoMountChanged={(e)=>this.props.autoMountChanged('Hyperspace', e)} + autoRestart={this.props.hyperspace.AutoRestart} + autoRestartChanged={(e)=>this.props.autoRestartChanged('Hyperspace', e)} changed={(e) => this.handleMountLocationChanged('Hyperspace', e.target.value)} clicked={this.handleMountUnMount} configClicked={()=>this.props.configClicked('Hyperspace')} @@ -222,6 +229,8 @@ class MountItems extends Component { allowMount={this.state.Sia.AllowMount} autoMount={this.props.sia.AutoMount} autoMountChanged={(e)=>this.props.autoMountChanged('Sia', e)} + autoRestart={this.props.sia.AutoRestart} + autoRestartChanged={(e)=>this.props.autoRestartChanged('Sia', e)} changed={(e) => this.handleMountLocationChanged('Sia', e.target.value)} clicked={this.handleMountUnMount} configClicked={()=>this.props.configClicked('Sia')} @@ -233,9 +242,11 @@ class MountItems extends Component { title={'Sia'}/>
this.props.autoMountChanged('SiaPrime', e)} + autoRestart={this.props.siaprime.AutoRestart} + autoRestartChanged={(e)=>this.props.autoRestartChanged('SiaPrime', e)} changed={(e) => this.handleMountLocationChanged('SiaPrime', e.target.value)} clicked={this.handleMountUnMount} configClicked={()=>this.props.configClicked('SiaPrime')} From ce55edfb3a34410199fc25326f7ca7df950a53c9 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 6 Nov 2018 15:45:24 -0600 Subject: [PATCH 25/91] Layout changes --- src/App.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index d7339cf..a6aedb5 100644 --- a/src/App.js +++ b/src/App.js @@ -736,7 +736,7 @@ class App extends Component { if (allowMount) { mainContent.push((
+ style={{height: '66%'}}> Date: Wed, 7 Nov 2018 14:55:53 -0600 Subject: [PATCH 26/91] SiaPrime changes --- electron.js | 7 +++++++ helpers.js | 4 ++-- src/App.js | 4 ++++ src/components/MountItem/MountItem.js | 12 +++++++----- src/containers/MountItems/MountItems.js | 3 ++- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/electron.js b/electron.js index 24c3e51..0d6cd06 100644 --- a/electron.js +++ b/electron.js @@ -254,6 +254,13 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { .then((results) => { let hsLocation = results.Hyperspace.Location; let siaLocation = results.Sia.Location; + if (!results.SiaPrime) { + results.SiaPrime = { + Active: false, + Location: '', + PID: -1, + }; + } let siaPrimeLocation = results.SiaPrime.Location; if (os.platform() === 'win32') { hsLocation = hsLocation.toUpperCase(); diff --git a/helpers.js b/helpers.js index 7857573..fef1fc3 100644 --- a/helpers.js +++ b/helpers.js @@ -175,8 +175,8 @@ module.exports.executeMount = (directory, version, storageType, location, exitCa args.push('-sp'); } if (os.platform() === 'linux') { - args.push("-o"); - args.push("big_writes"); + args.push('-o'); + args.push('big_writes'); } if (os.platform() === 'win32') { args.push('-hidden'); diff --git a/src/App.js b/src/App.js index a6aedb5..134aa02 100644 --- a/src/App.js +++ b/src/App.js @@ -643,6 +643,9 @@ class App extends Component { const allowConfig = this.state.LocationsLookup[selectedVersion] && this.state.LocationsLookup[selectedVersion].config_support; + const allowSiaPrime = this.state.LocationsLookup[selectedVersion] && + this.state.LocationsLookup[selectedVersion].siaprime_support; + const showDependencies = missingDependencies && !this.state.DownloadActive; @@ -738,6 +741,7 @@ class App extends Component {
{ rowSpan={6}> {e.preventDefault();} : props.configClicked} src={configureImage} style={{padding: 0, border: 0, margin: 0, cursor: 'pointer'}} width={'16px'}/> @@ -32,7 +32,7 @@ export default CSSModules((props) => { inputColumnSpan = 20; inputControl = { - ); } - const buttonDisplay = props.allowMount ? + const buttonDisplay = props.allowMount || props.disabled ? (props.mounted ? 'Unmount' : 'Mount') : {
diff --git a/src/assets/images/release_available.png b/src/assets/images/release_available.png index 07e449388972d66e74641848667e347304e80cdd..4dbba4cd0921295d2af0638f862dcd3dad97cc7c 100644 GIT binary patch literal 71729 zcmY&=2UwFy*LDyW78TeCib9YzhzLkgQ3z7v3Zg-Zp()iBk%&@5lNv=OfCLc&7D`k) z0-_Y@C?HaV(3LK|_g?>*hu!_&|9Y?8T+6gG=iKL>Gw00n`s-+^bME5bg+ie?FI`k6 zqEPHi6pHQd-`T)lCVp}Yf*-aU8tSU3E%-l1VL~YQ3y1y1Yh)B^HxK-W1@$uW0Qe)j z(nzV7cbYTwSvW5J>Hl=od&r(pSu@?)Id@jdV>xOf z+Qz*$I&1jg;10GAmagp+md34ZFL(bQy5ikctdeOQqVcTKvv{sh@sQ77&ubJ_$dBhX zi;B{hRDpmfP1nY6!vfhIDl6h5;6EA8^B3WtzZ(WubtdJko2h!La)SRRabDU1f6_KX zX6|6sC9#enfjM@apJui7SWqZRt`&s~G;2D|$#ET5UajGdxrk2Rm{D1sd#k}`nmrdG z<)#JI_T2cFH9msO&Nd8Z-`N~86MUgeUwT7y z_H0Ti&y+5-11!V%oSe0hkg(cxpXxSHy;Zs1T4yk5y1w8nK}&=N{%(ax!GD~t zn^SSZZwQSZiCkGok`{-JWT(dw;0MKTb^YdgKxAKt{H9!nc7&x#MqgVq&nTE4PyUGr z$d(&#kkXIw(3)QF)aA{vvX?pgkrgzD;-0`C-$-Ng#S!XNCEu<2DqlXDdHSDVTG@zg z5m{`Lz1H5j7cSvdk4OFTTdsIZ_pGmVzEhNN6!!AtbOJvl%7-ow!x~SwLud#0Zl^rc zOYo0}1fU9Js@WcY?GDjhpE>TCXrfx+JodQRCs`a0jz$JQS9>MoZEdDH9vR0SQAIU< zwfJOFd^czh+P37!#HF4PW5YE>hA}Q{B`>#;p`f={0F_xD=m47V(VfC zxHm3e5tI6vXFFh?xCc&QfoSknrBhl*Gv(Jk)v_<{g&nCfph-5IMFITOJh=ZWgFBXL zZrfC$jh-46I^+@D0RGODPqT;C4b2>RUH>SMrWZ}6&hf7sZZvQ*d znBZeI8zP2Ytr)Ru-**83qIp%Ve5{pS09^jsEdv`GF3P*#n zs2Zs$1K8_eV#{Jo^r$X7wwF$JVr+T$ud2D)nyhh0L!{JjZ5x6$N!i)BrhZxxi&c*d z39L$uh7M5Ed(RyDll%!*;XcEDOmJC8@d>2}wSs#U?1o!>+P{G|t!+!mv$Qr@(<3dk z10$1kuY4_pmU2G{+U;leFah9tc1E7^`aDRz+WA*ZgGj=0DdmYu&{|SSesmW6ViI0i zcPpouO)33>)-WE|^@x9RHN&EGw0J%Yv|b451Oj!71MeoL&g!Ws91M}Rp3z=N4|rQ% zZk%qsl9>QCAzF)o#(ocb^^omtUx0A7#hGTq0zhB`*ouU z^nz7@_vq<)(5I(t+n^C4fteC*Rsiqy5n~Q^{o|T*pw<4twi-m{xq~*0RM!b>UV|gw zH@Im&KX`zuDLjf-G(b0$^uL%|R4*HAn=jeg__h!@+3{&nNKq3s%PVj1R_(X~afO&U z@~^>qtD_;cU{nxuPU|M0=aC>*^`YzA2h9oB2G`>S1zOi%BtU|xxP{=}n~0!lLPar{ zdMp6Dc(?6T+t_EIuM!7LEaX^<&lLzJvEHGxgS)Fn8p<`?l?N(ehm71WkO95N!wZ9> z&geIBtCpoGjP9;>_yp{_+2&`k8I%CECjA}J+WHT&+D7(pCQzwrK)JfafQvRfbZE{G zq26!&Ls7&1a<3BRCvCv?-4hZL)pq%dAADvzK`)fb4XABOn$vsl`9Y~ez=b1m`c1{X zXMsheAj?;~m^F2hq1-hXj`R(r&;Om8-xf4iGcFljuP+L|=OrS#7-iaxJ-19b}vbbkj;m=GW$W4E5)QG?j93gI_~K@mD% zrS0-v7E1pD&CJwo$yOY-#Aa*3(0ghfr`@`XR*=R*bqmmE*uMFf{}{HsnSg0r@f(bB z4}@zvNf>?tnq$`6{#^TUTUTuZuUbF|>N`ny^csi~Xg%~4Y@1?>urq~rM*l_8={`P{ZybbcYppL#Xz>pO)eo_i~;XWp%t zgD?)otlU=Z2`;*>9I(3Z@fWmAedsI-QHZ$|zHnyMlO-0ac+d_3{6Qha&A79z=_^~1 zD;c`T$<7d-4=YcTQM5}unUK#m)h=faF`+<5oW{oPI%(aItTkouCWBb^8#~|e!fQzL z@;E$PC+_?&X6kwCnkCAs@>^2Z(-G-zZ%fy*U&(ak#(`+L#sWfNfiWUp2qIov3*KhD z*F>8KU7vD+JP@h;$*V8<{$!dHo;*dUugc>C3HH094dO6+(nIulF{(@<-=nV@9ICbE}-zhMR8NHi@KN z&*zLB)qo&EW;UrZGs^AY2S2vWGBGcy)B)?vM?wa~jfS%==^ImsMQpb% z(!kZ4kp1x2y|dSJqysxog2|b*?UoO=i9ylENroU$(QP70i_M;PwY@rLhu|d&Ikp&< z3)^_nz%_KnBn3(7!_{4Gzz_qkkxYA1EH^Z7E7I2TQ+J_?&k}ApYTF>;AODGhig?f} zZ!Z|9sK-iV+gv>@1-)US1lhUdP*|x_40q|AmX7~74>tCXtwNxYw43Wa_{j|04Dq)V z8%W+O*cVXBr@0vqSt64aplN+4Sf$=xLb`zH=*nh|M`Ug;$MCy`WyDCe>Bs+*hR%0(WL$iMVh$v-Q+e zi;Uvb&7{i%N+8&*T3Cl;k0Xl@c9e9fOV{C)<5eq+Th@GqH<0<05wJYh1zH?Zy6$c^GCdB@Un=e-D$-sEwQS6XerAg zIHfq%uCF%nIm3nHv{K;g%)7o>8(w~+x;*F%lc2OSrr{3dv^$2{7om$tY`aLK;LB+K z-%H6@cX0Oa;kuQs4F~SU=zuY* z&Cadk37@>kHsf>x+)?Yc2fe%>lHsaW<`LGD5ZNUcWg7uKBsU!Kkb}utc2XA?ep?gn zwQA~7>p#}ep6zAdtSkn`KbJrP8&ZIt`Sgm6;*e#L+MAlQauWw9=+Iob+dwQ`2)=wg zkm@ZW|9D>@pJ6gIhm7I&%AX>uJ+L>T_hRNeM9TScnvQnrf!2~p85sRBUa$HcRSv@z z>T}Q6Oq596w;XX4Ttd9DR~OmwM@!3N?v-O#A@mK{(P#t zI=r}$GN}tSa^WMSx{~ojvbq~I8AYoz#R-l@7S~Dh`=B|P)29-l6V!x{PWQjk?dKNz ze76d1)&Is3L5S>21V$fkfKVbjY&5?#efL|mWCkP(jVEDzWmpeROeotY4T3a zXGB8&nSaf30ST#lVmoyNlmIW_L`d&7_Dd#p{0X%hgxIR&Qc9DAt9lt$g!DkVQ(kdX z0a43NWMVCX^KiZEg)$F1;}VSIZ-QYAG~%{3dRdF#e@iOrIg6fgKTV2{3|zX~{b}~F z2u&oTcPJJYgUWP(t(@xYdu9NH}zGMCirUa4cKcby}qHVt5Qf(LZlO z9xHj$Z_>qso(sFq#kr^Ht5i6|=Fe?uIRp+IEIy;=p0c+lqsS!KLwM-OZ*bDjEFe=t z;rXy~Up;)@U{L8GI^DoG{ON4EopJG?H`JBg$y4UJQJ=xraK@3t@LlJ6l4;|E(j9RX|Y~8I}E?aTj>W{nzz|v60^997aZ35mIIib7D}o=VIIA z#ncCCF%FOSX09(;*P7?8+^=kfkxTMh=qWbUmBO^*s`Dz9-EqZEnAu@Jfy+hEwbBHaKF9S#L%g)OuN zJdg@7$ZoONHwubHC$Pnu9140N#5~u3qj9&&(zg(Y2$_iWa)}Jz6zlzP-luq;2ikg? zh#-O56}@6kqZ&$_tEe8SZf+~P^AI%llp|Ym%9T7HY_=cgW5SX5S3tR%k{u6pbv_HI zD`q(xJ2^zx!A^C#km(eJ$w>2=T9y`rTh=}WId1p{yELXdOt>p?r)dIpJLrRUi1sl7 zaxo;lX1R-omNb#i$wU>5*RxGloyxN{3FD2Z7Df(~H?`T8LJ;CV+?f;Gp zO(QQ)X-x!E>4cKt{;=$Bx9;U6sF3T(rqovbgj7TmmJ9YyD_ZTJ>#K&8zTKoBKNUb# zQz+T(=~+G9j|j``++Gk+uD|&c>XI0Xbn-FXE-%eg19+-40=fO5&`w3x6R&nVh7_mm zEO-(r?PHTW-uD;$yEGz^t^9iP(3X~Jff-%%fI0Q zBnc%B*G>xFPJ!m{MCgT4s>$bIs2ZKV6O+TqDr_4=tVA zk;%_%i}(5fn(+|`Sq|&S`Sg|aMm7i%N}fdekT#QIkPBA+_SnP`tLP0!)q)Eg&ok<} zbY2zcfPk7ZiFgU~eloYB%Wc)ohkNabgZiTbT98Wf{I-QXh^bM#k~HN{J#@M!w(zZw zTdyzFp%Xi@S1vN?XTRM5RZg7cN9{eR8$?LQigBM*jPJ1I$dYSE#pl+=czI}JocQ>afSIqUkIqEQbZw~`gek(h0t0+HxZB-sIXP!|7&5jaDQbF#fvH!S1q zp1Rk9l4Bd6L%bon+Yp+@2P!PPYS>W$dEj3WW>!YKD$Jw-nc>$Ek|&)5H?-lOVsX;P zSZr+0iB}<)o=k2;HUq_X3yb4Vs3HV>e)ZHlF6{zsm=9g-SsI2~c|Q8BOgc7l%XcqR zY}Q=G_=W3CYip|f8=yG+9VE75{&hxWy{RBsm^%-NfXL|zvKdlw>x{k3navrJhZT+wm}2HFf~b3CsDq@vpv zVmc*l;lG?Zyj(E(x8=KUZL>9kD^Dfh4UMm+N90>VwFx3>BmdbPlP`=ld%e?XrS1XM zRbTyUcM7yq_)|?2V+oB^qwJ3!f{4zkx;>*Mby)O9n@>Fi-JQ$4zbm zN?KIS(+8=RUM@ zSIgn`-jbP0p;WFQ(>SQyIV7pdxSyP*UZ=ePQn&Yt_)9pJYeUX2oc5W{$Wo63EBsS8 z;S8(ll`17)XOp^?8SCf^o%uU*pJkj|RsWjqk2x(uIq3dx3Ox+k6^B?xw&Z)a{Cj!F zyM{aDId%t9ZQw~E8;tCm^|H!F&2@MJ^&BY#5L~f^e)zH!$ya^6`(L%okn{Tfb$y4- zPi|w*5;5U$@{Db>$4BbEs5brEjjJY_T-`NGMkYtf1C(oef``_Ect^Ib?09b3s3s-d zoi{UE5ev73K?v|;tWmpq~v)h8)B1^En2?I&`+{|D?+( z0e&BKt(gh}ij1xJ75(AU@*N?g6}cOr%RhCPQ}0)PB@C*SX^Bv9p*Lonw7U)i-zXVJ zB8cbryL{DcE5)Src0AX`Z5eHSD@%umjLcaiWoiH5f685ktR$ALkMc(Eez zQzy}4f^wIo8&~GjxvJ>dkI+Psiiib7uY+6)E3To~U`TM|x2fV3cntqRc6TH!7I0%B5-& zx0A``*sm$a6;yZyF3vNw%N6`YTuGf!QEE=$QZ18cMzyKY-0qHCQ~BgMJ(`lx45jc! zE@@^LlC?YcKOVy8Z;S_g8lQI6-iX}`nngXMfsuR4_dI!G9zs^!+vT|@^DV}YtZh`} z)tOwp4*;ZR*$oXyq({v}H$~r(rc|qmZzp7YN*uEJ3rv7fk=_YRQ9vcfOaH*2Q|PF+ zYqYC5mTv12bhx}SQjb^`lWQ*WGAQiw_!AqR%;H4ZD(e3!WOCANqq&X%hELBTjf{|DbYUgABY5Ri4Uw+fuy(6pHPPyhz_SMVD1N)!?cz6JQ`P){2(+`_}7o9_cW2>w7@hPe0vtgqA_AFPP51T(ogKs8g+T2*8h z?}RiIU)eFd*D`i?C_A-y9W4erMAtz#VK$#plFgGLf@p`S7C@~^yJMXdzzdqCCo|)@L^q)^~xdHYEmusZ-pjZ>Z2Ev`YF;=6A=cG4=~zyW*ga1tZzaVTI0X z(MqZtogX#R9j>_MtHGXLym}2xPq9U+?!(FpNyeqqn4XxZ|KfNg&&jl8yYMyr8}1N? z-7&W1OaFh~yt8Ka1;F#IpSCORk&jSj*UjS0Cd0svhh5BM0RZ#9<_`Q86F_Yypb8RQ z=ee~#;Vppi3OO2vcWr}b-0LLB8M2jVT=FqjeibqG$$No26Kp*XNxm~A!Wz9mQG$gg z5~E+EZQcN9H$bdHGlUh1xXikPzxR9!%e`#Z;XRRTrvVi%02u(UE&xhd8cCnz_JHAr zAp!ptHJHxqSm0!TKG6mUU@Fb4au|d^PtX^zZBO;g^TzPXq8#Y>@)l@I_W(o~b(Amazy*%fNdr zoAb_QD8LwA4hi%WYUBMb@JT5Ue+r?~by<7*`>6@x%4@#WY|t{Np=byXF#3)wn;hIz zN~T;3!Ai-?Z)HjnfPkisY(TrinC931`@{xjsKffK*IN|%#7whoHj-5$VB1YZMYSPh zLWt|*U$~OHulR6Nh-sW4|KKZzg-qNe% z_MB`fKJ^oZKVeXKq~OAI;c5x)!l0|^C=y5YD%YWdh~{=?L$hT&p0}CrAQaB3f{Zd7 zzIyp@DT#=?#fu-d4g*eO)^3Xsmv9_ZKXLe!Yfl3lb3nL*&qwaBZ5Kc!;Dt+Ym0)28 z%${YxaI`BON?wZ`h?$Qxxr3xkoMJzyV9gTP@OP@vK6559SodZW>0YDdLBsJ+E(;FJf&k|OZU2BF;2VZ%l-Xi966|O4Ai&W`Mu2n3 zpBey0OQ?r*Wl#8~EW*1&CM(jT8m0#VGQsVNrOhizjp;pK;rnHG6g3^ zi@vq`v#KDlxX88~EeUjF(2wXy1S6hcy9+>*E28#=xt5n1Oy^r_OTu%TJn^_~IG64| z;7^rT*B<2fbhIR=R5JUAZYGuYbwpTY2plMUL4-8LS!iPg=p>5ma zPTpvZS9-hY0}X(r$r&T7LYOW4fO!KE6qUL!;dpAtF$nKn2)t#R2iXr@YXBG5Ke4q2 ztQ4XD-ps&&|G5T2Xz`<|HTjaj_-;jy)B+|>LY*Oj1XGsPL#R-ZuRI6)<_#N4I;=Y% zlq-D_!2B|Xh}UVJ0G#vT7(C%o(qa=Gj$8d=F#kg?hj{@~08$E7TYt9~Rq%v7rnKS; z1AxH*H+<>>=E%L_pa$IOaLkH$;E`3l8mpfW2;@f2Z5z>F93o zoTDz0rR4a%qx6;Dv+1UDDv;6nE1`HY`SE<-hr#^MO?Q*yKIuZx)FW#D81HlQ#5y*krhAjw&H>2NuFZ?4c21;8WNX&Jgf2Y@$s3@biSXP ze)h$YrCHBSzo$0`or7Avz88>9mrl6<6l*5Psn^=>0c3V7(oPltK=|Y*uh!gLy*vqQ zl{L!#UF=Zj%;7rxaj{@A}b$NPG6u zlS+ND-g00&jG|@jyPvJ_dS7!S7(VIasumGmQcR7EFXBaO6Im&Ju?E#E0|F7!n=rbh zyy)R_0#|_dVU10zGSRH|o^(Ro4}+f>Z#4j&UB6IN`4mh=(%Tx2HdHO!C4!Qlbael` zITc+1bDP(Xx;=#F@zbj1!jFrZf&jS1;3=o(;fl=;dbC_e{;=^4FkJnMAdEN8FSc^+ zIZ($!5*Hhcvp%#RxU~GNoiymMEAOV~(8sFgSw7)j)zc`_nK){g#od(cf^6Ml6xc8$yw293isvAgb%4V2fZ06|_27k5xqzIo^ zB&PVR&yjVVCkxRt7%;gbyKb6P$9vC8F9`o2M|OZ+9mC|>Lh&a;oQT1N+y}mw6XtxL5s$in^PoF39YlALM>FuC|N6h8c zy>y=}hkmPutS+PrkRwIUQGJ-d0G=k`;_j?gh{h!C1RD-!0jgO(u~z%?(=lwZDhI0V z+j@iEJ6PmM6ukte&Uen4yl0)7?_#d1c!?9$rX}f3CaKj4!s)fkphZi35}liEfA7Pg zCX#tyiO2jnp$<){s?6LpbMVOTU556 zP2+W-@uMvN zn8Hck7!5=_JmW_>(VFBk@77O1Dp#pOI*c?lAz+!iYqI9=9|{@6I}C1F;p*16H1lAL z9ne^9sJ7&HO~WzJxPA;e3x%s$WpgDrNnvS9xOb=-#W>&WC|T&_R{lmB<^oke!St?z z!ONFxUBFkEKM6@;Ini>;W>99T3_v1YJKV+1>EDc6cY6l=hhX3p|C8u!!Gbn=kKzx;`OAX8dDMTRqEo;kA z3KSj+q@ySm5m>EmIjhfcU|IYS^c*~UqMlf$BkF0?v%` zsEfRMFvJ{Gqnl2jb?iD0+{!8b2+&1lPIFAbSQzf(Eiarph;vcAVQ*X$(}x-XJn&Wy z&@VD`L8}c=6yDbnq{e2Vc0YtN-vFkioH-+Za%C1XvtIh6^RbN-VOSNN`a$1*j$Y zzzvg5Z3yRkD`CBjIZ)3}>?RtvIs??<*E9eR;MazQw$?lJqSltsGjrCck{a=WhV*yl zMbl)cPXY5K4PY}Hr~BqnWJ^GEJ&B2NZJKu`Klx;X(aa(Q14pGgl^xt^4GKWAM4UxS zmmeFzCS}nQQOXs`xL4R&3}_p!L{E)%d*>t+f~j92rV==S`B``zy9Mgh_D$b4Z;!%@ zD&B(tMZ07CFOwWV*XgmMXhC5OQ?|p#^C}=!Ls{&FFd;c~4&a1#0hnNPaYK?3!BZv- zzyz6mh*I7=3+LDRf8K~;1#a%Jd1Y z8yTGFWi@_Jo#vJVMC)*(6EaeXmEK>0x7&OvR|35l2v#nx@PnOw@~AI5B`OW?p>4hp zp+?N{Yad(G%XGs~lz97zJmV!r7;u7`1Qhy&uW%@MiIM|q`u&@a|3; z|4~oZ?b?e5{6rGB6a3`mm;^52eP9&i9lOph&}@k zK#+v>Z4kh>0fd>rx&2{mkASvX5L@gI>0^GS%3tC@k$PLlBD;!hJ?qF}u=yr5)qa^z zUbC&l*lyryFS|Odv$7GHHQ~1!B-@R?n3z||WKh5~*I`8&ov)f{7YJWkht+4MQ3p&k zX-es9yJ-WIFyi{d>YTdz8YmH&7HK3z9m+ zUz2`AS2Y?G<};%s-}qd=yYv@0Zy3%<A(CAdC#9m&s+vBDcCR2@?>iBAY63?1{sXX`EHk` z-NXQp$HBL|Il7)sgI|ukjDZ$>c`@#pMx3Lwv8q!N3u@ws>3dtJUVY$dcrs!qo}WG~ z(K$oZ2w+4T(PnJ+yN>LS#=F4EX2{BWQ&jG?is6R10r+gj#(DU{TC0F7eXmB8aYJkA zodC913@p4xz=_{c7xmTx#7NRY#_qUd7vpwKYo;5ZC)@QevGVs20Fe*?_L2H7LVpf*gc_!f>moniDo&rH(PO#1?J!>P~y;_a%Sb_ zw-r|~F|Ao&BQ7pj zOJNQ~EsKCVM$a;Yd&vn|8HIb^{cfpy!TX3~YGv8h$gyrAe2?ROyb=|ixrehpwF$)pg6El3apaaO?mSyqeCVwj)Acpzh|7Nc|w&;l{Pdi|(&moou;48?(BoU2Q7X-$LFL6bzpQu}D-Y%YY>23|S|ijKbE3GyG7vYN>Fjn4|jS9 zxoc}V!~=_7adO^T?muM-_WrgMBIOjr$Fr3z+%P~uaVCQ#+L7{t#K9nNIG5D_4Y}ap zQ|mZQ^gY^M{P`gouU!zvTyFX=N;e{u@~=KH2uB7&~~+c>+iW&W*^cq83caDxsQZgC*5t{ zdx7k=G=!Wy(3VXd-p@)Z(M#RW=arX}vl_Z}W8*`#ihtOq4wi8)eO&03$x(3R)$BpA z@%VFnb@G5FI?qCd=Tx(&gB->~;;1tNfeYcL04;t7w9zagJSs3j8D{H!(WzO^CUD zX+ZRv?!$@`tU;A49afr3OE(UKC8k$CgE!2)nN#`N?yj{N7daRwMob05rB}|qEw=7T z;x-dP^Q^K2eG@ZnR8d|5=L8snNJY`8D7LrmU-uTFToQ7_O88~g^6(M+!F^nd_i?jVeSv?_+xtXgMy?p_;eE7u9XmH446FTJHd-Y~P zM(u;T(y8bHmB9;T_Xwz#)~7Z zO>6-g+)an7>)PGU)%h9$$DT(b3zc7p3l1G1?jSLRFcUN2`?mpb$2;^);Fwg5(aTq9 zEkH-3@L(>{e(t^;LV!p-`8}zm9{U>ngYe zqcj_Ts_h9%Z$k{1^w>dMxX+EaXVzk^25M!8H}12gIoB$sy03~K29WZH^w_g?@IX8H zoN57)gTWHqZ*+TMX4$t@T4iZ6vXRXXMPjN;33P7kfydhn?EfcrwPMQ4QMJf`gK=2Q z^mIXQWcs0W74Ol09tre_GW!lv$$HX7xo?11gOQUI9b(O%9!QP30$QS1wAX$GRm`#e zSZ{0O?)UKs^Kg-;upOT&_F77Tlp1pj&yHgBandvkWE=}Lfk?VpdhW)SBMnJ?8~67} zo39(9NBX!pm`{yXul@@|m0G~Vc=fYD8Ik0>WSc#JgPC889_7CpC>@c~=DbjrgE_!h zzJ2_^J6TEa+W2PVEi1TM<@fHmp(g(ZA@qiJh zV<2*!-XZQ6n+TaF!Kr>V=eXympUP>ki=wsF15_LzQrK#w4DZNQfz5AKLZK>>_4DP_ z%65oQzBqO$bmR=zy<8|AtGeeL>&CplgMa$v{S5!Pn_%NU7I5RjoV3g9*0f>$9mmAg z)-`S?H#JT1d2W0t@2<^qOMm;D?2!ZkX`${B>3us;c!>02JblK)O0Db`gh^yenosqY zsncr}xjhnrwlr$7Lm7pw);{4-q_~d`xb?x1iFtpqh06r-KAo#H!SmJoZS5X$XAv)D zS?A6#Qs!Hr(ei;!Z+GHdZC{Bsr45t|MZub zROKZ>;DyXeM7dAyhjbRd!g_-vDiPzbbbc-QmC=kv`h2w4d)~O+!f!?|?of-n*qXM{ zRGT0HR!M--787mY?J~p>(!d5J)6>XmYq!lMRlYXZ*x4d&>}IH1RQY-*|NB3kolQjn zRYg@HNO`_w-`b3xxhq0>LnH{uy_0t}Oz}BnDjI2Tsk-@Cco(nomYVlmUWiihI}ij! zeS?GA$An%eo*i1Zg;<$;8#hTf>xpeG{`GF-ibe{C$UtZ5<==)x2(k_oEyS9I1CiJP zNp!s=o6c3j)auo#pWIp138ymO4AH2b`K-HTd!9^sai@Yu=Kl;xUFa?vDvqNXim~v9 zTde7HzfrNx(Uur!%g6SzbICAER;CL#+NU<}0q-3?0@=OIU~9QhTMK8N0JzjgQj^Zs zHp9~nQf}PXh5@b{89Iv);haHyI-Q% zUcg27d-?Q6TG=kRY^8zN%xM=qplxp3-|c;b22YOgS8%=3ei4#+S*a?OVUChFEL9c9 zsjQrlXU~``7m@G7Av=&ELj^N4jIOnuOMQ109F`<~^vYL;5qt3zjH2?Wm7kTTou5$ZI!lwQC*vx7N z_JEk9jrr^sL`}_EP|QV$olH97n6)$KfJq(8I=Lra@sGyV<$iD)(NmrHLY42AKpjhz zz}ltgeTWg=fnv6pOoM+LSnGa#Ed0g8X~!dN0o;&&j!9;0-{bz*MdjdQkWgtB28(ou z>tO#Qh|yYPouJKj*J6c)j)a{$R|5p(q|DcIqE<&#oQMmo=$YW6KPYS_`I9Y5+ThAY zae>!chNRxtsVKU2+;QeZh4il)QN!ctFv-qTQZ3S{AZHmkI@q;L1fn<9cpGa#={|%$eVX#XtVQL_%o%VDlPotc90My@K)1wIME#O}u;aG@UOUX> z*vgZ=es&;D@jawb4J@)T_S#YT4tc6~3X-zKtgkvS`WKMb9*DGfb>}K0k@tkHqKczm zJeOIxa8c4u9cE~LibE=J#7uD&PvD3mkp^Cqqu}W;FqB4S$5-9+&%DIqT*X;< zBc!g%Da?q2_>80mZSk@zuFqWlG;x&yfGbv!_p3{-n|R~a9uQ{tVOD&=2qn(e|4T_2 z1wpXK8>YH&tI94DmG+ztO#{>9tb_Wi0Zn#5R>_ax*(6iWCrxl_ke&ATLfy6+L9kg7meBR^L{azx( zq6>h>GFN(MJdg<00A`37Vgtmsy=YOO6sN|oa~_-Ndn&%JCn&j@s$M?E!aM&C*UUNv z4~FgDBlE#pn=Y#BfD+DiCn@cJ{K6s;avQ z3-%k*Pk%y92V&08-p{Da0g(;<6mq)Dg4=2x4Fhs|zfDxfeNuhgHx%9~dGE+jn>92; z+3M$zD3~pv+(Kv&*B?pj|Bjr6;{_p70+Ximl80&OzXpajZ>v55TUKyZk9?-P0;@gD zcaYL#A8poGf{$7O$(6^R9rCgKH8sLKqAqMG?N6PO00J%EulF|xpHNV4!9-!tr+j!# zB#5O!Cb}-(D)ml}s2MQ${_mA%LaJ3`U|$4uh7HI}Ml0?_;Txf)?K=d;o0a#XwL!c! zEG*#8=X2%p;K`<(VV&wJT9AHpfuv>gsde@3%_> z%C{oPX<+A0e+3kr0|@_Tz^$!=JSoDxz=73bFXr66S~P4IMzZZ5U-bhi4iFplr{Zdb;=K=0x_1Zsxa|z%L z*bj1=y$Ps8>h#NB<6uxRw->(dc0Z)|=JY#r@5xS_Xs{()fV)9fzDpe70$El_XcZ<~ z-zE(&l${izU>(b1_DCDg7l)A~bwy*Y`d?fE@k$7`g_Ab5sRpQ7z6;t9qYFdRxG>uQ zYAl;hNztVBZTg;6tGPScDo@Ea`l>fiQ+C`Mu zRfZ;8@sGNB-<;XGCdX()=cB#Q`0A=G;aC8o1uDj&b$!h}Tdck< zuUgj^J!2z6xiPdUD=YtD4rDb^_63L;Z{=CTgYV5=JPW&U!fpw=Ug(=F)7Jc(cC|_7 zfPfSFi6i{LyXDQ0een1S^Vrqk3bnujVU1a()qI^PsvZZ-ib#q?kZHyr#uZvje4C8e z#R9$`gU;QPXbj!2pBK2_Z(f#N_l3Om9xpb~=SDBi0B&T7BZ_6G{*#!ct(3!WEipEt zN_y@-s)}G26qBkrR|5nl69cQ3fyIKjE})O`=06L2V($$!gNuv(J9rh7PiCud-MXR5 z4-S2-`g+&uz;2ZURgafj18U&T(G8*XZ?3B6Dx%)`{>WK9z&nSEIe4EQdTuIV{u+eY zdc;&CsX`^}y)P)89?Qf3l#D4B@CH+I<&^ze*(>34A}~C$sl_C}H&RHvzU$0(IzpWYGfL4sw3rsfYLXG{&IS}GH^}EpXxzJ1^iDkt0ZGvU-EjA zKEUc}J9P|c8zK1y9Q8QyLMx%;Y9n8$iAgNH)8nCsMrZefoC$^pu5rs`Yj{!wodNEw zR1<Y*7i@ zUFn0>rCVh^6Zu;jX>r9)LBNWjl*uJ&yv|3Qo&xM-{v5ke1R$1mF)M;|A<82GtWhKD z3SFyAyl<(tD$9v{pzi)(4HZE{>#@IzqJtAKK0xhwv7v@+n7;yHx=bJ6D-g)o$1WOj zrv*}nfOAiGUdw8TJ2|aOtV&ABJc&KDpEc2=iYjl_&AM9(UU*)>dwUPnmL;imBf?J)0oL+Ls8Nj}?z=H=sem17cp+{1Sq@maMn84j0}hN3Vu7pI)R%OzbLjJ4flIMrXTZ*g z0h)B}@#n(82Tzgj0ZR4zRkmSjs8&V>2gY)KdcyPj3_W@LUK)DQ=TRI8k%> z#_<&V0384Jf8Q)PUsj9dLLsGf_k zuu6G6V3IHPWC(vk?m!*R1cvu$oH7V8OU9|Qw;=rxA=LR#%IB?p7i*9PJDBFqT_5(l z*>e#i?_~ccwg_lJTWe+%CbJ;B9Z}rDiK2XI>2MiZpPU_E!}g9?qn!Iqs?rZC`^>~> zd=42Einz{d_EO+_a9lKibdFoe_Pl*o8c4+WQl(Mus+ zaxj%8{<&UuJ)S)2kC6lXDdQvlZ07{5ER>%E))N;12oqs_rzH3wrhP*Id{YmVzMaQ<*yF}O zYCKN;-xD(5YF{2>XFA8>2)V&dIA zPtTzpz{+k|xarOF@LdoV6kBz)Yi~~sc9nMyrP?)^MgPPv9_jv_7#kCRoaGIiVk;IWG^vH=56osldlXjPXvisi8V2pL( zzzfgNvx}4m%J%2GpZSE{za`t0Gc1AYEd?q+zVdUF+zmNF1)iDAUx*7{Tu}h9UR2CX z&%4C-^5+9xA2%Dq32@EQ4se=i)1L6m1NK`#251WJHzrlLc~MpIJO_hjo!l%{Fz`mi zFP8B_KU^v*S-(*YeMO%&(c)ZEif19v@%9*YfsUfF4(e6F7}|u}eUJAIO%fj%$Q0bD z=X0b<0;vjacYZr$XSox+9)b~{6Y{nosXzoie{)7sSOI%7pZycz1C;1$WNl{%fKiY) zHcsyftuChpe3QPiBT*vG)$85TxZgtty#uE9W5WyqA=zJ8D)MWo1pcI|`V4sC+&fU& z)xFc11-R#uHL9^H!;5sU?$twvKIapyC#o=dR5H*6U4SKin97d~S@`l}l=x)Oui59j5U7=8r-bOSvBGfq-!27c^7H^t`@g3{_ zFzrELR-HL+KI8Gc=hy~iuGbnQ%3r!#h6Ls z`RWj&fv<~Z~>ZWxz zNzH^8%??WKF3z@!yjDe{pgwgIE62>`lE9EddRbgX}Np2(yrceWc#HYeK!{%+ofSCa04PXM4)|BtEf z4y3Yw|G$lfXdEdjt>Y1gjFLD}Jatefp<{1R2^rb4PEVfQCX)lIC(;2#|P@) zwTKxn64AEbN88?}lNDkEG#Rz-#OZLA3@_bUW5s?|L8iuF%OvN9S27bWSGEJuh%pUI zyW6G;r1d=@KKEe`l8&IxxzFr9skFQta+O)tVwjnA;^tbm1+cTu`MUasNvJkYj709~V&KPR< z`|+8kangU!r0on;F1!l$-+2@o-Qo)+i-y{FF~U!afyJJO1D7XuGviZ@vlrWmagabY zdM+t1mHSmpo&_e%ADYrFzWnTpEvF^Q;@8r^4`L@z7WMtZV`N&38=7W;JsWdVgk*U6W=xuIhH-3#rYNGedxv_%F|evZ3Q z&)Ac#QoaAxT?wUH7-_rLp40KI_nEe}bpaRx@>%-<_im`En+048~$YE_kuPqJhe_lk#`ABvPkR^*^tr;5c@pJiK`115nY0Mvd|GyDEeePhRh zVri`~ETmHYO|$MiV+!+*?(IclcaJC)YruPUTQ;>J0?wb`n=;65u{sbCR&5go{t#vj_llIZZc z)nj_GNMIPuNIqlE*X^z^e59=kld*>C!|kqKwHr-LH*2;F-`sI+Rc`^@7SLt+QDoLm<^6x;x`tNnflRH<(#wZlX+x*I^{cQA z1k<&i%9;cuvU+IJS8NcUF__ONnN>U@q(1K7BERA|R$kAXLYpsqaRz$(Abjh2jJQEb zt5-o>^%&y%IAy)xFo9InA_&v$Bu*Cll%%on%8b4cTQvxDe9cMEv^S6jr*j#yn#>)@ zr|o_%Vb%PQHr1+Ra%PKqp7S***iz^x*5$fCv8>^y&+=0(Vri|}_U$z`U_12?wJG`% zR0@k_l?oM*_zdi{{bjhSz~9r_zTC{cahZG~8fHJM8m@g89e7Ilgk@C)Z};-@Nxvy_x;(v^+fD8SXJy5%l`uDTVldxCBFw5%x^|R+NuE zb?LHx^z9uAuR=aNYebqy&a2pXq0l%@MBft5O72V&o#U=1XFypir(fXibpn{>0}b}=Wnp*RLuG2&CRGRkk&oIoy^i;Rk zLJ|SNQn>!}q6TVr7a+W+_iGG`i3M;45tukOETU8*BytAvP%KSGI%C2dLe5hYd@iL( z3fND#voAfIW|O@3mQ&m<#ck-H!vo=B>dZXT5^_VrT3yBCKCt=9vatDd)>gNfYzK!2 zE(e+UF7Eu6%q7;ubgU$>JU@W=(fc8j;$mwMam6=u2YlyPB>GOc$Xb6(WT->29+D-Y z>QqCIwiq&9WAVNUG4Asw+?P=vD(>7$-?+%@6==GJQ6D3d$zz^j{{5@Bc zmA=M?`FVO{U6=I6I<2Y#)+S_jc~6eDjN(>!0*L^RQc8qpS}g(2AdA1}mEmg%7h_dE z>kw72_A2D9Dw_$b*cXW^qo2%}_&sFK`eHM0T)v_L2jTycr2gzbpI_)%mjnTJe2=cl z&(G^*qR3-N&*>k`?_CsrVOu;JidFz|wCK`5roZ2*=6kCJ?=;@{`{(-W>(r!oX49)_ zO0nBPXu@<8xoiT%*ZM?YwUEp6zaN@o>wXP!2~AknLdnPTGTwX=Q@`dbJa+koQmIP_ z_As<}dy30%Nj4@-oT>W<hGU5A2J-*JR!@K_-A@;JH*& z=R6!=5CkoGOgxa0DAyT{FP2iM@%|%*^zhF1G%e=%pzQMHS|!p8PWo1rR((MkKn?vR z&@_1T=JU4P95`S6H;js?P#pbx!lxjPI?O*X1Nn+Ktni1}8?%OKz{WILMcPvS{cDA@ z;USy=h?8(xMLT!XM$9hpwM|lB~Zsn|x@xlF)sSa0b?NYUW@@P=N;6xpaom ziku7sP5E<20Dl}sl*@M@0Cxhybe=Vw#g~Zf+iwu4Z~8w!i=!<*hb?MO#u4#wC480e4JKw; z|MUC<+b4fbh(hivPTq2y4GyH$&Zt^@8j**g4)O10<6BnAll4r}2JiMZZMdim--ka| zE&b*WRh2ac>0*#orInN7T`$1lL1v!v-FXxwEwO{0+U{ngRR~e{WYj)ek3?>M~aQt-Lf^uhX_4%4>IY_Jtmde2MG@iEKG9T~c@~%x|46gv`jB z7JXR{r2LgUW>bB+@RCW$12`N z-kvZPaDE`1mYB%I;mPrMcg|r++qnOGD3*N9nl$gX!$i7UWK6_EW3$QoOsUBACR!^P zmob;;;i4tE?(M=MfM_CGB{d-_FC*=!efS&D>5#rcWThy~JeOCh+(p0P9Vk_3t*Y+m>#KKmvorZ;IhhyTR65b?0iwBT<6v%#PJP!RmTQki z>q6->I0*<&@!?av*T=MD&`OO*>>YR0+Lb_5oxD~nKxi&5aUYe1&@*x$+7PktNEPF0 ze(=mQ2fgCdH|t>4%GIyj>HbJ_)nGFT+g;_bFwdO^mZ9e*T4DdchC+M?Uh|ng#pjqamwW zE^E#WV(3*!)L*^antl8`YJuS%j2ho1AZ!%=pP`+2qQW6RLAfthFGfVCKF4J8?;7Ijx$`Lc#Y-o$dWaPui{|5I7UAr zbLiZzaqH%bh_WwKm14q)!|m_5%OxXa7Yhk(CaX43H8YMkGKTh-zCdtXu++ z@L%%q+XDww+zhrx?;k&tz50o^2o~l^MHp?j`IxJR53KILjA6<0HgUBmmde66I=aC5 zLz|tZk>@$bUEe-opA4YA-z*->dpP&{Y_lqy~|7f(eNhSm2jKb}!M>4Fu-?NJE8~ah<;zr87$#miJ z@D-7Wv)+Q>q28dd0e8Y|rSHW67ZN{m;9|nO#3)oL#C2~k#%OQ+Wk1u%Vd6?iara)( zN=swLco2_A+5KCmOOY&Uq-VmTs+d00b@9u}gL{|aiY(Tl6BCeNugTil<}Ko2NITGw z;)^s0?*l3`U}p;z`vsj&g|Cb7Q@^;?eBo9o?IU9sjQH?fE%i;>2{5W!aBNhIlp79{ zGWd#p@Xs$em&p#@2{q=h_icMyyu}ojKY$eY;@r%VLOKODW39EHwqjw~T3*Y=M50mw z{7;BDG;6E-(IkqCe*N^&>ntnvQf(y72V_*coKryuRgrQuXlfuU^73}H1h-0Ia0EIv6fepyVRG)j<(qc3(}&{>op ziAOL#!LK=Q#EkKCL^xTNOcdOg=+%Pz--Y5+6ig~9fS zTW8u#tOZm~AA%2fB=vo5Q?105omwQ1w?^W{w80);O;Y=D1U_KM_`uJDot?RRMh54GJ#kk-aASG3 zAqLA;-D+|s>Gz8lioOsXKYaT3;VnDM>qM4z4Z$xn@Y`yX2A5RL_P}i|C za$2$98`h(IX5jVRA;4Fa1wi#o$X4THYZ1J4(V%+aW}UC%m(w8c*N&qklZ3(#1UtWD z;&>CUMhl3eI3I>doaXhws06DYLx;ll;1~w9$KNb)`3VQzu>}SC;X(i#aP(=)sE)V? zabR>uRNjeyzpwpp$*BbBlnBf6QPcLUTfz=XRp3VsLE7jF~N1r<_0DAyd3yGn6 zJ^$;RbxRWT#y7dO6gaOi=bgerS0}S`&udp%TtaM=hf|j&RvMg6f`r^d67qD};f^&4 zWgid5C2=ArG2Zu#2%ii%7YBcWt9JE4Pj-;PYReD7T4f4~DRMZm zM?zy)UMMi)`zLRownXII8Ra0rgx88Lf~^uFPD~DaNrE8#! zEB;})dMspIg+V)cs!D1_z7`s7rY0n$SbX9m#)0R%a0zE?0}enA5+U{9??HB#vK;4% z07*1pGuawSKHBwR@N2&JGv=O`k?D6gMDboq@b{e)qBXJulL2sZi@+vc|?Qe$m z(L7Sn1_qQn0Q&b>T8t6l|18T8c9(H?K5AP1yX5g9@L)->BNy@pYZDy#{J`q9q7vX0SA^+Z|dzi!#S?|yFo9+`-vL!eWy?2p|}Zm^NEg}6%BrA1Bb{Gvv&282RGl2g{zAmTydS= ziSN~J!gidws~{^(`Id#dle!zgu&_=qG{yTnzo@c<`V|B#P+n;bif zhZJyYJB2>|6dDr_|FAsPc3AjCx|ZYIdK$Tu``@$tCbSDWHE!3G)Yo3bLUum40JkPk zzr-&EMs9Sw?%*)96)InX-AGTrd$kj)Gy-7Ro>0i6|G^sQ*O6~J7D`ztl2DKPpu%P% zNE~?AzJFxn0vq*2Ve?+|Y{gP=?H3m3%!c-gK}YbgugLJkek}SpR8RBx$VoRLR7kB1 z)#RzLQPZ31?5b29s;c25cgki`yIxd*5z#_YTYsywarS9Q1C-7msy)6qlq%C#dX|Fu z7X_9tL#Z1o8yBSWch!l4kmw@od5Mp^ewii>@WR#u?XLzm;80^`Qb9QaIw_S1L$7wa-P$#@_oFJm%yroi(s5T^1kixRwnW3`EN3VBbC#KVGg`)UKs;{T`nWA zqKro@CA-tdq1@*UNiJ|(PcIbbgS*st%5oTmr~^BONN#GO zqMeQl(}W=_n8*hy`!fj|WX1hdq53Y@Wo`9X{Sa((HLf-}wzmlk!ZTzv6Upw|2CU%l z8a!ZkMX6!c{RWnJ&b_*zJBqK+h((&@E6sqq;0wv~@Z6f7w?LT^kNsC+)u~7S59-1+(wh86){jw^ z9r&piR2_yJi4InxoXl9_O&ev{lYz3(-D18-V=u&dRFA~BiEU$2Tl4iPf`|$X$^C)w zG#$5LlqDac=2UJZLdd)E_0jI8-kkJ=lR^k!RE!0|GT1IW?* zBzG>@93_)RWA`^rT0q?=76Hj@)vVH^)aG%MCKj_wS2o`q6`Jn!~3CTmBt>^o{ z#zvk9-r|NW+|2k!_`=H+rJ?Y4hTQG^`lD#gk{^qIuHW^s=W)0&(l)!#UFUx+?Zgtd zF&_B(L-)7>Qp3$(2s4}FT*Nv=Hqjd!>KvE3@x9Jqi;wGe{g~C;2lyefY~_Xy=G_Eh znLUz`Mc0+L%idhfCL?VbE|W8~#dJ>k5ucFyZ*hR%Bjfp74G+jdD!Q>LpB8p>vv}pd z64hm)CoyH~1M9z<BZ6%Xn|YAx-!Q zf;W?Bi|;wV-}I%3_FVDA-S8@9e=Vvjw48*f|QnF&8cf z00xgcG@_5a4J=fcAewi_n8>{GZX6ue5wA=&P5+>=nK~S2eP?X}9~Xp%#J6AX^jzc{ zh@WxDAm-kh7}4EDEYb!+Uz%y!p4DB)WU~Cy-FW;J*EAHEFL0S!4>yZsz}}T_@Bn&R z4j})<;M3CXU_i?k{JPtYu+SaP3dEDELTC9*qxRE}h;-) zJdw(Fo;wXL#viqv5Wo3K#=VONXX6OlAlT0?!vM7~-tTo98*vw>A?LWTBZ%O1yd1o>M<@M}$^5i91; zj=pltS!3Ra6PE^gOMftJhP)5ssdC!Ro~`5yb=nJY?Angj?peSm(m~-}%tY@*idZ1; z3uL41y^Qr6{!t3SOr*iTyD0jWfM&<4U2^+ZCcnTBjG@`xU(g_l$67M-q5a{1$ixJ2%qGT=grYNq5@z`CWQJeGJB)ut@$xm@Pcw1gS16$ znDgMgk{(~lJW8<1za9wWzT5V+Zg6k|IrvHQm@J3D59 z(MM&lT@@9qTx!!40%1k|UKURJ&|mZL;YTh^R^94=Wy!waG(akj4>?{y5(tA*d=1+z zZBI<-i29Q!{>@FxmJG-`dj`5L4em8J+KtNX95XZHO5gMeFeucKgO0Pxi&=;WHib6P zM*zN?L=^LVSO1k;YE_W7&56V{N`V?0+ti+X5t_bvSe?tEo{eit#kujI7TOq__1`{uvm)$M5;&z6+AwsBuz|)VkVi5 zyq>=Ya7z$v++S7sgJ{ujA*cT+CGVa2-+`-Og6~mERpMIFkIcU(>iVJFl-qzNX&)|QoxLg)pJj}-Ow&DMtaW)70EE!7aVt7rpE z;g4F**y&_P6~cKhqb zkkviO^Lf=P1VZ&MN@XImBL<3u;g(KV_Wxj67>}((KHXXcp0&aV_^%rzeEcLPP8@IHuU7J}_~ zTCX5=I(#N~7p5FCU%qUOOV?uSi8iw=eJt7TV)&L7770znI1zvfeFqg=$PxPI=gXI( zLYb(K=NHolf=Hz(G7G^Qdwm&9DFNoulrqYGa1qGmCGf(|LMQGhuK7KBp;+|(j+y71 zR7ppRr0`Im!jwXVeP9i-+6TxI)}4^CI>&`8dCMxUrjmDK?njm!^ue;M^BPVep#x<%6*2)Tn!JBiJV$UAKP$j^l<*&%xShzocwCV}x&XK; zH36ke9Ku6YS8yjFnW75#`OLWU@ds6IiXL%16+Y7tvc@84M;jU!;g$pRWXciE;%FA+ z#u5t40Abyu1lG?5u&={KJIR{*>Ym!9)hrOrp;p=gq>@e0Tx1o|AA5FH+iZ+<@D4+` zb`Q=k%D6n23BjVh4cQ-fi`5btHQf3vUV%Nt6BSg~hi z9k$IWK{PS67z0*X2+0D!_YhTTyy7*W?DOWsQM|7u#v+?raI;zII%Z-YVXYqbWZPxD zX&P)sg|?*-YN5q}Q0~>Qf!eCj6T)@i5qO=skJpZ!2}Z}rC>HgKUDwprSu+$>0Dlo@-3z>vDTO0@^@rV!BdRR4>x ztmjPBFE&@y*R=5iAS}`seRoRQ=C9lUFqsA9*5sA2Q@4zScKtWFv{A7Xo{9>q;@`%9b)&0J!0VZ)Rt?PZ#U0;-sh6Rso-fYv9w+_N z|FEncL}FAn<94z2yc4@f<)q8QK`<~kE8zH&Eo{R#e()}d!493-P`okj)46a6t~b~P z7!cr{I-)?v2krAZHsJ1Tla|TGMAy(%A2Z&M3jzlq&06v+v8ouFZOJ3Gh)-$$cGfnK zwh_ZBE+0pE%%5{y_k-#-!2CuJ7|p4XhrwOlv#;S6>u!{R3N#&dqCw4J;YCmt(Hd}G z!6BWT_@s4VFl0sM|dR=O`N<{aP{ z4Sn+A_GBM+e7(&HDw9#xY;5sDC4fxGk;T7!{>@WBf#iqQ|{_#8iiT< zmqvJR{*6w?0ls)dy-?11&6H;k&D=md>~7@7cwSvI9tB)XV&OprtOqy~CNGPd-uWt< zv9Mya83CD&^AVx=HK-k8?N+j(%v6iyOuK8|WT>cCSz=rIxh5_1Vr=24rubRLX6rbw zXb&k?t@|C4z8Kh%Z+UgiTbPON*wn1E5O6Ual71@m{hufd&^NybjoVN+zxc=d%5)FI z$p}c0r{aJJAP07Bcw*YD3R*Zr1&qV4D&4_KHi-?3KZ>TnlJa`u%vpR5pr9tI{F6c(sG1UV|1WoRObER|Tti=}3s+XeJa&aNg=Oxm~E$tb$lV!MRz^}H% z(xjwpCp_UU32{VxGuc*p*d}ECgYt~xb^#@N z(5Hnx4HzSaY#5Jjd++k(K=@@4vPP21D4%(E29t>|M38i@%-NrA!uSOBP;5sf&bzrz zXTbs*pAEls@iqi1u`h_ge}OD&5<0e^{K8Z#j$=c=Ep}Ap!xzRKull$!%gjc3K_6~ zO5FH1^mb&&pBVrUSw^V0g&_P1rK6+y)P^ziEjK_n_oGN&^CYEbyz=#4m0Zv98K!-GxR`jfICFh6VDdvQD*z@;#QJ*4$y5jR!&rG`vclX(gz&oVcIiq#VF{sBc1#?#=QMe0+3DCaj2nhF z94z+zCBJk|ZHU3((j_O?m!y;)w8UX7h9BR~rZ!v$bPyGhpQ%CMnWtuO7^fgfU32~_ z$c@mw@;=!}p#jsM9kfjS?ItC!$mCJR8E$18q#X~O!#fK8!k0j5LgigrdsmaZb`M12 zT=VHhFA2QyJ5ZWosn-R|H6RSfq>z@MOo`Bsim=b8peLrY+`8WvK(kpMV+TJ8XiDM^ zLM<433+NBaw_)O(-jSC9b-EmAsvqbI#?8x}FTnxQj9_N0Ts!G!NRf|V_-=H#EulE0 zB10(26*`28yCLb~v=|?A_l$K#VML4Lsc#F_Qdrm#C?tD{;BCPD9Z?8xuWwp`Mu{f& zK*ps1brlsxpUyl?DE4Ck|GehlA~)Fi4ya(3f#*hm1nS98UE3Bs^KHnwEmwleTPLKa3Z)thU6=Ay_S0ajzS;qDoynvPd~4`7{=Zpfposy(Mj4cbH+Ap5>AcKrapSLY~ojoatZ z&F5C44Zv!q#H=G&fq5Dtzh?||)3G)>w_guBeELohrZUs1Df;4@riEiZYvS6xNY z=TD^XC6?5vQTPuVc8m?SUnA)|3oBp}E2WbI(t)NnBGQfl!#xb=RK` zyq>%p2jg8sZpnsrwhVTpe5fvRiSe{i zkU&U{tO4kchiQtA2h6oo$Wk!gRl6u{JXNUBDmyA-v0`3WD?RqSMfo%!K zE+~?;SXynr%+y4-fX`?`r)o6cLO2=@vjg@X8uQ}fA5asZx|Nr+Iix^U_>A^NLZ?C7 z$Fc=)EU|p2C3LbobK6^C(vA4pJDO!B4g|(e*a=M5wc6q$5!|#HKb1xUN>8q_-4bAWVchy?kQp3I6-6km-N zbE_>dv!(=A7&O7);8E7TTw@l zzh$dINTi6C?wj?`-0IiL4(3lUN3iX;cV3zQoNHi{RLtW z>hO)pLZY@pDYS_gTPSZ%?NS6kWQxpJxTK5sQldd6lp)7n#5@rjyXD&X42JdlBXUWx z=g-MORtR5LNithXDFQSa+l@?1-`Y?8NKZFXAvh4iQgfih=*Hh$u&~Isn)e$+7nkOp@g^N|83lJJKv=^@z2{VqYtr&hlbS!XpkCFGf z(`Zb~!ntL0q7S?2{(-Kj!`7X;X+LlTuyr4d-+%>madhF11A^<~5xCa9T*=D3_AS>m z06z(_VveVpZNU@JXt(|s^@HK~AADu9issJCU=7)mTZCayq*SiwpbQ)u{|)*<3BuEC zCMMjGpJ4>QJC>tbJvB*-_3X0z6P@4ElA`&fb z={zh(wpYpEJyZ?8U}3D`emM~6qC8T{ZX4+|6qm&;s-!5=2vX48BYU{NKG*7ayVRc8h;mT zS-}{BuAYEPMl_r9%J(lNw3SK$F9RhDoYjglEP#Z&XIN0=50__animrue{)ZDC`^#v zib6-8TgWMr(D{85$#?NOB4mN8$?moeaO$okHlqcXK~zgvaYld4nD_sm{?S~o+nz9n zywgtF`5VFb5Uv|(@i)W?dv>@8iJuhLT;l2w13+TLyq%O+w38dMk>A1lzQa zLqjJsn0fExa4XReSl8`@7h-{1RkL8q+mfD06~+`42yVjsKW#|?1pJJi)LaokVHuKG z*xlJjfNu_Z#sQ3Z%SvzRVr=1gunL>R#^mli=D@_4k)7JcAd=)gu?1so+nyS+r-c_A974WaY!W#l?3fq~g&3EgopR3L)@nP;W7di7$Jey$Z?o2FET!Z|QhOkTFyW{L#S--uVAf+0h$+Ck2)-!HhBS zLt0W1UM?gXG?RW*2$2FN<$u>s7ga~p1OVPk!@jDDKSp2x@f)vBEwlClj ze^{=_HxvT*wz8RWTH;j}8t+C>k^4qNLF(k{#$Drgtm8{w>__(w-}eNq1Wg~jL)@y1QgXIsDI#|d3}c&$Cf$;u_C`?Ph7UglAW zdkTMB22gvLd|1z4yqQ|-?)@Z1UAV?YKe1(~O}4Sy0eZN?MbNsZ zHYV|?eQLM2?4`p+w{KS)zi`6-&H`{UXOHMJgN|1PG1fBU< z$gqXIUy{2(nRg)K1X@7oaxwIt)CMH{X1%0mk&L|xJkjl~_L%?v z>tlBz%40#f(3)L8+{K_!3NXHX>3D(jDQ$4rng0YUbeiF&Env+PmHM3m6z4ZKFgwgZ zp2_5}NRivBwu3L^ax|JyoaOX#SrIrDEak26%%^o&dP}dt>|gA06xD#Peu4h zXv)ZI7Z(!r9y)@5OKzIGe9pZV2O3(8v_XOgIu=J%F6{)3>vhli(njTgR##!_QES1p zTy=OtCA_FF{RY@d#?KpcW`4K_UL*p!-nIVY9`l-&Z1nqEzauhp_GV@9y``{J;wJaC z+O5=r_pL=8h*Zty`3k!BpcCd0Kp&i#gzJal5#4mVE^dnN0rcHOjd#spT>t$1n#owU zHgsDSVj`7BCL75xm_FF}&B?|{Vf>6ItlyH$ivX2E-7T2wP1p|CZAr-~zLiQsOtB#c z-YpMyf^GXAs1-GxA8|DfqyUdk4%apmcOHTxK6KPk6OORAO4o4{RWzAtA(O6-N|JxU z6EzQ2Czo!MI^MEA!FvrRT7Cr8mpu!rzxw2|oM+1&!T_?xiOE8H(~LW02%E6)6C-n9 zTo|km;*j498=gt%ei8W!w!y2iaiSCOA0R9B^S;v-eYF7q&cPv>mMJPV&&4Jka3!?On3oPL*e5`)IF z)bk>1jnBE2YQS2MN;h7rzxIrP2|w04{%S!gxKEvo5qcLkD^_&JvSM){Lu!MYKD;Xy z!Vd~DmA%88-ieuvEkdJdlgM)s#}}utKCw6Q{L~szA;ct)T3T|Mn>hBm;CoN;Q!iSK zPkoMr6V+JA?eTV_mCg`TwChE`D=jD8ov`TZXz@SxXDskueK(_oy!k!dEW*YKK!0%; z*3KTFR7HV$^WMK7qd&yPB%g%dexo_CBDIoW6vz5R-N5dO@#GGE3@f%x)-r@z7lEm4 z)Hl4Dgbs|6A#{u8VKK`oI*B)o2M?Iz|9inh4^Ctp)@f>Sx9y*Lc<2becl-UA_L`?m zR8BD4f{MwO@9;ChWcg|5{=56ZIQIyATOuzgF}mvEmh$<{^u5VjFfv%*=&ko-`VtfZ z0foauC#vEJTM&?`XZr&*25zpc(!w-Yd>1-&zqM(e#MJhKZXKMgSM7E(=;whMRc^TF zmaO!_`DNLnUzY&mV?9CKS2dUn z=(`{ON`&y|3B{<`qt9AEmqh{G@hFYl=MqEuRf*Yr(!xHt~8KO$-2l%61 z4K>MD_@TcxFr2R*zw$zj~&!Vwo992F81WgEW}8y_i{k zqtF=zr?+~hbngrn8WINBL8*pzinf24Gxx!wcSG!ZOTYTG_1XrsRncZ9zbGaa{BZJt z<$Bbuwy|2`PrCwI5?C|W_Jre4Ggj;2!rI%!GfH}ISa;>+{~Bpf_0oakJ}-mqXCrXa z2l=Can`f+Uf&Nq*e{aRwAfTXTJ9ea|?j$|XzW?`6`%+^Lu~!>#G88WIeWOscbAT5d z9I3|Yxwn1$iSvKjqGm=6#I$>z7+Qt9&Ru29C9M!WT6|V<@0aqBf8U=>gHlBpr&=!8i{l52#)n|Kh$?+$b6P;;ry$n1$6KX7nkfF=zM1G=;aWv8ceFseyUgW)_6bGOY6hp;V&0J% zx64vCYkS}hD}jewF}<$K2`W0AxU(>mbH%20g(bl1jGhblUF78=(%S(?eC6vbv-I9u z-R|n(--KB^Oh1K))cH#*w=oxCKUsdbUdmj14tRXnt;525=U1((;Qna&pZ3dfN+nLK zKCpeFU|%ycZ)RBCAbr(D0w|MqZms_jlz?xE85(|rn_vSW!<%9R{K<|$&Z;i;{GtB})Fr2&l z?cF+bc4(dYJOM3Q8(?NC`o$Kj-PLdd3zCkf&KmBbwaBZ5hzxj?`4+nwtHY`AA}597 zBY0;)rW^0@THF0S*9BpXZh-C3tNFNH-~04{<4btGcYe-jlpI_xAiq-J{Bw1SJ$VxC zgDqwDm+*B6ijh1KHAPYaXfdJGw^tNm%W{6tNdkQFi^E~^)j~RLaSMO6PfX-o#k)S|e1&~~Nd73zyzTv%LWxCCp2{gp8HF@RWa@JHV!)PJu(Pyr`lsai<3 z_&IKeOB3*-T3`@tdA%+#+&l=ac+RB^y`fE2oZwB2cvtJ%sj@HnLMj`$DFMpdJT0-2 z`Zj9ANJHjip(h9RIeN>c$QSm$A<%^Z6!X^3I0M6DERKmG_EmS%cJW51UBV)6nL6un-UDXqJ?7 zeNHl?IHHfN>&#YIYjv~=^#IB;ZwvpZ0KAalG3SaLf zE%mYgx;3}lFT>Y+jX(MpRQS@*Z^ra`_d(U~=4a$N!_6YBa9op76QlX&SsZE)xzY_c z?H~OdER#aE+#<*y}^Gk_LcTRQvf(fpviUd`1)RCSSa%Q?2}ja zp4j62DRE`<8OQuLKAju<_%+azT)p>}9l1*vk78jzs&N?a%@_Wj(+b45Z$K%AGEH5t zE#z{l1+I)3dmX_a3pJ4&H}cf0y>L?g(Pcu*yVXEitH@@q@lcr{+4Ylf=;RWp$&La` z%lV7_(nf58ZS%_-aN^LbAPq|2BmXcQd9Ki#jEDR)S(aaQ}JeEQBet9~~QAqU?({`H}PZhiYgoN65{@66ha3qzSsD zC0cZ+LltATYX$X|KK|UgbvXk!d=k`z*xTC#!Cwq3m&c)t#rFbhIi|)A$)w)3C9V2# zs{J;k`&lZ*?F4SqPl%yt7*mq2Lnf$;MFS=g5Hb^23FJuh*X8v)^F@x*O$P z6;^r9Hqg5?`qxk;`V{whX5$?qmGYtkENj4p~mbx?^Y@XUg5l%3%TbO#-_r z8Uypi@Iw5pO725m7G3vG%6}5LSLD7K-`fsSbl3al$b+(zzybtKkd6&>&+LNa6D&yk z=^>w;-Wr=B@2_*I@1iZnbB@KV90=&&DH?5J)ji)fsi;y7iWpJ3H{ zo!EmUbu`PQ!3n%7RA871T_@RAHm|k*bV#4hmr4$aN zZt7N44F51&nFp~8{S8=XleX~`Rl_|vC_q((@_AaumaIULN_OCWqV1lH$-{f2_VgG_ z?oUd7HCKi^k+eDFc#%7dlLSo6>p^b;Y>(J{+Il=7yhalq#~15IDOZPLktz~1&U;$9 zvqC(ysE1G3mw$2Tr;UbC-yXyf(|~bwVg5LPQVj!{aN5LIXK0x@u9`)-CVavAAT?oj z@x+fD-yhuHB6g|*3_jHtKX_;bI=6p>W$E6>dr%JAgzVVFvIT1xjQgf-#1lLy%(SUG z-3^rB*iowa$Mt}sAf?g^BzB^=LwB}+k{W?Mlfg>JFq z`#Mh5L7}t(QhNH|2U>IITKL|=XSD<2M%KVVK)XD(G|PFfa6ZER!v(k+xzzTQ;}>0` z0EHC&9_g?ScS%M7p6J6Glq+na-mm8=aBwCMFGE{z`E&@ZJPJH6JmaK_LaBE zVMf@BgWJleZ`WpOcIQNZyf)0s!WL{XQ*xN8r!BhiN1G7S_Mce`X@3Ca(Z*}M13yl! z1#kLbo18T0gFwJ&6M}KZZ*_emKoJ_Ci4L8q!1Z=@HKo5Aq6g2l$Ekc>0xTa&KEg*& zND5nPGqrLHcekyW)GTd7u0vhBMG`FGL1YO(q$Xz{!$ZEd?RmYz;Zd346HvjvFy#ip+#P}OzKAxoYZnFHRpoHM=e1!68FjMbCfwhOqar@PxDltJy2sB)}qkFCU z2DYOVC3=r(2gy^XiZhT5RAXcB6!|oREr&?40*zFA&7^#iVbj-~yUeqB zBk(|TR9G>x{&@Nbi=7&!SerGn+?kEKCJFBirH$}`dHF8_XeSP%AImXwY3k<2!8uOf z?AxGd#UdzJz{U2T>l3PiOuWCB{yK2UP4C@I{81o1<$z53;{0dNNhZ+KgmqXNm}3Y*}fGk6hh|4z5} zoY>ex5kNg-e$`SP>)|2L_zVP~d-_+P<;ATg`Tg-QU#%cQ)b^g}_tFksaAeU3?bHXH zoP&ns4>e}$8f=tFlyY-2&|BFg zQin%7kFtuNjRzu?izC(4smU@uwXQOI7dHRWZ!=b#SXY_FWnoQfY@(WWwmUUm)vm&n z3s58%wQH5eTkN?*`8CSr6yV-N`8uPFSOK?ABKYXdecC!42uAQSUq(VTLFS8y&>PV@1WS%tlv!h(FTNs zx}QF?8wPO1;tM=EGtw6%M77XX2d8KIxHwUi(T0?J0PDuJ$d8d$5?ftkey^En)co>B(cT77^r5{FP58i4s+ zqmvI;hB^gV>?$>lTD}EUttT=|lWZVqRMaq6DvjN*mdI6NHx{1y_fa7B!yb8kuCbit zhnq>s^6B#$Nq6Bw6A;X-@DUg@NkqF{6WbB`bA72Dbx)A5bBWd#J={LO?I7mbHUz$F z@fvrKwVQ5#?s+hPzKe7OQod)klkU*om|^+(nz~BwyWn^C@KYw~kmS_PNk5vm7PGID zH5|g@4fHuA0 z5H5y!;#DaA!UTDJbT*NJ93yWRRkpb%z}*paWloLdig3;nwUpab-84{jOMwsOW#<3z z%lGtU7_%?(SQ9`SPhk$8MYfys1+XXhGF3FjJocQ4;L#eCL$Mif?JNT{*%AheL00t- z7PSW{6`~_9DfMI;7ukvE$!&T_@l##UoDQRi<*`xOxw!8FRS~9~3j>|yLudYlKldPW zqh9bOx&}Ia?0i6svM`S39?DcBRfR?6xu4%15h9iEP%izX^h^6y2RZds{aPm_@N%I* zW`_6cpEveFZ&F582Q0SuUP9&;>m}4>Qbg~KHCdTNnZ?!SowgEM6F5rP8Io?ZqW6f@ z%rk}AQMqaNP=CQ{P|vx&!j%!^cbt#nY5n5bx19mb@5g%@=B=08tK-qtKCnB3aX;0~`2FA0`sW8?H9cT?wD3`w)Q9Xjn%!uL$5P~^ zA{hz^Oxb&xES*%^F4!|VD9nWPSL(pcd}31n5W2K9&T1omn~v}qOzeQ|;*U4svP-?D zknl+E9>h|$(s7$r0KXLW*mc9|Gv+w=(Y zS@|+c#4r_6`~oL$(C6t>fi;o2P?D7n1z24QQrGA5J>kP{p~J6}L4W&}2^r{Rf>+Sub?$aVY?gvz`s?93nNoW2L3Su@mC$ZMy>gSiC zLGewP2_~IWw_^v#O>oX$`WPpVx$DbRwXv!&G~?2M%6Xw*BRq5jz4wlq`7B_%1A@Eu zr^wC2iQmo@lDcpqOXLM4a$hUgg@npUV>1{v_^XD^jBjS>$Chhq+dlBvL8>9X_fS*F z!eP8zJmZ&!8L3jlM`{3F8UgOYP`#_CgiMUh-Pjz6vkb9=JJMVuXSj*2_vaOCIM`y> z4=JJ?&%lzUy^VMY`yk|I1ms%}*GzL+bBt$}U8Ip_ZTU?L*0OZ>swO-?JG zfZ-xu^_n0{p?0Ua1=qU_8s-O+A5CXHPZCzc8K$1r)p4qzW*?AKT(u7XlKU8M)ttKh zgauCv(S@TQJCABiJjNi6IutuuFw%Q@Vjz>cbu}PmABTgFAVp5*PuT$xAb|n0UFsA# zt|V`><;IN?gOW!g)gL#({KsI*F0Anli11Q4K4LbQ)bDq)OobDC?^dtYILJd@Ic;dpIkOol@43>-!q9NA~GSs%m0vFpcx zm%omcKRu*ye!_OE$%A+;u7&l#QztWNL%vz+YYQKxBgC|LR*#(C%O|kjSLk>(GRAww zS?=?@UOhluZnh1(ksEp~_TUtL@&s;lOdNCfDUYR9pBy^mwnE~OK1bbJIEkYwGCtT^CU>l9uUKKx5Zt?$k&)#H z_a#&g)PCTjPoCJ?zJW`ERqPrX15@6>9=&yQI-aWv5=(m|D9bU)#X$O&xie`^$cQnpjr=cM?y-ff0Y`eBFd!Jo3?cH zkR2?bSQ{iq7f?G7X~ELbLQB$=m2@T*-UCp&oQK>Z17bXr1=@7HD{kT$x82-Zo*c&C z2uNekJXUv+#{a@(Mw}CR5l3Deh0b0`HL+RJq!wfuK5n9+H%mMqu&=r1>hy~tZKnR$ zsCkl7m@xzM+wTfm*#_b~7|FLZ%%pDUyLYS})hY$6ir>2DS)b~2zvVCjW}JD0oy#k8 zh<~5@AYE(zYjORf2JMGJ$wx1TR4DEO-}p>m$aV`VE6kvpgmA3OY)m(!vs(rUHkQy^ z!OxC2?^&=Dm^%5W+>;u@K)BW|ZH}WC zg}8~8w7Z`54Id2Lpg|(Pclj9#{LIN8IkQ7@{`qj2cP}x>)aM1Jh780@nj3*0#5;fr zBqOTl-s&u{TMoI3${E435V}G>NP(|7Krvp2OFv=oLo$Q9;!rH>`v>^> z4r9Fy8Zo>~rGn2|AbL>;7KuUOa_y)oAz%g5%Pc*vMH#Qa-I*{%QlNRSaI&F)JiQa%`*BD%8c4FwKt#dzB$E< z>*gp|qaoZEZgXi{(`crGk1?SvyObS_x(r=hZ6jt~JJ;RN8%~hE0IWJ}XF2aI#iw~P zZw#Gv?Riiki?>C>{7SJC%GLSWiwPTlKWXp)IcB!)T|=)Zj7-6UFutdkUVJ*)iGds! zZ`-P%mIt&h-4fVp`o$>rrYDQ~$Dt;7hwEb?x5&F#hSeWJ76wQ%c_ZVWs_n`4wXa+b zB~WsDYU-AZG`basqC^R_-S-@4BaBJGr%uH zOjYp{a4As+gi57_1+p+e9;?Z$ivyeYbYWpWY|t`soDDUO1RLH;17Ba?^46LQ1Y>l+z-M_{q zYk{jzqzOG!ZuU7<#1RxaVJ^O{WKV+Gg`i{jy_J8p(@v?O7Ul4;Aw93^ z8RvSG?eMcLwL&3TT}V#y*1YpaQ_MRV6W*7J{GkX@?IxyxS*wljp}o$h<$&$<)97qgH3% z9~{t#WxRg9cMh0vMq>XvW6ExhvuCnMgWX<(;Kg?TozH)7KVi!SPvWMb$mgpnJuVEo zFFPcs;{CJyIxsNO=evKm7|JO6yrT}~ku7p3CFPaeq9a^`2*P&1pap>9o(W9qF`4rj zP3E;I+x<7|)_W(+>n>79sIK%5LWKM`H&OH-c$)3&qz)9Sc7G1kJ1#diq(ONg^k0A) z^}%p;b3RY!Y5snca?;GE!E%#d0R%j1{@Y#Stoab6pnL&UHe%sNPA|AbIGgO@uK4@q4x@XYVi0@9+m2hGjLs(BVneG45p%Xa{+@q> z5Lx#VNDwTFDjfG7p>J7E735vTuIzAmC2a$S?K_iW@x)4Rcb#JRCF}J3Mv_97E*&M|^3&h2w>SN(8Aoo2nVdWV-j8x$GYienoGbk@`(KtZ(W?oD^i%kM_-1fvrALIE^ zoX&Abohg!Hl|%wu=qYR$;8oEkXSq4(sDe)SX_$;}+xk>J$bH?|Px!V&J)_q+>p^OS zT}Mz0Gl>E@w>Yc0h$Xb5kN0<6Tt;F*sn`h{#v{MY5ViRW-tX{Pg@j(EuCzbINOw^EgH>~r`RGQRDxG(= zWFX3$qHq?tf|mG2USR1+Xa~m^GVCoeTqjm5+fr= z3m^Y=Np9i=B!dDVHN=K(g>Lovk$p{};1O~vN$cyzEa*B;+G`K;ThQhCmZR(Qe6ShA z?JXl@hG_i*ILOAFwHNb2GMYGQv&7d9-GiC(PvSexIGaYj-D^ZZIL<9iP4aKG-QBc) zefhT+aO1%Se`w#oKt8M@JEA{#>oIzf2^mN_yTOlTw^JzH1_Y2nWa!OU*F=B<_=PkZ;GO(+Jt$GTR3!lpD{FL=OPGy|Gy{E`tMrVEFl!b^6)_DU58M^C#B)TJM56L zYX+1RFZbw2W9kY)U8GC`v$O&qa8MBV5V1DdJDxlZ%?&N*?r$|G#C(^<$ z3os6=)VaQAMbKd<$WK)9Fz>Y>SA&je z9ofo4bJVz08zr;p@P|GhY-e=7Y~?v2B5&Z&r;_tf%!M)K@os~vb1>+RM6EG(3xLm~9?N!de(WEJz_n0g(ZHCN)Kx6OH0 z{WO)BdMJQOqT(0>_86a6vy5^oh3rO^aZnl%xQW2KCY~S%A20lZ z0XDxL(sk$`S~`l>w7_RK4{0qJ%ANT8VPbSOs3jxZef0ncIf{faaqy7wFB3;L4uFC; zim}-kfbHXG2(SI^9sMOvQ<1NIk|+|qXD%ZKr&A>mKmU^`L7^(Xka<+^-!vm)=Am4& z?#mU`RyH>&d7)wUlq*tZHI3_%0qv{$5U$<3$>m#WQ2hnV5IIuDV5CxzL76uJj3W+> z)q%ZF9GzV+|241`Ke(blx!1i_WXhy^ed^1x4(-`D$BzGPdR5m#C%-zopwlS~{!dEi zHOikaBk4lhG-wp{7$YN}9RABOH|!Oarc18g@zTQHWW!wAYiB4PXeMj-nYTP;6FnU{ zv%I^ju0POA<$G_UXfS?jN6ocAqs7Tfs(X3UGeh89k;Ehj%$u9oxTGOuLD1w%GjC>n z?kB)Uk-OBU?c$WnfY&czJ;K|Yx@IGt^}TcZp3FH7s%fstTR2>YOEHuJKp?a5hV+&h zq+OE39;ZZZRc{^l0eIID`UCsFDT>N}w#a7AE$?ah{adLEkXTT*_mmk|tw7-?k-DS4 zq~Bkh>%NF7Wfh$4t5^n$mM1kTGvVp>7wpAsEYE2H(HNRGq?^vP)n=*DCBOcC5)Bxx?{PNQ-vgK6hQ^?M#n8I9(hv(1|JrZX{}+||r9CYQ=KHSG zyWvUN%U}FFLs`^W3qx3?vrUsHzaisljO)~M*-;2f+v2(#2mh!Qwj7+vuDgxK5||39 z*m+e`S!Mzz)dg@PlGP6Ia(nVkiIX-OW6@y*-3Nj!S&Lr-`-&4${+_R2qj>8UCSrF& zMj5z?s%^(7b(+$E{EUiVr9IAHaLV5EDqV6&jH;yd6^F#b_~#N|*?FtOIQvVDCZ6+1 zpF|HO(R7gRor%Xu6|B1e#~c+Qo+doMo+YQ~gSPH{v{{=a;F8E0_iKJf{vzR(Xe5Qd z-PCiQO!`q=hm!wRz$Dz^U^Ck~5-d{>pqcsUsz)95udkvK0iBh-RqE6ooB%bh1eUri z0sHO)r{L<|Z*LrD7THZa$IVw%6b9F`6fm00TrLXj7ilgU4!{{C8dNJiWVi4_Or zi{$vO+%Gq^Q6ypDi=_G;Jnn6_bx{$O2w^?DjblUeG6qS)rh9HL2l~!K)eaD+l^K5T zdIxPw!`s?;IJ)Yh&rPL%0G{#vSrUi4x9Z|~Zlbnn>e)9w#PV_=kpp#_WZwKSzz_P+ zh}GE`e(VskK#IP5xG>g{%U)VT zs`IR1uV0p%H&*9^7CmOa`V-Zz!#r9iH0rTJ=lvBjeiG&EgBH_-B^N;aOx4ttQmk!I zKyvvyR%HF$} zNuAFyN=GPz{GPJUc`h1@$X4bcL#^=-NnZmc7oz4#$TGB>I}Nd*UxX6Gu7?j5{K}Ds z5?$2PIb)^p<^*PFiqJupjLD=@Q>9g|+M9DXl#mhOI?n zm|a!4KBn#9H%;+!H9BJZ3Ap}y>HR$|Toq)jHWjcL2JJ)3C%NGku|EAw!zG#KFiwSQ zrRS8>&F|3sx!$&_Yj*DxMjvq)hCX?Ve)8KeBIdjHQ@^DH{NOwjn~*IhtP=m0sujwv z@bVFLO-|?yUT&h4ua}JO?!(<(sINky#uW;k++?6nT5^coM^=w{;h|Yd_TPE?S|{Z4 zRO2Ht-r&K4W7?yhe;Is$jHmvRRL)ph$dWnOnL*iF@~EUf^VA72j&%KvF9Y=UL3HpB zQtdI^BeNwPRMBd8oJj6cKw;)0V@menzXreCS@y62@%gP(FMM5UlBvip1Y39 ziT;`58yBxj3$t5GrpU!{Z+wGyWY~c`$@`heyr+xe##wHnaH^c3L9ywlNn;JvY%Ti~ zzVCYHm*}sqj802387zDz@Ra1F$kAZ-7YY!I_nO_r+K4)sr(*ZDzOm6@Le1WDocW!G zsfh+pbDb1bXOgrNdl(s6&ThbK#<4r;NQa0HndYSO1gEwGrwGnKhv==2)YNQ(ZVYQ@ zlEd`r4Y#M#k+;>+H`Y2L{Xzj+Pju85XY_v_Me^W*AqUJ@1tM{zHoqxNN^|26ih&}5 z{Q6>C`{0&=rpWJp>pU=vW6d%}vNXg2u+%);s*V~pKW1Y^d|*PvE%DZDD7-;Ijjr{y z;b)#n!H@9stqY~%-f}d=Smb*3+@fyTN^o()yJdEt?2w+vsBOL1*Ge@*M%G|nDQ&aH z^8?PIhw;VmtsSf#mw&fR_<4h++AB76$FwgOAm73>J0nI1=?y_}S3vX3N}7K^s)(8e zj!k1qR*LV0Y^6IlxRQQJTb^z{Sj){Y-KP_CvWkya?}Xt%0*tt&FdzEAABDomt&$t=IQC z60%c%utQeWCgQ|&sXQ|6vgn2+=hDwT_2OPG)GHwlVixwvE{b$U=V7mlxO};=uzBC% z4$=YMJQapjOD0NqN|Ld@PfHSJNd=58fq7<7BG)T~sp1aA^$vIMEe9DYq01AfJF1T~ z$;~_>D~CbJbM7Y`z_E)E^d8@M^7wMoj3a6SV8;k2@{SSG2K57c-Gi4tjoBauH5_?j zMtaN;DnU6z%F#(~FPsQ8XT<61y;SOkxoD5!(bN^+ULkhdUm6Gsx~Z+;i*l zkL4`Cf@^fifu>wKtSvE7=86=J`{0%|uxAPGNlysIS<~gTN=X^xN{omfugLCnYW!~V zycQ0F=Eikv`3Bw(87l6;XUyiAWX6J~1TaY?6GFR!1jKi|5&z+O-g-Ce^_pxLD6_1D zUw@byVZC zpZx8tnw4uc(KC;D3;qVI$h@7ZwLuMd1K4w?|0vK9A57vd4f=#T;4BFO_^O4 zZsPg2xu;EYaap^XjOG-L&(6~kxU7&>X&(fs(%yA<;}5`LLhWh4M=z(wsOdbqpSIBv zFn<9B^t$H{RikonQDcBeA-u>@QsX54olrQ&LQuv%YT~?3j9W zrlvN^!5!#>FbR1XMVyn+`2fF~DneB4V%JZVLnX@ljf79+5V)ojJFkb!$N;hwZV|cO zUiW1X=&i*0M1g?R%7hwY+{ve)*Lm{BoUfpGz*PFE0yBXYgo z!U$v+mKeE-pgX@2(j@M!vVT|sUah>c&}ExTm}B5q3;heNKkxlkn}ItjEKleaIiArd zfo`)MgeZjvJJCsbTg@j$-vPNBebIA1D83FM?X0}y;`mYSVhTKE5PE2@tQgV9CW3FZ zig7jju;_e}zy-;9HfLkaLrqFr#-(6XTFq`%`VHZ1uaE`OlQ;h(GGD%O=q!a$NZUA< zp7Sal1sj&earjeTpV-0#(uzSn{KcCBCnP!pbp}+$or0Mar8qyiqQ4Nv0)3NTiJj%S zz5)W**Jyg%TY=WSi&SV5;*F)YZW<2?A@1-(_?hPEfn&JAOjvAbtFa|Bz@|#!JL$*aMVp`)K`qYq)}8gYvo&KeHHZamDhon& z4#aBWk!-*EVl-BbZIYj}*)>l$6+;cOGmO;FHw1u@5?GtX3aKpPZ(KRQy* z>H64@B z{oOp)HnwPnKOxtvG-EZ&_%TIQ1YOaW_7<{#tc0k~|6`z73bU(7m+TwU-sdYKxo`Egu-Jem>2OCYmXY13UmP>?S`jZf7HU%pzF-tu^nq^q!p8vXSZ}Q{kZM&wPRe`! zMQV>70!Y04ZJ+Avv>IHQw~hzC=%sEFtPl@j$p1`eYrMI;X10u>qLXB0#X#d1eIVB%Pq zc+Nqa!Nnp!fFI56Lqd#K?)hZa^uZ(41I$0P$Y_<~o9=g660kx1i z%(W$&-{iv}>bNLWV&sWmg?#e6KyRc^@h_PDbBK#O52Mm2FF)*(7V@POL_V^M?z~10 zKk5mg_KJZoFm0N5@%%BLjjlM{q8TQ^xQ4W>6Z$|DkekTZHWw*dGx&}QF6WLuG36yH zUjiYxZ_G$Qy+ zL;E6Fe=G_lpMXOvJ8{T%*6|%S1r9YV=n+q20)s3EzQ3nhn1#5?=e}!0vjYZt<`R#s zPRK#mW4PK$SnAXIAJqkT~O{px( z;m%v?j%)t6E*H6NK~Z}dbR}Caf0qC2)+;VUB24W|$H!(?R;4iHh_P_+^);_@cC=3d zb*O-R$zLK-AhWU#x-WlWFxA!eT(Z4~k!0GjL7~C&^&^OHuGmZSzr}&x3L~)8+6~se zA$1?1*w!Q8uv&W89Z2VpKr^ggOnIs%>HHdbtqb$%?7z0Q{0iV?^^_USD$rk0s&`=6 z5N1-~x%^n5InWXI8G0=lF`s|Wps1nV$*5puImI=wP%Q|+;Y6^#Q3hcm zCqE4wy;kaT3VE@f9-LG2HbSXga7=i~qFxr-wvv{oyhmh01e(olT$h6&#wEfd43p#h z(@fwF!n}1;E9sET7#)0|pz9$uCMXQUl)43Z+rti^ht}hdL&0iWeeUF{rUk#nsZD8a`-O9{oQKxK2lBiSPHmpqGTgey zHS);jjxJTAQc984%0O|D7UeVuvd4h9Mbf<#MHYDE5n6um+&1--U zISrX@A;BWI&GLzu?Qr@Ie9-!juLEAJNE|}AKmTEu+XK_)2XAB9o^LJy(je+;G>*xU z^wK#y5ixfGw|V+Fq}|QfI0f18QE}05a`NCBd8~+MPl!KJ=(2fG3=eY7Z%u>xhFm>l zwju6)+`b)S9m9r{BEub`5=9t8Hnc}5yr-Bmaw0Z9Z<*Ak;SnJ=+cq!cRj#N=lnhtA zp9h&&05s#HX^-z|s*(o77u?sS6YThG28) zrlZ?_qC^_z%6A<{n|vz>w_yO9m@Xh;+6Zbj|8$*C-YW~yd{o0)45mshM zp+D{E7Ap|LNJ!Dthii_#sBYHZ1ey{=AslCDfmJZRZp=;e#MP`L(M=qaItP^)^Vm|# ztUwbQckKbxK_f?`Q9 zA>mzbD}Tc#$91e>Cd_*B*2T{&yAZdTTqIsQ^()_E??K`Mh4;|? zFQ#`5jA3Q10RZk5-NmrtDJowiPnZ0V3}ofKe?m}|4t*HpNRs5#k3ed*JHGM*atEnbcv1JoTo)>A z5#3bY!G<*sr){lE`1@dgzERymdjn{@cc4F^HaYQ{47;Mlx}S;cPIYVeqrsOCUV=@p z4od7V5wFp*3^?wQa5eVaL|2^1lI-i9OfQWC@PH}HQ7W%!jd~!s`-=!9O~fKQvDj;v zLgSBH);9yIpCL7pP=G%u;szlmNYMbccA-7_{Bu9R#1;)iicH+`G*im(QZINI7A}L* z=zI9@W$vH&%Autq#5OfWyWH`CY+w-M4Oo>7_xaxtCr*NG&=w*)UeNx%rwl?b?aM5^ z_C_+vU%}+|y6t>Ab_CMJiw6CoXSbv{#a_aQ6fQS?eC{`irASor5tYhueSz4XdR$i4 zO|A5aB|p&wn$Yw5CGHL9)k2>#8smK#FP4~etI1Sef=R25rDl3w55=Y`?qUGfmL2$f)JP`AFkV|b7 zd+_uyLh^5=SZ!uw3uNBA0Us!1ACE+l0eRL#o0nC^Ub48!B31h!IAh-s1chf}P`cjR zKd#wl$buaN8o15>2V-@7TfhBcPXeTH|0mrgFmb65_I(SVVkb$(M)5Ll}#!=50glcqq$p*@UD@LffIW zTjY%`6rs!e3fm*A?F1G?)|ls?XWWGUiO74Q2tF2fiEBUoru9L`W{HmWepEM!%#pWB zD8}spv{eePHKWwTsBWkpE=PIt(X0Jfo(sL31maJjBd@gdT==yqdx0F>TRHV%OD)*% zDBR#YJJhEOEsP-kn+*WaQZu)0$Le@gqK6eqYl@H7awY`;*r_vabR84)DufC^4 z)5B7yON!qJ;7%hamxWm6^D{fHGQCi`XH%z?8g9r-l>@r9IS(Z>e?W_P$Q$tLDL$B8 z|J**0zyK&$F&5vpPW0kQL~i5{e#K1LJGQJt8KIXpKe+NP6uL(fUH2C5z4uT?Y<8HW zi+p_Sco+=%m~c^)NCRpX?9bt2XDsNm0Dbgpq9Yk*I8OfkGu5=m_O8fS!a{Oct$o8T z%}><`Du#`3fASZ5V`QN*C-0pgl_ON8&Rum}0&i$>eFI3hEt8~Nde z5F~|xN$ta6QYiKr4$FC_Uu*{@BV-PF)xK{$g)kXV+5$b^rU#3Ca+xmVGfZ8OU-f$M zeVW-W3f}wKnyLQ)sf9br46CIAm|fTj?gZrUdnAA55 zt+z>IM)Lz?EA+i~G)n?ei1l}NOf$E9NdcETQ+y}=%LQPcsBDDpU#hgcy|2H2{L@GS ziM&2Jf100n@Sj0m%^n|JkqxC}*=DZOnL(;`?{%Pf6ahQ$pFzM*6l4CO-)s3SS~DtW zJB5S1z0Ya&nk-BRJrD=?bcjI@q{U08h-Ux5QU!j9p#=E}T}zTaj6DO)kwm`+zz2V6 zQkp^pVp?}J`h%Jx8vHW|C>7;idm#If5y7mkW2eIhk$YkyPW*z#PEyI#%={o% zK(a9yehF~R$C-J7p# zZ{S+8Kr}ZL3Ue`Jtw_kpk|w@X?S*Q(Ln(Lxb2o#H`>@H?iV*NUTt?$IKEL*1lU#Ty zo;KJGthc@zxC#$I%^H25i|gYW5ddlrdn`*Q&B@`~i^Ol}3*{bzGC{6@6MYKh>@UyE z1@#x$lJo-rz8de^K-=LD^4{Kk`jcPWM~hbU61>%jK)z zKyHc+IK;WApd#JhFixGj9z#=IB&@ z8A)XG-u@Sl@`W&m@x7O!sP}2v7^wT4&DO7BTOmhA1ZSZxpZYImH_5m@vsGuRN_*)g zgb?og?cTkH#{zZOj2j>tB~ZGdqdJ&Genj&b8r3~B8A~8Oc6GvmBrD5u{_(e3ihaIH zQH4U7?VO@bc|e-3DQgq?ZXn12 z^S<82u(~tPwkQri6(?j-4-^d{6J7h}f-`7MFIw zO1!-~*+i)G&&_z8wl4uO$=-|U+5n2Wt};w5oO5(xce+Mie4jnH$Y2z}l_=tAdNt2q zZ~P*FWF3a_w!7C5WT;IU2h!pa*V06We00Y=Vfp0<+*C`nxChsx6ffsFl9Uy})JM7ByotT(z;H-Ba~Io*VuCpM{Y>UQ<_(J>2c`_h{oEPwQ9MTypd4B8S+{Aki9PiBpaj*|Z!g^}Y zS<07QeWb7f+n<@o`$+9NWLTkd8QlVI??PCQ%Rmp~PpAhrDr2o83)b zi}PFe0yPm3&vKgo?ZZS_21#d6S}r{f&+GMz&d6kHl1z`CFSt&gOtVH9i0435U+C-h z-e3F=G_~Fg--UflG)EW%eLwxRWE1`eTN1=r4fEDHHBO5hxzgi3_G4dQ!#%=0@JNTM zr#{3=$76Ox;0?3Z_`2^Q{3H~?Z(scM?Qo0~gaCYrjytLR?b6BAo?wmZ$DSqaPEYmM z=EDNny1H`n4s^N%H!T7#F4bHpTpr15->MPBoViD^f$ef=y26az$q8w*0D3+-_Opdv zkX(m57BbJYNX>p>vjbo;$B=!nWM<`3MLvYNHuhB?NU!Y$krlYL1G%W7Fy#8-q3GL= z{VV9j>&V;C%1EbjRs(PV>SJE3xRY#~^%pV5zw(jX-m(t{@@OjNg_xVJMd>~B~ z3M461_WgSezxB~};MPC>k9xJPqt8?!atGlkn8vx|j7Q_fDdrX<{f=)|20UW(?9OhFVnp4;e2CzhMnDwJ<)>^7h^#0nvr2ViV*R z*NN1~u6hMTT=N6l;-j-dLn+jrk11k%`&^bXmK`eLgN?`S3E7Xn%W?>pLO4LEip%+{ z2bGWlNU}3&Hq3SNO{e}!P;E-zo((SjYx0+lmii~Q#WQ$1 z|LM~V)2U=w8@WP7Zj-^2%;lhX$0zGV3T#mIxQVO{!lX5FEQm>ULA0lEhA!ih#bt(c z(~SgG{y?j~t}so=NWqygnRzYn(D_~VQ^Nf?dOku``V;M)un?IX@@lFz3qn4Ne;uj+U&I-01*f0zwW-v^3G)qgnk3o^s zox=aa%7W^y*A4E{9M}OU5kEKCrwxg|Tc?t_U>=v-!@A`v?VxgBYImdhn@cS+9@{ZN z#t-m5?!&9v!OvL(CCh1SFFqygyNbAvl*ke%XbeQ9q`Gz@6stt!4$;q$FI=yRY4?I( zV$@EV))%+kH5p;MU4IJi1 z{~vcRfi1+x89}EMkX3u3_*wp(gvj`|9*nC@Fw=Z@f&8fsOjoc^bzDocOIu_+@Mc6L za1t&?IT+g$*GkcgJ}~dnb))y=r1*|!6tN?LmOXCT{_C=!>R=evZ4Q(lxVWM}1%srs zLDPjF%&#W64$pp~72Ast_Wr^E_Xj?|{>1ky3I%B(htM@Ss=qw8Ur>LGhNRzo^yx@#Fd*sX^vj^W#qs z4pAX;z2%B)c8_fUGMb#{S&2&bF{wbX128{1#`;8DFR5DA-xQzJcqBKg-%L=CmFu0} zLEcs6*=ZrbXTKw_hv=ouaBeWn{v&9shTXmLK8)uHBK7T`vlb@a(twtRXl*7_x_kRK zH1dPLUbW7Zv0S8M0gUyX&%O5FCl%FGPg5k`-st1>__FP`>?~hN-$}qU$t38gF|4X8 zArEPd(}r|g-Pw_EfBOPD5-!B<|ry=#xOc%QO8n zuf{c!4{x^Ab7*_ARF+2Z9zKaTZ7z0K4NbZOpCP`viD!rm{^PeAn%v%_7rD8Kt;Q1L zX#kx|-=iPHgarF21;JwCOhsFSAxkWa<=8L#bt`;)e0`T-q)`3fse^GH?Bx*j< znjiAMt4IO{>Mg@SGpJ#LDc~m`2ZpVVEj9eU=s zuEb5eNgCR}@&(4z#aLN<%V$Sjj(P4zEH+Tb7VTJ2db|I{OUao(D@vNdIYVt>v0jaVJ)9>73a>lmgS=b~*pZygT_hBKO= zW@7aca#BrzX#?bkfM16Lr%MpQR}6p5^Bg%Eu}F9ZWE=1MjEO>IdDH)SE|sMC6Y}*f zl@%mTm5@33B_Yuwry7BJPyi>k+huGI&+WsG)4}WW84~?bK!(-`_Ux9DD-&#sproga zOVXXvg^5%m5tc8ep&~Q01jfkPc-^zv0PLuO8&E>FKNcgm#soUK{%UJBxX)tc+ ziLR0DbRRZ61?-50ZxOHzkz1zU_lUY)myrNq?*Y)V(!(FBg25UGSogRY$drIWf@brB z&duE_Lo&8Ol(HuItQ_YWX#ywa?d-bT?0s_TG{;X>`4e&OQyVExwk|TBP!Su)w(;#X zm6!Aptceiv6!SBaf}fqb_ny~E^V5X#dS$tv-CO8&*y3n^q&m##C^nj&3xwGVao1Af zrW8A${#kud(0Mq`^M;HB7H)}e6+Nq;L=_9B+s8VXv)qZ^Kvv)Xh*_xQOuaWNlCLn< zP)Qx8lhIpbk;Ui;it<)gmVJ2{a+hs>>ps0Z+gqNW3ms75?^w*jk0$g*C@DzksqL)3 zob(||qjfIeRZecHq5Gf-P99F|3EHWt%X7MAV=tMJTM!)VwZ^$%zc-+a!!3|v;Qf{X zAw^nQbZ+IxpTL#tgND%OaqMlInjpmo`dtS5|G#J!!N$3JCR`%K zAr}hIx_W@jvz^0`1Jn+yNd&3lM9;vw7`TjZ8px|}VOE(jcGnke7mVy@q#&Qc$3)0> zKM)`ASS{yHa!rJ~dgjI4>bKR&eM7Y*%(@Y?i~EZr9Un9==y+^d&r6{ z8l{osFXaTDrf{%AxUw4K=JGO*X%tl{7_GercZYumlO1`5LzesUPLftimZWDm1Gl+s zf)4N!Rh7QnaiA4*;G4WTJ}t~6p+0qrBdeJlcmNn@I`x|ta~A^U1XGzogwGP*h!eOv z(Xr4)5|OP0kPhRuigy_7BfGU>TU^dm!3=Z@hRX5GUL+zlG0JdzBJN;HX6to*89*;e znuFZ1_4d*jBu>fBbJ&(;uw>K;n`rg-D1k|`SF}Ua4T;F#JSrSvbevF5WgKLNEwA&~ zC=Qvq{8uuQmAM>}1|&Bv9j6xzji4dxaQ8p1EXJ!etoYfV5h;+YbF}5j!m)~r&&Vj& zVT1^oJ@*g!Zst&ZsHSeI^;Cxd`K(hBVz0UPN;2fD3Y+?en~BpwO7kA~%9w!(c_w=< zFb5El9+2R$()q43K`GZ(G+>pRZjz>Nf93B> zlWPOgmi(CTI}`TJ^AhoUbgv_a=AFEcJhCZ+_*OA0%-_D4L0O1OO!Gs&&w3N?ZXuKU z6|A)9l#%gcvVT|3b@M5m0-<8qZT*+@ifHA$RcJqGydtE0nrIk``o8kx?f00GJ3>VJ z`b(2ac^`F`w6NqUGFr^MpX_3BJB?|%NtJrWXYzS(0Dajf&o8I=BMzt%FLR5naTa}X zWjwm`UMcARRrRESP_9vrNVl8Pgk-7tE=9-^*%`WxT*PE8dnJ3a?*?txAY4V329qUQ zxMaz$4G{)evM0+}$1wKoduHaH?)SZa&-?7>Is0=?0ge2^UUyrza_OcT~x>w`Z z#{O*YTY0AlNnU+N7lVyaRUj}Y)73XsYVJ9Wx=0OA^;X@F!q#f5pDQr0@brsiy9NSW zpWj#MTU;(zyl(8@cABI>!c%2#P^`Lc@T_e z(t5#kO&WPm)@_>qj)-XnDMIpuv)^HKF~oz~QXqH3wPX$iY2zLWm&IbV#4ZvWNV-`$ zfuIH%!0_LP$k8juUULFPO>`!%kn9D{ZI*?K$60Rf`K);aQCIOiz+ysfR!lfAF@MajjV3d3ks0y5d{DC@LaeVpigK z?d!H73nw#C@r}E@CXl>Opm8>nx3-hx^}344d=?{ggrD>J*phPGEdd@v((#18xiXwh znEmgfGu0_&%R)4H-N9J6ZlhQ?whKIo2{33kFUlpQWUz32?*H;w!Da_13oi!IT;mAj zc=BL^74E*_cIV)SgoV^#eVZZ(DZA-ft;SEuW+iP@}1 zI?)@C+Qhhlr;xf?#snFuAbZrC8wW(~RSc}k9X~(Q7g4a%1Kw}msA%!qDq*5Z$ID9T zVnE(F0oRx_yD2GGa5Km;bHe&8 zb!IuZkq19U+u$U_19|5(f2ldqa(rI(519<(K(yJ`B-P z1PEyyH#$13=9PPlA4mmFYv$-&f(1rqU(9n0>>ACQ3kl9z4>m4^I)-R1_wli zv*OANMvAKqe~*5`l#$OHsYtcxG!=WfM8{G+o92TSY{OPX+ z1@RATZmUn{ya~RwKL3{^2m;blmMb))B+wC30tiv_gR#`W{Bsz);fAGF+c5_of}*JB zu^uD`JoxQ{+0FZ#s2~g4-5qEfsyC|9l_?x^Gps#B@%<033T}eRU>u4fpzKyjNX$@ZUQ> z1if) zl{bI?aVIr_DP{VbvcgU>C;2j%LZd)7J7qPC77qd2@C|EfD(rxV6tNiT24L13n&Xw0 zg4l>E`K@!SX6?lvJrBft%}p6cuC-7HfT=mo1qM&4YtJ}=+Ze&g7r5=4_L`+5>&k)D zHlC=rAoI;d9UoaQaIoW(x#!B)de5i6E^?_MBhyOh7A9;L-lEJi}=Q~X>t^5l_ z!m-da5^xu5;zsHmKc}mmd>HZ*G=33TDo($1z=jctt0>s-%E3HE$ly8P@Y+X$^=GJQ zK%zzR(sr(ip(1Il?U>0nH0GPAN_&EAkAytZ;KRl%EeGP86pXOA1)! z&~6nB2I?-FP6d5=VXRXpsuAdMpjJ1kr_uE&UGf9bi^j1ARTZv%g~vn&C`|w0cfHuz z#3OM?nqvu!zmv)7-uYe=U1bu!c30h127{^mE4DmvfqozWL8R|57RJ;Vg|FG5Tx1SS zvs?4QxoOT+(6~e3bGU|}>xuN!)&T>J1AAfUBCem?0!>;@^gV0v6cZRJzdbp={|04V zJ5?HK#yfgXh3c&V=pbl#b*N|kv!zVD1A>(z*9mBvBkBz(qDT9p`}2>rD{Nln83+Rl zXU447S{~xH5rn(fLFeIS)M#-3!q7XX??{onj>8l=H#~o}1mm#XE>wBs4f81~$bm|WvsPf6)qp851=3?GHpzyk=N4)aOy?xqD%TuGR{*$LNTjtu1+E7*@+%I z^`d`A_I~(I;YR432)vl7=#ETsk7Vna5+4$CT4k=b?@%-vl@{u<5p5AtWP|p!>fl?%bJ|8ROd!&C5fSW~ z36d1imza3Tvq{k9pH~6TSbE6CTZ{f-d}W#-V=CixCbUKNmm9fs_99R8{9p-q@>E`l zO1kKcuZ82fhcVVevWDTaQurIF^#(!-|0eBWH29$*PI0^8>vN>g74K67F?^9Ew@4Q# zs{`F*nBi<=*=nb!Z4N7Qz`=PnS4uMW9nH`MnkIV4I7NBnv-SLQ*1^Sj8-c7fc}j}p z7iP5WK3C9R>e0EYR4OM-Ft-qIl;`cBW87t{66x2r89W$+dMj%$s93tLs31z!$RPI~`)u^h=j z7{av(qlpC|=g5kfQ4Yr8SKkznkTRM<7SLWgD7Chq@30cT;w+7?z*CV0E=(uwFqrQ7 z?7>3Bsetg~1x=wNcd8DBjmCNg(B8F!i4jVtqNlyW*b0QT2udbu{|2t%u9Uf=K8Zn8 zHPkL4Pyut^H4Un`ibvg@NUQv)j_VO`kg2NG8QIhG(q-)#t zbpKO?m!Af<7G(rK3p2K}{9?WH{wph<}d?cerZ35xSU-^FiS{*gPjXfi?ROE6#3u%@Qbc;IJv%_f z5iA4zRv~Ntf@{LHTNmvJkTjonER--PV+Ne%lFv345D@2rYOKEs`5_ z?srC{rN(%dWpwSb(C}qL%yEFlx%5W0Y z%Ic6?zn^~nHxuS}FZQQ(NR8ka#-#Lq@{tSI@8{bBFaMrN?)=Y=7bl4!pO8Q(QmU|cJ&oEQHsn)-UhW-Q9~;8`q}E=gexV{Ix7vpW%y@*NnJ^E%daIB?f@a`i;-6`z@=`kRvdBP0q~gy z|Bs01X0;4PTT25`s%S?%tj&*L-f|}{jAG1MX6zV~a`dsw5F9=Gk$e%42;(n{QXDs8 zfM#A8Sk>2sbZBVvD>H9hoLxXvo;9eUJrx1d!fScOiMT|9_ZUr$p}}lhJ`1zw4M)zv zHRjStW4^JRZ(k^8Y2bp42V-^;@_VyTxd;K0u6%;=U`TH=9k z3NgmEixbonH(c=4=2vCj>eT+}tNDrl4|>O;cJTtpei^Bqx7z#wll6&QHt5=`$~y|sCB zY9!@~{bBdJY(&kms+5n@sEAd@4HCEWDdgg_Rgh+-2olbBslqQ_ftU?`a$=`2^?hu` zVe-y1mX3nJTYkn7;HenBTf&FELIsNp{ce*VnzH{n(+PN$_r}RL&l_Z+=r{)t4<#w&$AIb?qK#)BL$}O8TU&xJ^y@UprF0l?6&DC zLfU0OG(1EXqp-&qL<9Ku|4x0-DfSrD$EMi-yFc`!M-ikapmz?7f6kDw)!IV$F7@q= z^y%rw-iH(uSWZqiJNM+Y?S>;OB|GVRPuWEQJ%;$5lgIDBTDA8Fsb%*PfD)+)q6zX~ z(tEz{uAx0MQfFDMlZ3dk4#;DiFYW1}T`m0kSXBK6P^~_dA``Bq1H7L-E6tajw*hWThyLS3yp(|EL+LjXK*hKtGZ=q=6w(y@l;RJu2Fo!@287A-nZ8dq|=pL{R+v~ zD*5?=tm`}1s)xPIj}nL1RlRPb>KZ}nNZPlAi@*+)Q?=xm!(M^JxmFE*=Xosl7)X3Y z`x;i7=>m2|w|GTcXz;B)BFIWRr!q+g!!(5^cPbaR{uPTJJ~Bbddv0@)Vb0Knmr1n_r7L7fQ4hd*#D4l&HWNgPM^;q(J?BkUm)KN{)v5`R) zVJGST+>)N)=6c&@pYLZM&qq*RSKAB6CX!x3NRxP0(R#4fb7DMi*d&XUvbdG{R&ZPi z%~*P-s6i}E?-BJjj1LIs{X7i!e{IhN_1q;M_u*D3++t2ko6#M0wVe%i*Jx})z%Ss< z2(bXxzk};|E4s$3NP)x;M$T*+s4!s;sQ+1D326%)FOJ+QteOuusf&35ZVV7y(|h~j z3=uHY@wq^|qLk-|cR?^hTosQ{aiu&0Waf+}y_3+H7syT-1?l>D5+3Zna|p>fdkUvE z{Rc!X9DbJ(m@X&?Vis4%cg)X&=N)=0Y!FAj6lFcn!(UfpEQu@|*C?tE*_e)y-b*(w zLeTrhS9Pg*_cnG^V>U~63w$QUeGk-9iB0;`h1-xu4RiQ&QzNX^%v#LKzx60_yI$GV z1$BW!Gwy;;F6Ht&Q-$t|0o#gip>>PvzV!-O6cIFpx$1`b8WTX?tIU#{>8O|+^FeR42yn-Ikjg^+qzQsKqHlk&W>K+*&&Ua|_4&oxqfqm;Sb-A*IWnaAe)^RDk zWnqHL*J2>NQ`gy=`?xY?QM#JY;a`#@Su%shXP3NdWvEGnt|{LIwQqy-+~2S@YREg%r?_RI4oJ{aKlfEzqp~(h@?Xb8 z6f$CO=`EaW@C#@>Q9(Hty%X@(%F?jzN#Ht$-7?WB3fLuQn4lHpMDvr^(Y;me`yZAM zh9xfyB$HSI+C_SJ*MCXscn^b5t#Qe~fzlOdFlcEsFgz zlO*zT_3*xZ>#5HShh|NoMdXyy1@g*Vxw+R>iQoK|+p!95Z=vz8`*R}{d?%ROye{hk z1$bClQ$kN;&*{?74qHeZxh1`${LHvpHw;^0-(;< zLT64 zeQ^7-zL-_*?adGSGM3y@F2aPqpiOg`2SDG+ zpA58#ppF0}r@to8p=+rG$S`Bg4V5|rhyEBFog}H~zjS}k{X$aVQjfL2ncn|Hqz1H( z{a0SZ_P5fY$=tn%s*gSM!}sTstFN+(Xt=r*SP7|Jh|=nu~GmSKa4~FvTE?cr~y!Am9lB zE)bF^DAA>N1ukpHuF(&*)phG}-%bqzDSYVzgeh)pYiE=QH+KdRRz7~x_05@S>gdV- z|ES1VzqrC}E0^KBA+cJj4@Riu+-Rbx(P;OLH+>Ued9#OXKRpx|g`x;ffdAxU_$zuNf8UNE053crV*HG zJ@;Snc|>^Dnn1%}E71Xt*g{-0TH&_yj`yQ#>z?M*qu6GdT0O=e_+Lal?W3^?-qj&y5Z8+Wzm&`d_^~xeVeupNACiHl>2qEoMDHAN$uKAn-!D& zknb^nlQo8X8yna2|+Z0KW38q%<5qZ&?NgN_}LrDJ39;+Hc`dKR+QVtw3rf` zv8kac`;clB^@u+Gi=*NFy}4}NT_=K!!dhaSep7?oiq6m>B%4LZ17WLvni%{AURAia z$}P*AvMq2YwF~;8G?b*ODCaY>wqCoot-1VOGw48VC$awogQLUDnjB@S?S?!u5kV+n zLg04TD9&&viNUi<6HC5sJ`>M>5wyCAT=GZb*MZAI=h@ z^I8IWa_X0^+kRqG47d{@Qdd9&@W~t(T^$xQ|kRU z(?k5q+5Ou&h_(Unz12xGhyYMEk&6o&KL_MqV`o#FJGS=} zV8GUc;kVQLc?;k{$Q(ljeX^rlxV!YBtuEpBjC9_0<|tS-a7V zYau_g0n1sBx$u_=yCy38J~TZe!p)=>4XV$2A{T`8qX97zm~{E?e5$Gh()>3mA%k4pyY<-Y zRCU*cZd)q#>0%vd2)9ub;VvF6D0rvvcJ^6nFf5$ z+|b|ydfI_?hC8dykut5G$p6!=al1|jzuIY}h}vUr=cu S7&Su^OSLrgP=$ZqdicK_9Lv4{ literal 79055 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 aZb&f;D?DNz>{o++(wS4{M)@b4Z~q@WO;->A From 741dc9a26036355a01e604ab11d0a84c2a5b3157 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 8 Nov 2018 16:13:28 -0600 Subject: [PATCH 30/91] Updated docs --- CHANGELOG.md | 1 + README.md | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e62778..45d2ed2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog # ## 1.0.2 ## +* OS X support * SiaPrime support ## 1.0.1 ## diff --git a/README.md b/README.md index b4598cb..06967d0 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Repertory UI -![alt text](https://image.ibb.co/mnhA1z/repertory_1_0_1.png) +![alt text](https://image.ibb.co/edOg5A/repertory-ui-1-0-2.png) ### GUI for [Repertory](https://bitbucket.org/blockstorage/repertory) ### Repertory allows you to mount Hyperspace or Sia blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows. # Downloads # -* [Repertory UI v1.0.1 Windows 64-bit](https://sia.pixeldrain.com/api/file/Alo1IF1u) +* [Repertory UI v1.0.2 Windows 64-bit]() # Supported Platforms # +* OS X * Windows 64-bit # Future Platforms # -* OS X * Linux 64-bit \ No newline at end of file From f264dad6ce39ca79202c20121876f0fe41fddf9f Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 9 Nov 2018 11:42:37 -0600 Subject: [PATCH 31/91] [Updated docs] [Launch hidden option] --- CHANGELOG.md | 1 + README.md | 3 ++- electron.js | 39 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45d2ed2..d9714da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog # ## 1.0.2 ## +* Launch hidden (notification icon only) * OS X support * SiaPrime support diff --git a/README.md b/README.md index 06967d0..db8fb91 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # Repertory UI ![alt text](https://image.ibb.co/edOg5A/repertory-ui-1-0-2.png) ### GUI for [Repertory](https://bitbucket.org/blockstorage/repertory) ### -Repertory allows you to mount Hyperspace or Sia blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows. +Repertory allows you to mount Sia, SiaPrime and/or Hyperspace blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows. # Downloads # +* [Repertory UI v1.0.2 OS X]() * [Repertory UI v1.0.2 Windows 64-bit]() # Supported Platforms # * OS X diff --git a/electron.js b/electron.js index d6761cb..ab042e4 100644 --- a/electron.js +++ b/electron.js @@ -19,14 +19,18 @@ let mainWindow; let mainWindowTray; let mountedPIDs = []; let expectedUnmount = {}; +let launchHidden = false; function createWindow() { + loadUiSettings(); + // Create the browser window. const height = process.env.ELECTRON_START_URL ? 394 : 374; mainWindow = new BrowserWindow({ width: 425, height: height, resizable: false, + show: !launchHidden, title: 'Repertory UI', webPreferences: { webSecurity: !process.env.ELECTRON_START_URL @@ -72,7 +76,8 @@ function createWindow() { } else { mainWindow.hide(); } - } + }, + checked: !launchHidden, }, { label: 'Auto-start', type: 'checkbox', click(item) { @@ -86,6 +91,16 @@ function createWindow() { { type: 'separator' }, + { + label: 'Launch Hidden', type: 'checkbox', click(item) { + launchHidden = !!item.checked; + saveUiSettings(); + }, + checked: launchHidden, + }, + { + type: 'separator' + }, { label: 'Exit', click(item) { app.quit(); @@ -93,7 +108,6 @@ function createWindow() { } ]); - mainContextWindow.items[0].checked = true; autoLauncher .isEnabled() .then((enabled) => { @@ -145,6 +159,27 @@ if (!instanceLock) { }); } +const loadUiSettings = () => { + const settingFile = path.join(helpers.resolvePath(Constants.DATA_LOCATIONS[os.platform()]), 'ui.json'); + try { + if (fs.statSync(settingFile).isFile()) { + const settings = JSON.parse(fs.readFileSync(settingFile, 'utf8')); + launchHidden = settings.launch_hidden; + } + } catch (e) { + } +}; + +const saveUiSettings = () => { + const settingFile = path.join(helpers.resolvePath(Constants.DATA_LOCATIONS[os.platform()]), 'ui.json'); + try { + fs.writeFileSync(settingFile, JSON.stringify({ + launch_hidden: launchHidden, + }), 'utf-8'); + } catch (e) { + } +}; + const standardIPCReply = (event, channel, data, error) => { event.sender.send(channel, { data: { From 1c10b8e6b6dfda215afb320fc5f0dd2bcba37397 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 9 Nov 2018 16:01:03 -0600 Subject: [PATCH 32/91] Removed icons --- public/favicon_old.ico | Bin 370070 -> 0 bytes public/icon_old.ico | Bin 370070 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 public/favicon_old.ico delete mode 100644 public/icon_old.ico diff --git a/public/favicon_old.ico b/public/favicon_old.ico deleted file mode 100644 index 530403fddc6e4a216a3686b344250e71ea990695..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370070 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 rt2mA7uXD| Date: Fri, 7 Dec 2018 19:59:20 -0600 Subject: [PATCH 33/91] OS X changes --- electron.js | 4 +- helpers.js | 4 +- src/components/MountItem/MountItem.css | 13 ++ src/components/MountItem/MountItem.js | 13 +- src/containers/MountItems/MountItems.js | 186 +++++++++--------------- src/index.css | 2 +- 6 files changed, 95 insertions(+), 127 deletions(-) diff --git a/electron.js b/electron.js index ab042e4..c3d5987 100644 --- a/electron.js +++ b/electron.js @@ -25,9 +25,9 @@ function createWindow() { loadUiSettings(); // Create the browser window. - const height = process.env.ELECTRON_START_URL ? 394 : 374; + const height = (process.env.ELECTRON_START_URL ? 394 : 374) - (os.platform() === 'win32' ? 0 : 20); mainWindow = new BrowserWindow({ - width: 425, + width: 425 + (os.platform() === 'win32' ? 0 : 130), height: height, resizable: false, show: !launchHidden, diff --git a/helpers.js b/helpers.js index 1e97d5f..9c94bf8 100644 --- a/helpers.js +++ b/helpers.js @@ -289,8 +289,8 @@ module.exports.getConfigTemplate = (directory, version, storageType) => { module.exports.getMissingDependencies = dependencies => { return new Promise((resolve, reject) => { - if (!dependencies || (dependencies.length === 0)) { - reject(Error('Dependency list is empty')); + if (!dependencies) { + reject(Error('Dependency list is invalid')); } let missing = []; diff --git a/src/components/MountItem/MountItem.css b/src/components/MountItem/MountItem.css index e69de29..81d91fc 100644 --- a/src/components/MountItem/MountItem.css +++ b/src/components/MountItem/MountItem.css @@ -0,0 +1,13 @@ +input.Input { + display: block; + margin: 0; + padding: 2px; + border-radius: var(--border_radius); + background: rgba(160, 160, 160, 0.1); + border: none; + box-shadow: none; + outline: none; + color: var(--text_color); + box-sizing: border-box; + width: 100%; +} \ No newline at end of file diff --git a/src/components/MountItem/MountItem.js b/src/components/MountItem/MountItem.js index 2fe581f..5356a14 100644 --- a/src/components/MountItem/MountItem.js +++ b/src/components/MountItem/MountItem.js @@ -39,16 +39,17 @@ export default CSSModules((props) => { selected={props.items.indexOf(props.location)}/>; } else { - inputColumnSpan = 60; + inputColumnSpan = 50; inputControl = ( - ); + ); } const buttonDisplay = props.allowMount || props.disabled ? @@ -61,7 +62,7 @@ export default CSSModules((props) => { const actionsDisplay = ( ); const autoMountControl = ( - { ); const autoRestartControl = ( - diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index 36030cd..3b93e23 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -60,12 +60,12 @@ class MountItems extends Component { }); }; - handleMountLocationChanged = (systemType, value) => { + handleMountLocationChanged = (storageType, value) => { if (this.props.platform === 'win32') { - this.props.changed(systemType, this.state[systemType].DriveLetters[value]); + this.props.changed(storageType, this.state[storageType].DriveLetters[value]); } else { - this.props.changed(systemType, value); + this.props.changed(storageType, value); } }; @@ -103,57 +103,36 @@ class MountItems extends Component { onDetectMountsReply = (event, arg) => { if (arg.data.Success) { - const sia = { - ...this.state.Sia, - AllowMount: true, - DriveLetters: (arg.data.DriveLetters.Sia), - Mounted: (arg.data.Locations.Sia.length > 0), - PID: arg.data.PIDS.Sia, - }; - const siaPrime = { - ...this.state.SiaPrime, - AllowMount: true, - DriveLetters: (arg.data.DriveLetters.SiaPrime), - Mounted: (arg.data.Locations.SiaPrime.length > 0), - PID: arg.data.PIDS.SiaPrime, - }; - const hs = { - ...this.state.Hyperspace, - AllowMount: true, - DriveLetters: (arg.data.DriveLetters.Hyperspace), - Mounted: (arg.data.Locations.Hyperspace.length > 0), - PID: arg.data.PIDS.Hyperspace, - }; + let state = {}; + let mountsBusy = false; + for (const name in this.state) { + state[name] = { + ...this.state[name], + AllowMount: true, + DriveLetters: (arg.data.DriveLetters[name]), + Mounted: (arg.data.Locations[name].length > 0), + PID: arg.data.PIDS[name], + }; + mountsBusy = mountsBusy || state[name].Mounted; + } + this.props.mountsBusy(mountsBusy); - this.props.mountsBusy(hs.Mounted || sia.Mounted); - - this.setState({ - Hyperspace: hs, - Sia: sia, - SiaPrime: siaPrime, - }, () => { - let hsLocation = arg.data.Locations.Hyperspace; - if ((hsLocation.length === 0) && (this.props.platform === 'win32')) { - hsLocation = this.props.hyperspace.MountLocation || arg.data.DriveLetters.Hyperspace[0]; - } - if (hsLocation !== this.props.hyperspace.MountLocation) { - this.props.changed('Hyperspace', hsLocation); - } - - let siaLocation = arg.data.Locations.Sia; - if ((siaLocation.length === 0) && (this.props.platform === 'win32')) { - siaLocation = this.props.sia.MountLocation || arg.data.DriveLetters.Sia[0]; - } - if (siaLocation !== this.props.sia.MountLocation) { - this.props.changed('Sia', siaLocation); - } - - let siaPrimeLocation = arg.data.Locations.SiaPrime; - if ((siaPrimeLocation.length === 0) && (this.props.platform === 'win32')) { - siaPrimeLocation = this.props.siaprime.MountLocation || arg.data.DriveLetters.SiaPrime[0]; - } - if (siaPrimeLocation !== this.props.siaprime.MountLocation) { - this.props.changed('SiaPrime', siaPrimeLocation); + this.setState(state, () => { + const updateMountLocation = (data, name) => { + const nameLower = name.toLowerCase(); + let location = data.Locations[name]; + if (location.length === 0) { + location = (this.props.platform === 'win32') ? + this.props[nameLower].MountLocation || data.DriveLetters[name][0] : + this.props[nameLower].MountLocation; + } + if (location !== this.props[nameLower].MountLocation) { + this.props.changed(name, location); + } + }; + + for (const name in this.state) { + updateMountLocation(arg.data, name); } this.performAutoMount(); @@ -177,7 +156,6 @@ class MountItems extends Component { }; onUnmountDriveReply = (event, arg) => { - console.log(arg); if ((this.props.platform === 'win32') && arg && arg.data && !arg.data.Expected && arg.data.Location && this.props[arg.data.StorageType.toLowerCase()].AutoRestart) { this.handleMountUnMount(arg.data.StorageType, true, arg.data.Location) } else { @@ -188,75 +166,51 @@ class MountItems extends Component { performAutoMount = ()=> { if (this.props.processAutoMount) { this.props.autoMountProcessed(); - if (this.props.hyperspace.AutoMount && - !this.state.Hyperspace.Mounted && - (this.props.hyperspace.MountLocation.length > 0)) { - this.handleMountUnMount('Hyperspace', true, this.props.hyperspace.MountLocation); - } - if (this.props.sia.AutoMount && - !this.state.Sia.Mounted && - (this.props.sia.MountLocation.length > 0)) { - this.handleMountUnMount('Sia', true, this.props.sia.MountLocation); - } - if (this.props.allowSiaPrime && this.props.siaprime.AutoMount && - !this.state.SiaPrime.Mounted && - (this.props.siaprime.MountLocation.length > 0)) { - this.handleMountUnMount('SiaPrime', true, this.props.siaprime.MountLocation); + const processAutoMount = (name) => { + const nameLower = name.toLowerCase(); + if (this.props[nameLower].AutoMount && + !this.state[name].Mounted && + (this.props[nameLower].MountLocation.length > 0)) { + this.handleMountUnMount(name, true, this.props[nameLower].MountLocation); + } + }; + for (const name in this.state) { + processAutoMount(name); } } }; render() { + let items = []; + for (const name in this.state) { + const nameLower = name.toLowerCase(); + items.push(( + this.props.autoMountChanged(name, e)} + autoRestart={this.props[nameLower].AutoRestart} + autoRestartChanged={(e)=>this.props.autoRestartChanged(name, e)} + changed={(e) => this.handleMountLocationChanged(name, e.target.value)} + clicked={this.handleMountUnMount} + configClicked={()=>this.props.configClicked(name)} + items={this.state[name].DriveLetters} + key={'mi_' + items.length} + location={this.props[nameLower].MountLocation} + mounted={this.state[name].Mounted} + pid={this.state[name].PID} + platform={this.props.platform} + title={name} /> + )); + if (items.length !== this.state.length) { + items.push(

) + } + } + return (
- this.props.autoMountChanged('Hyperspace', e)} - autoRestart={this.props.hyperspace.AutoRestart} - autoRestartChanged={(e)=>this.props.autoRestartChanged('Hyperspace', e)} - changed={(e) => this.handleMountLocationChanged('Hyperspace', e.target.value)} - clicked={this.handleMountUnMount} - configClicked={()=>this.props.configClicked('Hyperspace')} - items={this.state.Hyperspace.DriveLetters} - location={this.props.hyperspace.MountLocation} - mounted={this.state.Hyperspace.Mounted} - pid={this.state.Hyperspace.PID} - platform={this.props.platform} - title={'Hyperspace'}/> -
- this.props.autoMountChanged('Sia', e)} - autoRestart={this.props.sia.AutoRestart} - autoRestartChanged={(e)=>this.props.autoRestartChanged('Sia', e)} - changed={(e) => this.handleMountLocationChanged('Sia', e.target.value)} - clicked={this.handleMountUnMount} - configClicked={()=>this.props.configClicked('Sia')} - items={this.state.Sia.DriveLetters} - location={this.props.sia.MountLocation} - mounted={this.state.Sia.Mounted} - pid={this.state.Sia.PID} - platform={this.props.platform} - title={'Sia'}/> -
- this.props.autoMountChanged('SiaPrime', e)} - autoRestart={this.props.siaprime.AutoRestart} - autoRestartChanged={(e)=>this.props.autoRestartChanged('SiaPrime', e)} - changed={(e) => this.handleMountLocationChanged('SiaPrime', e.target.value)} - clicked={this.handleMountUnMount} - configClicked={()=>this.props.configClicked('SiaPrime')} - disabled={!this.props.allowSiaPrime} - items={this.state.SiaPrime.DriveLetters} - location={this.props.siaprime.MountLocation} - mounted={this.state.SiaPrime.Mounted} - pid={this.state.SiaPrime.PID} - platform={this.props.platform} - title={'SiaPrime'}/> + {items}
); } } diff --git a/src/index.css b/src/index.css index dab6ad0..6323f62 100644 --- a/src/index.css +++ b/src/index.css @@ -18,7 +18,7 @@ * { font-family: 'Nunito', sans-serif; - font-size: 3.5vw; + font-size: 4.4vmin; } *::-moz-focus-inner { From fdbbf1c1bfea227c8437083725ad52637a9a59db Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 8 Dec 2018 11:15:47 -0600 Subject: [PATCH 34/91] Layout changes --- electron.js | 4 ++-- src/App.js | 5 ++--- src/index.css | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/electron.js b/electron.js index c3d5987..993f192 100644 --- a/electron.js +++ b/electron.js @@ -25,7 +25,7 @@ function createWindow() { loadUiSettings(); // Create the browser window. - const height = (process.env.ELECTRON_START_URL ? 394 : 374) - (os.platform() === 'win32' ? 0 : 20); + const height = (process.env.ELECTRON_START_URL ? 402 : 382) - (os.platform() === 'win32' ? 0 : 20); mainWindow = new BrowserWindow({ width: 425 + (os.platform() === 'win32' ? 0 : 130), height: height, @@ -284,7 +284,7 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { }; const setImage = (hsLocation, siaLocation, siaPrimeLocation) => { - if (os.platform() === 'win32') { + if (os.platform() === 'win32' || os.platform() === 'linux') { let image; if ((siaLocation.length > 0) || (hsLocation.length > 0) || (siaPrimeLocation.length > 0)) { image = nativeImage.createFromPath(path.join(__dirname, '/build/logo_both.png')); diff --git a/src/App.js b/src/App.js index 81a36c6..320356c 100644 --- a/src/App.js +++ b/src/App.js @@ -698,8 +698,7 @@ class App extends Component { if (allowMount) { mainContent.push(( -
+
- + {mainContent}
diff --git a/src/index.css b/src/index.css index 6323f62..bb12ef1 100644 --- a/src/index.css +++ b/src/index.css @@ -18,7 +18,7 @@ * { font-family: 'Nunito', sans-serif; - font-size: 4.4vmin; + font-size: 4vmin; } *::-moz-focus-inner { From ff87b699abdcb2f3fc71b82c9637925e52880646 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 8 Dec 2018 18:16:04 -0600 Subject: [PATCH 35/91] Layout changes --- electron.js | 4 ++-- src/index.css | 4 +++- src/index.js | 4 ++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/electron.js b/electron.js index 993f192..4c5906f 100644 --- a/electron.js +++ b/electron.js @@ -25,9 +25,9 @@ function createWindow() { loadUiSettings(); // Create the browser window. - const height = (process.env.ELECTRON_START_URL ? 402 : 382) - (os.platform() === 'win32' ? 0 : 20); + const height = (process.env.ELECTRON_START_URL ? 400 : 380) - (os.platform() === 'win32' ? 0 : 24); mainWindow = new BrowserWindow({ - width: 425 + (os.platform() === 'win32' ? 0 : 130), + width: 428 + (os.platform() === 'win32' ? 0 : 120), height: height, resizable: false, show: !launchHidden, diff --git a/src/index.css b/src/index.css index bb12ef1..8fd7ee9 100644 --- a/src/index.css +++ b/src/index.css @@ -14,11 +14,13 @@ --heading_text_color: rgba(161, 190, 219, 0.7); --heading_other_text_color: var(--heading_text_color); --text_color_transition: color 0.3s; + + --default_font_size: 4vmin } * { font-family: 'Nunito', sans-serif; - font-size: 4vmin; + font-size: var(--default_font_size); } *::-moz-focus-inner { diff --git a/src/index.js b/src/index.js index a7d5c00..1057b5f 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,10 @@ if (!process.versions.hasOwnProperty('electron')) { const ipcRenderer = ((window && window.require) ? window.require('electron').ipcRenderer : null); if (ipcRenderer) { ipcRenderer.on(Constants.IPC_Get_Platform_Reply, (event, arg) => { + if (arg.data !== 'win32') { + let root = document.documentElement; + root.style.setProperty('--default_font_size', '4.4vmin'); + } ReactDOM.render(, document.getElementById('root')); registerServiceWorker(); }); From e95477f4210df55bade37ab6bd5fe589941de697 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 8 Dec 2018 23:36:43 -0600 Subject: [PATCH 36/91] Refactoring --- src/App.js | 121 +++++++++++------------- src/constants.js | 6 ++ src/containers/MountItems/MountItems.js | 105 +++++++++----------- 3 files changed, 107 insertions(+), 125 deletions(-) diff --git a/src/App.js b/src/App.js index 320356c..ecd111c 100644 --- a/src/App.js +++ b/src/App.js @@ -28,6 +28,14 @@ class App extends Component { constructor(props) { super(props); + for (const provider of Constants.PROVIDER_LIST) { + this.state[provider] = { + AutoMount: false, + AutoRestart: false, + MountLocation: '', + } + } + if (ipcRenderer) { ipcRenderer.on(Constants.IPC_Check_Installed_Reply, this.onCheckInstalledReply); ipcRenderer.on(Constants.IPC_Download_File_Complete, this.onDownloadFileComplete); @@ -60,15 +68,9 @@ class App extends Component { DownloadingRelease: false, DownloadingUpgrade: false, ExtractActive: false, - Hyperspace: { - AutoMount: false, - AutoRestart: false, - MountLocation: '', - }, LocationsLookup: {}, MissingDependencies: [], MountsBusy: false, - Platform: 'unknown', Release: 3, ReleaseTypes: [ 'Release', @@ -77,16 +79,6 @@ class App extends Component { 'Alpha', ], InstalledVersion: 'none', - Sia: { - AutoMount: false, - AutoRestart: false, - MountLocation: '', - }, - SiaPrime: { - AutoMount: false, - AutoRestart: false, - MountLocation: '', - }, UpgradeAvailable: false, UpgradeData: {}, UpgradeDismissed: false, @@ -112,7 +104,7 @@ class App extends Component { this.setState({ AllowDownload: false, }, ()=> { - const selectedVersion = this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]][this.state.Version]; + const selectedVersion = this.getSelectedVersion(); if (selectedVersion !== 'unavailable') { if (ipcRenderer) { let dependencies = []; @@ -161,6 +153,10 @@ class App extends Component { } }; + getSelectedVersion = () => { + return this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]][this.state.Version]; + }; + grabReleases = () => { if (this.props.platform !== 'unknown') { if (ipcRenderer) { @@ -178,7 +174,7 @@ class App extends Component { this.setState({ [storageType]: state, }, ()=> { - this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + this.saveState(); }); }; @@ -190,7 +186,7 @@ class App extends Component { this.setState({ [storageType]: state, }, ()=> { - this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + this.saveState(); }); }; @@ -233,7 +229,7 @@ class App extends Component { this.setState({ [storageType]: state, }, ()=> { - this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + this.saveState(); }); }; @@ -244,13 +240,13 @@ class App extends Component { Release: val, Version: versionIndex }, ()=> { - this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + this.saveState(); this.checkVersionInstalled( ); }); }; handleReleaseDownload = () => { - const selectedVersion = this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]][this.state.Version]; + const selectedVersion = this.getSelectedVersion(); const fileName = selectedVersion + '.zip'; if (ipcRenderer) { this.setState({ @@ -289,7 +285,7 @@ class App extends Component { this.setState({ Version: parseInt(e.target.value, 10), }, ()=> { - this.saveState(this.state.Release, this.state.Version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + this.saveState(); this.checkVersionInstalled( ); }); }; @@ -335,7 +331,7 @@ class App extends Component { onDownloadFileComplete = (event, arg) => { if (this.state.DownloadingRelease) { if (arg.data.Success) { - const selectedVersion = this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]][this.state.Version]; + const selectedVersion = this.getSelectedVersion(); ipcRenderer.send(Constants.IPC_Extract_Release, { Directory: Constants.DATA_LOCATIONS[this.props.platform], Source: arg.data.Destination, @@ -406,37 +402,23 @@ class App extends Component { onGetStateReply = (event, arg) => { if (arg.data) { - let hyperspace = arg.data.Hyperspace || this.state.Hyperspace; - if (hyperspace.AutoMount === undefined) { - hyperspace['AutoMount'] = false; - } - if (hyperspace.AutoRestart === undefined) { - hyperspace['AutoRestart'] = false; - } - - let sia = arg.data.Sia || this.state.Sia; - if (sia.AutoMount === undefined) { - sia['AutoMount'] = false; - } - if (sia.AutoRestart === undefined) { - sia['AutoRestart'] = false; - } - - let siaPrime = arg.data.SiaPrime || this.state.SiaPrime; - if (siaPrime.AutoMount === undefined) { - siaPrime['AutoMount'] = false; - } - if (siaPrime.AutoRestart === undefined) { - siaPrime['AutoRestart'] = false; - } - - this.setState({ - Hyperspace: hyperspace, + let state = { Release: arg.data.Release, - Sia: sia, - SiaPrime: siaPrime, Version: arg.data.Version, - }, ()=> { + }; + + for (const provider of Constants.PROVIDER_LIST) { + let data = arg.data[provider] || this.state[provider]; + if (data.AutoMount === undefined) { + data['AutoMount'] = false; + } + if (data.AutoRestart === undefined) { + data['AutoRestart'] = false; + } + state[provider] = data; + } + + this.setState(state, ()=> { this.grabReleases(); }); } else { @@ -450,7 +432,7 @@ class App extends Component { let version = this.state.Version; if ((version === -1) || !versionLookup[this.state.ReleaseTypes[this.state.Release]][version]) { version = latestVersion; - this.saveState(this.state.Release, version, this.state.Sia, this.state.Hyperspace, this.state.SiaPrime); + this.saveState(version); } this.setState({ @@ -541,17 +523,19 @@ class App extends Component { }); }; - saveState = (release, version, sia, hyperspace, siaPrime)=> { + saveState = version => { if (ipcRenderer) { + let state = { + Release: this.state.Release, + Version: version || this.state.Version, + }; + for (const provider of Constants.PROVIDER_LIST) { + state[provider] = this.state[provider]; + } + ipcRenderer.send(Constants.IPC_Save_State, { Directory: Constants.DATA_LOCATIONS[this.props.platform], - State: { - Hyperspace: hyperspace, - Release: release, - Sia: sia, - SiaPrime: siaPrime, - Version: version, - } + State: state }); } }; @@ -590,7 +574,7 @@ class App extends Component { render() { const selectedVersion = (this.state.Version === -1) ? 'unavailable' : - this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]][this.state.Version]; + this.getSelectedVersion(); const downloadEnabled = this.state.AllowDownload && !this.state.MountsBusy && @@ -697,9 +681,15 @@ class App extends Component { )); if (allowMount) { + let providerProps = {}; + for (const provider of Constants.PROVIDER_LIST) { + const providerLower = provider.toLowerCase(); + providerProps[providerLower] = this.state[provider]; + } mainContent.push((
-
)); diff --git a/src/constants.js b/src/constants.js index 407c7a5..ba7fdf0 100644 --- a/src/constants.js +++ b/src/constants.js @@ -9,6 +9,12 @@ exports.DATA_LOCATIONS = { }; exports.UI_RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory-ui/raw/master/releases.json'; +exports.PROVIDER_LIST = [ + 'Hyperspace', + 'Sia', + 'SiaPrime' +]; + exports.IPC_Check_Dependency_Installed = 'check_dependency_installed'; exports.IPC_Check_Dependency_Installed_Reply = 'check_dependency_installed'; diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index 3b93e23..9f1dfe9 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -14,6 +14,14 @@ if (!process.versions.hasOwnProperty('electron')) { class MountItems extends Component { constructor(props) { super(props); + for (const provider of Constants.PROVIDER_LIST) { + this.state[provider] = { + AllowMount: false, + DriveLetters: [], + Mounted: false, + PID: -1, + }; + } if (ipcRenderer) { ipcRenderer.on(Constants.IPC_Detect_Mounts_Reply, this.onDetectMountsReply); ipcRenderer.on(Constants.IPC_Mount_Drive_Reply, this.onMountDriveReply); @@ -23,26 +31,7 @@ class MountItems extends Component { } } - state = { - Hyperspace: { - AllowMount: false, - DriveLetters: [], - Mounted: false, - PID: -1, - }, - Sia: { - AllowMount: false, - DriveLetters: [], - Mounted: false, - PID: -1, - }, - SiaPrime: { - AllowMount: false, - DriveLetters: [], - Mounted: false, - PID: -1, - }, - }; + state = {}; componentWillUnmount = () => { if (ipcRenderer) { @@ -105,34 +94,34 @@ class MountItems extends Component { if (arg.data.Success) { let state = {}; let mountsBusy = false; - for (const name in this.state) { - state[name] = { - ...this.state[name], + for (const provider of Constants.PROVIDER_LIST) { + state[provider] = { + ...this.state[provider], AllowMount: true, - DriveLetters: (arg.data.DriveLetters[name]), - Mounted: (arg.data.Locations[name].length > 0), - PID: arg.data.PIDS[name], + DriveLetters: (arg.data.DriveLetters[provider]), + Mounted: (arg.data.Locations[provider].length > 0), + PID: arg.data.PIDS[provider], }; - mountsBusy = mountsBusy || state[name].Mounted; + mountsBusy = mountsBusy || state[provider].Mounted; } this.props.mountsBusy(mountsBusy); this.setState(state, () => { - const updateMountLocation = (data, name) => { - const nameLower = name.toLowerCase(); - let location = data.Locations[name]; + const updateMountLocation = (data, provider) => { + const providerLower = provider.toLowerCase(); + let location = data.Locations[provider]; if (location.length === 0) { location = (this.props.platform === 'win32') ? - this.props[nameLower].MountLocation || data.DriveLetters[name][0] : - this.props[nameLower].MountLocation; + this.props[providerLower].MountLocation || data.DriveLetters[provider][0] : + this.props[providerLower].MountLocation; } - if (location !== this.props[nameLower].MountLocation) { - this.props.changed(name, location); + if (location !== this.props[providerLower].MountLocation) { + this.props.changed(provider, location); } }; - for (const name in this.state) { - updateMountLocation(arg.data, name); + for (const provider of Constants.PROVIDER_LIST) { + updateMountLocation(arg.data, provider); } this.performAutoMount(); @@ -166,41 +155,41 @@ class MountItems extends Component { performAutoMount = ()=> { if (this.props.processAutoMount) { this.props.autoMountProcessed(); - const processAutoMount = (name) => { - const nameLower = name.toLowerCase(); - if (this.props[nameLower].AutoMount && - !this.state[name].Mounted && - (this.props[nameLower].MountLocation.length > 0)) { - this.handleMountUnMount(name, true, this.props[nameLower].MountLocation); + const processAutoMount = (provider) => { + const providerLower = provider.toLowerCase(); + if (this.props[providerLower].AutoMount && + !this.state[provider].Mounted && + (this.props[providerLower].MountLocation.length > 0)) { + this.handleMountUnMount(provider, true, this.props[providerLower].MountLocation); } }; - for (const name in this.state) { - processAutoMount(name); + for (const provider of Constants.PROVIDER_LIST) { + processAutoMount(provider); } } }; render() { let items = []; - for (const name in this.state) { - const nameLower = name.toLowerCase(); + for (const provider of Constants.PROVIDER_LIST) { + const providerLower = provider.toLowerCase(); items.push(( this.props.autoMountChanged(name, e)} - autoRestart={this.props[nameLower].AutoRestart} - autoRestartChanged={(e)=>this.props.autoRestartChanged(name, e)} - changed={(e) => this.handleMountLocationChanged(name, e.target.value)} + allowMount={this.state[provider].AllowMount} + autoMount={this.props[providerLower].AutoMount} + autoMountChanged={(e)=>this.props.autoMountChanged(provider, e)} + autoRestart={this.props[providerLower].AutoRestart} + autoRestartChanged={(e)=>this.props.autoRestartChanged(provider, e)} + changed={(e) => this.handleMountLocationChanged(provider, e.target.value)} clicked={this.handleMountUnMount} - configClicked={()=>this.props.configClicked(name)} - items={this.state[name].DriveLetters} + configClicked={()=>this.props.configClicked(provider)} + items={this.state[provider].DriveLetters} key={'mi_' + items.length} - location={this.props[nameLower].MountLocation} - mounted={this.state[name].Mounted} - pid={this.state[name].PID} + location={this.props[providerLower].MountLocation} + mounted={this.state[provider].Mounted} + pid={this.state[provider].PID} platform={this.props.platform} - title={name} /> + title={provider} /> )); if (items.length !== this.state.length) { items.push(
Date: Sun, 9 Dec 2018 19:27:04 -0600 Subject: [PATCH 37/91] Linux / OS X changes --- electron.js | 119 ++++++++++++++---------- helpers.js | 81 ++++++++-------- src/App.js | 6 +- src/constants.js | 6 ++ src/containers/MountItems/MountItems.js | 3 +- 5 files changed, 126 insertions(+), 89 deletions(-) diff --git a/electron.js b/electron.js index 4c5906f..1e84032 100644 --- a/electron.js +++ b/electron.js @@ -17,10 +17,15 @@ const AutoLaunch = require('auto-launch'); let mainContextWindow; let mainWindow; let mainWindowTray; -let mountedPIDs = []; +let mountedPIDs = {}; +let mountedLocations = []; let expectedUnmount = {}; let launchHidden = false; +function closeApplication() { + app.quit(); +} + function createWindow() { loadUiSettings(); @@ -50,7 +55,15 @@ function createWindow() { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. - mainWindow = null + mainWindow = null; + + // Unmount all items + console.log(mountedLocations); + for (const i in mountedLocations) { + helpers.stopMountProcess(mountedPIDs[mountedLocations[i]], mountedLocations[i]); + } + mountedLocations = []; + mountedPIDs = {}; }); if ((os.platform() === 'win32') || (os.platform() === 'linux')) { @@ -103,7 +116,7 @@ function createWindow() { }, { label: 'Exit', click(item) { - app.quit(); + closeApplication(); } } ]); @@ -118,14 +131,14 @@ function createWindow() { mainWindowTray.setContextMenu(mainContextWindow) }) .catch(() => { - app.quit(); + closeApplication(); }); } } const instanceLock = app.requestSingleInstanceLock(); if (!instanceLock) { - app.quit() + closeApplication(); } else { app.on('second-instance', () => { if (mainWindow) { @@ -146,7 +159,7 @@ if (!instanceLock) { // On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') { - app.quit() + closeApplication(); } }); @@ -181,13 +194,15 @@ const saveUiSettings = () => { }; const standardIPCReply = (event, channel, data, error) => { - event.sender.send(channel, { - data: { - ...data, - Error: error, - Success: !error, - } - }); + if (mainWindow) { + event.sender.send(channel, { + data: { + ...data, + Error: error, + Success: !error, + } + }); + } }; ipcMain.on(Constants.IPC_Check_Dependency_Installed, (event, data) => { @@ -237,11 +252,10 @@ ipcMain.on(Constants.IPC_Delete_File, (event, data) => { }); ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { - let driveLetters = { - Hyperspace: [], - Sia: [], - SiaPrime: [], - }; + let driveLetters = {}; + for (const provider of Constants.PROVIDER_LIST) { + driveLetters[provider] = []; + } const grabDriveLetters = (hsLocation, siaLocation, siaPrimeLocation) => { for (let i = 'c'.charCodeAt(0); i <= 'z'.charCodeAt(0); i++) { @@ -503,30 +517,42 @@ ipcMain.on(Constants.IPC_Install_Upgrade, (event, data) => { ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => { expectedUnmount[data.StorageType] = false; const dataDirectory = helpers.resolvePath(data.Directory); - const errorHandler = (pid, error) => { - mountedPIDs.splice(mountedPIDs.indexOf(pid), 1); - standardIPCReply(event, Constants.IPC_Unmount_Drive_Reply, { - Expected: expectedUnmount[data.StorageType], - Location: data.Location, - PID: -1, - StorageType: data.StorageType, - }, error || Error(data.StorageType + ' Unmounted')); - }; - helpers.executeMount(dataDirectory, data.Version, data.StorageType, data.Location, (error, pid) => { - errorHandler(pid, error); - }) - .then(pid => { - if (pid !== -1) { - mountedPIDs.push(pid); - } - standardIPCReply(event, Constants.IPC_Mount_Drive_Reply, { - PID: pid, - StorageType: data.StorageType, - }); - }) - .catch(error => { - errorHandler(-1, error); - }); + + if (mountedLocations.indexOf(data.Location) !== -1) { + console.log(data.StorageType + ' already mounted: ' + data.Location); + } else { + mountedLocations.push(data.Location); + mountedPIDs[data.Location] = -1; + const errorHandler = (pid, error) => { + if (mountedLocations.indexOf(data.Location) !== -1) { + mountedLocations.splice(mountedLocations.indexOf(data.Location), 1); + delete mountedPIDs[data.Location]; + } + + standardIPCReply(event, Constants.IPC_Unmount_Drive_Reply, { + Expected: expectedUnmount[data.StorageType], + Location: data.Location, + PID: -1, + StorageType: data.StorageType, + }, error || Error(data.StorageType + ' Unmounted')); + }; + helpers + .executeMount(dataDirectory, data.Version, data.StorageType, data.Location, data.NoConsoleSupported, (error, pid) => { + errorHandler(pid, error); + }) + .then(pid => { + if (pid !== -1) { + mountedPIDs[data.Location] = pid; + } + standardIPCReply(event, Constants.IPC_Mount_Drive_Reply, { + PID: pid, + StorageType: data.StorageType, + }); + }) + .catch(error => { + errorHandler(-1, error); + }); + } }); ipcMain.on(Constants.IPC_Save_State, (event, data) => { @@ -556,17 +582,14 @@ ipcMain.on(Constants.IPC_Set_Config_Values, (event, data) => { }); ipcMain.on(Constants.IPC_Shutdown, () => { - app.quit(); + closeApplication(); }); ipcMain.on(Constants.IPC_Unmount_Drive, (event, data) => { expectedUnmount[data.StorageType] = true; helpers - .stopProcessByPID(data.PID) - .then((pid)=> { - if (mountedPIDs.indexOf(pid) === -1) { - event.sender.send(Constants.IPC_Unmount_Drive_Reply); - } + .stopMountProcess(data.PID, data.Location) + .then(()=> { }) .catch((e) => { console.log(e); diff --git a/helpers.js b/helpers.js index 9c94bf8..665e853 100644 --- a/helpers.js +++ b/helpers.js @@ -4,6 +4,7 @@ const os = require('os'); const axios = require('axios'); const exec = require('child_process').exec; const spawn = require('child_process').spawn; +const Constants = require('./src/constants'); const tryParse = (j, def) => { try { @@ -37,23 +38,15 @@ module.exports.detectRepertoryMounts = (directory, version) => { }); process.on('exit', () => { - resolve(tryParse(result, { - Hyperspace: { + let defaultData = {}; + for (const provider of Constants.PROVIDER_LIST) { + defaultData[provider] = { Active: false, Location: '', PID: -1, - }, - Sia: { - Active: false, - Location: '', - PID: -1, - }, - SiaPrime: { - Active: false, - Location: '', - PID: -1, - }, - })); + }; + } + resolve(tryParse(result, defaultData)); }); process.unref(); }); @@ -163,29 +156,33 @@ module.exports.executeAsync = (command, args=[]) => { }); }; -module.exports.executeMount = (directory, version, storageType, location, exitCallback) => { +module.exports.executeMount = (directory, version, storageType, location, noConsoleSupported, exitCallback) => { return new Promise((resolve) => { const processOptions = { - detached: true, + detached: os.platform() === 'win32', shell: true, + stdio: 'ignore', }; const command = path.join(directory, version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory'); const args = []; - if (storageType.toLowerCase() === 'hyperspace') { - args.push('-hs'); - } else if (storageType.toLowerCase() === 'siaprime') { - args.push('-sp'); + if (Constants.PROVIDER_ARG[storageType.toLowerCase()].length > 0) { + args.push(Constants.PROVIDER_ARG[storageType.toLowerCase()]); } + if ((os.platform() === 'linux') || (os.platform() === 'darwin')) { args.push('-o'); args.push('big_writes'); + args.push('-f'); + if (noConsoleSupported) { + args.push('-nc'); + } } else if (os.platform() === 'win32') { args.push('-hidden'); } args.push(location); - const process = new spawn(command, args, processOptions); + let process = new spawn(command, args, processOptions); const pid = process.pid; const timeout = setTimeout(() => { @@ -196,11 +193,15 @@ module.exports.executeMount = (directory, version, storageType, location, exitCa clearTimeout(timeout); exitCallback(err, pid); }); + process.on('exit', (code) => { clearTimeout(timeout); exitCallback(code, pid); }); - process.unref(); + + if (os.platform() === 'win32') { + process.unref(); + } }); }; @@ -215,10 +216,8 @@ module.exports.getConfig = (directory, version, storageType) => { const command = path.join(directory, version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory'); const args = []; args.push('-dc'); - if (storageType.toLowerCase() === 'hyperspace') { - args.push('-hs'); - } else if (storageType.toLowerCase() === 'siaprime') { - args.push('-sp'); + if (Constants.PROVIDER_ARG[storageType.toLowerCase()].length > 0) { + args.push(Constants.PROVIDER_ARG[storageType.toLowerCase()]); } const process = new spawn(command, args, processOptions); @@ -263,10 +262,8 @@ module.exports.getConfigTemplate = (directory, version, storageType) => { const command = path.join(directory, version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory'); const args = []; args.push('-gt'); - if (storageType.toLowerCase() === 'hyperspace') { - args.push('-hs'); - } else if (storageType.toLowerCase() === 'siaprime') { - args.push('-sp'); + if (Constants.PROVIDER_ARG[storageType.toLowerCase()].length > 0) { + args.push(Constants.PROVIDER_ARG[storageType.toLowerCase()]); } const process = new spawn(command, args, processOptions); @@ -428,10 +425,8 @@ module.exports.setConfigValue = (name, value, directory, storageType, version) = args.push('-set'); args.push(name); args.push(value); - if (storageType.toLowerCase() === 'hyperspace') { - args.push('-hs'); - } else if (storageType.toLowerCase() === 'siaprime') { - args.push('-sp'); + if (Constants.PROVIDER_ARG[storageType.toLowerCase()].length > 0) { + args.push(Constants.PROVIDER_ARG[storageType.toLowerCase()]); } const process = new spawn(command, args, processOptions); @@ -448,23 +443,31 @@ module.exports.setConfigValue = (name, value, directory, storageType, version) = }); }; -module.exports.stopProcessByPID = pid => { +module.exports.stopMountProcess = (pid, location) => { return new Promise((resolve, reject) => { const processOptions = { detached: true, - shell: false, + shell: true, windowsHide: true, }; - const command = (os.platform() === 'win32') ? 'taskkill.exe' : 'kill'; + let procName = 'kill'; + if (location && location.length > 0) { + procName = 'fusermount'; + } + const command = (os.platform() === 'win32') ? 'taskkill.exe' : procName; const args = []; if (os.platform() === 'win32') { args.push('/PID'); } - args.push(pid); + if (procName === 'fusermount') { + args.push('-u'); + args.push(location); + } else { + args.push(pid); + } const process = new spawn(command, args, processOptions); - process.on('error', (err) => { reject(err); }); diff --git a/src/App.js b/src/App.js index ecd111c..9343c4a 100644 --- a/src/App.js +++ b/src/App.js @@ -588,7 +588,10 @@ class App extends Component { this.state.LocationsLookup[selectedVersion].config_support; const allowSiaPrime = this.state.LocationsLookup[selectedVersion] && - this.state.LocationsLookup[selectedVersion].siaprime_support; + this.state.LocationsLookup[selectedVersion].siaprime_support; + + const noConsoleSupported = this.state.LocationsLookup[selectedVersion] && + this.state.LocationsLookup[selectedVersion].no_console_supported; const showDependencies = missingDependencies && !this.state.DownloadActive; @@ -691,6 +694,7 @@ class App extends Component { { - if ((this.props.platform === 'win32') && arg && arg.data && !arg.data.Expected && arg.data.Location && this.props[arg.data.StorageType.toLowerCase()].AutoRestart) { + if (arg && arg.data && !arg.data.Expected && arg.data.Location && this.props[arg.data.StorageType.toLowerCase()].AutoRestart) { this.handleMountUnMount(arg.data.StorageType, true, arg.data.Location) } else { this.detectMounts(); From 3c007cdee002b0b04de49c3738bf42a4e6c0b8e9 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 9 Dec 2018 19:28:35 -0600 Subject: [PATCH 38/91] Updated docs --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9714da..2dff8d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ * Launch hidden (notification icon only) * OS X support * SiaPrime support +* Unmount on application exit +* Partial Linux support ## 1.0.1 ## * Added configuration settings for Repertory 1.0.0-alpha.2 and above From ed91305763866af4b3bb446dfb0aad753bbed6b1 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 9 Dec 2018 20:06:01 -0600 Subject: [PATCH 39/91] [Close to tray] [Unmount fixes] --- electron.js | 36 +++++++++++++++++++++++++++--------- helpers.js | 7 +++++-- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/electron.js b/electron.js index 1e84032..a8d7d86 100644 --- a/electron.js +++ b/electron.js @@ -14,7 +14,7 @@ const AutoLaunch = require('auto-launch'); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. -let mainContextWindow; +let trayContextMenu; let mainWindow; let mainWindowTray; let mountedPIDs = {}; @@ -22,6 +22,11 @@ let mountedLocations = []; let expectedUnmount = {}; let launchHidden = false; +let isQuiting = false; +app.on('before-quit', function () { + isQuiting = true; +}); + function closeApplication() { app.quit(); } @@ -58,7 +63,6 @@ function createWindow() { mainWindow = null; // Unmount all items - console.log(mountedLocations); for (const i in mountedLocations) { helpers.stopMountProcess(mountedPIDs[mountedLocations[i]], mountedLocations[i]); } @@ -77,7 +81,7 @@ function createWindow() { }); const image = nativeImage.createFromPath(path.join(__dirname, '/build/logo.png')); - mainContextWindow = Menu.buildFromTemplate([ + trayContextMenu = Menu.buildFromTemplate([ { label: 'Visible', type: 'checkbox', click(item) { if (item.checked) { @@ -115,20 +119,32 @@ function createWindow() { type: 'separator' }, { - label: 'Exit', click(item) { + label: 'Exit and Unmount', click(item) { closeApplication(); } } ]); + mainWindow.on('close', function (event) { + if (!isQuiting) { + event.preventDefault(); + if (mainWindow.isVisible()) { + mainWindow.hide(); + trayContextMenu.items[0].checked = false; + mainWindowTray.setContextMenu(trayContextMenu); + } + event.returnValue = false; + } + }); + autoLauncher .isEnabled() .then((enabled) => { - mainContextWindow.items[1].checked = enabled; + trayContextMenu.items[1].checked = enabled; mainWindowTray = new Tray(image); mainWindowTray.setToolTip('Repertory UI'); - mainWindowTray.setContextMenu(mainContextWindow) + mainWindowTray.setContextMenu(trayContextMenu) }) .catch(() => { closeApplication(); @@ -143,8 +159,9 @@ if (!instanceLock) { app.on('second-instance', () => { if (mainWindow) { mainWindow.show(); - if (mainContextWindow) { - mainContextWindow.items[0].checked = true; + if (trayContextMenu && mainWindowTray) { + trayContextMenu.items[0].checked = true; + mainWindowTray.setContextMenu(trayContextMenu) } if (mainWindow.isMinimized()) { mainWindow.restore(); @@ -589,7 +606,8 @@ ipcMain.on(Constants.IPC_Unmount_Drive, (event, data) => { expectedUnmount[data.StorageType] = true; helpers .stopMountProcess(data.PID, data.Location) - .then(()=> { + .then((result)=> { + console.log(result); }) .catch((e) => { console.log(e); diff --git a/helpers.js b/helpers.js index 665e853..2860a42 100644 --- a/helpers.js +++ b/helpers.js @@ -471,8 +471,11 @@ module.exports.stopMountProcess = (pid, location) => { process.on('error', (err) => { reject(err); }); - process.on('exit', () => { - setTimeout(()=>resolve(pid), 3000); + process.on('exit', (code) => { + resolve({ + PID: pid, + Code: code, + }); }); process.unref(); }); From af836c305c83df211889281b6f61aea9defb711d Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 9 Dec 2018 20:16:36 -0600 Subject: [PATCH 40/91] Updated docs --- CHANGELOG.md | 1 + src/constants.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dff8d2..0c3a266 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * SiaPrime support * Unmount on application exit * Partial Linux support +* Close to notification area ## 1.0.1 ## * Added configuration settings for Repertory 1.0.0-alpha.2 and above diff --git a/src/constants.js b/src/constants.js index 36aa8bb..8f86720 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,13 +1,13 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory/raw/master/releases.json'; +exports.RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory/raw/1.0.0-alpha.4_branch/releases.json'; exports.DATA_LOCATIONS = { linux: '~/.local/repertory/ui', darwin: '~/Library/Application Support/repertory/ui', win32: '%LOCALAPPDATA%\\repertory\\ui' }; -exports.UI_RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory-ui/raw/master/releases.json'; +exports.UI_RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory-ui/raw/1.0.2_branch/releases.json'; exports.PROVIDER_LIST = [ 'Hyperspace', From 61b2f6e6f6ee250293c38eb414a7ac9070e80226 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Mon, 10 Dec 2018 00:04:18 -0600 Subject: [PATCH 41/91] Added unmount --- electron.js | 30 +++++++++++-------------- helpers.js | 29 ++++++++---------------- src/components/MountItem/MountItem.js | 2 +- src/containers/MountItems/MountItems.js | 7 +----- 4 files changed, 24 insertions(+), 44 deletions(-) diff --git a/electron.js b/electron.js index a8d7d86..b5adbfa 100644 --- a/electron.js +++ b/electron.js @@ -17,7 +17,7 @@ const AutoLaunch = require('auto-launch'); let trayContextMenu; let mainWindow; let mainWindowTray; -let mountedPIDs = {}; +let mountedData = {}; let mountedLocations = []; let expectedUnmount = {}; let launchHidden = false; @@ -64,10 +64,11 @@ function createWindow() { // Unmount all items for (const i in mountedLocations) { - helpers.stopMountProcess(mountedPIDs[mountedLocations[i]], mountedLocations[i]); + const data = mountedData[mountedLocations[i]]; + helpers.stopMountProcess(data.DataDirectory, data.Version, data.StorageType); } mountedLocations = []; - mountedPIDs = {}; + mountedData = {}; }); if ((os.platform() === 'win32') || (os.platform() === 'linux')) { @@ -363,11 +364,6 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { Hyperspace: hsLocation, Sia: siaLocation, SiaPrime: siaPrimeLocation, - }, - PIDS: { - Hyperspace: results.Hyperspace.PID, - Sia: results.Sia.PID, - SiaPrime: results.SiaPrime.PID, } }); }) @@ -539,17 +535,20 @@ ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => { console.log(data.StorageType + ' already mounted: ' + data.Location); } else { mountedLocations.push(data.Location); - mountedPIDs[data.Location] = -1; + mountedData[data.Location] = { + DataDirectory: dataDirectory, + Version: data.Version, + StorageType: data.StorageType, + }; const errorHandler = (pid, error) => { if (mountedLocations.indexOf(data.Location) !== -1) { mountedLocations.splice(mountedLocations.indexOf(data.Location), 1); - delete mountedPIDs[data.Location]; + delete mountedData[data.Location]; } standardIPCReply(event, Constants.IPC_Unmount_Drive_Reply, { Expected: expectedUnmount[data.StorageType], Location: data.Location, - PID: -1, StorageType: data.StorageType, }, error || Error(data.StorageType + ' Unmounted')); }; @@ -557,12 +556,8 @@ ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => { .executeMount(dataDirectory, data.Version, data.StorageType, data.Location, data.NoConsoleSupported, (error, pid) => { errorHandler(pid, error); }) - .then(pid => { - if (pid !== -1) { - mountedPIDs[data.Location] = pid; - } + .then(() => { standardIPCReply(event, Constants.IPC_Mount_Drive_Reply, { - PID: pid, StorageType: data.StorageType, }); }) @@ -603,9 +598,10 @@ ipcMain.on(Constants.IPC_Shutdown, () => { }); ipcMain.on(Constants.IPC_Unmount_Drive, (event, data) => { + const dataDirectory = helpers.resolvePath(data.Directory); expectedUnmount[data.StorageType] = true; helpers - .stopMountProcess(data.PID, data.Location) + .stopMountProcess(dataDirectory, data.Version, data.StorageType) .then((result)=> { console.log(result); }) diff --git a/helpers.js b/helpers.js index 2860a42..8f496e3 100644 --- a/helpers.js +++ b/helpers.js @@ -159,7 +159,7 @@ module.exports.executeAsync = (command, args=[]) => { module.exports.executeMount = (directory, version, storageType, location, noConsoleSupported, exitCallback) => { return new Promise((resolve) => { const processOptions = { - detached: os.platform() === 'win32', + detached: false, shell: true, stdio: 'ignore', }; @@ -199,9 +199,7 @@ module.exports.executeMount = (directory, version, storageType, location, noCons exitCallback(code, pid); }); - if (os.platform() === 'win32') { - process.unref(); - } + process.unref(); }); }; @@ -443,31 +441,22 @@ module.exports.setConfigValue = (name, value, directory, storageType, version) = }); }; -module.exports.stopMountProcess = (pid, location) => { +module.exports.stopMountProcess = (directory, version, storageType) => { return new Promise((resolve, reject) => { const processOptions = { - detached: true, + detached: false, shell: true, windowsHide: true, }; - let procName = 'kill'; - if (location && location.length > 0) { - procName = 'fusermount'; - } - const command = (os.platform() === 'win32') ? 'taskkill.exe' : procName; - const args = []; - if (os.platform() === 'win32') { - args.push('/PID'); - } - if (procName === 'fusermount') { - args.push('-u'); - args.push(location); - } else { - args.push(pid); + const command = path.join(directory, version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory'); + const args = ['-unmount']; + if (Constants.PROVIDER_ARG[storageType.toLowerCase()].length > 0) { + args.push(Constants.PROVIDER_ARG[storageType.toLowerCase()]); } const process = new spawn(command, args, processOptions); + const pid = process.pid; process.on('error', (err) => { reject(err); }); diff --git a/src/components/MountItem/MountItem.js b/src/components/MountItem/MountItem.js index 5356a14..3f2742f 100644 --- a/src/components/MountItem/MountItem.js +++ b/src/components/MountItem/MountItem.js @@ -60,7 +60,7 @@ export default CSSModules((props) => { width='19px'/>; const actionsDisplay = ( - + + )); + } + } + + retryDisplay = ( + + +

Mount Failed

+ {retryList} +
+
+ ) + } + let items = []; for (const provider of Constants.PROVIDER_LIST) { const providerLower = provider.toLowerCase(); @@ -212,6 +297,7 @@ class MountItems extends Component { return (
+ {retryDisplay} {items}
); } From 71d329b61b051aff68b7cd7918744e56e231879c Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Wed, 12 Dec 2018 13:21:11 -0600 Subject: [PATCH 51/91] Fix cancel --- src/containers/MountItems/MountItems.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index 5d3a6d7..ced4801 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -51,7 +51,7 @@ class MountItems extends Component { }; delete retryItems[storageType]; this.setState({ - DisplayRetry: Object.keys(retryItems) > 0, + DisplayRetry: Object.keys(retryItems).length > 0, RetryItems: retryItems, }, stateCallback); } From 2e651af8ec2f1bf0a539c9735813321e7d52058e Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Wed, 12 Dec 2018 15:29:38 -0600 Subject: [PATCH 52/91] Layout changes --- electron.js | 4 ---- src/containers/MountItems/MountItems.js | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/electron.js b/electron.js index fb93e0f..546ca87 100644 --- a/electron.js +++ b/electron.js @@ -386,7 +386,6 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { }); }) .catch(error => { - console.log(error); if (os.platform() === 'win32') { grabDriveLetters({}); } @@ -502,7 +501,6 @@ ipcMain.on(Constants.IPC_Grab_UI_Releases, (event) => { }); ipcMain.on(Constants.IPC_Install_Dependency, (event, data) => { - console.log(data); if (data.Source.toLowerCase().endsWith('.dmg')) { helpers .executeAsync('hdiutil', ['attach', data.Source]) @@ -513,7 +511,6 @@ ipcMain.on(Constants.IPC_Install_Dependency, (event, data) => { }); }) .catch(error=> { - console.log(error); standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { Source: data.Source, URL: data.URL, @@ -593,7 +590,6 @@ ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => { StorageType: data.StorageType, }; const errorHandler = (pid, error) => { - console.log(pid, error); if (mountedLocations.indexOf(data.Location) !== -1) { mountedLocations.splice(mountedLocations.indexOf(data.Location), 1); delete mountedData[data.Location]; diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index ced4801..4d82010 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -248,14 +248,19 @@ class MountItems extends Component { let retryDisplay; if (this.state.DisplayRetry) { let retryList = []; + let retryListCount = 0; for (const storageType in this.state.RetryItems) { if (this.state.RetryItems.hasOwnProperty(storageType)) { + retryListCount++; retryList.push((

Retrying {storageType} in {this.state.RetryItems[storageType].RetrySeconds}(s)

)); + if (retryListCount < Object.keys(this.state.RetryItems).length) { + retryList.push(
); + } } } From 538a2c5f8ab115dc343c247466f054193d87ea1e Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Wed, 12 Dec 2018 17:38:57 -0600 Subject: [PATCH 53/91] Retry mount fixes --- src/containers/MountItems/MountItems.js | 119 ++++++++++++------------ 1 file changed, 61 insertions(+), 58 deletions(-) diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index 4d82010..eb9b662 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -6,7 +6,6 @@ import CSSModules from 'react-css-modules'; import styles from './MountItems.css'; import Modal from '../../components/UI/Modal/Modal'; import MountItem from '../../components/MountItem/MountItem'; -import RootElem from '../../hoc/RootElem/RootElem'; const Constants = require('../../constants'); @@ -18,6 +17,7 @@ if (!process.versions.hasOwnProperty('electron')) { class MountItems extends Component { constructor(props) { super(props); + for (const provider of Constants.PROVIDER_LIST) { this.state[provider] = { AllowMount: false, @@ -25,6 +25,7 @@ class MountItems extends Component { Mounted: false, }; } + if (ipcRenderer) { ipcRenderer.on(Constants.IPC_Detect_Mounts_Reply, this.onDetectMountsReply); ipcRenderer.on(Constants.IPC_Mount_Drive_Reply, this.onMountDriveReply); @@ -72,18 +73,19 @@ class MountItems extends Component { }; detectMounts = ()=> { - this.props.mountsBusy(true); - ipcRenderer.send(Constants.IPC_Detect_Mounts, { - Directory: this.props.directory, - Version: this.props.version, - }); + if (!this.state.DisplayRetry) { + this.props.mountsBusy(true); + ipcRenderer.send(Constants.IPC_Detect_Mounts, { + Directory: this.props.directory, + Version: this.props.version, + }); + } }; handleMountLocationChanged = (storageType, value) => { if (this.props.platform === 'win32') { this.props.changed(storageType, this.state[storageType].DriveLetters[value]); - } - else { + } else { this.props.changed(storageType, value); } }; @@ -91,54 +93,52 @@ class MountItems extends Component { handleMountUnMount = (storageType, mount, location) => { if (!location || (location.trim().length === 0)) { this.props.errorHandler('Mount location is not set'); - } else { - if (ipcRenderer) { - let allowAction = true; - if (mount && (this.props.platform !== 'win32')) { - const result = ipcRenderer.sendSync(Constants.IPC_Check_Mount_Location, { - Location: location, - }); - if (!result.Success) { - allowAction = false; - this.props.errorHandler(result.Error.toString()); + } else if (ipcRenderer) { + let allowAction = true; + if (mount && (this.props.platform !== 'win32')) { + const result = ipcRenderer.sendSync(Constants.IPC_Check_Mount_Location, { + Location: location, + }); + if (!result.Success) { + allowAction = false; + this.props.errorHandler(result.Error.toString()); + } + } + + if (allowAction) { + const storageState = { + ...this.state[storageType], + AllowMount: false, + }; + + this.props.mountsBusy(true); + + this.setState({ + [storageType]: storageState, + }, () => { + if (mount) { + ipcRenderer.send(Constants.IPC_Mount_Drive, { + Directory: this.props.directory, + Location: location, + NoConsoleSupported: this.props.noConsoleSupported, + StorageType: storageType, + Version: this.props.version, + }); + } else { + ipcRenderer.send(Constants.IPC_Unmount_Drive, { + Directory: this.props.directory, + Location: location, + StorageType: storageType, + Version: this.props.version, + }); } - } - - if (allowAction) { - const state = { - ...this.state[storageType], - AllowMount: false, - }; - - this.props.mountsBusy(true); - - this.setState({ - [storageType]: state, - }, () => { - if (mount) { - ipcRenderer.send(Constants.IPC_Mount_Drive, { - Directory: this.props.directory, - Location: location, - NoConsoleSupported: this.props.noConsoleSupported, - StorageType: storageType, - Version: this.props.version, - }); - } else { - ipcRenderer.send(Constants.IPC_Unmount_Drive, { - Directory: this.props.directory, - Location: location, - StorageType: storageType, - Version: this.props.version, - }); - } - }); - } + }); } } }; onDetectMountsReply = (event, arg) => { - if (arg.data.Success) { + if (!this.state.DisplayRetry && arg.data.Success) { let state = {}; let mountsBusy = false; for (const provider of Constants.PROVIDER_LIST) { @@ -199,7 +199,13 @@ class MountItems extends Component { retryItems[storageType] = { RetrySeconds: 10, }; + const storageState = { + ...this.state[arg.data.StorageType], + AllowMount: false, + Mounted: false, + }; this.setState({ + [storageType]: storageState, DisplayRetry: true, RetryItems: retryItems, }, () => { @@ -252,21 +258,18 @@ class MountItems extends Component { for (const storageType in this.state.RetryItems) { if (this.state.RetryItems.hasOwnProperty(storageType)) { retryListCount++; - retryList.push(( - -

Retrying {storageType} in {this.state.RetryItems[storageType].RetrySeconds}(s)

- -
- )); + retryList.push(); if (retryListCount < Object.keys(this.state.RetryItems).length) { - retryList.push(
); + retryList.push(
); } } } retryDisplay = ( - +

Mount Failed

{retryList}
From 2042d7140f823f90759176c84386f8fa5996d19b Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Wed, 12 Dec 2018 20:00:27 -0600 Subject: [PATCH 54/91] Removed extra character --- src/containers/MountItems/MountItems.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index eb9b662..aeb2860 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -260,7 +260,7 @@ class MountItems extends Component { retryListCount++; retryList.push(); + key={'b' + retryListCount}>Cancel {storageType} Remount ({this.state.RetryItems[storageType].RetrySeconds}s)); if (retryListCount < Object.keys(this.state.RetryItems).length) { retryList.push(
); } From b4f1158bba36f1d59123351c27c4a4ccd7958c1c Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Wed, 12 Dec 2018 20:13:38 -0600 Subject: [PATCH 55/91] Layout changes --- src/containers/MountItems/MountItems.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index aeb2860..96a4e2e 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -270,7 +270,7 @@ class MountItems extends Component { retryDisplay = ( -

Mount Failed

+

Mount Failed

{retryList}
From e825beb665707883fc1d09929a25caa1aef8df8e Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Wed, 12 Dec 2018 22:00:06 -0600 Subject: [PATCH 56/91] Default close behavior on OS X --- electron.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/electron.js b/electron.js index 546ca87..e0716cf 100644 --- a/electron.js +++ b/electron.js @@ -175,19 +175,7 @@ if (!instanceLock) { app.on('ready', createWindow); app.on('window-all-closed', () => { - // On OS X it is common for applications and their menu bar - // to stay active until the user quits explicitly with Cmd + Q - if (process.platform !== 'darwin') { - closeApplication(); - } - }); - - app.on('activate', () => { - // On OS X it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (mainWindow === null) { - createWindow() - } + closeApplication(); }); } From 63d69f0b9ee9ff131ca996d5062b14df539dc926 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Wed, 12 Dec 2018 23:00:42 -0600 Subject: [PATCH 57/91] Package upgrades --- package.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index a923459..3f06e43 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "version": "1.0.2", "private": true, "dependencies": { - "@fortawesome/fontawesome-svg-core": "^1.2.1", - "@fortawesome/free-solid-svg-icons": "^5.1.1", + "@fortawesome/fontawesome-svg-core": "^1.2.10", + "@fortawesome/free-solid-svg-icons": "^5.6.1", "@fortawesome/react-fontawesome": "^0.1.0", "auto-launch": "^5.0.5", "autoprefixer": "7.1.6", @@ -17,7 +17,7 @@ "babel-runtime": "6.26.0", "case-sensitive-paths-webpack-plugin": "2.1.1", "chalk": "1.1.3", - "color": "^3.0.0", + "color": "^3.1.0", "color-string": "^1.5.2", "css-loader": "0.28.7", "dotenv": "4.0.0", @@ -35,23 +35,23 @@ "fs-extra": "3.0.1", "html-webpack-plugin": "2.29.0", "jest": "20.0.4", - "node-schedule": "^1.3.0", - "npm": "^6.4.1", + "node-schedule": "^1.3.1", + "npm": "^6.5.0", "object-assign": "4.1.1", "postcss-flexbugs-fixes": "3.2.0", "postcss-loader": "2.0.8", "promise": "8.0.1", "raf": "3.4.0", "react": "^16.6.1", - "react-css-modules": "^4.7.4", - "react-dev-utils": "^5.0.1", + "react-css-modules": "^4.7.8", + "react-dev-utils": "^5.0.3", "react-dom": "^16.6.1", - "react-loader-spinner": "^2.2.0", + "react-loader-spinner": "^2.3.0", "react-tooltip": "^3.9.0", "resolve": "1.6.0", "style-loader": "0.19.0", "sw-precache-webpack-plugin": "0.11.4", - "unzipper": "^0.9.3", + "unzipper": "^0.9.4", "url-loader": "0.6.2", "webpack": "3.8.1", "webpack-dev-server": "2.9.4", From b25062e466e23dd0b165337e7c7ce1ca1c80d398 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 13 Dec 2018 00:19:30 -0600 Subject: [PATCH 58/91] Monitor detached mounts --- electron.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/electron.js b/electron.js index e0716cf..432b357 100644 --- a/electron.js +++ b/electron.js @@ -21,6 +21,8 @@ let mountedData = {}; let mountedLocations = []; let expectedUnmount = {}; let launchHidden = false; +let firstMountCheck = true; +let manualMountDetection = {}; let isQuiting = false; app.on('before-quit', function () { @@ -190,6 +192,36 @@ const loadUiSettings = () => { } }; +const monitorMount = (sender, storageType, dataDirectory, version, pid, location) => { + manualMountDetection[storageType] = setInterval(() => { + helpers + .detectRepertoryMounts(dataDirectory, version) + .then(result => { + if (result[storageType].PID !== pid) { + if (result[storageType].PID === -1) { + clearTimeout(manualMountDetection[storageType]); + delete manualMountDetection[storageType]; + + sender.send(Constants.IPC_Unmount_Drive_Reply, { + data: { + Expected: expectedUnmount[storageType], + Location: location, + StorageType: storageType, + Error: Error(storageType + ' Unmounted').toString(), + Success: false, + } + }); + } else { + pid = result[storageType].PID; + } + } + }) + .catch(e => { + console.log(e); + }); + },6000); +}; + const saveUiSettings = () => { const settingFile = path.join(helpers.resolvePath(Constants.DATA_LOCATIONS[os.platform()]), 'ui.json'); try { @@ -349,18 +381,22 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { helpers .detectRepertoryMounts(dataDirectory, data.Version) .then((results) => { - let data = {}; + let storageData = {}; let locations = {}; for (const provider of Constants.PROVIDER_LIST) { - data[provider] = results[provider] ? results[provider] : { + storageData[provider] = results[provider] ? results[provider] : { Active: false, Location: '', PID: -1, }; - if (data[provider].PID !== -1) { + locations[provider] = storageData[provider].Location; + + if (storageData[provider].PID !== -1) { expectedUnmount[provider] = false; + if (firstMountCheck) { + monitorMount(event.sender, provider, dataDirectory, data.Version, storageData[provider].PID, storageData[provider].Location); + } } - locations[provider] = data[provider].Location; } if (os.platform() === 'win32') { @@ -368,6 +404,9 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { } setImage(locations); + if (firstMountCheck) { + firstMountCheck = false; + } standardIPCReply(event, Constants.IPC_Detect_Mounts_Reply, { DriveLetters: driveLetters, Locations: locations, @@ -635,6 +674,11 @@ ipcMain.on(Constants.IPC_Shutdown, () => { }); ipcMain.on(Constants.IPC_Unmount_Drive, (event, data) => { + if (manualMountDetection[data.StorageType]) { + clearInterval(manualMountDetection[data.StorageType]); + delete manualMountDetection[data.StorageType]; + } + const dataDirectory = helpers.resolvePath(data.Directory); expectedUnmount[data.StorageType] = true; helpers From add2797fdada30735a165073adcdcf12e54e383b Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 13 Dec 2018 01:01:40 -0600 Subject: [PATCH 59/91] Updated package name --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 3f06e43..0f8b972 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,7 @@ "homepage": "./", "build": { "appId": "repertory-ui", + "artifactName": "${productName}_${version}_${os}_${arch}.${ext}", "files": [ "./electron.js", "./src/constants.js", @@ -130,6 +131,9 @@ "linux": { "icon": "./build/icon.icns" }, + "mac": { + "icon": "./build/icon.icns" + }, "win": { "icon": "./build/icon.ico" }, From 98e06b4498714162fc119458dedc39cadfc96e88 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 13 Dec 2018 13:30:40 -0600 Subject: [PATCH 60/91] Layout changes --- electron.js | 18 ++--- package.json | 2 +- src/App.js | 2 +- .../ReleaseVersionDisplay.js | 72 +++++++++++++------ 4 files changed, 61 insertions(+), 33 deletions(-) diff --git a/electron.js b/electron.js index 432b357..5175b7c 100644 --- a/electron.js +++ b/electron.js @@ -37,7 +37,7 @@ function createWindow() { loadUiSettings(); // Create the browser window. - const height = (process.env.ELECTRON_START_URL ? 400 : 380) - (os.platform() === 'win32' ? 0 : 24); + const height = (process.env.ELECTRON_START_URL ? 364 : 344) - ((os.platform() === 'win32') || (os.platform() === 'darwin') ? 0 : 24); mainWindow = new BrowserWindow({ width: 428 + (os.platform() === 'win32' ? 0 : 120), height: height, @@ -181,6 +181,13 @@ if (!instanceLock) { }); } +const clearManualMountDetection = (storageType) => { + if (manualMountDetection[storageType]) { + clearInterval(manualMountDetection[storageType]); + delete manualMountDetection[storageType]; + } +}; + const loadUiSettings = () => { const settingFile = path.join(helpers.resolvePath(Constants.DATA_LOCATIONS[os.platform()]), 'ui.json'); try { @@ -199,9 +206,7 @@ const monitorMount = (sender, storageType, dataDirectory, version, pid, location .then(result => { if (result[storageType].PID !== pid) { if (result[storageType].PID === -1) { - clearTimeout(manualMountDetection[storageType]); - delete manualMountDetection[storageType]; - + clearManualMountDetection(storageType); sender.send(Constants.IPC_Unmount_Drive_Reply, { data: { Expected: expectedUnmount[storageType], @@ -674,10 +679,7 @@ ipcMain.on(Constants.IPC_Shutdown, () => { }); ipcMain.on(Constants.IPC_Unmount_Drive, (event, data) => { - if (manualMountDetection[data.StorageType]) { - clearInterval(manualMountDetection[data.StorageType]); - delete manualMountDetection[data.StorageType]; - } + clearManualMountDetection(data.StorageType); const dataDirectory = helpers.resolvePath(data.Directory); expectedUnmount[data.StorageType] = true; diff --git a/package.json b/package.json index 0f8b972..ee8436a 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "linux": { "icon": "./build/icon.icns" }, - "mac": { + "mac": { "icon": "./build/icon.icns" }, "win": { diff --git a/src/App.js b/src/App.js index 1bd8781..816c872 100644 --- a/src/App.js +++ b/src/App.js @@ -684,7 +684,7 @@ class App extends Component { let key = 0; mainContent.push((
+ style={{height: '25%'}}> { - let optionsDisplay = null; + let optionsDisplay = []; + let key = 0; if (props.releaseExtracting) { - optionsDisplay = '}/> + optionsDisplay.push(( + (dimensions.columns / 3) * 2} + colSpan={'remain'} + key={key++} + rowSpan={4} + text={'Activating'} + textAlign={'left'} + type={'Heading2'}/> + )); + optionsDisplay.push(( + (dimensions.columns / 3) * 2} + colSpan={'remain'} + key={key++} + row={5} + rowSpan={7} + text={props.installedVersion} + textAlign={'left'}/> + )); + } else if (props.downloadDisabled) { + optionsDisplay.push(( + (dimensions.columns / 3) * 2} + colSpan={'remain'} + key={key++} + rowSpan={4} + text={'Installed'} + textAlign={'left'} + type={'Heading2'}/> + )); + + optionsDisplay.push(( + (dimensions.columns / 3) * 2} + colSpan={'remain'} + key={key++} + row={5} + rowSpan={7} + text={props.installedVersion} + textAlign={'left'}/> + )); } else { - optionsDisplay = ; + optionsDisplay.push(( + + )); } return ( @@ -56,18 +94,6 @@ export default CSSModules((props) => { row={5} rowSpan={7} selected={props.version}/> - (dimensions.columns / 3) * 2} - colSpan={'remain'} - rowSpan={4} - text={'Installed'} - textAlign={'left'} - type={'Heading2'}/> - (dimensions.columns / 3) * 2} - colSpan={'remain'} - row={5} - rowSpan={7} - text={props.installedVersion} - textAlign={'left'}/> {optionsDisplay} ); From 8618bf99650adfd6864e06322c880233fd6c91bf Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 13 Dec 2018 15:00:07 -0600 Subject: [PATCH 61/91] [Partial browse mount location] [Layout changes] --- electron.js | 16 +++++++++- src/components/MountItem/MountItem.css | 3 +- src/components/MountItem/MountItem.js | 41 +++++++++++++++++-------- src/constants.js | 2 ++ src/containers/MountItems/MountItems.js | 12 ++++++++ 5 files changed, 58 insertions(+), 16 deletions(-) diff --git a/electron.js b/electron.js index 5175b7c..defc41c 100644 --- a/electron.js +++ b/electron.js @@ -1,6 +1,6 @@ // Modules to control application life and create native browser window -const {app, BrowserWindow, Tray, nativeImage, Menu} = require('electron'); +const {app, BrowserWindow, Tray, nativeImage, Menu, dialog} = require('electron'); const {ipcMain} = require('electron'); const Constants = require('./src/constants'); const path = require('path'); @@ -249,6 +249,20 @@ const standardIPCReply = (event, channel, data, error) => { } }; +ipcMain.on(Constants.IPC_Browse_Directory, (event, data) => { + dialog.showOpenDialog(mainWindow, { + defaultPath: data.Location, + properties: ['openDirectory'], + title: data.Title, + }, (filePaths) => { + if (filePaths && (filePaths.length > 0)) { + event.returnValue = filePaths[0]; + } else { + event.returnValue = ''; + } + }); +}); + ipcMain.on(Constants.IPC_Check_Dependency_Installed, (event, data) => { try { const exists = fs.lstatSync(data.File).isFile(); diff --git a/src/components/MountItem/MountItem.css b/src/components/MountItem/MountItem.css index 81d91fc..5deeed2 100644 --- a/src/components/MountItem/MountItem.css +++ b/src/components/MountItem/MountItem.css @@ -1,7 +1,6 @@ input.Input { - display: block; margin: 0; - padding: 2px; + padding: 5px; border-radius: var(--border_radius); background: rgba(160, 160, 160, 0.1); border: none; diff --git a/src/components/MountItem/MountItem.js b/src/components/MountItem/MountItem.js index 3f2742f..a67039c 100644 --- a/src/components/MountItem/MountItem.js +++ b/src/components/MountItem/MountItem.js @@ -27,29 +27,44 @@ export default CSSModules((props) => { } let inputColumnSpan; - let inputControl = null; + let inputControls = null; if (props.platform === 'win32') { inputColumnSpan = 20; - inputControl = ; + inputControls = ; } else { - inputColumnSpan = 50; - inputControl = ( - - ); + + )); + inputControls.push(( + + )); } const buttonDisplay = props.allowMount || props.disabled ? @@ -101,7 +116,7 @@ export default CSSModules((props) => { rowSpan={5} text={props.title} type={'Heading1'}/> - {inputControl} + {inputControls} {actionsDisplay} {autoMountControl} {autoRestartControl} diff --git a/src/constants.js b/src/constants.js index 4d0a498..2485d99 100644 --- a/src/constants.js +++ b/src/constants.js @@ -21,6 +21,8 @@ exports.PROVIDER_ARG = { siaprime: '-sp' }; +exports.IPC_Browse_Directory = 'browse_directory'; + exports.IPC_Check_Dependency_Installed = 'check_dependency_installed'; exports.IPC_Check_Dependency_Installed_Reply = 'check_dependency_installed'; diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index 96a4e2e..2480e4a 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -82,6 +82,17 @@ class MountItems extends Component { } }; + handleBrowseLocation = (storageType, location) => { + location = ipcRenderer.sendSync(Constants.IPC_Browse_Directory, { + Title: storageType + ' Mount Location', + Location: location, + }); + if (location && (location.length > 0)) { + console.log(location); + //this.handleMountLocationChanged(storageType, location); + } + }; + handleMountLocationChanged = (storageType, value) => { if (this.props.platform === 'win32') { this.props.changed(storageType, this.state[storageType].DriveLetters[value]); @@ -287,6 +298,7 @@ class MountItems extends Component { autoMountChanged={(e)=>this.props.autoMountChanged(provider, e)} autoRestart={this.props[providerLower].AutoRestart} autoRestartChanged={(e)=>this.props.autoRestartChanged(provider, e)} + browseClicked={this.handleBrowseLocation} changed={(e) => this.handleMountLocationChanged(provider, e.target.value)} clicked={this.handleMountUnMount} configClicked={()=>this.props.configClicked(provider)} From 9b2f12200c962b5c8e7907568ce97d59817c291f Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 13 Dec 2018 19:05:00 -0600 Subject: [PATCH 62/91] OS X changes --- electron.js | 144 ++++++++++++++++++++--------------------- package.json | 4 +- public/icon_color.icns | Bin 0 -> 31551 bytes public/logo_hs.png | Bin 3471 -> 0 bytes public/logo_sia.png | Bin 3471 -> 0 bytes 5 files changed, 73 insertions(+), 75 deletions(-) create mode 100644 public/icon_color.icns delete mode 100644 public/logo_hs.png delete mode 100644 public/logo_sia.png diff --git a/electron.js b/electron.js index defc41c..6f9733a 100644 --- a/electron.js +++ b/electron.js @@ -74,86 +74,84 @@ function createWindow() { mountedData = {}; }); - if ((os.platform() === 'win32') || (os.platform() === 'linux')) { - const appPath = (os.platform() === 'win32') ? - path.resolve(path.join(app.getAppPath(), '..\\..\\repertory-ui.exe')) : - process.env.APPIMAGE; + const appPath = (os.platform() === 'win32') ? path.resolve(path.join(app.getAppPath(), '..\\..\\repertory-ui.exe')) : + (os.platform() === 'darwin') ? app.getAppPath() : + process.env.APPIMAGE; - const autoLauncher = new AutoLaunch({ - name: 'Repertory UI', - path: appPath, - }); + const autoLauncher = new AutoLaunch({ + name: 'Repertory UI', + path: appPath, + }); - const image = nativeImage.createFromPath(path.join(__dirname, '/build/logo.png')); - trayContextMenu = Menu.buildFromTemplate([ - { - label: 'Visible', type: 'checkbox', click(item) { - if (item.checked) { - mainWindow.show(); - if (mainWindow.isMinimized()) { - mainWindow.restore(); - } - mainWindow.focus() - } else { - mainWindow.hide(); + const image = nativeImage.createFromPath(path.join(__dirname, (os.platform() === 'darwin') ? '/build/icon.icns' : '/build/logo.png')); + trayContextMenu = Menu.buildFromTemplate([ + { + label: 'Visible', type: 'checkbox', click(item) { + if (item.checked) { + mainWindow.show(); + if (mainWindow.isMinimized()) { + mainWindow.restore(); } - }, - checked: !launchHidden, - }, - { - label: 'Auto-start', type: 'checkbox', click(item) { - if (item.checked) { - autoLauncher.enable(); - } else { - autoLauncher.disable(); - } - } - }, - { - type: 'separator' - }, - { - label: 'Launch Hidden', type: 'checkbox', click(item) { - launchHidden = !!item.checked; - saveUiSettings(); - }, - checked: launchHidden, - }, - { - type: 'separator' - }, - { - label: 'Exit and Unmount', click(item) { - closeApplication(); - } - } - ]); - - mainWindow.on('close', function (event) { - if (!isQuiting) { - event.preventDefault(); - if (mainWindow.isVisible()) { + mainWindow.focus() + } else { mainWindow.hide(); - trayContextMenu.items[0].checked = false; - mainWindowTray.setContextMenu(trayContextMenu); } - event.returnValue = false; + }, + checked: !launchHidden, + }, + { + label: 'Auto-start', type: 'checkbox', click(item) { + if (item.checked) { + autoLauncher.enable(); + } else { + autoLauncher.disable(); + } } - }); - - autoLauncher - .isEnabled() - .then((enabled) => { - trayContextMenu.items[1].checked = enabled; - - mainWindowTray = new Tray(image); - mainWindowTray.setToolTip('Repertory UI'); - mainWindowTray.setContextMenu(trayContextMenu) - }) - .catch(() => { + }, + { + type: 'separator' + }, + { + label: 'Launch Hidden', type: 'checkbox', click(item) { + launchHidden = !!item.checked; + saveUiSettings(); + }, + checked: launchHidden, + }, + { + type: 'separator' + }, + { + label: 'Exit and Unmount', click() { closeApplication(); - }); - } + } + } + ]); + + mainWindow.on('close', function (event) { + if (!isQuiting) { + event.preventDefault(); + if (mainWindow.isVisible()) { + mainWindow.hide(); + trayContextMenu.items[0].checked = false; + mainWindowTray.setContextMenu(trayContextMenu); + } + event.returnValue = false; + } + }); + + autoLauncher + .isEnabled() + .then((enabled) => { + trayContextMenu.items[1].checked = enabled; + + mainWindowTray = new Tray(image); + mainWindowTray.setToolTip('Repertory UI'); + mainWindowTray.setContextMenu(trayContextMenu) + }) + .catch(() => { + closeApplication(); + }); } const instanceLock = app.requestSingleInstanceLock(); diff --git a/package.json b/package.json index ee8436a..41afae9 100644 --- a/package.json +++ b/package.json @@ -129,10 +129,10 @@ "./helpers.js" ], "linux": { - "icon": "./build/icon.icns" + "icon": "./build/logo.png" }, "mac": { - "icon": "./build/icon.icns" + "icon": "./build/icon_color.icns" }, "win": { "icon": "./build/icon.ico" diff --git a/public/icon_color.icns b/public/icon_color.icns new file mode 100644 index 0000000000000000000000000000000000000000..6f2482bfe4f7ba9d8a27150d520827d7c54cf499 GIT binary patch literal 31551 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 ID#>F7BL>j5n#ln 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 diff --git a/public/logo_sia.png b/public/logo_sia.png deleted file mode 100644 index bf5c63da289e266f69c94f3e7d5e6988845d777c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3471 zcmb_ei$B!c7T>?0-wZQS!x)O>5vB&^aFQMv5eB6s26-G25)CCv%#S$INnRoHm^7U{ zB9A-5cV4RErz1(I)z_4s~{RDxqTc%B15p7?D;ps;A8 zR499%cIcq&N4yMaJIE4wsz@zvrrBD%#g6ccy`x4Qln(BsW|nQq<445wcQ*6p%^%_7 zV{vN&{ms4^O+3=8>-HNgt>L*3hB5VstI0uBEAp@{W}Bm81jr?u%4g(BzxeCKI+Y#2 zHm+$E?_!PtR!gF#_=`7TMq-JZxXl4jDF&AL(Y@NC#)4zb3Z+C{fUMmOR}6Qe1!*Yt zs10=y1O@DpaMOkOYY1x`-sZzq&CbhKX;QemxHz@aXOK98_zznJiaXee>^p3tdOYz! z|8W@y(7I8aA}@UV+9~{eGGr<+LUC^q53DD*+UL3T@({yUh5k6H4R&12nmyz}}1x;j|((<$4 z)0XqY{WuhsJqc)hS+x6DiCcQ8`)iqb*liy%w zIrhzq!j=u(X4qo1g5fFXR$%TzcY(9?|%BIm7dh`#@s>u{SqCyoeVLq>-I0!)Gd`pS%Ox17*GK~rFkGtQy2gQ z068Fi3$(!Bs6cJlXQnk@n!j;2Ti^9QBcAhcF7vzLy`;CBC8DByoss9I>RB*}8z~#V z)U6_lx#382l3%V(x998hcp1~~lw`ZAo5)YFG+?^J%e#CXr32Ly24P)+DVLUiiL!Cu zZY~=~4qW4~E7%3;oSa0}u79`z=hkIYrw{t{jp?UUVw*q|k=xyLjGV;iI~|6h%b3@2 zci!c0xEJJmG$0R=`1X4cA|oKHJfZ(+TD)qXXXH8~kW*L}4@ zBt!Z)H7y&I{@)PBDv$a`}R2*DJ3%G?T#{$Z+9 zKT%UZrQnOv9Si<#RqM-E)FuAh%3V*y7MXX4I5|}MiPmWN)|+APC++5d)!icND95CL=} zkWf!Sub8&CnLm)GRh0?E9pGb(dGcuU(|wzj{IpNJJ3(%H026>4jx~WWw5J-`PQ{Zs1c=dGp=+tiSQ8j z*m0^_n%0&^QMr9PHgm6{o5mlH(i%w!=+EtHO}*lZ)aC;GajOtg@T!-A0Rmhw%=YTS zqWv2L^^~x)F7$x#p+;T*m>0_bLw`ZI+J9s7`Ol_8GJxayC0|~PjoxsH{z=X$*Su^c z{h6PV+Ae>LLm$hruG<~`t{vemy=a`K=aK4-vY_v`qm`(iqgP9ow}I7IF>`c<-b(H2brNlL~xw z(G;A&&Q#ZpKd<0^IQ`Yf90I>l(E5O=8{q*ZUYY&UoS)wcac7+_e4sqg8s0}v98gkr z0ELwR?@{t&+Qnd~^U;~;k1v^s;47uK8H&+Qstd#9Ay(gWu)JQ0tieLirm3!6iN#Ba zs)tuX;_puW$~Y7c)WV_5n1KeGdGxT=4oMdG!izn=XNt`gyGZ~>pHt9Uta1Hp)a_dx z3-`rL4w9FJJh}IV5jx-jmPJbzN>tG3;@l~>?KXN&Roo%82Rk3a;@9rhNP-gv%*%7% zty4x=4p@ZwSV^EG@LpzyJb(q^=v%f>uXDp?T|xc$2|c*el3A2L5`R_cQ-_DlD@^1?=We?_JX3UfKGI+R*ghn4 z_#&s4!gI;trVwMqum=_75-D!L<~H^0yJWm)ke099h(45j!KkRgi5$V~h)tA-W8Gag znY`q%cW19<3uA5`55bIVO{{FVWr800EX1KZex+{?j9a&6vh0(Fuuek0c5|I)yx`$27xrI&q9E}J zkm23hZq`lZ*x_Z#Xw)Iz&bxICBic2-G2g)1OdelaSV^g2@=)E@L$Uf=vRB4TGg=(?D$5V!GSNC20P)m$b&s_>@zcSQg z6p(B=VLd1@98zt1N*0ZMPz8$Myfx6?^Z6)=5mskX(S{Ex!_Y?#Cl`Mi?sGmN>hD<_ zu*NALB^gH>eXWi!(WnG39e@;EO=&SZRy=$p_6Xxu*Q~)OI!u%f&a0ONBx=MylDqgt zHnv8%(B;Cj$sa*0dq1t6E;tJbr4D&Ym#K||uI=Je?LNyQf)ESV^eK+lPK;SJnK#G} z+=8(z&?H#To0=H(<7f7+>{dGOvHK58?zlBi#?5L|+gC%XM%P$~V2|RFX_@^l*h&L| g6g>Vru~NjEEtEYPjn959|8|ph@UU&o0so|b17_HKApigX From 45a68ddbf7a4497b5f1ba68a356370c0f8b5cac7 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 13 Dec 2018 23:07:09 -0600 Subject: [PATCH 63/91] Layout changes --- electron.js | 4 ++-- public/logo.xcf | Bin 0 -> 3986 bytes src/components/MountItem/MountItem.css | 2 +- src/index.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 public/logo.xcf diff --git a/electron.js b/electron.js index 6f9733a..38dbfce 100644 --- a/electron.js +++ b/electron.js @@ -37,9 +37,9 @@ function createWindow() { loadUiSettings(); // Create the browser window. - const height = (process.env.ELECTRON_START_URL ? 364 : 344) - ((os.platform() === 'win32') || (os.platform() === 'darwin') ? 0 : 24); + const height = (process.env.ELECTRON_START_URL ? 364 : 344) - ((os.platform() === 'win32') || (os.platform() === 'darwin') ? 0 : 20); mainWindow = new BrowserWindow({ - width: 428 + (os.platform() === 'win32' ? 0 : 120), + width: 428 + (os.platform() === 'win32' ? 0 : 170), height: height, resizable: false, show: !launchHidden, diff --git a/public/logo.xcf b/public/logo.xcf new file mode 100644 index 0000000000000000000000000000000000000000..f69826ecd32ccefb5f034fcf7595d5fff6fb83f8 GIT binary patch literal 3986 zcmeHK-A)rh6rOD2G_ct3t;XNC^2ASNb;#*=(=&U|P7&YZK`ZO82$bHCN*?<>_RgV+jWe*)$J z%R+M(NbZ0lK<0rdU>R6YHjOJ{{4R91gQd%@L9gfZJ@gql@9Yenrso{;53YB_cc1O; zlcx|4b$iW@Q|=7iL*g*nVx^IH(slS~&~*>j)1`K&HRuk8ycDYPuyfGlmB*D(B8;kX ztz+sz#8mC)R~t0dA00PaZok8;dM}VCQKaI^@A|IC-G1xH8PWVfyFGHevjfuX%aml! zPo;Y>#QH8fQ(vW?xi59BrpOzUIv^TB4rfewokZb{geqh+T zFsUdFiTyM>Hf#c|3yBw`4qF>70TM4s%~*gD8aCS!){U_wR+&T`+5-OT%lDw~=;rsj zC2UGgMIo%``lessB=&c8Ok-|K9aB9UlK5hDbo8o@6W=0ypb|ecA0TRt3M-=?ufx2! z$0Xv=7BC4~$8>${WkHwA=nX)S^;PlfAv;O+m7_4nlBD;n79G8+uVnaeDW~?Ko7~qE zf@zy+l-L?-<|-7#0xO6Zo5Psfp^M>JuZm|)(1kFr5Z22^&EKdIJ4yADq=3efelfPs zqF42jK8o;xN}p;zz(@_wmQf2)$cj0Zh40@%?jLowWx*+!MTIc$wYpymzpExG?-Yw6 znI}d^N3Zgpc@yCSmGLzn#PFU_SY$=y_99Xu%TnO~9^`r#_bCcGJS!-K`KvbkYJ=EG z%Afwmr??d|*9i84=_@vtM-`J$nEE literal 0 HcmV?d00001 diff --git a/src/components/MountItem/MountItem.css b/src/components/MountItem/MountItem.css index 5deeed2..bd0afe4 100644 --- a/src/components/MountItem/MountItem.css +++ b/src/components/MountItem/MountItem.css @@ -1,6 +1,6 @@ input.Input { margin: 0; - padding: 5px; + padding: 3px; border-radius: var(--border_radius); background: rgba(160, 160, 160, 0.1); border: none; diff --git a/src/index.js b/src/index.js index 1057b5f..6ada234 100644 --- a/src/index.js +++ b/src/index.js @@ -13,7 +13,7 @@ if (!process.versions.hasOwnProperty('electron')) { ipcRenderer.on(Constants.IPC_Get_Platform_Reply, (event, arg) => { if (arg.data !== 'win32') { let root = document.documentElement; - root.style.setProperty('--default_font_size', '4.4vmin'); + root.style.setProperty('--default_font_size', '4.8vmin'); } ReactDOM.render(, document.getElementById('root')); registerServiceWorker(); From 302b31cf73b99bbcb853765db5c2d5e93533c6d9 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 13 Dec 2018 23:16:46 -0600 Subject: [PATCH 64/91] Layout changes --- electron.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron.js b/electron.js index 38dbfce..167ba62 100644 --- a/electron.js +++ b/electron.js @@ -39,7 +39,7 @@ function createWindow() { // Create the browser window. const height = (process.env.ELECTRON_START_URL ? 364 : 344) - ((os.platform() === 'win32') || (os.platform() === 'darwin') ? 0 : 20); mainWindow = new BrowserWindow({ - width: 428 + (os.platform() === 'win32' ? 0 : 170), + width: 428 + (os.platform() === 'win32' ? 0 : 160), height: height, resizable: false, show: !launchHidden, From 1ea1804fd0576e86ebc4eee4c3a60d560bc015e4 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 14 Dec 2018 15:35:43 -0600 Subject: [PATCH 65/91] Logo changes --- public/logo.xcf | Bin 3986 -> 5490 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/public/logo.xcf b/public/logo.xcf index f69826ecd32ccefb5f034fcf7595d5fff6fb83f8..ab3f1a64ede89ecc29fc7efd6f61b4d9bfe4b9f7 100644 GIT binary patch literal 5490 zcmeHLPiqrF6rUvhlm1DYv`HzYm1(t-f{`Q*r3!5WJ(Pk4Q4b;_q{${-ZIjwW-JX(z z2k`@V@*v{J@B@e^5f6R6jjyT? zQ|VO)0A+q^AOirUR{-e2WpoUr=}4f4K$2CUGk0JmM-d@XhR zGn8d(!gprOiUlSSfc63Z_31e17@a+?YqF-3$PmG;5YNj91Izu-D=Uh zS9LscLpz|g4|JrU?RC5-X(U+!_1FnfF~g#$)hNdN8=CgpIUWh&20o5R5@fw4os4Vk zrFt9FwIX%sjnUV;SM?Tp@8N?f^hMk216igKXN!n$Cxpcm3kyGsU`%)Dn7h_a`&kqe zEXEbwdRb08%kCegUaFTMZL=lgpIW@RdsQ#v-#vUVg_R#?6PN~PbEpL`ghYge;QM=! z_xD=coZz&{X$3d$>5P-^x%VroVM8JxjE>&D%4_7ChYzO6Pi?RJaZV^qvlw!F5nTpO~P3d46 fFF>(f*{4`-jy*Dp`4j%ZObKbqY5Z>p?XsL13JMH`N!J&WFYPT6m5SNW6U$|R4 z;d}2iV@!RJSy_}hvn|uykZG4?7VcaZ4O8TB%yQU?!w%R=6QX(m&lOOV2}HW*m1c2W zNMIpQr69f1M@p#O%X8)}bV8Lg?M-Ip#SRbJ2ke`xFf Date: Sat, 15 Dec 2018 00:00:09 -0600 Subject: [PATCH 66/91] Fix browse disabled --- src/components/MountItem/MountItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MountItem/MountItem.js b/src/components/MountItem/MountItem.js index a67039c..5e8e0a3 100644 --- a/src/components/MountItem/MountItem.js +++ b/src/components/MountItem/MountItem.js @@ -60,7 +60,7 @@ export default CSSModules((props) => { From 0c087f7d95d7cfd41b9108e36965f6f28465ef4d Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 15 Dec 2018 00:20:49 -0600 Subject: [PATCH 67/91] Package changes --- package.json | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 41afae9..4934dee 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,9 @@ "name": "repertory-ui", "version": "1.0.2", "private": true, + "author": "scott.e.graves@gmail.com", + "description": "GUI for Repertory - Repertory allows you to mount Hyperspace, Sia and/or SiaPrime blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows.", + "license": "MIT", "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.10", "@fortawesome/free-solid-svg-icons": "^5.6.1", @@ -129,13 +132,18 @@ "./helpers.js" ], "linux": { - "icon": "./build/logo.png" + "category": "Utility", + "icon": "./build/logo.png", + "target": "AppImage" }, "mac": { - "icon": "./build/icon_color.icns" + "category": "public.app-category.utilities", + "icon": "./build/icon_color.icns", + "target": "dmg" }, "win": { - "icon": "./build/icon.ico" + "icon": "./build/icon.ico", + "target": "nsis" }, "directories": { "buildResources": "public" From d5595e4c92c0c1f5edcdc0e473a3f168f1b851dd Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 15 Dec 2018 00:35:30 -0600 Subject: [PATCH 68/91] Set mount location --- src/containers/MountItems/MountItems.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index 2480e4a..03dd635 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -88,8 +88,7 @@ class MountItems extends Component { Location: location, }); if (location && (location.length > 0)) { - console.log(location); - //this.handleMountLocationChanged(storageType, location); + this.handleMountLocationChanged(storageType, location); } }; From 8a469b0d41a753ec127df73f824bcc2e467d2f94 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 16 Dec 2018 00:06:07 -0600 Subject: [PATCH 69/91] OS X changes --- electron.js | 38 ++++++++++++++++++-------------------- public/logo_both_mac.png | Bin 0 -> 269 bytes public/logo_mac.png | Bin 0 -> 265 bytes src/index.js | 3 ++- 4 files changed, 20 insertions(+), 21 deletions(-) create mode 100644 public/logo_both_mac.png create mode 100644 public/logo_mac.png diff --git a/electron.js b/electron.js index 167ba62..3a7af3c 100644 --- a/electron.js +++ b/electron.js @@ -37,9 +37,9 @@ function createWindow() { loadUiSettings(); // Create the browser window. - const height = (process.env.ELECTRON_START_URL ? 364 : 344) - ((os.platform() === 'win32') || (os.platform() === 'darwin') ? 0 : 20); + const height = (process.env.ELECTRON_START_URL ? 364 : 344) - ((os.platform() === 'win32') ? 0 : 20); mainWindow = new BrowserWindow({ - width: 428 + (os.platform() === 'win32' ? 0 : 160), + width: 428 + ((os.platform() === 'win32') ? 0 : (os.platform() === 'darwin') ? 150 : 160), height: height, resizable: false, show: !launchHidden, @@ -83,7 +83,7 @@ function createWindow() { path: appPath, }); - const image = nativeImage.createFromPath(path.join(__dirname, (os.platform() === 'darwin') ? '/build/icon.icns' : '/build/logo.png')); + const image = nativeImage.createFromPath(path.join(__dirname, (os.platform() === 'darwin') ? '/build/logo_mac.png' : '/build/logo.png')); trayContextMenu = Menu.buildFromTemplate([ { label: 'Visible', type: 'checkbox', click(item) { @@ -373,25 +373,23 @@ ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { }; const setImage = (locations) => { - if (os.platform() === 'win32' || os.platform() === 'linux') { - let driveInUse; - if (Object.keys(locations).length > 0) { - for (const provider of Constants.PROVIDER_LIST) { - driveInUse = locations[provider].length > 0; - if (driveInUse) - break; - } + let driveInUse; + if (Object.keys(locations).length > 0) { + for (const provider of Constants.PROVIDER_LIST) { + driveInUse = locations[provider].length > 0; + if (driveInUse) + break; } - - let image; - if (driveInUse) { - image = nativeImage.createFromPath(path.join(__dirname, '/build/logo_both.png')); - } else { - image = nativeImage.createFromPath(path.join(__dirname, '/build/logo.png')); - } - - mainWindowTray.setImage(image); } + + let image; + if (driveInUse) { + image = nativeImage.createFromPath(path.join(__dirname, os.platform() === 'darwin' ? '/build/logo_both_mac.png' : '/build/logo_both.png')); + } else { + image = nativeImage.createFromPath(path.join(__dirname, os.platform() === 'darwin' ? '/build/logo_mac.png' : '/build/logo.png')); + } + + mainWindowTray.setImage(image); }; const dataDirectory = helpers.resolvePath(data.Directory); diff --git a/public/logo_both_mac.png b/public/logo_both_mac.png new file mode 100644 index 0000000000000000000000000000000000000000..849bbb1da2dd7dd86554d390e8ab6bc9db23af5e GIT binary patch literal 269 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjS3F%DLp(Z@6C}(Ilov~d-&@h&IO;-no|`Lmpb?94#m%*-qtcjmwWk8P}s&$(G1ofC=gvktBiHrIQlaJ%V3 za;wwE^se||+ez-a2_2Tf4$<66{?9ay&C~Nc-2V97lhYG(8G)uGzgQKJ*7PG_okpaX z%Ur!L{r16s6#w~f8deBQb3J^Z=`t%{VR~0z0PB3+b%&;PwW%>Mh#1ZPWqZtY8PIzopr0B6f+tpET3 literal 0 HcmV?d00001 diff --git a/public/logo_mac.png b/public/logo_mac.png new file mode 100644 index 0000000000000000000000000000000000000000..0836d8ec3f5d99ce02fa6155a6507a0109cf5498 GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gj7d%}YLp(Z@6C}(In7`!-&-fQ= znf2hnsn>@j#9XG`&_hT*v87p`kXcC)VsJo-Tmdl;(aT3+;-f?y0A68 zb)E|(N5Aa!yPn)<_iMXvW98xD=~=jN^$gBOcWy6A zi4+K}yKTSh&pY;{4-a&@+xD>vs&1DBnk~1GOK*R8tF9=oF9Sp0{9RV6ks`lbP0l+XkK0D5j! literal 0 HcmV?d00001 diff --git a/src/index.js b/src/index.js index 6ada234..62b9876 100644 --- a/src/index.js +++ b/src/index.js @@ -11,10 +11,11 @@ if (!process.versions.hasOwnProperty('electron')) { const ipcRenderer = ((window && window.require) ? window.require('electron').ipcRenderer : null); if (ipcRenderer) { ipcRenderer.on(Constants.IPC_Get_Platform_Reply, (event, arg) => { - if (arg.data !== 'win32') { + if (arg.data === 'linux') { let root = document.documentElement; root.style.setProperty('--default_font_size', '4.8vmin'); } + ReactDOM.render(, document.getElementById('root')); registerServiceWorker(); }); From 97582f48500c19b32cc54f35e770ec3ffd8504c9 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 16 Dec 2018 00:20:07 -0600 Subject: [PATCH 70/91] Refactoring --- electron.js | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/electron.js b/electron.js index 3a7af3c..07a2437 100644 --- a/electron.js +++ b/electron.js @@ -33,6 +33,31 @@ function closeApplication() { app.quit(); } +function setWindowVisibility(show) { + if (show) { + mainWindow.show(); + if (os.platform() === 'darwin') { + app.dock.show(); + } + + if (mainWindow.isMinimized()) { + mainWindow.restore(); + } + + mainWindow.focus(); + } else { + mainWindow.hide(); + if (os.platform() === 'darwin') { + app.dock.hide(); + } + } + + if (trayContextMenu && mainWindowTray) { + trayContextMenu.items[0].checked = show; + mainWindowTray.setContextMenu(trayContextMenu) + } +} + function createWindow() { loadUiSettings(); @@ -87,15 +112,7 @@ function createWindow() { trayContextMenu = Menu.buildFromTemplate([ { label: 'Visible', type: 'checkbox', click(item) { - if (item.checked) { - mainWindow.show(); - if (mainWindow.isMinimized()) { - mainWindow.restore(); - } - mainWindow.focus() - } else { - mainWindow.hide(); - } + setWindowVisibility(item.checked); }, checked: !launchHidden, }, @@ -132,9 +149,7 @@ function createWindow() { if (!isQuiting) { event.preventDefault(); if (mainWindow.isVisible()) { - mainWindow.hide(); - trayContextMenu.items[0].checked = false; - mainWindowTray.setContextMenu(trayContextMenu); + setWindowVisibility(false); } event.returnValue = false; } @@ -160,15 +175,7 @@ if (!instanceLock) { } else { app.on('second-instance', () => { if (mainWindow) { - mainWindow.show(); - if (trayContextMenu && mainWindowTray) { - trayContextMenu.items[0].checked = true; - mainWindowTray.setContextMenu(trayContextMenu) - } - if (mainWindow.isMinimized()) { - mainWindow.restore(); - } - mainWindow.focus() + setWindowVisibility(true, true); } }); From a7a810ea12a14333425fef0d9d4e3c6ed7620aec Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 16 Dec 2018 00:29:43 -0600 Subject: [PATCH 71/91] OS X changes --- electron.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron.js b/electron.js index 07a2437..f9c47fa 100644 --- a/electron.js +++ b/electron.js @@ -62,7 +62,7 @@ function createWindow() { loadUiSettings(); // Create the browser window. - const height = (process.env.ELECTRON_START_URL ? 364 : 344) - ((os.platform() === 'win32') ? 0 : 20); + const height = (process.env.ELECTRON_START_URL || (os.platform() === 'darwin') ? 364 : 344) - ((os.platform() === 'win32') ? 0 : 20); mainWindow = new BrowserWindow({ width: 428 + ((os.platform() === 'win32') ? 0 : (os.platform() === 'darwin') ? 150 : 160), height: height, From dc6a622037ce8eb052876e87195ea3762de3e694 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 16 Dec 2018 00:41:43 -0600 Subject: [PATCH 72/91] Fix dock --- electron.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/electron.js b/electron.js index f9c47fa..453d343 100644 --- a/electron.js +++ b/electron.js @@ -74,6 +74,10 @@ function createWindow() { } }); + if ((os.platform() === 'darwin') && launchHidden) { + app.dock.hide(); + } + // and load the index.html of the app. const startUrl = process.env.ELECTRON_START_URL || url.format({ pathname: path.join(__dirname, '/build/index.html'), @@ -175,7 +179,7 @@ if (!instanceLock) { } else { app.on('second-instance', () => { if (mainWindow) { - setWindowVisibility(true, true); + setWindowVisibility(true); } }); From dbd761184e0e47d2a61146259f8f65f3afbb140f Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 18 Dec 2018 14:34:14 -0600 Subject: [PATCH 73/91] Package upgrades --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4934dee..3696d0c 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "resolve": "1.6.0", "style-loader": "0.19.0", "sw-precache-webpack-plugin": "0.11.4", - "unzipper": "^0.9.4", + "unzipper": "^0.9.6", "url-loader": "0.6.2", "webpack": "3.8.1", "webpack-dev-server": "2.9.4", @@ -72,7 +72,7 @@ }, "devDependencies": { "cross-env": "^5.2.0", - "electron": "^3.0.11", + "electron": "^3.0.13", "electron-builder": "^20.38.3", "extract-text-webpack-plugin": "^3.0.2", "webpack-browser-plugin": "^1.0.20" From 64ca0350cff72f1974f0f0a0eeb57457b227f3b4 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 21 Dec 2018 12:57:02 -0600 Subject: [PATCH 74/91] Logo changes --- public/logo.xcf | Bin 5490 -> 9222 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/public/logo.xcf b/public/logo.xcf index ab3f1a64ede89ecc29fc7efd6f61b4d9bfe4b9f7..3b73421de6a898139821c4754d02ed532c43345e 100644 GIT binary patch literal 9222 zcmeHN&ubGw6rN4mnp9&qHm$)ncH3HsLL`Z?h@f2&e}RH{5)q+I(->$QX`-%p*!%$^ zo;-N;Af81$h=_RfBpyUOdJs<{9z1w(d~e@OcD8P{U=q``55D={yqVdVdGlsE)3#Vz zxN2DWIpcadlVOZ$0zi!214IEDTKfT^V_-sn!~k7@F~FeEvEBgGKM5Qu!lzUD^1?!4 zu?l(T)7y?M6{f3&S>r~jdc`<-`s_I@(VeQLh3R4;Ra`2~irN}WR;oAW3r3|pUz*+1 zo181=%k$+WBk53TsW>xjr1zyA@li6OXb&`<@o6f{jg=K_YE`aI=Sz!4BP06)<4r%K zu%)goma0Z+F@L2{!S?03xk{m0A0W2=-9#2|Q}lx(+IPxCzY%Z0OuS<^@$enuoiB)u zr^I8|iPf~e&Zva42PQ25RtSh%J;1oU959OdR1H$73qU)z3kw~{2?MmF36} z#F*CWf*yQE_O4gN-G>A}Anv(Oyy+ov=rM6vtWEE0%5Q#0yyYWtkZWx?RPTB=xqgWoENH>)wpQi=xxpJRejN#9^2RBsxLOq z3-`=W_fDhq=G=?^b#!n;R^APbk5s$^+hLP?`)SR-!@Iw?-}M{gCO#8u0;rn;sMiGW zK^w|s4_W|F+27v$SZA%g`FG-AUD+ny(T=4CDWVGi(mzPN{XDUg)*wZI^q(M(Ilrue z-*BCw{NO2K_Z-2!)!4Uq<9BE?_hQg3(ih$+;B7uy^k?HvNAIZ{ zZ1cGJPEVW`O8gSBlbVns#7P^sK$l{I zf&hu%CHC$ilO5*Tsxi#R7$FF(0XFz|KS&>~-mizbiHnmKaN;<3(8_h(jRF5!pvcfJ zB_n4q;&{mPDFf5c1!=e8o+OcGDTv2EA;x#G7{qG~>UAdL{Qm5N6h|ksqyWWP+R8cB zPP&_wa<9{H4kDe+R;?H-d!B-sS`cqQn3km)?YqEKgT@PIScmF6?S z(OJw8aN=cu*4m#%YbV7^2q)yq$a7b(&tAmK$a|kMFpYebb{lF+7%Ty?;D-p0vIvy@ zKT!XEV@q%YCleQN);*iEvK@D?!WdR$^of#@vlr_=`o^aWOrxKr-44JxArNN+u(rz) z<`EVKd*eXgTi(wA$H6mQz*)b{q?K|0`=FEdZ2+g~%6Qe)>$4Z@H-6Wr3{2zo^WO$P WN$8$^+0DbO8`f?0p!)9K*4Zz3$`w=q delta 757 zcmZqk_@pJ4o|#*qP?4ObP-b9g$N&TlAUsh_hf!gpb0MQ0dlpELfq}~iLh~$w(0rF5 zw7@9{Ez|{}VWfx@h&B10p!{S(CXLDQQfnsP6yj%M`ZxKNkQ5iQ5=0$)++;psF)8LC z2$v-WLbFCdXtt2acEVAU7YMJL{DFmIvY$xMmZ2*h2 zh`VeK5NBePWWLGqE&$6y2n`?w!ca?i_e@?OE5^io zW%CZ%UyO467m$=H0NEf6Rm%Tn@&$P@CIObsFXRs~G6|lTyhc$ Date: Wed, 26 Dec 2018 16:42:14 -0600 Subject: [PATCH 75/91] OS X fixes --- electron.js | 28 ++++++++++++++-------------- package.json | 3 ++- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/electron.js b/electron.js index 453d343..00acdd3 100644 --- a/electron.js +++ b/electron.js @@ -84,9 +84,17 @@ function createWindow() { protocol: 'file:', slashes: true }); - mainWindow.loadURL(startUrl); - // Emitted when the window is closed. + mainWindow.on('close', function (event) { + if (!isQuiting) { + event.preventDefault(); + if (mainWindow.isVisible()) { + setWindowVisibility(false); + } + event.returnValue = false; + } + }); + mainWindow.on('closed', function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time @@ -112,7 +120,6 @@ function createWindow() { path: appPath, }); - const image = nativeImage.createFromPath(path.join(__dirname, (os.platform() === 'darwin') ? '/build/logo_mac.png' : '/build/logo.png')); trayContextMenu = Menu.buildFromTemplate([ { label: 'Visible', type: 'checkbox', click(item) { @@ -149,28 +156,21 @@ function createWindow() { } ]); - mainWindow.on('close', function (event) { - if (!isQuiting) { - event.preventDefault(); - if (mainWindow.isVisible()) { - setWindowVisibility(false); - } - event.returnValue = false; - } - }); + const image = nativeImage.createFromPath(path.join(__dirname, (os.platform() === 'darwin') ? '/build/logo_mac.png' : '/build/logo.png')); + mainWindowTray = new Tray(image); autoLauncher .isEnabled() .then((enabled) => { trayContextMenu.items[1].checked = enabled; - - mainWindowTray = new Tray(image); mainWindowTray.setToolTip('Repertory UI'); mainWindowTray.setContextMenu(trayContextMenu) }) .catch(() => { closeApplication(); }); + + mainWindow.loadURL(startUrl); } const instanceLock = app.requestSingleInstanceLock(); diff --git a/package.json b/package.json index 3696d0c..18148a1 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,8 @@ "start": "node scripts/start.js", "build": "node scripts/build.js", "test": "node scripts/test.js --env=jsdom", - "electron-dev": "cross-env ELECTRON_START_URL=http://localhost:3000 electron .", + "electron-dev": "cross-env ELECTRON_START_URL=http://localhost:3000 electron %NODE_DEBUG_OPTION% .", + "electron-dev-unix": "cross-env ELECTRON_START_URL=http://localhost:3000 electron $NODE_DEBUG_OPTION .", "pack": "npm run build && electron-builder --dir", "dist": "npm run build && electron-builder" }, From b6a260549c9352d403b48319e52eef53405a57bc Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Wed, 26 Dec 2018 16:48:56 -0600 Subject: [PATCH 76/91] OS X fixes --- electron.js | 1 + package.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/electron.js b/electron.js index 00acdd3..6730883 100644 --- a/electron.js +++ b/electron.js @@ -66,6 +66,7 @@ function createWindow() { mainWindow = new BrowserWindow({ width: 428 + ((os.platform() === 'win32') ? 0 : (os.platform() === 'darwin') ? 150 : 160), height: height, + fullscreen: false, resizable: false, show: !launchHidden, title: 'Repertory UI', diff --git a/package.json b/package.json index 18148a1..fcc31a4 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,8 @@ "mac": { "category": "public.app-category.utilities", "icon": "./build/icon_color.icns", - "target": "dmg" + "target": "dmg", + "darwinDarkModeSupport": true }, "win": { "icon": "./build/icon.ico", From 15c22712623df961d715dbf9c44a2fd71d825483 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Wed, 26 Dec 2018 16:50:07 -0600 Subject: [PATCH 77/91] Fix dark mode support --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fcc31a4..128aaec 100644 --- a/package.json +++ b/package.json @@ -141,7 +141,7 @@ "category": "public.app-category.utilities", "icon": "./build/icon_color.icns", "target": "dmg", - "darwinDarkModeSupport": true + "darkModeSupport": true }, "win": { "icon": "./build/icon.ico", From 642f9cbe2ca26ab37cf90e1cec6d4161829fee29 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 18 Jan 2019 13:25:46 -0600 Subject: [PATCH 78/91] OS X changes --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 128aaec..3b59caa 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "fs-extra": "3.0.1", "html-webpack-plugin": "2.29.0", "jest": "20.0.4", + "mac-open": "^0.1.3", "node-schedule": "^1.3.1", "npm": "^6.5.0", "object-assign": "4.1.1", From a8f1724166a76c001f3a2b779da64e80fd8f47a5 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 18 Jan 2019 16:39:52 -0600 Subject: [PATCH 79/91] OS X changes --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b59caa..4e853c6 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "jest": "20.0.4", "mac-open": "^0.1.3", "node-schedule": "^1.3.1", - "npm": "^6.5.0", + "npm": "^6.6.0", "object-assign": "4.1.1", "postcss-flexbugs-fixes": "3.2.0", "postcss-loader": "2.0.8", From d16d417c99faf2410fd53c26ca4df789c4241977 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 29 Jan 2019 17:13:59 -0600 Subject: [PATCH 80/91] Refactoring --- electron.js | 36 +++- src/App.js | 186 +++++++----------- src/containers/Configuration/Configuration.js | 86 ++++---- src/containers/IPCContainer/IPCContainer.js | 51 +++++ src/containers/MountItems/MountItems.js | 39 ++-- 5 files changed, 209 insertions(+), 189 deletions(-) create mode 100644 src/containers/IPCContainer/IPCContainer.js diff --git a/electron.js b/electron.js index 6730883..ce482a2 100644 --- a/electron.js +++ b/electron.js @@ -259,7 +259,7 @@ const standardIPCReply = (event, channel, data, error) => { } }; -ipcMain.on(Constants.IPC_Browse_Directory, (event, data) => { +ipcMain.on(Constants.IPC_Browse_Directory + '_sync', (event, data) => { dialog.showOpenDialog(mainWindow, { defaultPath: data.Location, properties: ['openDirectory'], @@ -286,6 +286,23 @@ ipcMain.on(Constants.IPC_Check_Dependency_Installed, (event, data) => { } }); +ipcMain.on(Constants.IPC_Check_Dependency_Installed + '_sync', (event, data) => { + try { + const exists = fs.lstatSync(data.File).isFile(); + event.returnValue = { + data: { + Exists: exists + }, + }; + } catch (e) { + event.returnValue = { + data: { + Exists: false + }, + }; + } +}); + ipcMain.on(Constants.IPC_Check_Installed, (event, data) => { const dataDirectory = helpers.resolvePath(data.Directory); const destination = path.join(dataDirectory, data.Version); @@ -310,7 +327,7 @@ ipcMain.on(Constants.IPC_Check_Installed, (event, data) => { }); }); -ipcMain.on(Constants.IPC_Check_Mount_Location, (event, data) => { +ipcMain.on(Constants.IPC_Check_Mount_Location + '_sync', (event, data) => { let response = { Success: true, Error: '' @@ -342,6 +359,21 @@ ipcMain.on(Constants.IPC_Delete_File, (event, data) => { } }); +ipcMain.on(Constants.IPC_Delete_File + '_sync', (event, data) => { + try { + if (fs.existsSync(data.FilePath)) { + fs.unlinkSync(data.FilePath); + } + event.returnValue = { + data: true, + }; + } catch (e) { + event.returnValue = { + data: false, + }; + } +}); + ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => { let driveLetters = {}; for (const provider of Constants.PROVIDER_LIST) { diff --git a/src/App.js b/src/App.js index 816c872..bc9983a 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,4 @@ -import React, {Component} from 'react'; +import React from 'react'; import axios from 'axios'; import styles from './App.css'; import Box from './components/UI/Box/Box'; @@ -15,16 +15,12 @@ import ReleaseVersionDisplay from './components/ReleaseVersionDisplay/ReleaseVer import Text from './components/UI/Text/Text'; import UpgradeIcon from './components/UpgradeIcon/UpgradeIcon'; import UpgradeUI from './components/UpgradeUI/UpgradeUI'; +import IPCContainer from './containers/IPCContainer/IPCContainer'; const Constants = require('./constants'); const Scheduler = require('node-schedule'); -let ipcRenderer = null; -if (!process.versions.hasOwnProperty('electron')) { - ipcRenderer = ((window && window.require) ? window.require('electron').ipcRenderer : null); -} - -class App extends Component { +class App extends IPCContainer { constructor(props) { super(props); @@ -36,20 +32,18 @@ class App extends Component { } } - if (ipcRenderer) { - ipcRenderer.on(Constants.IPC_Check_Installed_Reply, this.onCheckInstalledReply); - ipcRenderer.on(Constants.IPC_Download_File_Complete, this.onDownloadFileComplete); - ipcRenderer.on(Constants.IPC_Download_File_Progress, this.onDownloadFileProgress); - ipcRenderer.on(Constants.IPC_Extract_Release_Complete, this.onExtractReleaseComplete); - ipcRenderer.on(Constants.IPC_Get_State_Reply, this.onGetStateReply); - ipcRenderer.on(Constants.IPC_Grab_Releases_Reply, this.onGrabReleasesReply); - ipcRenderer.on(Constants.IPC_Grab_UI_Releases_Reply, this.onGrabUiReleasesReply); - ipcRenderer.on(Constants.IPC_Install_Dependency_Reply, this.onInstallDependencyReply); - ipcRenderer.on(Constants.IPC_Install_Upgrade_Reply, this.onInstallUpgradeReply); + this.setRequestHandler(Constants.IPC_Check_Installed_Reply, this.onCheckInstalledReply); + this.setRequestHandler(Constants.IPC_Download_File_Complete, this.onDownloadFileComplete); + this.setRequestHandler(Constants.IPC_Download_File_Progress, this.onDownloadFileProgress); + this.setRequestHandler(Constants.IPC_Extract_Release_Complete, this.onExtractReleaseComplete); + this.setRequestHandler(Constants.IPC_Get_State_Reply, this.onGetStateReply); + this.setRequestHandler(Constants.IPC_Grab_Releases_Reply, this.onGrabReleasesReply); + this.setRequestHandler(Constants.IPC_Grab_UI_Releases_Reply, this.onGrabUiReleasesReply); + this.setRequestHandler(Constants.IPC_Install_Dependency_Reply, this.onInstallDependencyReply); + this.setRequestHandler(Constants.IPC_Install_Upgrade_Reply, this.onInstallUpgradeReply); - ipcRenderer.send(Constants.IPC_Get_State, Constants.DATA_LOCATIONS[this.props.platform]); - Scheduler.scheduleJob('23 11 * * *', this.updateCheckScheduledJob); - } + this.sendRequest(Constants.IPC_Get_State, Constants.DATA_LOCATIONS[this.props.platform]); + Scheduler.scheduleJob('23 11 * * *', this.updateCheckScheduledJob); } state = { @@ -106,18 +100,16 @@ class App extends Component { }, ()=> { const selectedVersion = this.getSelectedVersion(); if (selectedVersion !== 'unavailable') { - if (ipcRenderer) { - let dependencies = []; - if (this.state.LocationsLookup[selectedVersion] && this.state.LocationsLookup[selectedVersion].dependencies) { - dependencies = this.state.LocationsLookup[selectedVersion].dependencies; - } - - ipcRenderer.send(Constants.IPC_Check_Installed, { - Dependencies: dependencies, - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Version: selectedVersion, - }); + let dependencies = []; + if (this.state.LocationsLookup[selectedVersion] && this.state.LocationsLookup[selectedVersion].dependencies) { + dependencies = this.state.LocationsLookup[selectedVersion].dependencies; } + + this.sendRequest(Constants.IPC_Check_Installed, { + Dependencies: dependencies, + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Version: selectedVersion, + }); } }); }; @@ -128,9 +120,7 @@ class App extends Component { } if (this.state.ErrorCritical) { - if (ipcRenderer) { - ipcRenderer.send(Constants.IPC_Shutdown); - } + this.sendRequest(Constants.IPC_Shutdown); } else { this.setState({ DisplayError: false, @@ -139,20 +129,6 @@ class App extends Component { } }; - componentWillUnmount = () => { - if (ipcRenderer) { - ipcRenderer.removeListener(Constants.IPC_Check_Installed_Reply, this.onCheckInstalledReply); - ipcRenderer.removeListener(Constants.IPC_Download_File_Complete, this.onDownloadFileComplete); - ipcRenderer.removeListener(Constants.IPC_Download_File_Progress, this.onDownloadFileProgress); - ipcRenderer.removeListener(Constants.IPC_Extract_Release_Complete, this.onExtractReleaseComplete); - ipcRenderer.removeListener(Constants.IPC_Get_State_Reply, this.onGetStateReply); - ipcRenderer.removeListener(Constants.IPC_Grab_Releases_Reply, this.onGrabReleasesReply); - ipcRenderer.removeListener(Constants.IPC_Grab_UI_Releases_Reply, this.onGrabUiReleasesReply); - ipcRenderer.removeListener(Constants.IPC_Install_Dependency_Reply, this.onInstallDependencyReply); - ipcRenderer.removeListener(Constants.IPC_Install_Upgrade_Reply, this.onInstallUpgradeReply); - } - }; - extractFileNameFromURL = url => { const parts = url.split('/'); return parts[parts.length - 1]; @@ -161,7 +137,7 @@ class App extends Component { extractRelease = (data) => { if (data.Success) { const selectedVersion = this.getSelectedVersion(); - ipcRenderer.send(Constants.IPC_Extract_Release, { + this.sendRequest(Constants.IPC_Extract_Release, { Directory: Constants.DATA_LOCATIONS[this.props.platform], Source: data.Destination, Version: selectedVersion, @@ -183,10 +159,8 @@ class App extends Component { grabReleases = () => { if (this.props.platform !== 'unknown') { - if (ipcRenderer) { - ipcRenderer.send(Constants.IPC_Grab_Releases); - ipcRenderer.send(Constants.IPC_Grab_UI_Releases); - } + this.sendRequest(Constants.IPC_Grab_Releases); + this.sendRequest(Constants.IPC_Grab_UI_Releases); } }; @@ -227,19 +201,17 @@ class App extends Component { }; handleDependencyDownload = (url) => { - if (ipcRenderer) { - this.setState({ - DownloadActive: true, - DownloadingDependency: true, - DownloadName: this.extractFileNameFromURL(url), - }, ()=> { - ipcRenderer.send(Constants.IPC_Download_File, { - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Filename: this.state.DownloadName, - URL: url, - }); + this.setState({ + DownloadActive: true, + DownloadingDependency: true, + DownloadName: this.extractFileNameFromURL(url), + }, ()=> { + this.sendRequest(Constants.IPC_Download_File, { + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Filename: this.state.DownloadName, + URL: url, }); - } + }); }; handleMountLocationChanged = (storageType, location) => { @@ -269,38 +241,32 @@ class App extends Component { handleReleaseDownload = () => { const selectedVersion = this.getSelectedVersion(); const fileName = selectedVersion + '.zip'; - if (ipcRenderer) { - this.setState({ - DownloadActive: true, - DownloadingRelease: true, - DownloadName: fileName, - }, () => { - ipcRenderer.send(Constants.IPC_Download_File, { - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Filename: this.state.DownloadName, - URL: this.state.LocationsLookup[selectedVersion].urls[0], - }); + this.setState({ + DownloadActive: true, + DownloadingRelease: true, + DownloadName: fileName, + }, () => { + this.sendRequest(Constants.IPC_Download_File, { + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Filename: this.state.DownloadName, + URL: this.state.LocationsLookup[selectedVersion].urls[0], }); - } + }); }; handleUIDownload = () => { - if (ipcRenderer) { - this.setState({ - DownloadActive: true, - DownloadingUpgrade: true, - DownloadName: 'UI Upgrade', - }, ()=> { - const url = this.state.UpgradeData.urls[0]; - ipcRenderer.send(Constants.IPC_Download_File, { - Directory: Constants.DATA_LOCATIONS[this.props.platform], - Filename: this.props.platform === 'win32' ? 'upgrade.exe' : this.extractFileNameFromURL(url), - URL: url, - }); + this.setState({ + DownloadActive: true, + DownloadingUpgrade: true, + DownloadName: 'UI Upgrade', + }, ()=> { + const url = this.state.UpgradeData.urls[0]; + this.sendRequest(Constants.IPC_Download_File, { + Directory: Constants.DATA_LOCATIONS[this.props.platform], + Filename: this.props.platform === 'win32' ? 'upgrade.exe' : this.extractFileNameFromURL(url), + URL: url, }); - } else { - this.setState({UpgradeDismissed: true}); - } + }); }; handleVersionChanged = (e) => { @@ -314,7 +280,7 @@ class App extends Component { installDependency = data => { if (data.Success) { - ipcRenderer.send(Constants.IPC_Install_Dependency, { + this.sendRequest(Constants.IPC_Install_Dependency, { Source: data.Destination, URL: data.URL, }); @@ -330,7 +296,7 @@ class App extends Component { installUpgrade = data => { if (data.Success) { - ipcRenderer.send(Constants.IPC_Install_Upgrade, { + this.sendRequest(Constants.IPC_Install_Upgrade, { Source: data.Destination, }); } else { @@ -404,7 +370,7 @@ class App extends Component { }; onExtractReleaseComplete = (event, arg) => { - ipcRenderer.send(Constants.IPC_Delete_File, { + this.sendRequest(Constants.IPC_Delete_File, { FilePath: arg.data.Source, }); @@ -521,7 +487,7 @@ class App extends Component { if (arg.data.Success && arg.data.Source.toLowerCase().endsWith('.dmg')) { this.waitForDependencyInstall(arg.data.URL); } else { - ipcRenderer.send(Constants.IPC_Delete_File, { + this.sendRequest(Constants.IPC_Delete_File, { FilePath: arg.data.Source, }); this.checkVersionInstalled(); @@ -529,7 +495,7 @@ class App extends Component { }; onInstallUpgradeReply = (event, arg) => { - ipcRenderer.sendSync(Constants.IPC_Delete_File, { + this.sendSyncRequest(Constants.IPC_Delete_File, { FilePath: arg.data.Source, }); @@ -541,20 +507,18 @@ class App extends Component { }; saveState = version => { - if (ipcRenderer) { - let state = { - Release: this.state.Release, - Version: version || this.state.Version, - }; - for (const provider of Constants.PROVIDER_LIST) { - state[provider] = this.state[provider]; - } - - ipcRenderer.send(Constants.IPC_Save_State, { - Directory: Constants.DATA_LOCATIONS[this.props.platform], - State: state - }); + let state = { + Release: this.state.Release, + Version: version || this.state.Version, + }; + for (const provider of Constants.PROVIDER_LIST) { + state[provider] = this.state[provider]; } + + this.sendRequest(Constants.IPC_Save_State, { + Directory: Constants.DATA_LOCATIONS[this.props.platform], + State: state + }); }; setErrorState = (error, action, critical) => { @@ -578,7 +542,7 @@ class App extends Component { }); const i = setInterval(()=> { - const ret = ipcRenderer.sendSync(Constants.IPC_Check_Dependency_Installed, { + const ret = this.sendSyncRequest(Constants.IPC_Check_Dependency_Installed, { File: dep.file, }); if (ret.data.Exists || !ret.data.Success) { diff --git a/src/containers/Configuration/Configuration.js b/src/containers/Configuration/Configuration.js index e783df7..ce89457 100644 --- a/src/containers/Configuration/Configuration.js +++ b/src/containers/Configuration/Configuration.js @@ -5,28 +5,22 @@ import Button from '../../components/UI/Button/Button'; import ConfigurationItem from '../../components/ConfigurationItem/ConfigurationItem'; import CSSModules from 'react-css-modules'; import Modal from '../../components/UI/Modal/Modal'; +import IPCContainer from '../IPCContainer/IPCContainer'; const Constants = require('../../constants'); -let ipcRenderer = null; -if (!process.versions.hasOwnProperty('electron')) { - ipcRenderer = ((window && window.require) ? window.require('electron').ipcRenderer : null); -} - -class Configuration extends Component { +class Configuration extends IPCContainer { constructor(props) { super(props); - if (ipcRenderer) { - ipcRenderer.on(Constants.IPC_Get_Config_Template_Reply, this.onGetConfigTemplateReply); - ipcRenderer.on(Constants.IPC_Get_Config_Reply, this.onGetConfigReply); - ipcRenderer.on(Constants.IPC_Set_Config_Values_Reply, this.onSetConfigValuesReply); + this.setRequestHandler(Constants.IPC_Get_Config_Template_Reply, this.onGetConfigTemplateReply); + this.setRequestHandler(Constants.IPC_Get_Config_Reply, this.onGetConfigReply); + this.setRequestHandler(Constants.IPC_Set_Config_Values_Reply, this.onSetConfigValuesReply); - ipcRenderer.send(Constants.IPC_Get_Config_Template, { - Directory: this.props.directory, - StorageType: this.props.storageType, - Version: this.props.version, - }); - } + this.sendRequest(Constants.IPC_Get_Config_Template, { + Directory: this.props.directory, + StorageType: this.props.storageType, + Version: this.props.version, + }); } state = { @@ -78,14 +72,6 @@ class Configuration extends Component { } }; - componentWillUnmount = () => { - if (ipcRenderer) { - ipcRenderer.removeListener(Constants.IPC_Get_Config_Reply, this.onGetConfigReply); - ipcRenderer.removeListener(Constants.IPC_Get_Config_Template_Reply, this.onGetConfigTemplateReply); - ipcRenderer.removeListener(Constants.IPC_Set_Config_Values_Reply, this.onSetConfigValuesReply); - } - }; - createItemList = (config, template) => { const objectList = []; const itemList = Object @@ -165,7 +151,7 @@ class Configuration extends Component { this.setState({ Template: arg.data.Template, }, ()=> { - ipcRenderer.send(Constants.IPC_Get_Config, { + this.sendRequest(Constants.IPC_Get_Config, { Directory: this.props.directory, StorageType: this.props.storageType, Version: this.props.version, @@ -183,37 +169,35 @@ class Configuration extends Component { }; saveAndClose = () => { - if (ipcRenderer) { - this.setState({ - Saving: true, - }, ()=> { - const changedItems = []; - for (const item of this.state.ChangedItems) { - changedItems.push({ - Name: item.label, - Value: item.value, - }); - } + this.setState({ + Saving: true, + }, ()=> { + const changedItems = []; + for (const item of this.state.ChangedItems) { + changedItems.push({ + Name: item.label, + Value: item.value, + }); + } - if (this.state.ChangedObjectLookup) { - for (const key of Object.keys(this.state.ChangedObjectLookup)) { - for (const item of this.state.ChangedObjectLookup[key]) { - changedItems.push({ - Name: key + '.' + item.label, - Value: item.value, - }); - } + if (this.state.ChangedObjectLookup) { + for (const key of Object.keys(this.state.ChangedObjectLookup)) { + for (const item of this.state.ChangedObjectLookup[key]) { + changedItems.push({ + Name: key + '.' + item.label, + Value: item.value, + }); } } + } - ipcRenderer.send(Constants.IPC_Set_Config_Values, { - Directory: this.props.directory, - Items: changedItems, - StorageType: this.props.storageType, - Version: this.props.version, - }); + this.sendRequest(Constants.IPC_Set_Config_Values, { + Directory: this.props.directory, + Items: changedItems, + StorageType: this.props.storageType, + Version: this.props.version, }); - } + }); }; render() { diff --git a/src/containers/IPCContainer/IPCContainer.js b/src/containers/IPCContainer/IPCContainer.js new file mode 100644 index 0000000..9fde958 --- /dev/null +++ b/src/containers/IPCContainer/IPCContainer.js @@ -0,0 +1,51 @@ +import {Component} from 'react'; + +export default class extends Component { + constructor(props) { + super(props); + + if (!process.versions.hasOwnProperty('electron')) { + this.ipcRenderer = ((window && window.require) ? window.require('electron').ipcRenderer : null); + } + } + + handlerList = {}; + ipcRenderer; + + componentWillUnmount() { + if (this.ipcRenderer) { + for (let name in this.handlerList) { + if (this.handlerList.hasOwnProperty(name)) { + this.ipcRenderer.removeListener(name, this.handlerList[name]); + } + } + } + + this.handlerList = {}; + }; + + sendRequest = (name, data) => { + if (this.ipcRenderer) { + this.ipcRenderer.send(name, data); + } + }; + + sendSyncRequest = (name, data) => { + if (this.ipcRenderer) { + return this.ipcRenderer.sendSync(name + '_sync', data); + } else { + return { + Success: false, + Error: 'IPC not available. Running in browser?', + }; + } + }; + + setRequestHandler = (name, callback) => { + if (this.ipcRenderer) { + this.handlerList[name] = callback; + this.ipcRenderer.on(name, callback); + } + }; + +}; \ No newline at end of file diff --git a/src/containers/MountItems/MountItems.js b/src/containers/MountItems/MountItems.js index 03dd635..2da4b9e 100644 --- a/src/containers/MountItems/MountItems.js +++ b/src/containers/MountItems/MountItems.js @@ -1,20 +1,15 @@ import React from 'react'; -import {Component} from 'react'; import Box from '../../components/UI/Box/Box'; import Button from '../../components/UI/Button/Button'; import CSSModules from 'react-css-modules'; import styles from './MountItems.css'; import Modal from '../../components/UI/Modal/Modal'; import MountItem from '../../components/MountItem/MountItem'; +import IPCContainer from '../IPCContainer/IPCContainer'; const Constants = require('../../constants'); -let ipcRenderer = null; -if (!process.versions.hasOwnProperty('electron')) { - ipcRenderer = ((window && window.require) ? window.require('electron').ipcRenderer : null); -} - -class MountItems extends Component { +class MountItems extends IPCContainer { constructor(props) { super(props); @@ -26,13 +21,11 @@ class MountItems extends Component { }; } - if (ipcRenderer) { - ipcRenderer.on(Constants.IPC_Detect_Mounts_Reply, this.onDetectMountsReply); - ipcRenderer.on(Constants.IPC_Mount_Drive_Reply, this.onMountDriveReply); - ipcRenderer.on(Constants.IPC_Unmount_Drive_Reply, this.onUnmountDriveReply); + this.setRequestHandler(Constants.IPC_Detect_Mounts_Reply, this.onDetectMountsReply); + this.setRequestHandler(Constants.IPC_Mount_Drive_Reply, this.onMountDriveReply); + this.setRequestHandler(Constants.IPC_Unmount_Drive_Reply, this.onUnmountDriveReply); - this.detectMounts(); - } + this.detectMounts(); } retryIntervals = {}; @@ -58,24 +51,20 @@ class MountItems extends Component { } }; - componentWillUnmount = () => { + componentWillUnmount() { for (const storageType in this.state.RetryItems) { if (this.state.RetryItems.hasOwnProperty(storageType)) { this.cancelRetryMount(storageType); } } - if (ipcRenderer) { - ipcRenderer.removeListener(Constants.IPC_Detect_Mounts_Reply, this.onDetectMountsReply); - ipcRenderer.removeListener(Constants.IPC_Mount_Drive_Reply, this.onMountDriveReply); - ipcRenderer.removeListener(Constants.IPC_Unmount_Drive_Reply, this.onUnmountDriveReply); - } + super.componentWillUnmount(); }; detectMounts = ()=> { if (!this.state.DisplayRetry) { this.props.mountsBusy(true); - ipcRenderer.send(Constants.IPC_Detect_Mounts, { + this.sendRequest(Constants.IPC_Detect_Mounts, { Directory: this.props.directory, Version: this.props.version, }); @@ -83,7 +72,7 @@ class MountItems extends Component { }; handleBrowseLocation = (storageType, location) => { - location = ipcRenderer.sendSync(Constants.IPC_Browse_Directory, { + location = this.sendSyncRequest(Constants.IPC_Browse_Directory, { Title: storageType + ' Mount Location', Location: location, }); @@ -103,10 +92,10 @@ class MountItems extends Component { handleMountUnMount = (storageType, mount, location) => { if (!location || (location.trim().length === 0)) { this.props.errorHandler('Mount location is not set'); - } else if (ipcRenderer) { + } else { let allowAction = true; if (mount && (this.props.platform !== 'win32')) { - const result = ipcRenderer.sendSync(Constants.IPC_Check_Mount_Location, { + const result = this.sendSyncRequest(Constants.IPC_Check_Mount_Location, { Location: location, }); if (!result.Success) { @@ -127,7 +116,7 @@ class MountItems extends Component { [storageType]: storageState, }, () => { if (mount) { - ipcRenderer.send(Constants.IPC_Mount_Drive, { + this.sendRequest(Constants.IPC_Mount_Drive, { Directory: this.props.directory, Location: location, NoConsoleSupported: this.props.noConsoleSupported, @@ -135,7 +124,7 @@ class MountItems extends Component { Version: this.props.version, }); } else { - ipcRenderer.send(Constants.IPC_Unmount_Drive, { + this.sendRequest(Constants.IPC_Unmount_Drive, { Directory: this.props.directory, Location: location, StorageType: storageType, From 3ab1a0f61e49d6fa8d4eec5a4a9bda1d6e7a8db6 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 15 Feb 2019 13:55:43 -0600 Subject: [PATCH 81/91] [Don't mount if missing dependencies] [Electron to v4] --- package.json | 6 +++--- src/App.js | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 4e853c6..8f11bb0 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "css-loader": "0.28.7", "dotenv": "4.0.0", "dotenv-expand": "4.2.0", - "electron-debug": "^2.0.0", + "electron-debug": "^2.1.0", "eslint": "4.10.0", "eslint-config-react-app": "^2.1.0", "eslint-loader": "1.9.0", @@ -74,8 +74,8 @@ }, "devDependencies": { "cross-env": "^5.2.0", - "electron": "^3.0.13", - "electron-builder": "^20.38.3", + "electron": "^4.0.5", + "electron-builder": "^20.38.5", "extract-text-webpack-plugin": "^3.0.2", "webpack-browser-plugin": "^1.0.20" }, diff --git a/src/App.js b/src/App.js index bc9983a..18a30d1 100644 --- a/src/App.js +++ b/src/App.js @@ -563,8 +563,9 @@ class App extends IPCContainer { (selectedVersion !== 'unavailable') && (selectedVersion !== this.state.InstalledVersion); - const allowMount = this.state.InstalledVersion !== 'none'; const missingDependencies = (this.state.MissingDependencies.length > 0); + const allowMount = this.state.InstalledVersion !== 'none' && !missingDependencies; + const allowConfig = this.state.LocationsLookup[selectedVersion] && this.state.LocationsLookup[selectedVersion].config_support; From 1e76114db134bdc4c36d6dff268a3626a570d73f Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 15 Feb 2019 14:05:02 -0600 Subject: [PATCH 82/91] [Don't mount if missing dependencies] [Electron to v4] --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43eaaa9..9ac382a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ * OS X support * SiaPrime support * Partial Linux support +* Electron to v4 +* Prevent mount if dependencies are missing ## 1.0.1 ## * Added configuration settings for Repertory 1.0.0-alpha.2 and above From e410483a08d7651495242778ee81e67004c1c7f9 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 17 Mar 2019 23:02:18 -0500 Subject: [PATCH 83/91] Electron to 4.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8f11bb0..2a81922 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ }, "devDependencies": { "cross-env": "^5.2.0", - "electron": "^4.0.5", + "electron": "^4.1.0", "electron-builder": "^20.38.5", "extract-text-webpack-plugin": "^3.0.2", "webpack-browser-plugin": "^1.0.20" From 4b5a0725bd7704dbbf9450e201fcb56926ca17d0 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 6 Apr 2019 07:43:46 -0500 Subject: [PATCH 84/91] Fix dependency installation on OS X --- electron.js | 18 +++++++++++------- package.json | 1 - src/App.js | 6 ++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/electron.js b/electron.js index ce482a2..1b87945 100644 --- a/electron.js +++ b/electron.js @@ -113,7 +113,7 @@ function createWindow() { }); const appPath = (os.platform() === 'win32') ? path.resolve(path.join(app.getAppPath(), '..\\..\\repertory-ui.exe')) : - (os.platform() === 'darwin') ? app.getAppPath() : + (os.platform() === 'darwin') ? path.resolve(path.join(path.dirname(app.getAppPath()), '../MacOS/repertory-ui')) : process.env.APPIMAGE; const autoLauncher = new AutoLaunch({ @@ -277,21 +277,25 @@ ipcMain.on(Constants.IPC_Check_Dependency_Installed, (event, data) => { try { const exists = fs.lstatSync(data.File).isFile(); standardIPCReply(event, Constants.IPC_Check_Dependency_Installed_Reply, { - Exists: exists, + data: { + Exists: exists, + }, }); } catch (e) { standardIPCReply(event, Constants.IPC_Check_Dependency_Installed_Reply, { - Exists: false, - }, e); + data : { + Exists: false, + }, + }); } }); ipcMain.on(Constants.IPC_Check_Dependency_Installed + '_sync', (event, data) => { try { - const exists = fs.lstatSync(data.File).isFile(); + const ls = fs.lstatSync(data.File); event.returnValue = { data: { - Exists: exists + Exists: ls.isFile() || ls.isSymbolicLink(), }, }; } catch (e) { @@ -589,7 +593,7 @@ ipcMain.on(Constants.IPC_Grab_UI_Releases, (event) => { ipcMain.on(Constants.IPC_Install_Dependency, (event, data) => { if (data.Source.toLowerCase().endsWith('.dmg')) { helpers - .executeAsync('hdiutil', ['attach', data.Source]) + .executeAsync('open', ['-a', 'Finder', '-W', data.Source]) .then(() => { standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { Source: data.Source, diff --git a/package.json b/package.json index 2a81922..d709b33 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,6 @@ "fs-extra": "3.0.1", "html-webpack-plugin": "2.29.0", "jest": "20.0.4", - "mac-open": "^0.1.3", "node-schedule": "^1.3.1", "npm": "^6.6.0", "object-assign": "4.1.1", diff --git a/src/App.js b/src/App.js index 18a30d1..a169f40 100644 --- a/src/App.js +++ b/src/App.js @@ -545,9 +545,11 @@ class App extends IPCContainer { const ret = this.sendSyncRequest(Constants.IPC_Check_Dependency_Installed, { File: dep.file, }); - if (ret.data.Exists || !ret.data.Success) { + if (ret.data.Exists) { clearInterval(i); - this.checkVersionInstalled(); + setTimeout(() => { + this.checkVersionInstalled(); + }, 10000); } }, 3000); }; From f3473f4f1ba7319cb7e1489351a721238980aab9 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 6 Apr 2019 21:25:55 -0500 Subject: [PATCH 85/91] Packaging changes --- package.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d709b33..9a7d2a5 100644 --- a/package.json +++ b/package.json @@ -68,8 +68,13 @@ "test": "node scripts/test.js --env=jsdom", "electron-dev": "cross-env ELECTRON_START_URL=http://localhost:3000 electron %NODE_DEBUG_OPTION% .", "electron-dev-unix": "cross-env ELECTRON_START_URL=http://localhost:3000 electron $NODE_DEBUG_OPTION .", - "pack": "npm run build && electron-builder --dir", - "dist": "npm run build && electron-builder" + "pack": "npm run build && electron-builder --dir --x64", + "dist": "npm run build && electron-builder --x64", + "dist-all": "npm run build && electron-builder --x64 --win --linux --mac", + "dist-mac": "npm run build && electron-builder --x64 --mac", + "dist-linux": "npm run build && electron-builder --x64 --linux", + "dist-win": "npm run build && electron-builder --x64 --win", + "postinstall": "electron-builder install-app-deps" }, "devDependencies": { "cross-env": "^5.2.0", From 2218910fbd1799849bb4dc18daee8041fa444a17 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 6 Apr 2019 22:04:20 -0500 Subject: [PATCH 86/91] OS X UI upgrade --- electron.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron.js b/electron.js index 1b87945..faf0556 100644 --- a/electron.js +++ b/electron.js @@ -638,7 +638,7 @@ ipcMain.on(Constants.IPC_Install_Upgrade, (event, data) => { }); } else if (data.Source.toLocaleLowerCase().endsWith('.dmg')) { helpers - .executeAsync('hdiutil', ['attach', data.Source]) + .executeAsync('open', ['-a', 'Finder', data.Source]) .then(() => { closeApplication(); }) From 31a91dbd68cc92fa0311c523fc417958c5aca572 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 6 Apr 2019 22:10:38 -0500 Subject: [PATCH 87/91] Change release location --- src/constants.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants.js b/src/constants.js index 2485d99..bd45c0d 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,13 +1,13 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory/raw/1.0.0-alpha.4_branch/releases.json'; +exports.RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory/raw/master/releases.json'; exports.DATA_LOCATIONS = { linux: '~/.local/repertory/ui', darwin: '~/Library/Application Support/repertory/ui', win32: '%LOCALAPPDATA%\\repertory\\ui' }; -exports.UI_RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory-ui/raw/1.0.2_branch/releases.json'; +exports.UI_RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory-ui/raw/master/releases.json'; exports.PROVIDER_LIST = [ 'Hyperspace', From e59d6665cd170a68448718bacec380f33fa17af2 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 6 Apr 2019 22:12:28 -0500 Subject: [PATCH 88/91] Prepare for releases --- releases.json | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/releases.json b/releases.json index e7ad179..2d4775e 100644 --- a/releases.json +++ b/releases.json @@ -4,26 +4,21 @@ "1.0.2": { "hash": "", "urls": [] - }, - "1.0.1": { + } + }, + "darwin": { + "1.0.2": { "hash": "", - "urls": [ - "https://sia.pixeldrain.com/api/file/Alo1IF1u" - ] - }, - "1.0.0": { - "hash": "", - "urls": [ - "https://sia.pixeldrain.com/api/file/qXM6pVZZ" - ] + "urls": [] } } }, "Versions": { "win32": [ - "1.0.2", - "1.0.1", - "1.0.0" + "1.0.2" + ], + "darwin": [ + "1.0.2" ] } } \ No newline at end of file From 19f7010c721c9de85298b6a0dcf697fc8fca2a80 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 6 Apr 2019 22:38:51 -0500 Subject: [PATCH 89/91] Set Windows release --- releases.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases.json b/releases.json index 2d4775e..9676fa2 100644 --- a/releases.json +++ b/releases.json @@ -3,7 +3,7 @@ "win32": { "1.0.2": { "hash": "", - "urls": [] + "urls": ["https://pixeldrain.com/u/4oJeVntd"] } }, "darwin": { From b21e0df789bc1fbc2ad1bc5b3e021675083b4817 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 6 Apr 2019 22:50:33 -0500 Subject: [PATCH 90/91] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index db8fb91..a4c4632 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Repertory allows you to mount Sia, SiaPrime and/or Hyperspace blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows. # Downloads # * [Repertory UI v1.0.2 OS X]() -* [Repertory UI v1.0.2 Windows 64-bit]() +* [Repertory UI v1.0.2 Windows 64-bit](https://pixeldrain.com/u/4oJeVntd) # Supported Platforms # * OS X * Windows 64-bit From b560a9975bbb7f9049ac1f6c8df0f8f0b386b2a7 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 6 Apr 2019 23:04:49 -0500 Subject: [PATCH 91/91] Added OS X release --- README.md | 2 +- releases.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a4c4632..581f9b5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ### GUI for [Repertory](https://bitbucket.org/blockstorage/repertory) ### Repertory allows you to mount Sia, SiaPrime and/or Hyperspace blockchain storage solutions via FUSE on Linux/OS X or via WinFSP on Windows. # Downloads # -* [Repertory UI v1.0.2 OS X]() +* [Repertory UI v1.0.2 OS X](https://pixeldrain.com/u/OtxPlbOI) * [Repertory UI v1.0.2 Windows 64-bit](https://pixeldrain.com/u/4oJeVntd) # Supported Platforms # * OS X diff --git a/releases.json b/releases.json index 9676fa2..7f41b9f 100644 --- a/releases.json +++ b/releases.json @@ -9,7 +9,7 @@ "darwin": { "1.0.2": { "hash": "", - "urls": [] + "urls": ["https://pixeldrain.com/u/OtxPlbOI"] } } },