chrome js console: can I use it as ES6 react js component in desktop JS application?
up vote
-1
down vote
favorite
Is any way to have my own instance of Chrome console as react component in my desktop application. Being desktop application assumes that to have my application up and running
- I will use Chrome
- I can write and install Chrome plugins.
- I can build my own browser based on framework like CEF C# https://github.com/cefsharp/CefSharp/ or https://electronjs.org
The code to illustrate what I am looking for on JS script side of my application:
class App extends Component {
constructor() {
super();
this.logger_one = null;
this.logger_two = null;
}
render() {
return (<div>
<SomeOtherComponent .../>
<ChromeConsole ref={(r)=>{this.logger_one = r}} />
<hr/>
<ChromeConsole ref={(r)=>{this.logger_two = r}} />
</div>
)
}
event_handler_one() {
logger_one.log("something happen for one...");
}
event_handler_two() {
logger_two.log("something happen for two...");
}
}
this.logger_one
and this.logger_two
suppose to refer to instances of an object like console so I can use this API: https://developers.google.com/web/tools/chrome-devtools/console/console-reference
I need to get a reference to Chrome console instances, not custom-made console replacement. It is important since I do need all that nice features available for js developers but for a different purpose - observation and understanding my system behavior.
javascript reactjs google-chrome-devtools
|
show 6 more comments
up vote
-1
down vote
favorite
Is any way to have my own instance of Chrome console as react component in my desktop application. Being desktop application assumes that to have my application up and running
- I will use Chrome
- I can write and install Chrome plugins.
- I can build my own browser based on framework like CEF C# https://github.com/cefsharp/CefSharp/ or https://electronjs.org
The code to illustrate what I am looking for on JS script side of my application:
class App extends Component {
constructor() {
super();
this.logger_one = null;
this.logger_two = null;
}
render() {
return (<div>
<SomeOtherComponent .../>
<ChromeConsole ref={(r)=>{this.logger_one = r}} />
<hr/>
<ChromeConsole ref={(r)=>{this.logger_two = r}} />
</div>
)
}
event_handler_one() {
logger_one.log("something happen for one...");
}
event_handler_two() {
logger_two.log("something happen for two...");
}
}
this.logger_one
and this.logger_two
suppose to refer to instances of an object like console so I can use this API: https://developers.google.com/web/tools/chrome-devtools/console/console-reference
I need to get a reference to Chrome console instances, not custom-made console replacement. It is important since I do need all that nice features available for js developers but for a different purpose - observation and understanding my system behavior.
javascript reactjs google-chrome-devtools
2
"certain events" like what?
– zfrisch
Nov 9 at 23:01
2
Well not an actual instance of Chrome console but you can copy it's functionality... an example of this is the console div in the Stack Snippets feature on this site
– Patrick Evans
Nov 9 at 23:05
@PatrickEvans i was unable to follow your hint. the question will have bounty so please elaborate. I need to have multiple loggers in my app main window with somewhat elaborate functionality. just having textarea instances is an initial option only.
– lowtech
Nov 11 at 14:58
Yes, it's obviously possible to create a component that displays strings prettily based on some state. Are you asking for a library recommendation, hoping someone will write one for you, or do you have a specific question?
– Jonas Høgh
Nov 12 at 19:36
2
That is unfortunately considered off-topic here on SO - see softwarerecs.stackexchange.com
– Jonas Høgh
Nov 12 at 20:19
|
show 6 more comments
up vote
-1
down vote
favorite
up vote
-1
down vote
favorite
Is any way to have my own instance of Chrome console as react component in my desktop application. Being desktop application assumes that to have my application up and running
- I will use Chrome
- I can write and install Chrome plugins.
- I can build my own browser based on framework like CEF C# https://github.com/cefsharp/CefSharp/ or https://electronjs.org
The code to illustrate what I am looking for on JS script side of my application:
class App extends Component {
constructor() {
super();
this.logger_one = null;
this.logger_two = null;
}
render() {
return (<div>
<SomeOtherComponent .../>
<ChromeConsole ref={(r)=>{this.logger_one = r}} />
<hr/>
<ChromeConsole ref={(r)=>{this.logger_two = r}} />
</div>
)
}
event_handler_one() {
logger_one.log("something happen for one...");
}
event_handler_two() {
logger_two.log("something happen for two...");
}
}
this.logger_one
and this.logger_two
suppose to refer to instances of an object like console so I can use this API: https://developers.google.com/web/tools/chrome-devtools/console/console-reference
I need to get a reference to Chrome console instances, not custom-made console replacement. It is important since I do need all that nice features available for js developers but for a different purpose - observation and understanding my system behavior.
javascript reactjs google-chrome-devtools
Is any way to have my own instance of Chrome console as react component in my desktop application. Being desktop application assumes that to have my application up and running
- I will use Chrome
- I can write and install Chrome plugins.
- I can build my own browser based on framework like CEF C# https://github.com/cefsharp/CefSharp/ or https://electronjs.org
The code to illustrate what I am looking for on JS script side of my application:
class App extends Component {
constructor() {
super();
this.logger_one = null;
this.logger_two = null;
}
render() {
return (<div>
<SomeOtherComponent .../>
<ChromeConsole ref={(r)=>{this.logger_one = r}} />
<hr/>
<ChromeConsole ref={(r)=>{this.logger_two = r}} />
</div>
)
}
event_handler_one() {
logger_one.log("something happen for one...");
}
event_handler_two() {
logger_two.log("something happen for two...");
}
}
this.logger_one
and this.logger_two
suppose to refer to instances of an object like console so I can use this API: https://developers.google.com/web/tools/chrome-devtools/console/console-reference
I need to get a reference to Chrome console instances, not custom-made console replacement. It is important since I do need all that nice features available for js developers but for a different purpose - observation and understanding my system behavior.
javascript reactjs google-chrome-devtools
javascript reactjs google-chrome-devtools
edited Nov 19 at 22:52
asked Nov 9 at 22:58
lowtech
1,51011529
1,51011529
2
"certain events" like what?
– zfrisch
Nov 9 at 23:01
2
Well not an actual instance of Chrome console but you can copy it's functionality... an example of this is the console div in the Stack Snippets feature on this site
– Patrick Evans
Nov 9 at 23:05
@PatrickEvans i was unable to follow your hint. the question will have bounty so please elaborate. I need to have multiple loggers in my app main window with somewhat elaborate functionality. just having textarea instances is an initial option only.
– lowtech
Nov 11 at 14:58
Yes, it's obviously possible to create a component that displays strings prettily based on some state. Are you asking for a library recommendation, hoping someone will write one for you, or do you have a specific question?
– Jonas Høgh
Nov 12 at 19:36
2
That is unfortunately considered off-topic here on SO - see softwarerecs.stackexchange.com
– Jonas Høgh
Nov 12 at 20:19
|
show 6 more comments
2
"certain events" like what?
– zfrisch
Nov 9 at 23:01
2
Well not an actual instance of Chrome console but you can copy it's functionality... an example of this is the console div in the Stack Snippets feature on this site
– Patrick Evans
Nov 9 at 23:05
@PatrickEvans i was unable to follow your hint. the question will have bounty so please elaborate. I need to have multiple loggers in my app main window with somewhat elaborate functionality. just having textarea instances is an initial option only.
– lowtech
Nov 11 at 14:58
Yes, it's obviously possible to create a component that displays strings prettily based on some state. Are you asking for a library recommendation, hoping someone will write one for you, or do you have a specific question?
– Jonas Høgh
Nov 12 at 19:36
2
That is unfortunately considered off-topic here on SO - see softwarerecs.stackexchange.com
– Jonas Høgh
Nov 12 at 20:19
2
2
"certain events" like what?
– zfrisch
Nov 9 at 23:01
"certain events" like what?
– zfrisch
Nov 9 at 23:01
2
2
Well not an actual instance of Chrome console but you can copy it's functionality... an example of this is the console div in the Stack Snippets feature on this site
– Patrick Evans
Nov 9 at 23:05
Well not an actual instance of Chrome console but you can copy it's functionality... an example of this is the console div in the Stack Snippets feature on this site
– Patrick Evans
Nov 9 at 23:05
@PatrickEvans i was unable to follow your hint. the question will have bounty so please elaborate. I need to have multiple loggers in my app main window with somewhat elaborate functionality. just having textarea instances is an initial option only.
– lowtech
Nov 11 at 14:58
@PatrickEvans i was unable to follow your hint. the question will have bounty so please elaborate. I need to have multiple loggers in my app main window with somewhat elaborate functionality. just having textarea instances is an initial option only.
– lowtech
Nov 11 at 14:58
Yes, it's obviously possible to create a component that displays strings prettily based on some state. Are you asking for a library recommendation, hoping someone will write one for you, or do you have a specific question?
– Jonas Høgh
Nov 12 at 19:36
Yes, it's obviously possible to create a component that displays strings prettily based on some state. Are you asking for a library recommendation, hoping someone will write one for you, or do you have a specific question?
– Jonas Høgh
Nov 12 at 19:36
2
2
That is unfortunately considered off-topic here on SO - see softwarerecs.stackexchange.com
– Jonas Høgh
Nov 12 at 20:19
That is unfortunately considered off-topic here on SO - see softwarerecs.stackexchange.com
– Jonas Høgh
Nov 12 at 20:19
|
show 6 more comments
2 Answers
2
active
oldest
votes
up vote
2
down vote
NOTES
The
window.console
object is a native implementation that can not be instantiated as there's no constructor function or class available. But that is fine, because your "two" loggers can use the samewindow.console
without a problem.The structure
<ChromeConsole ref={(r)=>{this.logger_one = r}} />
will store inthis.logger_one
a reference to the DOM JSX element (See Refs on React docs), so it will not be a reference that we can manipulate. But that is fine, because we can use any other attribute.
You can use a functional component to define a property (example console
) and use it to return the window console:
export default const ChromeConsole = ({ id, console }) => {
console(window.console);
return (<div data-logger-id={id} />);
}
Use it then as:
class App extends Component {
constructor() {
super();
this.logger_one = null;
this.logger_two = null;
}
render() {
return (
<div>
<SomeOtherComponent .../>
<ChromeConsole id="one" console={(r)=>{this.logger_one = r}} />
<button onClick={event_handler_one} />
<hr/>
<ChromeConsole id="two" console={(r)=>{this.logger_two = r}} />
<button onClick={event_handler_two} />
</div>
);
}
event_handler_one = () => {
this.logger_one.log("something happen for one...");
}
event_handler_two = () => {
this.logger_two.log("something happen for two...");
}
}
add a comment |
up vote
1
down vote
Here is my proposition:
<div id="log"></div>
<input id="command" onkeyup="handleCmdEnter(event,this)"/>
And js:
var old = console.log;
var logger = document.getElementById('log');
console.log = function (message) {
if (typeof message == 'object') {
logger.innerHTML += (JSON && JSON.stringify ? JSON.stringify(message) : message) + '<br />';
} else {
logger.innerHTML += message + '<br />';
}
}
window.handleCmdEnter = (event, input) => {
if(event.key=='Enter'){
let val = input.value;
input.value ='';
logger.innerHTML+='<br>'+val;
try {
let res = eval(val);
logger.innerHTML+='<br>'+res;
} catch (e) {
old({e});
logger.innerHTML+='<br>EXCEPTION:'+e.message;
logger.innerHTML+='<br>Stacktrace:'+e.stack;
}
}
}
console.log('xxx');
And here is working example.
This solution doesn't include styles and use 'eval' (=evil) function. It's override "console.log" function (you can override other console functions like error
, debug
,... and also intercepts more console parameters using arguments
).
I only give base idea above how to do it, it needs to be developed (as js library) to have more functionality but StackOverflow is go place to put such code.
well, but i do need Chrome console. I've updated the question. Sorry for confusion
– lowtech
Nov 15 at 21:43
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
NOTES
The
window.console
object is a native implementation that can not be instantiated as there's no constructor function or class available. But that is fine, because your "two" loggers can use the samewindow.console
without a problem.The structure
<ChromeConsole ref={(r)=>{this.logger_one = r}} />
will store inthis.logger_one
a reference to the DOM JSX element (See Refs on React docs), so it will not be a reference that we can manipulate. But that is fine, because we can use any other attribute.
You can use a functional component to define a property (example console
) and use it to return the window console:
export default const ChromeConsole = ({ id, console }) => {
console(window.console);
return (<div data-logger-id={id} />);
}
Use it then as:
class App extends Component {
constructor() {
super();
this.logger_one = null;
this.logger_two = null;
}
render() {
return (
<div>
<SomeOtherComponent .../>
<ChromeConsole id="one" console={(r)=>{this.logger_one = r}} />
<button onClick={event_handler_one} />
<hr/>
<ChromeConsole id="two" console={(r)=>{this.logger_two = r}} />
<button onClick={event_handler_two} />
</div>
);
}
event_handler_one = () => {
this.logger_one.log("something happen for one...");
}
event_handler_two = () => {
this.logger_two.log("something happen for two...");
}
}
add a comment |
up vote
2
down vote
NOTES
The
window.console
object is a native implementation that can not be instantiated as there's no constructor function or class available. But that is fine, because your "two" loggers can use the samewindow.console
without a problem.The structure
<ChromeConsole ref={(r)=>{this.logger_one = r}} />
will store inthis.logger_one
a reference to the DOM JSX element (See Refs on React docs), so it will not be a reference that we can manipulate. But that is fine, because we can use any other attribute.
You can use a functional component to define a property (example console
) and use it to return the window console:
export default const ChromeConsole = ({ id, console }) => {
console(window.console);
return (<div data-logger-id={id} />);
}
Use it then as:
class App extends Component {
constructor() {
super();
this.logger_one = null;
this.logger_two = null;
}
render() {
return (
<div>
<SomeOtherComponent .../>
<ChromeConsole id="one" console={(r)=>{this.logger_one = r}} />
<button onClick={event_handler_one} />
<hr/>
<ChromeConsole id="two" console={(r)=>{this.logger_two = r}} />
<button onClick={event_handler_two} />
</div>
);
}
event_handler_one = () => {
this.logger_one.log("something happen for one...");
}
event_handler_two = () => {
this.logger_two.log("something happen for two...");
}
}
add a comment |
up vote
2
down vote
up vote
2
down vote
NOTES
The
window.console
object is a native implementation that can not be instantiated as there's no constructor function or class available. But that is fine, because your "two" loggers can use the samewindow.console
without a problem.The structure
<ChromeConsole ref={(r)=>{this.logger_one = r}} />
will store inthis.logger_one
a reference to the DOM JSX element (See Refs on React docs), so it will not be a reference that we can manipulate. But that is fine, because we can use any other attribute.
You can use a functional component to define a property (example console
) and use it to return the window console:
export default const ChromeConsole = ({ id, console }) => {
console(window.console);
return (<div data-logger-id={id} />);
}
Use it then as:
class App extends Component {
constructor() {
super();
this.logger_one = null;
this.logger_two = null;
}
render() {
return (
<div>
<SomeOtherComponent .../>
<ChromeConsole id="one" console={(r)=>{this.logger_one = r}} />
<button onClick={event_handler_one} />
<hr/>
<ChromeConsole id="two" console={(r)=>{this.logger_two = r}} />
<button onClick={event_handler_two} />
</div>
);
}
event_handler_one = () => {
this.logger_one.log("something happen for one...");
}
event_handler_two = () => {
this.logger_two.log("something happen for two...");
}
}
NOTES
The
window.console
object is a native implementation that can not be instantiated as there's no constructor function or class available. But that is fine, because your "two" loggers can use the samewindow.console
without a problem.The structure
<ChromeConsole ref={(r)=>{this.logger_one = r}} />
will store inthis.logger_one
a reference to the DOM JSX element (See Refs on React docs), so it will not be a reference that we can manipulate. But that is fine, because we can use any other attribute.
You can use a functional component to define a property (example console
) and use it to return the window console:
export default const ChromeConsole = ({ id, console }) => {
console(window.console);
return (<div data-logger-id={id} />);
}
Use it then as:
class App extends Component {
constructor() {
super();
this.logger_one = null;
this.logger_two = null;
}
render() {
return (
<div>
<SomeOtherComponent .../>
<ChromeConsole id="one" console={(r)=>{this.logger_one = r}} />
<button onClick={event_handler_one} />
<hr/>
<ChromeConsole id="two" console={(r)=>{this.logger_two = r}} />
<button onClick={event_handler_two} />
</div>
);
}
event_handler_one = () => {
this.logger_one.log("something happen for one...");
}
event_handler_two = () => {
this.logger_two.log("something happen for two...");
}
}
answered Nov 18 at 1:17
Gatsbimantico
1,379927
1,379927
add a comment |
add a comment |
up vote
1
down vote
Here is my proposition:
<div id="log"></div>
<input id="command" onkeyup="handleCmdEnter(event,this)"/>
And js:
var old = console.log;
var logger = document.getElementById('log');
console.log = function (message) {
if (typeof message == 'object') {
logger.innerHTML += (JSON && JSON.stringify ? JSON.stringify(message) : message) + '<br />';
} else {
logger.innerHTML += message + '<br />';
}
}
window.handleCmdEnter = (event, input) => {
if(event.key=='Enter'){
let val = input.value;
input.value ='';
logger.innerHTML+='<br>'+val;
try {
let res = eval(val);
logger.innerHTML+='<br>'+res;
} catch (e) {
old({e});
logger.innerHTML+='<br>EXCEPTION:'+e.message;
logger.innerHTML+='<br>Stacktrace:'+e.stack;
}
}
}
console.log('xxx');
And here is working example.
This solution doesn't include styles and use 'eval' (=evil) function. It's override "console.log" function (you can override other console functions like error
, debug
,... and also intercepts more console parameters using arguments
).
I only give base idea above how to do it, it needs to be developed (as js library) to have more functionality but StackOverflow is go place to put such code.
well, but i do need Chrome console. I've updated the question. Sorry for confusion
– lowtech
Nov 15 at 21:43
add a comment |
up vote
1
down vote
Here is my proposition:
<div id="log"></div>
<input id="command" onkeyup="handleCmdEnter(event,this)"/>
And js:
var old = console.log;
var logger = document.getElementById('log');
console.log = function (message) {
if (typeof message == 'object') {
logger.innerHTML += (JSON && JSON.stringify ? JSON.stringify(message) : message) + '<br />';
} else {
logger.innerHTML += message + '<br />';
}
}
window.handleCmdEnter = (event, input) => {
if(event.key=='Enter'){
let val = input.value;
input.value ='';
logger.innerHTML+='<br>'+val;
try {
let res = eval(val);
logger.innerHTML+='<br>'+res;
} catch (e) {
old({e});
logger.innerHTML+='<br>EXCEPTION:'+e.message;
logger.innerHTML+='<br>Stacktrace:'+e.stack;
}
}
}
console.log('xxx');
And here is working example.
This solution doesn't include styles and use 'eval' (=evil) function. It's override "console.log" function (you can override other console functions like error
, debug
,... and also intercepts more console parameters using arguments
).
I only give base idea above how to do it, it needs to be developed (as js library) to have more functionality but StackOverflow is go place to put such code.
well, but i do need Chrome console. I've updated the question. Sorry for confusion
– lowtech
Nov 15 at 21:43
add a comment |
up vote
1
down vote
up vote
1
down vote
Here is my proposition:
<div id="log"></div>
<input id="command" onkeyup="handleCmdEnter(event,this)"/>
And js:
var old = console.log;
var logger = document.getElementById('log');
console.log = function (message) {
if (typeof message == 'object') {
logger.innerHTML += (JSON && JSON.stringify ? JSON.stringify(message) : message) + '<br />';
} else {
logger.innerHTML += message + '<br />';
}
}
window.handleCmdEnter = (event, input) => {
if(event.key=='Enter'){
let val = input.value;
input.value ='';
logger.innerHTML+='<br>'+val;
try {
let res = eval(val);
logger.innerHTML+='<br>'+res;
} catch (e) {
old({e});
logger.innerHTML+='<br>EXCEPTION:'+e.message;
logger.innerHTML+='<br>Stacktrace:'+e.stack;
}
}
}
console.log('xxx');
And here is working example.
This solution doesn't include styles and use 'eval' (=evil) function. It's override "console.log" function (you can override other console functions like error
, debug
,... and also intercepts more console parameters using arguments
).
I only give base idea above how to do it, it needs to be developed (as js library) to have more functionality but StackOverflow is go place to put such code.
Here is my proposition:
<div id="log"></div>
<input id="command" onkeyup="handleCmdEnter(event,this)"/>
And js:
var old = console.log;
var logger = document.getElementById('log');
console.log = function (message) {
if (typeof message == 'object') {
logger.innerHTML += (JSON && JSON.stringify ? JSON.stringify(message) : message) + '<br />';
} else {
logger.innerHTML += message + '<br />';
}
}
window.handleCmdEnter = (event, input) => {
if(event.key=='Enter'){
let val = input.value;
input.value ='';
logger.innerHTML+='<br>'+val;
try {
let res = eval(val);
logger.innerHTML+='<br>'+res;
} catch (e) {
old({e});
logger.innerHTML+='<br>EXCEPTION:'+e.message;
logger.innerHTML+='<br>Stacktrace:'+e.stack;
}
}
}
console.log('xxx');
And here is working example.
This solution doesn't include styles and use 'eval' (=evil) function. It's override "console.log" function (you can override other console functions like error
, debug
,... and also intercepts more console parameters using arguments
).
I only give base idea above how to do it, it needs to be developed (as js library) to have more functionality but StackOverflow is go place to put such code.
edited Nov 15 at 14:55
answered Nov 15 at 14:02
Kamil Kiełczewski
8,27375586
8,27375586
well, but i do need Chrome console. I've updated the question. Sorry for confusion
– lowtech
Nov 15 at 21:43
add a comment |
well, but i do need Chrome console. I've updated the question. Sorry for confusion
– lowtech
Nov 15 at 21:43
well, but i do need Chrome console. I've updated the question. Sorry for confusion
– lowtech
Nov 15 at 21:43
well, but i do need Chrome console. I've updated the question. Sorry for confusion
– lowtech
Nov 15 at 21:43
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53234325%2fchrome-js-console-can-i-use-it-as-es6-react-js-component-in-desktop-js-applicat%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
"certain events" like what?
– zfrisch
Nov 9 at 23:01
2
Well not an actual instance of Chrome console but you can copy it's functionality... an example of this is the console div in the Stack Snippets feature on this site
– Patrick Evans
Nov 9 at 23:05
@PatrickEvans i was unable to follow your hint. the question will have bounty so please elaborate. I need to have multiple loggers in my app main window with somewhat elaborate functionality. just having textarea instances is an initial option only.
– lowtech
Nov 11 at 14:58
Yes, it's obviously possible to create a component that displays strings prettily based on some state. Are you asking for a library recommendation, hoping someone will write one for you, or do you have a specific question?
– Jonas Høgh
Nov 12 at 19:36
2
That is unfortunately considered off-topic here on SO - see softwarerecs.stackexchange.com
– Jonas Høgh
Nov 12 at 20:19