emhass 0.8.0__py3-none-any.whl → 0.8.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- emhass/forecast.py +3 -3
- emhass/optimization.py +3 -0
- emhass/retrieve_hass.py +1 -1
- emhass/static/advanced.html +32 -0
- emhass/static/basic.html +12 -0
- emhass/static/img/feather-sprite.svg +1 -0
- emhass/static/script.js +425 -0
- emhass/static/style.css +132 -23
- emhass/templates/index.html +36 -340
- emhass/templates/template.html +1 -0
- emhass/web_server.py +66 -23
- {emhass-0.8.0.dist-info → emhass-0.8.2.dist-info}/METADATA +37 -25
- emhass-0.8.2.dist-info/RECORD +23 -0
- emhass-0.8.0.dist-info/RECORD +0 -19
- {emhass-0.8.0.dist-info → emhass-0.8.2.dist-info}/LICENSE +0 -0
- {emhass-0.8.0.dist-info → emhass-0.8.2.dist-info}/WHEEL +0 -0
- {emhass-0.8.0.dist-info → emhass-0.8.2.dist-info}/entry_points.txt +0 -0
- {emhass-0.8.0.dist-info → emhass-0.8.2.dist-info}/top_level.txt +0 -0
emhass/static/script.js
ADDED
@@ -0,0 +1,425 @@
|
|
1
|
+
//on page reload get saved data
|
2
|
+
window.onload = async function () {
|
3
|
+
pageSelected = await loadBasicOrAdvanced();
|
4
|
+
|
5
|
+
//add listener for basic and advanced html switch
|
6
|
+
document.getElementById("basicOrAdvanced").addEventListener("click", () => SwitchBasicOrAdvanced());
|
7
|
+
};
|
8
|
+
|
9
|
+
//add listeners to buttons (based on page)
|
10
|
+
function loadButtons(page) {
|
11
|
+
switch (page) {
|
12
|
+
case "advanced":
|
13
|
+
[
|
14
|
+
"dayahead-optim",
|
15
|
+
"forecast-model-fit",
|
16
|
+
"forecast-model-predict",
|
17
|
+
"forecast-model-tune",
|
18
|
+
"perfect-optim",
|
19
|
+
"publish-data",
|
20
|
+
"naive-mpc-optim"
|
21
|
+
].forEach((id) =>
|
22
|
+
document.getElementById(id).addEventListener("click", () => formAction(id, "advanced"))
|
23
|
+
);
|
24
|
+
["input-plus", "input-minus"].forEach((id) =>
|
25
|
+
document.getElementById(id).addEventListener("click", () => dictInputs(id))
|
26
|
+
);
|
27
|
+
document.getElementById("input-select").addEventListener("change", () => getSavedData());
|
28
|
+
document.getElementById("input-clear").addEventListener("click", () => ClearInputData());
|
29
|
+
break;
|
30
|
+
case "basic":
|
31
|
+
document.getElementById("dayahead-optim-basic").addEventListener("click", () => formAction("dayahead-optim", "basic"));
|
32
|
+
break;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
//on check present basic or advanced html inside form element
|
37
|
+
async function loadBasicOrAdvanced(RequestedPage) {
|
38
|
+
let basicFile = "basic.html";
|
39
|
+
let advencedFile = "advanced.html";
|
40
|
+
var formContainer = document.getElementById("TabSelection"); //container element to house basic or advanced data
|
41
|
+
//first check any function arg
|
42
|
+
if (arguments.length == 1) {
|
43
|
+
switch (RequestedPage) {
|
44
|
+
case "basic":
|
45
|
+
htmlData = await getHTMLData(basicFile);
|
46
|
+
formContainer.innerHTML = htmlData;
|
47
|
+
loadButtons("basic"); //load buttons based on basic or advanced
|
48
|
+
if (testStorage()) { localStorage.setItem("TabSelection", "basic") } //remember mode (save to localStorage)
|
49
|
+
return "basic"; //return basic to get saved data
|
50
|
+
case "advanced":
|
51
|
+
htmlData = await getHTMLData(advencedFile);
|
52
|
+
formContainer.innerHTML = htmlData;
|
53
|
+
loadButtons("advanced");
|
54
|
+
if (testStorage()) { localStorage.setItem("TabSelection", "advanced") }
|
55
|
+
getSavedData();
|
56
|
+
return "advanced";
|
57
|
+
default:
|
58
|
+
htmlData = await getHTMLData(advencedFile);
|
59
|
+
formContainer.innerHTML = htmlData;
|
60
|
+
loadButtons("advanced");
|
61
|
+
getSavedData();
|
62
|
+
return "advanced";
|
63
|
+
}
|
64
|
+
}
|
65
|
+
//then check localStorage
|
66
|
+
if (testStorage()) {
|
67
|
+
if (localStorage.getItem("TabSelection") !== null && localStorage.getItem("TabSelection") === "advanced") { //if advance
|
68
|
+
htmlData = await getHTMLData(advencedFile);
|
69
|
+
formContainer.innerHTML = htmlData;
|
70
|
+
loadButtons("advanced");
|
71
|
+
getSavedData();
|
72
|
+
return "advanced";
|
73
|
+
}
|
74
|
+
else { //else run basic (first time)
|
75
|
+
htmlData = await getHTMLData(basicFile);
|
76
|
+
formContainer.innerHTML = htmlData;
|
77
|
+
loadButtons("basic");
|
78
|
+
return "basic";
|
79
|
+
}
|
80
|
+
} else {
|
81
|
+
//if localStorage not supported, set to advanced page
|
82
|
+
htmlData = await getHTMLData(advencedFile);
|
83
|
+
formContainer.innerHTML = htmlData;
|
84
|
+
loadButtons("advanced");
|
85
|
+
return "advanced";
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
//on button press, check current displayed page data and switch
|
90
|
+
function SwitchBasicOrAdvanced() {
|
91
|
+
var formContainerChildID = document.getElementById("TabSelection").firstElementChild.id
|
92
|
+
if (formContainerChildID === 'basic') {
|
93
|
+
loadBasicOrAdvanced("advanced")
|
94
|
+
}
|
95
|
+
else {
|
96
|
+
loadBasicOrAdvanced("basic")
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
//set current url
|
101
|
+
function getHTMLURL() {
|
102
|
+
var currentUrl
|
103
|
+
if (window.location) {
|
104
|
+
currentUrl = window.location.href; //get current url to append
|
105
|
+
}
|
106
|
+
else { currentUrl = "" }
|
107
|
+
return currentUrl
|
108
|
+
}
|
109
|
+
|
110
|
+
//get html data from basic.html or advanced.html
|
111
|
+
async function getHTMLData(htmlFile) {
|
112
|
+
const response = await fetch(getHTMLURL() + `static/` + htmlFile);
|
113
|
+
blob = await response.blob(); //get data blob
|
114
|
+
htmlTemplateData = await new Response(blob).text(); //obtain html from blob
|
115
|
+
return await htmlTemplateData;
|
116
|
+
}
|
117
|
+
|
118
|
+
//function pushing data via post, triggered by button action
|
119
|
+
async function formAction(action, page) {
|
120
|
+
|
121
|
+
if (page !== "basic") { //dont try to get input data in basic mode
|
122
|
+
var data = inputToJson(page);
|
123
|
+
}
|
124
|
+
else { var data = {} } //send no data
|
125
|
+
|
126
|
+
if (data !== 0) { //don't run if there is an error in the input (box/list) Json data
|
127
|
+
showChangeStatus("loading", {}); // show loading div for status
|
128
|
+
const response = await fetch(getHTMLURL() + `action/${action}`, {
|
129
|
+
//fetch data from webserver.py
|
130
|
+
method: "POST",
|
131
|
+
headers: {
|
132
|
+
"Content-Type": "application/json",
|
133
|
+
},
|
134
|
+
body: JSON.stringify(data), //note that post can only send data via strings
|
135
|
+
});
|
136
|
+
if (response.status == 201) {
|
137
|
+
showChangeStatus(response.status, {});
|
138
|
+
if (page !== "basic") {
|
139
|
+
saveStorage(); //save to storage if successful
|
140
|
+
}
|
141
|
+
return true
|
142
|
+
} //if successful
|
143
|
+
else {
|
144
|
+
showChangeStatus(response.status, await response.json());
|
145
|
+
return false
|
146
|
+
} // else get Log data from response
|
147
|
+
} else {
|
148
|
+
showChangeStatus("remove"); //replace loading, show tick or cross with none
|
149
|
+
return false
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
//function in control of status icons of post above
|
154
|
+
async function showChangeStatus(status, logJson) {
|
155
|
+
var loading = document.getElementById("loader"); //element showing statuses
|
156
|
+
if (status === "remove") {
|
157
|
+
//remove all
|
158
|
+
loading.innerHTML = "";
|
159
|
+
loading.classList.remove("loading");
|
160
|
+
} else if (status === "loading") {
|
161
|
+
//show loading logo
|
162
|
+
loading.innerHTML = "";
|
163
|
+
loading.classList.add("loading"); //append class with loading animation styling
|
164
|
+
} else if (status === 201) {
|
165
|
+
//if status is 201, then show a tick
|
166
|
+
loading.classList.remove("loading");
|
167
|
+
loading.innerHTML = `<p class=tick>✓</p>`;
|
168
|
+
getTemplate(); //get updated templates
|
169
|
+
} else {
|
170
|
+
//then show a cross
|
171
|
+
loading.classList.remove("loading");
|
172
|
+
loading.innerHTML = `<p class=cross>⤬</p>`; //show cross icon to indicate an error
|
173
|
+
if (logJson.length != 0) {
|
174
|
+
document.getElementById("alert-text").textContent =
|
175
|
+
"\r\n\u2022 " + logJson.join("\r\n\u2022 "); //show received log data in alert box
|
176
|
+
document.getElementById("alert").style.display = "block";
|
177
|
+
document.getElementById("alert").style.textAlign = "left";
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
//get rendered html template with containing new table data
|
183
|
+
async function getTemplate() {
|
184
|
+
//fetch data from webserver.py
|
185
|
+
let htmlTemplateData = "";
|
186
|
+
response = await fetch(getHTMLURL() + `template/table-template`, {
|
187
|
+
method: "GET",
|
188
|
+
});
|
189
|
+
blob = await response.blob(); //get data blob
|
190
|
+
htmlTemplateData = await new Response(blob).text(); //obtain html from blob
|
191
|
+
templateDiv = document.getElementById("template"); //get template container element to override
|
192
|
+
templateDiv.innerHTML = htmlTemplateData; //override container inner html with new data
|
193
|
+
var scripts = Array.from(templateDiv.getElementsByTagName("script")); //replace script tags manually
|
194
|
+
for (const script of scripts) {
|
195
|
+
var TempScript = document.createElement("script");
|
196
|
+
TempScript.innerHTML = script.innerHTML;
|
197
|
+
script.parentElement.appendChild(TempScript);
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
201
|
+
//test localStorage support
|
202
|
+
function testStorage() {
|
203
|
+
try {
|
204
|
+
localStorage.setItem("test", { test: "123" });
|
205
|
+
localStorage.removeItem("test");
|
206
|
+
return true;
|
207
|
+
} catch (error) {
|
208
|
+
return false;
|
209
|
+
}
|
210
|
+
return false;
|
211
|
+
}
|
212
|
+
|
213
|
+
//function gets saved data (if any)
|
214
|
+
function getSavedData() {
|
215
|
+
dictInputs(); //check selected current (List or Box) is correct
|
216
|
+
if (testStorage()) {
|
217
|
+
//if local storage exists and works
|
218
|
+
let selectElement = document.getElementById("input-select"); // select button element
|
219
|
+
var input_container = document.getElementById("input-container"); // container div containing all dynamic input elements (Box/List)
|
220
|
+
if (
|
221
|
+
localStorage.getItem("input_container_content") &&
|
222
|
+
localStorage.getItem("input_container_content") !== "{}"
|
223
|
+
) {
|
224
|
+
//If items already stored in local storage, then override default
|
225
|
+
if (selectElement.value == "Box") {
|
226
|
+
//if Box is selected, show saved json data into box
|
227
|
+
document.getElementById("text-area").value = localStorage.getItem(
|
228
|
+
"input_container_content"
|
229
|
+
);
|
230
|
+
}
|
231
|
+
if (selectElement.value == "List") {
|
232
|
+
//if List is selected, show saved json data into box
|
233
|
+
storedJson = JSON.parse(
|
234
|
+
localStorage.getItem("input_container_content")
|
235
|
+
);
|
236
|
+
if (Object.keys(storedJson).length > 0) {
|
237
|
+
input_container.innerHTML = "";
|
238
|
+
i = 1;
|
239
|
+
for (const ikey in storedJson) {
|
240
|
+
input_container.appendChild(
|
241
|
+
createInputListDiv(ikey, JSON.stringify(storedJson[ikey]))
|
242
|
+
); //call function to present each key as an list div element (with saved values)
|
243
|
+
}
|
244
|
+
}
|
245
|
+
}
|
246
|
+
}
|
247
|
+
}
|
248
|
+
}
|
249
|
+
|
250
|
+
//using localStorage, store json data from input-list(List)/text-area(from input-box) elements for saved state save on page refresh (will save state on successful post)
|
251
|
+
function saveStorage() {
|
252
|
+
var data = JSON.stringify(inputToJson());
|
253
|
+
if (testStorage() && data != "{}") {
|
254
|
+
//don't bother saving if empty and/or storage don't exist
|
255
|
+
localStorage.setItem("input_container_content", data);
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
//function gets values from input-list/text-area(from input-box) elements and return json dict object
|
260
|
+
function inputToJson() {
|
261
|
+
var input_container = document.getElementById("input-container"); //container
|
262
|
+
let inputListArr = document.getElementsByClassName("input-list"); //list
|
263
|
+
let inputTextArea = document.getElementById("text-area"); //box
|
264
|
+
let input_container_child = null;
|
265
|
+
input_container_child = input_container.firstElementChild; //work out which element is first inside container div
|
266
|
+
var jsonReturnData = {};
|
267
|
+
|
268
|
+
if (input_container_child == null) {
|
269
|
+
//if no elements in container then return empty
|
270
|
+
return jsonReturnData;
|
271
|
+
}
|
272
|
+
//if List return box json
|
273
|
+
if (
|
274
|
+
input_container_child.className == "input-list" &&
|
275
|
+
inputListArr.length > 0
|
276
|
+
) {
|
277
|
+
//if list is first and if list is greater then 0, otherwise give empty dict
|
278
|
+
|
279
|
+
let jsonTempData = "{";
|
280
|
+
for (let i = 0; i < inputListArr.length; i++) {
|
281
|
+
let key = inputListArr[i].getElementsByClassName("input-key")[0].value;
|
282
|
+
var value =
|
283
|
+
inputListArr[i].getElementsByClassName("input-value")[0].value;
|
284
|
+
//curate a string with list elements to parse into json later
|
285
|
+
if (key !== "") {
|
286
|
+
//key must not be empty
|
287
|
+
if (i !== 0) {
|
288
|
+
jsonTempData = jsonTempData.concat(",");
|
289
|
+
} //add comma before every parameter, exuding the first
|
290
|
+
jsonTempData = jsonTempData.concat('"' + key + '":' + value);
|
291
|
+
}
|
292
|
+
}
|
293
|
+
jsonTempData = jsonTempData.concat("}");
|
294
|
+
try {
|
295
|
+
jsonReturnData = JSON.parse(jsonTempData);
|
296
|
+
} catch (error) {
|
297
|
+
//if json error, show in alert box
|
298
|
+
document.getElementById("alert-text").textContent =
|
299
|
+
"\r\n" +
|
300
|
+
error +
|
301
|
+
"\r\n" +
|
302
|
+
"JSON Error: String values may not be wrapped in quotes";
|
303
|
+
document.getElementById("alert").style.display = "block";
|
304
|
+
document.getElementById("alert").style.textAlign = "center";
|
305
|
+
return 0;
|
306
|
+
}
|
307
|
+
}
|
308
|
+
//if Box return box json
|
309
|
+
if (
|
310
|
+
input_container_child.className == "input-box" &&
|
311
|
+
inputTextArea.value != ""
|
312
|
+
) {
|
313
|
+
//if Box is first and text is not empty, otherwise give empty dict
|
314
|
+
try {
|
315
|
+
jsonReturnData = JSON.parse(inputTextArea.value);
|
316
|
+
} catch (error) {
|
317
|
+
//if json error, show in alert box
|
318
|
+
document.getElementById("alert-text").textContent = "\r\n" + error;
|
319
|
+
document.getElementById("alert").style.display = "block";
|
320
|
+
return 0;
|
321
|
+
}
|
322
|
+
}
|
323
|
+
return jsonReturnData;
|
324
|
+
}
|
325
|
+
|
326
|
+
//function creates input list div element (and pass it values if given)
|
327
|
+
function createInputListDiv(ikey, ivalue) {
|
328
|
+
let div = document.createElement("div");
|
329
|
+
div.className = "input-list";
|
330
|
+
div.innerHTML = `
|
331
|
+
<input class="input-key" type="text" placeholder="pv_power_forecast" >
|
332
|
+
<p>:</p>
|
333
|
+
<input class="input-value" type="text" placeholder="[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 141.22, 246.18, 513.5, 753.27, 1049.89, 1797.93, 1697.3, 3078.93, 1164.33, 1046.68, 1559.1, 2091.26, 1556.76, 1166.73, 1516.63, 1391.13, 1720.13, 820.75, 804.41, 251.63, 79.25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]" >
|
334
|
+
`;
|
335
|
+
|
336
|
+
if (ikey && ivalue) {
|
337
|
+
//if value and key is provided (from local storage) then add as elements values
|
338
|
+
div.getElementsByClassName("input-key")[0].value = String(ikey);
|
339
|
+
div.getElementsByClassName("input-value")[0].value = String(ivalue);
|
340
|
+
}
|
341
|
+
|
342
|
+
return div;
|
343
|
+
}
|
344
|
+
|
345
|
+
//function assigned to control (add and remove) input (Box and List) elements
|
346
|
+
function dictInputs(action) {
|
347
|
+
var input_container = document.getElementById("input-container"); // container div containing all dynamic input elements
|
348
|
+
let selectElement = document.getElementById("input-select"); // select button
|
349
|
+
let input_container_child = null;
|
350
|
+
let input_container_child_name = null;
|
351
|
+
if (input_container.children.length > 0) {
|
352
|
+
input_container_child = input_container.firstElementChild; // figure out what is the first element inside of container (ie: "text-area" (input-box) or "input-list" (list))
|
353
|
+
input_container_child_name = input_container.firstElementChild.className;
|
354
|
+
}
|
355
|
+
//if list is selected, remove text-area (from Box) element and replace (with input-list)
|
356
|
+
if (selectElement.value == "List") {
|
357
|
+
if (action == "input-plus" || input_container_child_name == "input-box") {
|
358
|
+
//if plus button pressed, or Box element exists
|
359
|
+
if (input_container_child_name == "input-box") {
|
360
|
+
input_container_child.remove();
|
361
|
+
}
|
362
|
+
input_container.appendChild(createInputListDiv(false, false)); //call to createInputListDiv function to craft input-list element (with no values) and append inside container element
|
363
|
+
}
|
364
|
+
if (action == "input-minus") {
|
365
|
+
//minus button pressed, remove input-list element
|
366
|
+
if (input_container.children.length > 0) {
|
367
|
+
let inputListArr = document.getElementsByClassName("input-list");
|
368
|
+
let obj = inputListArr.item(inputListArr.length - 1);
|
369
|
+
obj.innerHTML = "";
|
370
|
+
obj.remove();
|
371
|
+
}
|
372
|
+
}
|
373
|
+
}
|
374
|
+
//if box is selected, remove input-list elements and replace (with text-area)
|
375
|
+
if (selectElement.value == "Box") {
|
376
|
+
if (
|
377
|
+
input_container_child_name == "input-list" ||
|
378
|
+
input_container_child === null
|
379
|
+
) {
|
380
|
+
// if input list exists or no Box element
|
381
|
+
input_container.innerHTML = ""; //remove input-list list elements via erasing container innerHTML
|
382
|
+
let div = document.createElement("div"); //add input-box element
|
383
|
+
div.className = "input-box";
|
384
|
+
div.innerHTML = `
|
385
|
+
<textarea id="text-area" rows="30" placeholder="{}"></textarea>
|
386
|
+
`;
|
387
|
+
input_container.appendChild(div); //append inside of container element
|
388
|
+
}
|
389
|
+
}
|
390
|
+
}
|
391
|
+
|
392
|
+
//clear stored input data from localStorage (if any), clear input elements
|
393
|
+
async function ClearInputData(id) {
|
394
|
+
if (
|
395
|
+
testStorage() &&
|
396
|
+
localStorage.getItem("input_container_content") !== null
|
397
|
+
) {
|
398
|
+
localStorage.setItem("input_container_content", "{}");
|
399
|
+
}
|
400
|
+
ClearInputElements();
|
401
|
+
}
|
402
|
+
|
403
|
+
//clear input elements
|
404
|
+
async function ClearInputElements() {
|
405
|
+
let selectElement = document.getElementById("input-select");
|
406
|
+
var input_container = document.getElementById("input-container");
|
407
|
+
if (selectElement.value == "Box") {
|
408
|
+
document.getElementById("text-area").value = "{}";
|
409
|
+
}
|
410
|
+
if (selectElement.value == "List") {
|
411
|
+
input_container.innerHTML = "";
|
412
|
+
}
|
413
|
+
}
|
414
|
+
|
415
|
+
// //Run day ahead, then publish actions
|
416
|
+
// async function DayheadOptimPublish() {
|
417
|
+
// response = await formAction("dayahead-optim", "basic")
|
418
|
+
// if (response) { //if successful publish data
|
419
|
+
// formAction("publish-data", "basic")
|
420
|
+
// }
|
421
|
+
//}
|
422
|
+
|
423
|
+
|
424
|
+
|
425
|
+
|
emhass/static/style.css
CHANGED
@@ -150,6 +150,15 @@ a {
|
|
150
150
|
text-decoration: none;
|
151
151
|
}
|
152
152
|
|
153
|
+
a:hover {
|
154
|
+
color: #251fe3;
|
155
|
+
}
|
156
|
+
|
157
|
+
a:active {
|
158
|
+
color: #070f71;
|
159
|
+
}
|
160
|
+
|
161
|
+
|
153
162
|
a:active,
|
154
163
|
a:hover {
|
155
164
|
outline-width: 0;
|
@@ -407,6 +416,7 @@ h2 {
|
|
407
416
|
color: #111111;
|
408
417
|
}
|
409
418
|
|
419
|
+
|
410
420
|
button:hover,
|
411
421
|
.alert:hover,
|
412
422
|
select:hover {
|
@@ -414,6 +424,10 @@ select:hover {
|
|
414
424
|
background-color: #e1e1e1;
|
415
425
|
}
|
416
426
|
|
427
|
+
button:active {
|
428
|
+
background-color: #d7d7db;
|
429
|
+
}
|
430
|
+
|
417
431
|
button,
|
418
432
|
input,
|
419
433
|
optgroup,
|
@@ -430,15 +444,6 @@ input {
|
|
430
444
|
overflow: visible;
|
431
445
|
}
|
432
446
|
|
433
|
-
button,
|
434
|
-
.alert,
|
435
|
-
select {
|
436
|
-
text-transform: none;
|
437
|
-
border-width: 1px;
|
438
|
-
border-style: solid;
|
439
|
-
box-shadow: #3d3d3d 3px 3px;
|
440
|
-
;
|
441
|
-
}
|
442
447
|
|
443
448
|
button,
|
444
449
|
html [type="button"],
|
@@ -535,6 +540,21 @@ template {
|
|
535
540
|
display: none;
|
536
541
|
}
|
537
542
|
|
543
|
+
/* feather icons css
|
544
|
+
https://github.com/feathericons/feather */
|
545
|
+
.feather {
|
546
|
+
width: 27px;
|
547
|
+
height: 27px;
|
548
|
+
stroke: currentColor;
|
549
|
+
stroke-width: 2;
|
550
|
+
stroke-linecap: round;
|
551
|
+
stroke-linejoin: round;
|
552
|
+
fill: none;
|
553
|
+
margin-right: 12px;
|
554
|
+
filter: drop-shadow( #282928 .4px .5px);
|
555
|
+
}
|
556
|
+
|
557
|
+
|
538
558
|
/* -------------- */
|
539
559
|
|
540
560
|
/* EMHASS added style */
|
@@ -543,11 +563,45 @@ button,
|
|
543
563
|
.main-svg,
|
544
564
|
.mystyle,
|
545
565
|
.alert,
|
566
|
+
.info,
|
546
567
|
table {
|
547
568
|
border-radius: 7px;
|
548
569
|
/* overflow: visible; */
|
549
570
|
}
|
550
571
|
|
572
|
+
button,
|
573
|
+
.alert,
|
574
|
+
.info,
|
575
|
+
select {
|
576
|
+
text-transform: none;
|
577
|
+
border-width: 1px;
|
578
|
+
border-style: solid;
|
579
|
+
box-shadow: #3d3d3d 3px 3px;
|
580
|
+
}
|
581
|
+
|
582
|
+
|
583
|
+
.alert, .info {
|
584
|
+
max-width: 50%;
|
585
|
+
}
|
586
|
+
|
587
|
+
.info {
|
588
|
+
margin: 0 auto;
|
589
|
+
margin-top: 2em;
|
590
|
+
padding-top: 1em;
|
591
|
+
}
|
592
|
+
|
593
|
+
h2 {
|
594
|
+
margin-bottom: .3em;
|
595
|
+
}
|
596
|
+
|
597
|
+
.table_div h4{
|
598
|
+
margin-top: .5em;
|
599
|
+
}
|
600
|
+
|
601
|
+
.info p {
|
602
|
+
line-height: 2em;
|
603
|
+
}
|
604
|
+
|
551
605
|
table {
|
552
606
|
max-width: 50%;
|
553
607
|
}
|
@@ -634,6 +688,13 @@ th {
|
|
634
688
|
cursor: pointer;
|
635
689
|
}
|
636
690
|
|
691
|
+
#top-links {
|
692
|
+
display: flex;
|
693
|
+
position: absolute;
|
694
|
+
right: 13px;
|
695
|
+
top: 13px;
|
696
|
+
}
|
697
|
+
|
637
698
|
/* Post task status styling */
|
638
699
|
.loading-div {
|
639
700
|
display: flex;
|
@@ -727,10 +788,24 @@ th {
|
|
727
788
|
}
|
728
789
|
}
|
729
790
|
|
791
|
+
/* Basic and Advanced fade transitions */
|
792
|
+
.TabSelection, #advance, #basic, button, select, .info {
|
793
|
+
animation-name: fadeInOpacity;
|
794
|
+
animation-iteration-count: 1;
|
795
|
+
animation-timing-function: ease-in-out;
|
796
|
+
animation-duration: .3s;
|
797
|
+
}
|
798
|
+
|
799
|
+
.input-list, .input-box {
|
800
|
+
animation-name: fadeInOpacity;
|
801
|
+
animation-iteration-count: 1;
|
802
|
+
animation-timing-function: ease-in-out;
|
803
|
+
animation-duration: .1s;
|
804
|
+
}
|
805
|
+
|
730
806
|
/* Alert box styling */
|
731
807
|
.alert {
|
732
808
|
display: box;
|
733
|
-
max-width: fit-content;
|
734
809
|
overflow-x: auto;
|
735
810
|
align-items: center;
|
736
811
|
align-self: center;
|
@@ -862,6 +937,10 @@ th {
|
|
862
937
|
.layer-below {
|
863
938
|
display: none !important;
|
864
939
|
}
|
940
|
+
|
941
|
+
.info, .alert {
|
942
|
+
max-width: 100%;
|
943
|
+
}
|
865
944
|
}
|
866
945
|
|
867
946
|
/* Dark Theme Support */
|
@@ -872,13 +951,20 @@ th {
|
|
872
951
|
}
|
873
952
|
|
874
953
|
img,
|
875
|
-
figure {
|
876
|
-
-webkit-filter: invert(
|
877
|
-
filter: invert(
|
954
|
+
figure, svg.main-svg{
|
955
|
+
-webkit-filter: invert(.82);
|
956
|
+
filter: invert(.82);
|
957
|
+
}
|
958
|
+
|
959
|
+
figure, svg.main-svg{
|
960
|
+
border-color: #181818;
|
961
|
+
border-style: solid;
|
962
|
+
border-width: 1px;
|
878
963
|
}
|
879
964
|
|
880
965
|
button,
|
881
966
|
.alert,
|
967
|
+
.info,
|
882
968
|
select {
|
883
969
|
color: #e1e1e1;
|
884
970
|
background-color: #282928;
|
@@ -892,22 +978,36 @@ th {
|
|
892
978
|
background-color: #3d3d3d;
|
893
979
|
}
|
894
980
|
|
981
|
+
button:active {
|
982
|
+
background-color: #111111;
|
983
|
+
}
|
984
|
+
|
895
985
|
h2,
|
896
986
|
kbd,
|
897
987
|
a {
|
898
988
|
background-color: #111111;
|
899
989
|
color: #ccf3ff;
|
900
|
-
border:
|
990
|
+
border: #3f3f3f;
|
991
|
+
}
|
992
|
+
|
993
|
+
a:hover {
|
994
|
+
color: #d2e8f0;
|
901
995
|
}
|
902
996
|
|
903
|
-
|
904
|
-
|
997
|
+
|
998
|
+
a:active {
|
999
|
+
color: #aaccd6;
|
905
1000
|
}
|
906
1001
|
|
907
|
-
.
|
908
|
-
|
909
|
-
|
910
|
-
|
1002
|
+
.modebar-btn svg path {
|
1003
|
+
fill: #111 !important;
|
1004
|
+
}
|
1005
|
+
.modebar-btn svg {
|
1006
|
+
filter:invert(100%) sepia(64%) saturate(2%) hue-rotate(294deg) brightness(85%) contrast(93%) !important
|
1007
|
+
}
|
1008
|
+
.modebar-btn--logo svg{
|
1009
|
+
filter: None !important;
|
1010
|
+
/* filter: invert(100%) saturate(100%) brightness(87%) contrast(100%) !important */
|
911
1011
|
}
|
912
1012
|
|
913
1013
|
.g-gtitle,
|
@@ -938,9 +1038,18 @@ th {
|
|
938
1038
|
background-color: #3f3f3f;
|
939
1039
|
}
|
940
1040
|
|
941
|
-
|
942
|
-
|
943
|
-
|
1041
|
+
tr:hover td,
|
1042
|
+
th, td:first-child, td:last-child
|
1043
|
+
{
|
1044
|
+
border-radius: 7px
|
1045
|
+
}
|
1046
|
+
|
1047
|
+
.modebar-group{
|
1048
|
+
background-color: #0000 !important;
|
1049
|
+
}
|
1050
|
+
|
1051
|
+
.modebar-btn{
|
1052
|
+
background: #3f3f3f;
|
944
1053
|
}
|
945
1054
|
|
946
1055
|
.input-list input,
|