First upload

This commit is contained in:
Zaher Salman
2021-06-06 18:34:29 +02:00
commit 7735c3d78d
11 changed files with 7599 additions and 0 deletions

32
TrimSP.cfg Normal file
View File

@@ -0,0 +1,32 @@
[Files]
fileNamePrefix=SrTiO3
workPath=/tmp/test
[Layers]
numLayer=2
L1Comp=SrTiO3
L1rho=5.12
L1d=300
L2Comp=SrTiO3
L2rho=5.12
L2d=10000
[ProjectileParameters]
workPath=/tmp/test
fileNamePrefix=SrTiO3
ProjType=Muon
numberProj=1000
z0=0
dz=20
valEnergy=2000
sigEnergy=450
valAngle=0
sigAngle=15
ranSeed=78741
[ScanSequence]
scanSeq=1
comboScan=EScan
scanType=scanLoop
scanFrom=1000
scanStep=2000
scanTo=14000
scanList=1000
scanListdz=

253
TrimSP.html Normal file
View File

@@ -0,0 +1,253 @@
<!DOCTYPE html>
<html class="mcss">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<link rel="stylesheet" href="ZGUI.css">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<script src="TrimSPlib.js"></script>
<script src="TrimSPelec.js"></script>
<script src="myplots.js"></script>
<script type="text/javascript">
const ipcRenderer = require('electron').ipcRenderer;
const fs = require('fs');
const exec = require('child_process').execSync;
</script>
<title>Trim.SP</title>
</head>
<body onresize="resizePl()" onload="adjust_table();adjust_scans();">
<table style="width: 100%;">
<tr><td>
<div class="col-full">
<div class="tab">
<button class="tablinks" onclick="openTab(event,'Layers')" id="btnLayers">Layers</button>
<button class="tablinks" onclick="openTab(event,'Scans')" id="btnScans">Scans</button>
<button class="tablinks" onclick="openTab(event,'Plots')" id="btnPlots">Plots</button>
<button class="tablinks" onclick="openTab(event,'Other')" id="btnOther">Other Params</button>
</div>
<div id="Layers" class="tabcontent">
<table style="width: 100%;">
<tr>
<td style="vertical-align: top;">
<table cellpadding="5">
<tr>
<td><label>File name prefix:</label><input name="fileNamePrefix" id="fileNamePrefix" type="text" size="7" value="SrTiO3"/>
<label>saved in:</label><input type="text" id="workPath" name="workPath" value="/tmp/test" onchange="console.log(this.value);"/>
</tr>
<tr><td>
<b>Layers</b>
</td></tr>
<tr><td>
<label>Number of
Layers: </label><input name="numLayer" id="numLayer" type="number" size="3" step="1" min="1" max="100" value="1" onchange="adjust_table()">
</td></tr>
<tr><td>
<table id="LTable" border="2" cellpadding="10">
<tr><td><b>Layer #</b></td><td><b>Composition</b></td><td><b>Density [g/cm<sup>3</sup>]</b></td><td><b>Thickness [A]</b></td></tr>
</table>
</td></tr>
</table>
</td>
<td style="vertical-align: top;">
<table cellpadding="5">
<tr><td collspan="2"><b>Projectile parameters</b></td></tr>
<tr><td>Projectile</td>
<td><select name="ProjType" id="ProjType" onchange="ProjSmartDefaults()" onload="ProjSmartDefaults()">
<option selected="selected" value="Muon">Muon</option>
<option value="Li8">Li8</option>
<option value="B12">B12</option>
<option value="H">H</option>
</select>
</td>
</tr>
<tr><td>Number of projectiles</td>
<td><input name="numberProj" id="numberProj" type="text" size="7" value="1000" onchange="//ProjNumberLimit()"></td>
</tr>
<tr><td>Starting depth [A]</td><td><input name="z0" id="z0" type="text" size="7" value="0"></td></tr>
<tr><td>Depth increment [A]</td><td><input name="dz" id="dz" type="text" size="7" value="20"></td></tr>
<tr><td>Energy [eV]</td><td><input name="valEnergy" id="valEnergy" type="text" size="7" value="2000"></td></tr>
<tr><td>Energy sigma [eV]</td><td><input name="sigEnergy" id="sigEnergy" type="text" size="7" value="450"></td></tr>
<tr><td>Angel [deg]</td><td><input name="valAngle" id="valAngle" type="text" size="7" value="0"></td></tr>
<tr><td>Angle sigma [deg]</td><td><input name="sigAngle" id="sigAngle" type="text" size="7" value="15"></td></tr>
<tr><td>Random seed</td><td><input name="ranSeed" id="ranSeed" type="text" size="7" value="78741"></td></tr>
<tr><td><button onclick="document.getElementById('btnPlots').click();tester();">Start</button></td><td></td></tr>
</table>
</td>
</tr>
</table>
</div>
<div id="Scans" class="tabcontent">
<input type="checkbox" name="scanSeq" id="scanSeq" onChange="adjust_scans();"> Enable scan on
<select name="scanType" id="scanType" onchange="adjust_scans();">
<option value="scanLoop">Loop</option>
<option value="scanVals">Set of Values</option>
</select>
<div id="ScansLine" style="visibility: hidden;">
<br>Set of Values: <input name="scanList" id="scanList" type="text" value="1000">
corresponding depth increment <input name="scanListdz" id="scanListdz" type="text" value="">
</div>
<table id="ScansTable" style="width: 100%;visibility: hidden;">
<tr>
<td colspan="3">Scan parameter
<select name="comboScan" id="comboScan" onchange="">
<option value="EScan">Energy</option>
<option value="SigEScan">Energy Sigma</option>
<option value="AngleScan">Angle</option>
<option value="SigAngleScan">Angle Sigma</option>
<option value="NProjScan">Number of Projectiles</option>
<option value="dScan">Thickness of layer1</option>
</select>
</td>
</tr>
<tr>
<td>
<!input type="radio" name="ScanType" value="Loop" checked onChange="">
<!input type="radio" name="ScanType" value="ScanList" onChange="">
From: <input name="scanFrom" id="scanFrom" type="text" value="1000">
</td>
<td>
Step: <input name="scanStep" id="scanStep" type="text" value="2000">
</td>
<td>
To: <input name="scanTo" id="scanTo" type="text" value="14000">
</td>
</tr>
</table>
</div>
<div id="Plots" class="tabcontent">
<table style="width: 100%;">
<tr>
<td align="center"><div id="plotRge"><!-- Plotly chart will be drawn inside this DIV --></div></td>
<td align="center"><div id="plotFrac"><!-- Plotly chart will be drawn inside this DIV --></div></td>
</tr>
</table>
</div>
<div id="Other" class="tabcontent">
<table cellpadding="5">
<tr>
<td>EF</td>
<td>
<input name="parEF" id="parEF" type="number" size="7" step="0.1" value="0.5">
</td>
<td>KK0</td>
<td>
<input name="parKK0" id="parKK0" type="number" step="1" min="0" max="4" value="2">
</td>
</tr>
<tr>
<td>ESB</td>
<td>
<input name="parESB" id="parESB" type="number" size="7" step="0.1" value="0.0">
</td>
<td>KK0R</td>
<td>
<input name="parKK0R" id="parKK0R" type="number" step="1" min="0" max="4" value="2">
</td>
</tr>
<tr>
<td>SHEATH</td>
<td>
<input name="parSHEATH" id="parSHEATH" type="number" size="7" step="0.1" value="0.0">
</td>
<td>KDEE1</td>
<td>
<input name="parKDEE1" id="parKDEE1" type="number" step="1" min="1" max="5" value="4">
</td>
</tr>
<tr>
<td>ERC</td>
<td>
<input name="parERC" id="parERC" type="number" size="7" step="0.1" value="0.0">
</td>
<td>KDEE2</td>
<td>
<input name="parKDEE2" id="parKDEE2" type="number" step="1" min="1" max="3" value="3">
</td>
</tr>
<tr>
<td>RD</td>
<td>
<input name="parRD" id="parRD" type="number" size="7" step="0.1" value="50.0">
</td>
<td>IPOT</td>
<td>
<input name="parIPOT" id="parIPOT" type="number" step="1" min="1" max="3" value="2">
</td>
</tr>
<tr>
<td>CA</td>
<td>
<input name="parCA" id="parCA" type="number" size="7" step="0.1" value="1.0">
</td>
<td>IPOTR</td>
<td>
<input name="parIPOTR" id="parIPOTR" type="number" step="1" min="0" max="3" value="1">
</td>
</tr>
<tr>
<td></td>
<td></td>
<td>IRL</td>
<td>
<input name="parIRL" id="parIRL" type="number" step="1" min="0" max="2" value="0">
</td>
</tr>
</table>
</div>
</div>
</td></tr>
<!tr>
<!td>
<!progress id="myBar" max=100 min=0><!/progress>
<!/td>
<!/tr>
</table>
</body>
<script>
// Catch calls for open file
ipcRenderer.on('openFile', function(event, filename) {
console.log('Open file '+filename);
fs.readFile(filename.toString(), function read(err, data) {
if (err) {
throw err;
}
setValues(data);
});
});
// Catch calls for selectfolder
ipcRenderer.on('selectFolder', function(event, foldername) {
// If foldername is empty use default value
if (foldername == '') {foldername ="/tmp/test";}
document.getElementById("workPath").value = foldername;
console.log("folder="+foldername);
});
// Catch calls for save as
ipcRenderer.on('saveFile', function(event, filename) {
// If filename is empty use default value
if (filename == '') {filename='TrimSP.cfg';}
// Get values from all fields and prepare config file
let trimSPcfg=prep_cfg(0);
// Save file to filename
console.log('Save file to '+filename);
try { fs.writeFileSync(filename, trimSPcfg, 'utf-8'); }
catch(e) { alert('Failed to save the file !'); }
});
// Catch calls for plotProf
ipcRenderer.on('plotProf', function(event, filename) {
console.log("filename="+filename);
plotProfiles(filename);
});
// Catch calls for plotFrac
ipcRenderer.on('plotFrac', function(event, filename) {
console.log("filename="+filename);
plotFractions(filename);
});
// Catch calls for plotMean
ipcRenderer.on('plotMean', function(event, filename) {
console.log("filename="+filename);
plotMean(filename);
});
// Get the element with id="defaultOpen" and click on it
document.getElementById("btnLayers").click();
</script>
</html>

56
TrimSPelec.js Normal file
View File

@@ -0,0 +1,56 @@
// This file contains function that are Electron/Node specific
function getFiles(dir, filelist){
fileList = [];
var files = fs.readdirSync(dir);
for(var i of files){
if (!files.hasOwnProperty(i)) continue;
var name = dir+'/'+files[i];
if (!fs.statSync(name).isDirectory()){
fileList.push(name);
}
}
return fileList;
}
function execute(command) {
exec(command, {stdio: 'inherit'});
}
function checkDir(directory) {
// Check whether director exists, if not create it
if (!fs.existsSync(directory)) {
// Folder does not exist try to create it
fs.mkdir(directory,{recursive: true}, (err) => {
if (err) {
alert('Cannot create data folder '+directory);
return(0);
}
});
}
return(1);
}
function writeAsciiFile(filename,content) {
// Write string content into ascii file filename
try { fs.writeFileSync(filename, content, 'utf-8'); }
catch(e) {
alert('Failed to save '+filename);
return(0);
}
return(1);
}
function readAsciiFile(filename) {
// Read ascii file filename and return content in a string
var content;
// If an array of filenames was sent take the first one only
if (Array.isArray(filename)) {filename=filename[0];}
try {
content = fs.readFileSync(filename, 'utf8');
} catch(e) {
alert('Failed to read '+filename);
return(0);
}
return(content);
}

1251
TrimSPlib.js Normal file

File diff suppressed because it is too large Load Diff

177
ZGUI.css Normal file
View File

@@ -0,0 +1,177 @@
* {
box-sizing: border-box;
}
td {
white-space: nowrap;
}
.guitable {
background-color: #DDDDDD;
border: 1px solid #000000;
/* border-collapse: collapse; */
border-radius: 10px;
border: none;
border-spacing: 0px;
padding: 5px;
margin-left: auto;
margin-right: auto;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.guitable tr:last-child td:first-child {
border-bottom-left-radius: 12px;
}
.guitable tr:last-child td:last-child {
border-bottom-right-radius: 12px;
}
.guitable tr:first-child td:first-child {
border-top-left-radius: 12px;
}
.guitable tr:first-child td:last-child {
border-top-right-radius: 12px;
}
.guitable tr:nth-child(odd) {
background-color: #DDDDDD;
}
.guitable tr:nth-child(even) {
background-color: #DDDDDD;
}
/* For mobile phones: */
[class*="col-"] {
width: 100%;
}
@media only screen and (min-width: 700px) {
/* For tablets: */
.col-s-1 {width: 50%;background-color: #DDDDDD;}
.col-s-2 {width: 50%;background-color: #DDDDDD;}
.col-s-full {width: 100%;background-color: #F2F2F2;}
[class*="col-"] {
width: 100%;
}
@media only screen and (min-width: 990px) {
/* For desktop: */
.col-1 {width: 50%;background-color: #F2F2F2;}
.col-2 {width: 50%;background-color: #F2F2F2;}
.col-full {width: 100%;background-color: #F2F2F2;}
}
[class*="col-"] {
float: left;
padding: 5px;
border: none;
}
.row::after {
content: "";
clear: both;
display: table;
}
.group_name {
padding-left:1em;
padding-right:1em;
font-size:105%;
font-weight:bold;
width: 1%;
white-space: nowrap;
/* text-align: center; */
}
.yellow_td {
padding-left:1em;
padding-right:1em;
background-color: yellow;
width: 1%;
white-space: nowrap;
}
.gray_td {
padding-left:1em;
padding-right:1em;
background-color: gray;
width: 1%;
white-space: nowrap;
}
.nocol_td {
padding-left:1em;
padding-right:1em;
width: 1%;
white-space: nowrap;
}
/* Style the tab */
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
/* Style the buttons that are used to open the tab content */
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
font-size:105%;
font-weight:bold;
}
/* Change background color of buttons on hover */
.tab button:hover {
background-color: #ddd;
}
/* Create an active/current tablink class */
.tab button.active {
background-color: #ccc;
}
/* Style the tab content */
.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
.tabcontent {
animation: fadeEffect 1s; /* Fading effect takes 1 second */
}
/* Go from zero to full opacity */
@keyframes fadeEffect {
from {opacity: 0;}
to {opacity: 1;}
}
/* Chrome, Safari, Opera */
@-webkit-keyframes example {
0% {background-color:red; left:20px; top:0px;}
25% {background-color:orange; left:25px; top:0px;}
50% {background-color:green; left:30px; top:0px;}
75% {background-color:orange; left:25px; top:0px;}
100% {background-color:red; left:20px; top:0px;}
}
/* Standard syntax */
@keyframes example {
0% {background-color:red; left:20px; top:0px;}
25% {background-color:orange; left:25px; top:0px;}
50% {background-color:green; left:30px; top:0px;}
75% {background-color:orange; left:25px; top:0px;}
100% {background-color:red; left:20px; top:0px;}
}
#myBar {
width: 10%;
height: 30px;
background-color: #4CAF50;
text-align: center; /* To center it horizontally (if you want) */
line-height: 30px; /* To center it vertically */
color: white;
}

232
main.js Normal file
View File

@@ -0,0 +1,232 @@
const { app, BrowserWindow, Menu, dialog, ipcMain, fs } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 950,
height: 580,
webPreferences: {
nodeIntegration: true,
nativeWindowOpen: true
}
})
const template = [
{
label: 'File',
submenu: [
{
label: 'Open',
accelerator: 'CmdOrCtrl+O',
click () {
dialog.showOpenDialog(win,
{ title : "Load configuration file",
defaultPath : "./",
//buttonLabel : "Custom button",
filters :[
{name: 'Config file type', extensions: ['cfg']},
],
properties: ['openFile']}
).then(result => {
console.log(result.canceled);
console.log(result.filePaths);
if (!result.canceled) {
var focusedWindow = BrowserWindow.getFocusedWindow();
focusedWindow.webContents.send('openFile',result.filePaths);
}
}).catch(err => {
console.log(err);
})
}
},
{
label: 'Select Folder...',
accelerator: 'CmdOrCtrl+F',
click () {
dialog.showOpenDialog(win,
{ title: "Select folder",
defaultPath : "./",
properties:["openDirectory"]}
).then(result => {
console.log(result.filePaths)
var focusedWindow = BrowserWindow.getFocusedWindow();
focusedWindow.webContents.send('selectFolder',result.filePaths);
}).catch(err => {
console.log(err);
})
}
},
{
label: 'Save',
accelerator: 'CmdOrCtrl+S',
click () {
var focusedWindow = BrowserWindow.getFocusedWindow();
focusedWindow.webContents.send('saveFile','');
}
},
{
label: 'Save As...',
accelerator: 'CmdOrCtrl+Shift+S',
click () {
dialog.showSaveDialog(win,
{ title : "Save configuration file",
defaultPath : "./",
filters :[
{name: 'Config file type', extensions: ['cfg']},
{name: 'All Files', extensions: ['*']}
],
properties: ['showOverwriteConfirmation']}
).then(result => {
var focusedWindow = BrowserWindow.getFocusedWindow();
focusedWindow.webContents.send('saveFile',result.filePath);
}).catch(err => {
console.log(err);
})
}
},
{
label: 'Print',
accelerator: 'CmdOrCtrl+P',
click () {
var focusedWindow = BrowserWindow.getFocusedWindow();
const options = {};
focusedWindow.webContents.print(options, (success, errorType) => {
if (!success) console.log(errorType)
})
}
},
{
role: 'quit'
}
]
},
{
role: 'editMenu'
},
{
label: 'Plot',
submenu: [
{
label: 'Plot Profiles',
//accelerator: 'CmdOrCtrl+P P',
click () {
dialog.showOpenDialog(win,
{ title : "Select rge files",
filters :[
{name: 'Profile file type', extensions: ['rge']},
{name: 'All Files', extensions: ['*']}
],
properties: ['openFile', 'multiSelections']}
).then(result => {
console.log(result.canceled);
console.log(result.filePaths);
if (!result.canceled) {
var focusedWindow = BrowserWindow.getFocusedWindow();
focusedWindow.webContents.send('plotProf',result.filePaths);
}
}).catch(err => {
console.log(err);
})
}
},
{
label: 'Plot Fractions',
//accelerator: 'CmdOrCtrl+P F',
click () {
dialog.showOpenDialog(win,
{ title : "Select sequence file",
filters :[
{name: 'Sequence file type', extensions: ['dat']},
{name: 'All Files', extensions: ['*']}
],
properties: ['openFile']}
).then(result => {
console.log(result.canceled);
console.log(result.filePaths);
if (!result.canceled) {
var focusedWindow = BrowserWindow.getFocusedWindow();
focusedWindow.webContents.send('plotFrac',result.filePaths);
}
}).catch(err => {
console.log(err);
})
}
},
{
label: 'Plot Mean',
//accelerator: 'CmdOrCtrl+P M',
click () {
dialog.showOpenDialog(win,
{ title : "Select sequence file",
filters :[
{name: 'Sequence file type', extensions: ['dat']},
{name: 'All Files', extensions: ['*']}
],
properties: ['openFile']}
).then(result => {
console.log(result.canceled);
console.log(result.filePaths);
if (!result.canceled) {
var focusedWindow = BrowserWindow.getFocusedWindow();
focusedWindow.webContents.send('plotMean',result.filePaths);
}
}).catch(err => {
console.log(err);
})
}
}
]
},
{
role: 'viewMenu'
},
{
role: 'windowMenu'
},
{
role: 'help',
submenu: [
{
role: 'about'
},
{
label: 'Learn More',
click () { require('electron').shell.openExternal('http://electron.atom.io') }
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
win.loadFile('TrimSP.html');
// Comment the following line to start without Dev
// win.openDevTools();
}
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
ipcMain.on('folderSelect', (event) => {
dialog.showOpenDialog({ title: "Select folder",
defaultPath : "./",
properties:["openDirectory"]}
).then(result => {
console.log(result.filePaths)
var focusedWindow = BrowserWindow.getFocusedWindow();
focusedWindow.webContents.send('selectFolder',result.filePaths);
}).catch(err => {
console.log(err);
})
});

115
myplots.js Normal file
View File

@@ -0,0 +1,115 @@
const Plotly = require('plotly.js-dist');
function Plot_xy(plotdiv,x,y,labels){
// Plot (x,y) scatter with x/ylabels
// place generated plot in div named plotdiv
//var plotDiv = document.getElementById(plotdiv);
let xlable = '';
let ylable = '';
let legend = '';
// labels are arranged as xlable, ylabel, legend
if (labels[0]) xlabel=labels[0];
if (labels[1]) ylabel=labels[1];
if (labels[2]) legend=labels[2];
let traces = [{
x: x,
y: y,
mode: 'lines+markers',
line: {shape: 'spline'},
name: legend
}];
let layout = {
autosize: true,
xaxis: {title: xlabel},
yaxis: {title: ylabel}
}
Plotly.plot(plotdiv, traces, layout);
// Resize
if (plotdiv == "plotRge") resizePl(1);
if (plotdiv == "plotFrac") resizePl(2);
};
function Plot_xyerr(plotdiv,x, y,dy,xlabel,ylabel){
// Plot (x,y) scatter with x/ylabels
// place generated plot in div named plotdiv
// and y error bars in dy
var traces = [{
x: x,
y: y,
mode: 'lines+markers',
error_y: {
type: 'data',
array : dy,
visible: true
},
}];
var layout = {
xaxis: {title: xlabel},
yaxis: {title: ylabel}
}
Plotly.plot(plotdiv, traces, layout);
};
function Plot_xyerrpm(plotdiv,x, y,dyp,dym,xlabel,ylabel){
// Plot (x,y) scatter with x/ylabels
// place generated plot in div named plotdiv
// and aymmetric y error bars in dyp and dym
var plotDiv = document.getElementById("plot");
var traces = [{
x: x,
y: y,
mode: 'lines+markers',
error_y: {
type: 'data',
symmetric: false,
array : dyp,
arrayminus: dym,
visible: true
},
}];
var layout = {
xaxis: {title: xlabel},
yaxis: {title: ylabel}
}
Plotly.plot(plotdiv,traces,layout);
};
function sizePlot(){
var plotDiv=this.document.getElementById("newPlot");
let newx=this.innerWidth-25;
let newy=this.innerHeight-25;
var update ={
width: newx,
height: newy
};
Plotly.relayout(plotDiv,update);
}
function resizePl(flag){
let newx=this.innerWidth/2-50;
let newy=this.innerHeight-85;
var plotDiv1=this.document.getElementById("plotRge");
var plotDiv2=this.document.getElementById("plotFrac");
var update ={
width: newx,
height: newy
};
if (flag == null) {
Plotly.relayout(plotDiv1,update);
Plotly.relayout(plotDiv2,update);
} else if (flag == 1) {
Plotly.relayout(plotDiv1,update);
} else if ( flag == 2) {
Plotly.relayout(plotDiv2,update);
}
}

5210
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

53
package.json Normal file
View File

@@ -0,0 +1,53 @@
{
"name": "TrimSP",
"version": "1.0.0",
"description": "Trim.SP simulation to calculate stopping profile of implanted probes.",
"main": "main.js",
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make"
},
"keywords": [],
"author": "Zaher Salman",
"license": "GPL2",
"devDependencies": {
"@electron-forge/cli": "^6.0.0-beta.57",
"@electron-forge/maker-deb": "^6.0.0-beta.57",
"@electron-forge/maker-rpm": "^6.0.0-beta.57",
"@electron-forge/maker-squirrel": "^6.0.0-beta.57",
"@electron-forge/maker-zip": "^6.0.0-beta.57",
"electron": "^11.2.1"
},
"dependencies": {
"electron-squirrel-startup": "^1.0.0",
"plotly.js-dist": "^1.58.4"
},
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"name": "TrimSP"
}
},
{
"name": "@electron-forge/maker-zip",
"platforms": [
"darwin"
]
},
{
"name": "@electron-forge/maker-deb",
"config": {}
},
{
"name": "@electron-forge/maker-rpm",
"config": {}
}
]
}
}
}

220
plotly.css Normal file
View File

@@ -0,0 +1,220 @@
.js-plotly-plot .plotly, .js-plotly-plot .plotly div {
direction: ltr;
font-family: 'Open Sans', verdana, arial, sans-serif;
margin: 0;
padding: 0; }
.js-plotly-plot .plotly input, .js-plotly-plot .plotly button {
font-family: 'Open Sans', verdana, arial, sans-serif; }
.js-plotly-plot .plotly input:focus, .js-plotly-plot .plotly button:focus {
outline: none; }
.js-plotly-plot .plotly a {
text-decoration: none; }
.js-plotly-plot .plotly a:hover {
text-decoration: none; }
.js-plotly-plot .plotly .crisp {
shape-rendering: crispEdges; }
.js-plotly-plot .plotly .user-select-none {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none; }
.js-plotly-plot .plotly svg {
overflow: hidden; }
.js-plotly-plot .plotly svg a {
fill: #447adb; }
.js-plotly-plot .plotly svg a:hover {
fill: #3c6dc5; }
.js-plotly-plot .plotly .main-svg {
position: absolute;
top: 0;
left: 0;
pointer-events: none; }
.js-plotly-plot .plotly .main-svg .draglayer {
pointer-events: all; }
.js-plotly-plot .plotly .cursor-default {
cursor: default; }
.js-plotly-plot .plotly .cursor-pointer {
cursor: pointer; }
.js-plotly-plot .plotly .cursor-crosshair {
cursor: crosshair; }
.js-plotly-plot .plotly .cursor-move {
cursor: move; }
.js-plotly-plot .plotly .cursor-col-resize {
cursor: col-resize; }
.js-plotly-plot .plotly .cursor-row-resize {
cursor: row-resize; }
.js-plotly-plot .plotly .cursor-ns-resize {
cursor: ns-resize; }
.js-plotly-plot .plotly .cursor-ew-resize {
cursor: ew-resize; }
.js-plotly-plot .plotly .cursor-sw-resize {
cursor: sw-resize; }
.js-plotly-plot .plotly .cursor-s-resize {
cursor: s-resize; }
.js-plotly-plot .plotly .cursor-se-resize {
cursor: se-resize; }
.js-plotly-plot .plotly .cursor-w-resize {
cursor: w-resize; }
.js-plotly-plot .plotly .cursor-e-resize {
cursor: e-resize; }
.js-plotly-plot .plotly .cursor-nw-resize {
cursor: nw-resize; }
.js-plotly-plot .plotly .cursor-n-resize {
cursor: n-resize; }
.js-plotly-plot .plotly .cursor-ne-resize {
cursor: ne-resize; }
.js-plotly-plot .plotly .cursor-grab {
cursor: -webkit-grab;
cursor: grab; }
.js-plotly-plot .plotly .modebar {
position: absolute;
top: 2px;
right: 2px; }
.js-plotly-plot .plotly .ease-bg {
-webkit-transition: background-color 0.3s ease 0s;
-moz-transition: background-color 0.3s ease 0s;
-ms-transition: background-color 0.3s ease 0s;
-o-transition: background-color 0.3s ease 0s;
transition: background-color 0.3s ease 0s; }
.js-plotly-plot .plotly .modebar--hover > :not(.watermark) {
opacity: 0;
-webkit-transition: opacity 0.3s ease 0s;
-moz-transition: opacity 0.3s ease 0s;
-ms-transition: opacity 0.3s ease 0s;
-o-transition: opacity 0.3s ease 0s;
transition: opacity 0.3s ease 0s; }
.js-plotly-plot .plotly:hover .modebar--hover .modebar-group {
opacity: 1; }
.js-plotly-plot .plotly .modebar-group {
float: left;
display: inline-block;
box-sizing: border-box;
padding-left: 8px;
position: relative;
vertical-align: middle;
white-space: nowrap; }
.js-plotly-plot .plotly .modebar-btn {
position: relative;
font-size: 16px;
padding: 3px 4px;
height: 22px;
/* display: inline-block; including this breaks 3d interaction in .embed mode. Chrome bug? */
cursor: pointer;
line-height: normal;
box-sizing: border-box; }
.js-plotly-plot .plotly .modebar-btn svg {
position: relative;
top: 2px; }
.js-plotly-plot .plotly .modebar.vertical {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-end;
max-height: 100%; }
.js-plotly-plot .plotly .modebar.vertical svg {
top: -1px; }
.js-plotly-plot .plotly .modebar.vertical .modebar-group {
display: block;
float: none;
padding-left: 0px;
padding-bottom: 8px; }
.js-plotly-plot .plotly .modebar.vertical .modebar-group .modebar-btn {
display: block;
text-align: center; }
.js-plotly-plot .plotly [data-title] {
/**
* tooltip body
*/ }
.js-plotly-plot .plotly [data-title]:before, .js-plotly-plot .plotly [data-title]:after {
position: absolute;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
display: none;
opacity: 0;
z-index: 1001;
pointer-events: none;
top: 110%;
right: 50%; }
.js-plotly-plot .plotly [data-title]:hover:before, .js-plotly-plot .plotly [data-title]:hover:after {
display: block;
opacity: 1; }
.js-plotly-plot .plotly [data-title]:before {
content: '';
position: absolute;
background: transparent;
border: 6px solid transparent;
z-index: 1002;
margin-top: -12px;
border-bottom-color: #69738a;
margin-right: -6px; }
.js-plotly-plot .plotly [data-title]:after {
content: attr(data-title);
background: #69738a;
color: white;
padding: 8px 10px;
font-size: 12px;
line-height: 12px;
white-space: nowrap;
margin-right: -18px;
border-radius: 2px; }
.js-plotly-plot .plotly .vertical [data-title]:before, .js-plotly-plot .plotly .vertical [data-title]:after {
top: 0%;
right: 200%; }
.js-plotly-plot .plotly .vertical [data-title]:before {
border: 6px solid transparent;
border-left-color: #69738a;
margin-top: 8px;
margin-right: -30px; }
.js-plotly-plot .plotly .select-outline {
fill: none;
stroke-width: 1;
shape-rendering: crispEdges; }
.js-plotly-plot .plotly .select-outline-1 {
stroke: white; }
.js-plotly-plot .plotly .select-outline-2 {
stroke: black;
stroke-dasharray: 2px 2px; }
.plotly-notifier {
font-family: 'Open Sans', verdana, arial, sans-serif;
position: fixed;
top: 50px;
right: 20px;
z-index: 10000;
font-size: 10pt;
max-width: 180px; }
.plotly-notifier p {
margin: 0; }
.plotly-notifier .notifier-note {
min-width: 180px;
max-width: 250px;
border: 1px solid #fff;
z-index: 3000;
margin: 0;
background-color: #8c97af;
background-color: rgba(140, 151, 175, 0.9);
color: #fff;
padding: 10px;
overflow-wrap: break-word;
word-wrap: break-word;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto; }
.plotly-notifier .notifier-close {
color: #fff;
opacity: 0.8;
float: right;
padding: 0 5px;
background: none;
border: none;
font-size: 20px;
font-weight: bold;
line-height: 20px; }
.plotly-notifier .notifier-close:hover {
color: #444;
text-decoration: none;
cursor: pointer; }

BIN
trimspNL Executable file

Binary file not shown.