{"id":19003646,"url":"https://github.com/mpaperno/dsep4tp","last_synced_at":"2025-04-22T18:14:32.789Z","repository":{"id":144830381,"uuid":"570743699","full_name":"mpaperno/DSEP4TP","owner":"mpaperno","description":"Dynamic Script Engine Plugin for Touch Portal - A complete, standalone, multi-threaded JavaScript environment available as a plugin for use with Touch Portal macro launcher software.","archived":false,"fork":false,"pushed_at":"2023-03-13T09:09:42.000Z","size":7805,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"next","last_synced_at":"2025-04-17T09:00:56.488Z","etag":null,"topics":["dynamic-script","expression-evaluator","javascript","javascript-engine","math-eval","math-evaluator","script-engine","touch-portal","touch-portal-plugin","touchportal","touchportalplugin"],"latest_commit_sha":null,"homepage":"http://dse.tpp.max.paperno.us/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mpaperno.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-11-26T01:38:26.000Z","updated_at":"2024-03-04T08:49:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"e9f5a5b6-0f85-4658-a72c-0dcd504676fc","html_url":"https://github.com/mpaperno/DSEP4TP","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpaperno%2FDSEP4TP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpaperno%2FDSEP4TP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpaperno%2FDSEP4TP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpaperno%2FDSEP4TP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mpaperno","download_url":"https://codeload.github.com/mpaperno/DSEP4TP/tar.gz/refs/heads/next","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250296202,"owners_count":21407037,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dynamic-script","expression-evaluator","javascript","javascript-engine","math-eval","math-evaluator","script-engine","touch-portal","touch-portal-plugin","touchportal","touchportalplugin"],"created_at":"2024-11-08T18:19:45.588Z","updated_at":"2025-04-22T18:14:32.779Z","avatar_url":"https://github.com/mpaperno.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dynamic Script Engine Plugin for Touch Portal\n\n[![Made for Touch Portal](https://img.shields.io/static/v1?style=flat\u0026labelColor=5884b3\u0026color=black\u0026label=made%20for\u0026message=Touch%20Portal\u0026logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAetJREFUeNp0UruqWlEQXUePb1HERi18gShYWVqJYGeXgF+Qzh9IGh8QiOmECIYkpRY21pZWFnZaqWBhUG4KjWih4msys8FLbrhZMOfsx6w1e9beWjAYBOMtx0eOGBEZzuczrtcreAyTyQSz2QxN04j3f3J84vim8+cNR4s3rKfTSUQQi8UQjUYlGYvFAtPpVIQ0u90eZrGvnHLXuOKcB1GpkkqlUCqVEA6HsVqt4HA4EAgEMJvNUC6XMRwOwWTRfhIi3e93WK1W1Go1dbTBYIDj8YhOp4NIJIJGo4FEIoF8Po/JZAKLxQIIUSIUChGrEy9Sr9cjQTKZJJvNRtlsVs3r9Tq53W6Vb+Cy0rQyQtd1OJ1O9b/dbpCTyHoul1O9z+dzGI1Gla7jFUiyGBWPx9FsNpHJZNBqtdDtdlXfAv3vZLmCB6SiJIlJhUIB/X7/cS0viXI8n8+nrBcRIblcLlSrVez3e4jrD6LsK3O8Xi8Vi0ViJ4nVid2kB3a7HY3HY2q325ROp8nv94s5d0XkSsR90OFwoOVySaPRiF6DiHs8nmdXn+QInIxKpaJclWe4Xq9fxGazAQvDYBAKfssDeMeD7zITc1gR/4M8isvlIn2+F3N+cIjMB76j4Ha7fb7bf8H7v5j0hYef/wgwAKl+FUPYXaLjAAAAAElFTkSuQmCC)](https://www.touch-portal.com)\n[![Latest Release](https://img.shields.io/github/v/release/mpaperno/DSEP4TP?include_prereleases\u0026display_name=release)](https://github.com/mpaperno/DSEP4TP/releases)\n![Supported Platforms](https://img.shields.io/badge/platforms-Windows%20|%20MacOS%20|%20Linux-AA7722)\n[![GPLv3 License](https://img.shields.io/badge/license-GPLv3-blue.svg)](LICENSE.GPL.txt)\n[![Discord](https://img.shields.io/static/v1?style=flat\u0026color=7289DA\u0026\u0026labelColor=7289DA\u0026message=Discord%20Chat\u0026label=\u0026logo=discord\u0026logoColor=white)](https://discord.gg/pvVsJ6gy3y)\n\u003c!-- \u003cimg alt=\"Lines of code\" src=\"https://img.shields.io/tokei/lines/github/mpaperno/DSEP4TP?color=green\u0026label=LoC\u0026logo=cplusplus\u0026logoColor=f34b7d\"\u003e --\u003e\n\n\n**A complete, standalone, multi-threaded JavaScript environment available as a plugin\nfor use with [Touch Portal](https://www.touch-portal.com/) macro launcher software.**\n\n**This is the ultimate in Touch Portal extensibility short of writing your own plugin.**\n\n\u003cdiv class=\"hide-on-site\"\u003e\n\n**Visit [dse.tpp.max.paperno.us](https://dse.tpp.max.paperno.us) for all details, including this README.**\n\n\u003c/div\u003e\n\n----------\n\u003cdiv class=\"darkmode_inverted_image\"\u003e\n\u003cimg align=\"right\" src=\"https://dse.tpp.max.paperno.us/images/logo/banner_420x105.png\"\u003e\n\u003c/div\u003e\n\n## Features\n**This plugin evaluates expressions using a JavaScript \"engine\" and (optionally) returns results as a Touch Portal _State_.**\u003cbr /\u003e\n(If you're not familiar, Touch Portal uses States to display information to the user and/or trigger events.)\n\nYou can send other dynamic States/Values to this plugin as part of the expressions it evaluates, for example to do some math on a numeric value,\nor to format a piece of text in a particular way. It can evaluate anything from basic math to complex JavaScript modules.\n\nYou do **not** need to know anything about JavaScript to start using the basic features of this plugin.\u003cbr /\u003e\nThe original idea was for something to do math operations in one step and with more features (not a Touch Portal strong point), and it can certainly do that with aplomb.\u003cbr /\u003e\nIt then grew into a full-blown scripting environment, which you may choose to utilize at any level you wish.\n\nSo, what can yo udo with this? A lot! Here's a non-exhaustive list of **some examples**.\u003cbr /\u003e\n(Note: The `${value:MyVariable}` in the examples represents Touch Portal's notation for a dynamic\nglobal Value or a plugin State and will be replaced by Touch Portal with the actual variable value _before_ it is sent to the plugin.)\n\n### One-liner Expressions\n* Evaluate basic math using using a dynamic value from Touch Portal:\n  * `${value:MyVariable} * 100 / (33 + 25)`\n* Use wide array of math functions from basic rounding to trig and calc:\n  * `sin( ( round(${value:MyVariable} * 100) / 100 ) % 360 ) * (180 / Math.PI)`\n* Format strings in multiple ways:\n  * For example with \".NET\" style formatting:\n    * `Format(\"MyVariable to 2 decimals:\\n {0:F2}\", ${value:MyVariable})`\n  * Or if you prefer \"printf\" style:\n    * `sprintf(\"MyVariable to 2 decimals:\\n %.2f\", ${value:MyVariable})`\n  * Or with JavaScript \"interpolated strings\" if you like that:\n    * `` `MyVariable to 2 decimals:\\n ${(${value:MyVariable}).toFixed(2)}` ``\n* Use inline conditional evaluation (\"if X then do Y otherwise do Z\"); E.g. show text based on a value:\n  * `(${value:MyVariable} == 0 ? \"The value is False\" : \"The value is True\")`\n* Do math on dates and times, also with formatting support:\n  * `new Date().addDays(${value:test.dynamic_value_1}).format(\"yyyy  MMM dd, dddd\")`  (eg. \"2022 Dec 15, Thursday\")\n* Calculate a color and use it in a Touch Portal button:\n  * `Color(\"#FF000088\").spin(${value:MyVariable} * 3.6).argb()`\n* Send an image to use as a Touch Portal button icon. E.g. with dynamic image name:\n  * `File.read(\"images/status_icon_${value:MyVariable}.png\", 'b').toBase64()`\n* Get an image from the Internet for a button icon:\n  * `Net.request(\"https://dse.tpp.max.paperno.us/images/logo/icon_64.png\").get().base64()`\n* Read any number of lines from a file, starting from beginning, end, or a specific line number. E.g. read the last 5 lines of a log with a dynamic name:\n  * `` File.readLines(`../logs/console-${new Date().format(\"yyyyMMdd\")}.log`, 5, -1)) ``\n* Extract a value from a JSON object in a file:\n  * `JSON.parse(File.read(\"data.json\")).myProperty`\n* Or get JSON from a Web site and display a named value from the data:\n  * `Net.request(\"https://jsonplaceholder.typicode.com/todos/1\").get().json().title`\n* Update any State or Value in Touch Portal:\n  * `TP.stateUpdateById(\"MyVariable\", ${value:MyVariable} * 25)`\n* Send yourself a notification via Touch Portal:\n  * `TP.showNotification(\"myNotififyId\", \"Something Happened\", \"Hey, something happened, check it out!\")`\n\n### Scripts\n* JavaScript scripts of any complexity can be loaded from file(s) and functions within those scripts can be invoked with dynamic arguments\n  (eg. from Touch Portal states/values).\n* Use simple \"standalone\" scripts or full **JS modules**, which can import other modules and are also cached between uses for excellent performance.\n* An `include()` function is available to read an evaluate any block of code from another file, and `require()` to import modules or parts of them,\n  both available for easy code re-use within standalone scripts or modules.\n* Full `console.log()` (and family) support for debugging/etc; output is sent to a separate plugin log file dedicated for scripting output and errors.\n* Scripts can **run in the background**, for example processing timed events or callbacks from asynchronous processes (eg. a network request or file system watcher).\n* Scripts can **send State/Value updates to Touch Portal** at any time, and they can also create and remove states, among other things\n  (you can literally write a simple Touch Portal \"plugin\" using the scripting engine itself).\n\n### Overall\n* Extensive support for **ECMAScript level 7**, plus custom extensions:\n  * **[File system](@ref FileSystem)** interaction, from one-line read/write utilities to full byte-by-byte access.\n  * Flexible **string, date, and number formatting** with .NET [String.Format style](@ref String.format()) or [\"printf\"](@ref sprintf()) style functions.\n  * Support for **timed/recurring operations** with `setTimeout()`/`setInterval()`.\n  * **Network requests** supported via familiar [Fetch API](@ref FetchAPI) and [XMLHttpRequest](@ref stdlib-xmlhttpreq).\n  * **Touch Portal [interaction](@ref TP)**: update any State or global Value, create and remove States, change Slider positions, send Notifications, and\n    much more (in fact full interaction with Touch Portal, as a plugin, is available to the script environment).\n  * **Color manipulation**/utility library.\n  * **External command and application launching** with optional inter-process data exchange using `Process` class.\n  * Sophisticated system-level **Clipboard interactions** using a provided module.\n  * Lots of convenience extensions to built-in JS objects like Date, Number, Math and String.\n  * Other [global](@ref Global) object extensions and [utilities](@ref Util),\n    eg. for encoding/decoding **base-64 data**, **environment variable** access, **locale data**, **hashing algorithms**, and more.\n  * Infinitely **extensible** via either JavaScript libraries/modules _or_ C++ integration.\n* Any expression/script action can be **saved to persistent settings** and re-created automatically at startup,\n  with a number of options for what the default value should be (fixed, custom expression, etc). Script instances can also save their own custom data\n  structures to preserve state between runs.\n* Expressions and scripts can run in either a single Shared scripting engine instance or in separated **Private engine instances** to keep environments isolated.\n  Instances are _persistent_ throughout the life of the plugin (or until deleted explicitly).\n* **Multi-threaded** for quick response times and non-blocking behavior (long-running scripts will not prevent other scripts from running).\n* Extensively **documented**, with **examples** and scripting **reference**.\n* Written in **optimized C++** for high performance.\n* Runs on **Windows, MacOS, and Linux**.\n\n-------------\n## Download and Install\n\nNote: As with all plugins, this requires the Touch Portal Pro (paid) version to function. Use the latest available Touch Portal version for best results.\n\n1. Get the latest version of this plugin for your operating system from the [Releases](https://github.com/mpaperno/DSEP4TP/releases) page.\n2. The plugin is distributed and installed as a standard Touch Portal `.tpp` plugin file. If you know how to import a plugin, just do that... otherwise continue here.\n3. Import the plugin:\n    1. Start/open _Touch Portal_.\n    2. Click the Settings \"gear\" icon at the top-right and select \"Import plugin...\" from the menu.\n    3. Browse to where you downloaded this plugin's `.tpp` file and select it.\n    4. When prompted by _Touch Portal_ to trust the plugin startup script, select \"Trust Always\" or \"Yes\" (the source code is public!).\n       * \"Trust Always\" will automatically start the plugin each time Touch Portal starts.\n       * \"Yes\" will start the plugin this time and then prompt again each time Touch Portal starts.\n       * If you select \"No\" then you can still start the plugin manually from Touch Portal's _Settings -\u003e Plug-ins_ dialog.\n4. That's it. You should now have the plugin's actions available to you in Touch Portal.\n\n### Updates\n\nUnless stated otherwise in the notes of a particular release version, it is OK to just re-install a newer version of the plugin \"on top of\"\na previous version without uninstalling the old version first. Either way is OK, just keep in mind that uninstalling the plugin via Touch Portal\nwill also remove any current log files as well.\n\n### Update Notifications\n\nIn GitHub (with an account) you can _Watch_ -\u003e _Custom_ -\u003e _Releases_ this repository (button at top right).\n\nOr subscribe to the [ATOM feed](https://github.com/mpaperno/DSEP4TP/releases.atom) for release notifications.\n\nRelease announcements are also made in the Touch Portal Discord Server room [#dynamic-script-engine](https://discord.gg/FhYsZNFgyw)\n\nOr use the provided [example script](@ref example_fetch_and_notify) to check for new versions right from Touch Portal!\n\n\u003cdiv class=\"hide-on-site\"\u003e\n\n-------------\n## Documentation\n\n[Full Documentation \u0026 Examples @ dse.tpp.max.paperno.us](https://dse.tpp.max.paperno.us) - includes this README as well.\n\n[Plugin Quick Start.](https://dse.tpp.max.paperno.us/plugin_quick_start.html)\n\n\u003c/div\u003e\n\n-------------\n## Support and Discussion\n\nUse the GitHub [Issues](https://github.com/mpaperno/DSEP4TP/issues) feature for bug reports and concise feature suggestions.\nUse [Discussions](https://github.com/mpaperno/DSEP4TP/discussions) for any other topic.\n\nThere is also a [Discord support forum](https://discord.gg/sdvqk2MHwj) on my server, an [announcements channel](https://discord.gg/ZXy3m6Y7Ba),\nand discussion rooms on my server @ [#dse-general](https://discord.gg/pvVsJ6gy3y)\nand at Touch Portal's Discord server channel [#dynamic-script-engine](https://discord.gg/FhYsZNFgyw)\n\n**All feedback and input is always welcome! I'd love to know how you're using _DSEP_!**\n\n-------------\n## Troubleshooting\n\nThe most likely cause of something not working right is going to be scripting syntax errors or data being passed to functions in unexpected format (eg. un-escaped backslashes).\n\nSee the [Status and Logging](doc/pages/Status.md) documentation page for more details on script error reporting and plugin logging in general.\n\n-------------\n## Credits\n\nThis project is written, tested, and documented by myself, Maxim (Max) Paperno.\u003cbr/\u003e\nhttps://github.com/mpaperno/\n\n**Contributions are welcome!**\n\nUses portions of the [_Qt Library_](http://qt.io) under the terms of the GPL v3 license.\n\nUses and includes a slightly modified version of the\n[String.format for JavaScript](https://github.com/dmester/sffjs) library,\nused under the terms of the zlib license.\n\nUses and includes a modified version of the\n[TinyColor](https://github.com/bgrins/TinyColor) library,\nused under the terms of the MIT license.\n\nUses and includes the `sprintf` function from\n[Locutus](https://github.com/locutusjs/locutus) project,\nused under the terms of the Locutus license.\n\nDocumentation generated with [Doxygen](https://www.doxygen.nl/) and styled with the most excellent [Doxygen Awesome](https://jothepro.github.io/doxygen-awesome-css).\n\n-------------\n## Copyright, License, and Disclaimer\n\nDynamic Script Engine Project \u003cbr /\u003e\nCOPYRIGHT: Maxim Paperno; All Rights Reserved.\n\nThis program and associated files may be used under the terms of the GNU\nGeneral Public License as published by the Free Software Foundation,\neither version 3 of the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nA copy of the GNU General Public License is included in this repository\nand is also available at \u003chttp://www.gnu.org/licenses/\u003e.\n\nThis project may also use 3rd-party Open Source software under the terms\nof their respective licenses. The copyright notice above does not apply\nto any 3rd-party components used within.\n\n\u003cspan class=\"next_section_button\"\u003e\nGo To: [Scripting Library Reference](modules.html)\n\u003c/span\u003e\n\n\u003cspan class=\"next_section_button\"\u003e\nGo To: [Examples](@ref plugin_examples)\n\u003c/span\u003e\n\n\u003cspan class=\"next_section_button\"\u003e\nGo To: [Plugin Documentation](@ref documentation)\n\u003c/span\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpaperno%2Fdsep4tp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmpaperno%2Fdsep4tp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpaperno%2Fdsep4tp/lists"}