├── .babelrc
├── .eslintrc
├── .github
└── workflows
│ └── release-package.yml
├── .gitignore
├── .npmignore
├── .npmrc
├── .nvmrc
├── .prettierignore
├── .prettierrc
├── CHANGELOG.md
├── DETAIL.md
├── LICENSE
├── README.md
├── dist
├── scripts
│ ├── TCG copy.d.ts
│ ├── TCG copy.js
│ ├── TCG nobuffer.d.ts
│ ├── TCG nobuffer.js
│ ├── TCG origin.d.ts
│ ├── TCG origin.js
│ ├── TCG.d.ts
│ ├── TCG.js
│ ├── global.d.ts
│ └── global.js
└── src
│ ├── index.d.ts
│ ├── index.js
│ └── lib
│ ├── CLIApplication.d.ts
│ ├── CLIApplication.js
│ └── CLIWidgets
│ ├── CLIButton.d.ts
│ ├── CLIButton.js
│ ├── CLICanvas.d.ts
│ ├── CLICanvas.js
│ ├── CLICheckbox.d.ts
│ ├── CLICheckbox.js
│ ├── CLICustom.d.ts
│ ├── CLICustom.js
│ ├── CLIImage.d.ts
│ ├── CLIImage.js
│ ├── CLILabel.d.ts
│ ├── CLILabel.js
│ ├── CLIPanel.d.ts
│ ├── CLIPanel.js
│ ├── CLIRadio.d.ts
│ ├── CLIRadio.js
│ ├── CLITextbox.d.ts
│ ├── CLITextbox.js
│ ├── CLIWebview.d.ts
│ └── CLIWebview.js
├── imgs
├── dog.jpg
├── tcg.gif
└── video.gif
├── package.json
├── scripts
├── TCG nobuffer.ts
├── TCG origin.ts
├── TCG.ts
└── global.ts
├── src
├── index.ts
└── lib
│ ├── CLIApplication.ts
│ └── CLIWidgets
│ ├── CLIButton.ts
│ ├── CLICanvas.ts
│ ├── CLICheckbox.ts
│ ├── CLICustom.ts
│ ├── CLIImage.ts
│ ├── CLILabel.ts
│ ├── CLIPanel.ts
│ ├── CLIRadio.ts
│ ├── CLITextbox.ts
│ └── CLIWebview.ts
├── tests
├── default.js
├── default.jsx
├── normal.js
├── tcg.js
├── tcg2.js
└── tcg3.js
├── transform-jsx-syntax.js
└── tsconfig.json
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": ["@babel/plugin-syntax-jsx", "./transform-jsx-syntax"]
4 | }
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "extends": [
4 | "eslint:recommended",
5 | "plugin:@typescript-eslint/recommended"
6 | ],
7 | "parser": "@typescript-eslint/parser",
8 | "parserOptions": { "project": ["./tsconfig.json"], "ecmaFeatures": { "jsx": true }, "ecmaVersion": "latest", "sourceType": "module" },
9 | "plugins": [
10 | "@typescript-eslint"
11 | ],
12 | "rules": {
13 | "@typescript-eslint/strict-boolean-expressions": [
14 | 2,
15 | {
16 | "allowString" : false,
17 | "allowNumber" : false
18 | }
19 | ]
20 | },
21 | "ignorePatterns": ["src/**/*.test.ts", "src/frontend/generated/*"]
22 | }
--------------------------------------------------------------------------------
/.github/workflows/release-package.yml:
--------------------------------------------------------------------------------
1 | name: Node.js Package
2 |
3 | on:
4 | release:
5 | types: [created]
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | - uses: actions/setup-node@v3
13 | with:
14 | node-version: 16
15 | - run: npm ci
16 | - run: npm test
17 |
18 | publish-gpr:
19 | needs: build
20 | runs-on: ubuntu-latest
21 | permissions:
22 | packages: write
23 | contents: read
24 | steps:
25 | - uses: actions/checkout@v4
26 | - uses: actions/setup-node@v3
27 | with:
28 | node-version: 16
29 | registry-url: https://npm.pkg.github.com/
30 | - run: npm ci
31 | - run: npm publish
32 | env:
33 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .env
3 | package-lock.json
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .github/
2 | imgs/
3 | node_modules/
4 | scripts/
5 | src/
6 | tests/
7 | .gitignore
8 | .npmrc
9 | CHANGELOG.md
10 | DETAIL.md
11 | package-lock.json
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | @ice1:registry=https://npm.pkg.github.com
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v3.0.25
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "prettier.semi": true,
3 | "prettier.tabWidth": 4
4 | }
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### 3.0.21 (30 Nov, 2023)
2 |
3 | #### Three CLI Graphics
4 | - Implementation of triple buffering
5 |
6 | ---
7 |
8 | ### 3.0.19 (30 Nov, 2023)
9 |
10 | #### Three CLI Graphics
11 | - TCG ready to use (You can draw a 3d figure)
12 |
13 | ---
14 |
15 | ### 2.9.14 (21 Nov, 2023)
16 |
17 | #### Three CLI Graphics
18 | - A `scripts` folder has been created for TCG library use.
19 | - Externally tested. To be uploaded later
20 |
21 | ---
22 |
23 | ### 1.8.1 (17 Nov, 2023)
24 |
25 | #### CLIApplication
26 | - Add an `onChange` event to events and defaultEvents, and in the case of `CLITextbox`, call the function if the text has been modified.
27 |
28 | #### More Documents
29 | - `CHANGELOG.md` created to record what you did today and what you updated
--------------------------------------------------------------------------------
/DETAIL.md:
--------------------------------------------------------------------------------
1 | ## 💫 Package Detail
2 |
3 | This is a detailed description of the package.
4 |
5 | ### 🎬 Usage
6 |
7 | In the most known way:
8 | ```jsx
9 | const title = ;
10 | const title = new CLILabel({ text: "title", styles: { "text-color": "#222831", y: 2 }});
11 | ```
12 |
13 | #### 💾 Configuration required for use
14 |
15 | ##### directory structure
16 | ```
17 | - build
18 | - node_modules
19 | - babel.config.js
20 | - index.js (main)
21 | - package.json
22 | - package-lock.json
23 | - transform-syntax-linterf.js
24 | ```
25 |
26 | ##### npm package installation
27 | ```bash
28 | $ npm install babel linterf linterf-scripts
29 | $ npm install --save-dev @babel/cli @babel/core @babel/plugin-syntax-jsx @babel/plugin-transform-react-jsx @babel/preset-env @babel/preset-react
30 | ```
31 |
32 | ##### package.json
33 | ```json
34 | "scripts": {
35 | "build": "linterf-scripts"
36 | }
37 | ```
38 |
39 | ##### babel.config.js
40 | ```js
41 | module.exports = {
42 | "presets": ["@babel/preset-env"],
43 | "plugins": ["@babel/plugin-syntax-jsx", "./transform-syntax-linterf"],
44 |
45 | "ignore": ["node_modules", "build"]
46 | // Add folders to exclude
47 | }
48 | ```
49 |
50 | ##### transform-syntax-linterf
51 | ```js
52 | module.exports = function(babel) {
53 | const { types: t } = babel;
54 |
55 | const supportedElements = [];
56 | // Make sure you write down the names of the widgets you want to use!
57 |
58 | return {
59 | name: 'transform-jsx-syntax',
60 | visitor: {
61 | JSXElement(path) {
62 | const elementName = path.node.openingElement.name.name;
63 |
64 | if (supportedElements.includes(elementName)) {
65 | const pathAttr = path.node.openingElement.attributes;
66 | const pathProps = pathAttr.map((attr) => {
67 | const key = attr.name.name;
68 | let value;
69 |
70 | if (t.isJSXExpressionContainer(attr.value)) value = attr.value.expression;
71 | else value = attr.value;
72 |
73 | return t.objectProperty(t.stringLiteral(key), value);
74 | });
75 |
76 | const newElement = t.newExpression(t.identifier(elementName), [
77 | t.objectExpression(pathProps),
78 | ]);
79 |
80 | path.replaceWith(newElement);
81 | }
82 | },
83 | },
84 | };
85 | };
86 | ```
87 |
88 | We're all ready now! Please write the code and build it at the terminal.
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright 2023 kithub-Inc
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 💫 linterf
4 |
5 | > ***install `GraphicsMagick`***
6 | >
7 | > Be sure to watch [DETAIL.md](https://github.com/ICe1BotMaker/linterf/blob/master/DETAIL.md) before using it!
8 |
9 | ### 💬 An advanced version of nodecli-gui
10 |
11 | - **Widgets**: Panel, Button, Label, Checkbox, Radio, Image, Textbox, Webview, Custom
12 | - **Presets**: Modal (create-later)
13 | - **Functions**: TCG (3D CLI Graphic)
14 |
15 |
17 |
18 | #### 🆕 **TCG ?**
19 | - A 3D engine using cli, and text is drawn on the screen using location and size data.
20 |
21 | ##### When running tcg, use the program below to run it.
22 | - [**Windows Terminal**](https://apps.microsoft.com/detail/9N0DX20HK701?hl=ko-kr&gl=US)
23 |
24 |
25 |
26 | ```jsx
27 | const { CLIApplication } = require(`linterf`);
28 | const global = require(`linterf/dist/scripts/global`);
29 |
30 | const app = new CLIApplication();
31 |
32 | const tcg = new global.TCG([
33 | {
34 | id: `cube`,
35 | center: { x: .5, y: .8, z: .5 },
36 | rotation: { x: .5, y: .5, z: 0 },
37 | vertices: [
38 | { x: 0, y: .7, z: 0 },
39 | { x: 1, y: .7, z: 0 },
40 | { x: 0, y: 1.3, z: 0 },
41 | { x: 1, y: 1.3, z: 0 },
42 | { x: 0, y: .7, z: 1 },
43 | { x: 1, y: .7, z: 1 },
44 | { x: 0, y: 1.3, z: 1 },
45 | { x: 1, y: 1.3, z: 1 },
46 | ]
47 | }
48 | ], { events: {
49 | onFrame: (objects, camera) => {
50 | if (objects[0].vertices[0].x >= 5) {
51 | objects[0].center.x = .5;
52 | objects[0].vertices.map((e, idx) => e.x = (((idx + 1) % 2) === 0));
53 | }
54 |
55 | objects[0].center.x += .15;
56 | objects[0].rotation.y += .2;
57 | objects[0].vertices.map(e => e.x += .15);
58 | }
59 | } });
60 |
61 | app.append(tcg);
62 | app.show(24);
63 | ```
64 |
65 | ### 💾 Installation
66 |
67 | ```bash
68 | $ npm install linterf
69 | ```
70 |
71 | ### 💾 Usage
72 |
73 | ```jsx
74 | const { CLIApplication, CLILabel } = require(`linterf`);
75 |
76 | const app = new CLIApplication();
77 |
78 | const title = ;
79 |
80 | app.append(title);
81 | app.show(30); // frame: 30
82 | ```
83 |
84 | ### 🎥 Run
85 |
86 | ```bash
87 | $ npx linterf-scripts
88 | ```
--------------------------------------------------------------------------------
/dist/scripts/TCG copy.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from '../src/lib/CLIApplication';
2 | export interface Iobject {
3 | id: string;
4 | center: Iposition;
5 | rotation: Iposition;
6 | vertices: Iposition[];
7 | buffer: {
8 | buffer1: any[];
9 | buffer2: any[];
10 | buffer3: any[];
11 | currentBuffer: any[];
12 | };
13 | }
14 | export interface Iposition {
15 | x: number;
16 | y: number;
17 | z: number;
18 | }
19 | export declare class TCG {
20 | data: app.Idata;
21 | camera: Iposition;
22 | objects: Iobject[];
23 | constructor(objects: Iobject[], props?: app.Iproperties);
24 | private rotateX;
25 | private rotateY;
26 | private rotateZ;
27 | private drawToBuffer;
28 | private swapBuffers;
29 | private drawBufferToConsole;
30 | private clearBuffer;
31 | private draw;
32 | private connectAndDraw;
33 | private drawLine;
34 | prerun(widget: app.Iwidget): void;
35 | }
36 |
--------------------------------------------------------------------------------
/dist/scripts/TCG copy.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.TCG = void 0;
30 | const chalk_1 = __importDefault(require("chalk"));
31 | const app = __importStar(require("../src/lib/CLIApplication"));
32 | class TCG {
33 | constructor(objects, props) {
34 | this.data = {
35 | "type": "tcg",
36 | "properties": {
37 | "accepts": ["accepts", "paths", "global", "styles", "events", "defaultEvents", "text", "placeholder", "checked"],
38 | "paths": [],
39 | "global": "",
40 | "styles": {
41 | "x": 1,
42 | "y": 1,
43 | "visible": true
44 | },
45 | "events": {},
46 | "defaultEvents": {}
47 | }
48 | };
49 | this.camera = { x: 1, y: -1, z: 0 };
50 | this.objects = [];
51 | objects = objects.map(e => {
52 | e.buffer = { buffer1: [], buffer2: [], buffer3: [], currentBuffer: [] };
53 | return e;
54 | });
55 | this.objects = this.objects.concat(objects);
56 | if (props)
57 | this.data.properties = app.setProps(props, this.data.properties);
58 | }
59 | rotateX(point, angle, center) {
60 | const y = (point.y - center.y) * Math.cos(angle) - (point.z - center.z) * Math.sin(angle) + center.y;
61 | const z = (point.y - center.y) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
62 | return Object.assign(Object.assign({}, point), { y, z });
63 | }
64 | rotateY(point, angle, center) {
65 | const x = (point.x - center.x) * Math.cos(angle) + (point.z - center.z) * Math.sin(angle) + center.x;
66 | const z = -(point.x - center.x) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
67 | return Object.assign(Object.assign({}, point), { x, z });
68 | }
69 | rotateZ(point, angle, center) {
70 | const x = (point.x - center.x) * Math.cos(angle) - (point.y - center.y) * Math.sin(angle) + center.x;
71 | const y = (point.x - center.x) * Math.sin(angle) + (point.y - center.y) * Math.cos(angle) + center.y;
72 | return Object.assign(Object.assign({}, point), { x, y });
73 | }
74 | drawToBuffer(buffer, x, y, char) {
75 | if (!buffer[y])
76 | buffer[y] = [];
77 | buffer[y][x] = char;
78 | }
79 | swapBuffers(object) {
80 | if (object.buffer.currentBuffer === object.buffer.buffer1) {
81 | object.buffer.currentBuffer = object.buffer.buffer2;
82 | }
83 | else if (object.buffer.currentBuffer === object.buffer.buffer2) {
84 | object.buffer.currentBuffer = object.buffer.buffer3;
85 | }
86 | else {
87 | object.buffer.currentBuffer = object.buffer.buffer1;
88 | }
89 | }
90 | drawBufferToConsole(buffer) {
91 | for (let row of buffer)
92 | if (row)
93 | process.stdout.write(row.join('') + '\n');
94 | }
95 | clearBuffer(buffer) {
96 | for (let i = 0; i < buffer.length; i++)
97 | buffer[i] = [];
98 | }
99 | draw() {
100 | process.stdout.write('\x1Bc');
101 | this.objects.forEach(object => {
102 | if (!object.buffer)
103 | object.buffer = { buffer1: [], buffer2: [], buffer3: [], currentBuffer: [] };
104 | this.clearBuffer(object.buffer.currentBuffer);
105 | let rotatedVertices = object.vertices.map(point => this.rotateX(this.rotateY(this.rotateZ(point, object.rotation.z, object.center), object.rotation.y, object.center), object.rotation.x, object.center));
106 | let translatedVertices = rotatedVertices.map(point => ({
107 | x: point.x - this.camera.x,
108 | y: point.y - this.camera.y,
109 | z: point.z - this.camera.z
110 | }));
111 | this.connectAndDraw([0, 1, 3, 2], translatedVertices);
112 | this.connectAndDraw([4, 5, 7, 6], translatedVertices);
113 | this.connectAndDraw([0, 1, 5, 4], translatedVertices);
114 | this.connectAndDraw([2, 3, 7, 6], translatedVertices);
115 | this.connectAndDraw([0, 2, 6, 4], translatedVertices);
116 | this.connectAndDraw([1, 3, 7, 5], translatedVertices);
117 | this.swapBuffers(object);
118 | this.drawBufferToConsole(object.buffer.currentBuffer);
119 | });
120 | }
121 | connectAndDraw(faceVertices, vertices) {
122 | for (let i = 0; i < faceVertices.length; i++) {
123 | const start = faceVertices[i];
124 | const end = faceVertices[(i + 1) % faceVertices.length];
125 | const startPoint = vertices[start];
126 | const endPoint = vertices[end];
127 | const startScreenX = Math.round(startPoint.x * 10) + 40;
128 | const startScreenY = Math.round(startPoint.y * 10) + 5;
129 | const endScreenX = Math.round(endPoint.x * 10) + 40;
130 | const endScreenY = Math.round(endPoint.y * 10) + 5;
131 | this.drawLine(startScreenX, startScreenY, endScreenX, endScreenY);
132 | }
133 | }
134 | drawLine(x0, y0, x1, y1) {
135 | const dx = Math.abs(x1 - x0);
136 | const dy = Math.abs(y1 - y0);
137 | const sx = x0 < x1 ? 1 : -1;
138 | const sy = y0 < y1 ? 1 : -1;
139 | let err = dx - dy;
140 | while (true) {
141 | process.stdout.cursorTo(x0 - 20, y0 - 10);
142 | process.stdout.write(chalk_1.default.white('█'));
143 | if (x0 === x1 && y0 === y1)
144 | break;
145 | const e2 = 2 * err;
146 | if (e2 > -dy) {
147 | err -= dy;
148 | x0 += sx;
149 | }
150 | if (e2 < dx) {
151 | err += dx;
152 | y0 += sy;
153 | }
154 | }
155 | }
156 | prerun(widget) {
157 | // console.log("Objects:", this.objects);
158 | var _a;
159 | const { events } = widget.data.properties;
160 | (_a = events.onFrame) === null || _a === void 0 ? void 0 : _a.call(events, this.objects, this.camera);
161 | this.draw();
162 | }
163 | }
164 | exports.TCG = TCG;
165 |
--------------------------------------------------------------------------------
/dist/scripts/TCG nobuffer.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from '../src/lib/CLIApplication';
2 | export interface Iobject {
3 | id: string;
4 | center: Iposition;
5 | rotation: Iposition;
6 | vertices: Iposition[];
7 | }
8 | export interface Iposition {
9 | x: number;
10 | y: number;
11 | z: number;
12 | }
13 | export declare class TCG {
14 | data: app.Idata;
15 | camera: Iposition;
16 | objects: Iobject[];
17 | constructor(objects: Iobject[], props?: app.Iproperties);
18 | private rotateX;
19 | private rotateY;
20 | private rotateZ;
21 | private draw;
22 | private connectAndDraw;
23 | private drawLine;
24 | prerun(widget: app.Iwidget): void;
25 | }
26 |
--------------------------------------------------------------------------------
/dist/scripts/TCG nobuffer.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.TCG = void 0;
30 | const chalk_1 = __importDefault(require("chalk"));
31 | const app = __importStar(require("../src/lib/CLIApplication"));
32 | class TCG {
33 | constructor(objects, props) {
34 | this.data = {
35 | "type": "tcg",
36 | "properties": {
37 | "accepts": ["accepts", "paths", "global", "styles", "events", "defaultEvents", "text", "placeholder", "checked"],
38 | "paths": [],
39 | "global": "",
40 | "styles": {
41 | "x": 1,
42 | "y": 1,
43 | "visible": true
44 | },
45 | "events": {},
46 | "defaultEvents": {}
47 | }
48 | };
49 | this.camera = { x: 1, y: -1, z: 0 };
50 | this.objects = [];
51 | this.objects = this.objects.concat(objects);
52 | if (props)
53 | this.data.properties = app.setProps(props, this.data.properties);
54 | }
55 | rotateX(point, angle, center) {
56 | const y = (point.y - center.y) * Math.cos(angle) - (point.z - center.z) * Math.sin(angle) + center.y;
57 | const z = (point.y - center.y) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
58 | return Object.assign(Object.assign({}, point), { y, z });
59 | }
60 | rotateY(point, angle, center) {
61 | const x = (point.x - center.x) * Math.cos(angle) + (point.z - center.z) * Math.sin(angle) + center.x;
62 | const z = -(point.x - center.x) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
63 | return Object.assign(Object.assign({}, point), { x, z });
64 | }
65 | rotateZ(point, angle, center) {
66 | const x = (point.x - center.x) * Math.cos(angle) - (point.y - center.y) * Math.sin(angle) + center.x;
67 | const y = (point.x - center.x) * Math.sin(angle) + (point.y - center.y) * Math.cos(angle) + center.y;
68 | return Object.assign(Object.assign({}, point), { x, y });
69 | }
70 | draw() {
71 | process.stdout.write('\x1Bc');
72 | this.objects.forEach(object => {
73 | let rotatedVertices = object.vertices.map(point => this.rotateX(this.rotateY(this.rotateZ(point, object.rotation.z, object.center), object.rotation.y, object.center), object.rotation.x, object.center));
74 | let translatedVertices = rotatedVertices.map(point => ({
75 | x: point.x - this.camera.x,
76 | y: point.y - this.camera.y,
77 | z: point.z - this.camera.z
78 | }));
79 | this.connectAndDraw([0, 1, 3, 2], translatedVertices);
80 | this.connectAndDraw([4, 5, 7, 6], translatedVertices);
81 | this.connectAndDraw([0, 1, 5, 4], translatedVertices);
82 | this.connectAndDraw([2, 3, 7, 6], translatedVertices);
83 | this.connectAndDraw([0, 2, 6, 4], translatedVertices);
84 | this.connectAndDraw([1, 3, 7, 5], translatedVertices);
85 | });
86 | }
87 | connectAndDraw(faceVertices, vertices) {
88 | for (let i = 0; i < faceVertices.length; i++) {
89 | const start = faceVertices[i];
90 | const end = faceVertices[(i + 1) % faceVertices.length];
91 | const startPoint = vertices[start];
92 | const endPoint = vertices[end];
93 | const startScreenX = Math.round(startPoint.x * 10) + 40;
94 | const startScreenY = Math.round(startPoint.y * 10) + 5;
95 | const endScreenX = Math.round(endPoint.x * 10) + 40;
96 | const endScreenY = Math.round(endPoint.y * 10) + 5;
97 | this.drawLine(startScreenX, startScreenY, endScreenX, endScreenY);
98 | }
99 | }
100 | drawLine(x0, y0, x1, y1) {
101 | const dx = Math.abs(x1 - x0);
102 | const dy = Math.abs(y1 - y0);
103 | const sx = x0 < x1 ? 1 : -1;
104 | const sy = y0 < y1 ? 1 : -1;
105 | let err = dx - dy;
106 | while (true) {
107 | process.stdout.cursorTo(x0 - 20, y0 - 10);
108 | process.stdout.write(chalk_1.default.white('█'));
109 | if (x0 === x1 && y0 === y1)
110 | break;
111 | const e2 = 2 * err;
112 | if (e2 > -dy) {
113 | err -= dy;
114 | x0 += sx;
115 | }
116 | if (e2 < dx) {
117 | err += dx;
118 | y0 += sy;
119 | }
120 | }
121 | }
122 | prerun(widget) {
123 | var _a;
124 | const { events } = widget.data.properties;
125 | (_a = events.onFrame) === null || _a === void 0 ? void 0 : _a.call(events, this.objects, this.camera);
126 | this.draw();
127 | }
128 | }
129 | exports.TCG = TCG;
130 |
--------------------------------------------------------------------------------
/dist/scripts/TCG origin.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from '../src/lib/CLIApplication';
2 | export interface Iobject {
3 | id: string;
4 | center: Iposition;
5 | rotation: Iposition;
6 | vertices: Iposition[];
7 | buffer: {
8 | buffer1: any[];
9 | buffer2: any[];
10 | buffer3: any[];
11 | currentBuffer: any[];
12 | };
13 | }
14 | export interface Iposition {
15 | x: number;
16 | y: number;
17 | z: number;
18 | }
19 | export declare class TCG {
20 | data: app.Idata;
21 | camera: Iposition;
22 | objects: Iobject[];
23 | constructor(objects: Iobject[], props?: app.Iproperties);
24 | private rotateX;
25 | private rotateY;
26 | private rotateZ;
27 | private drawToBuffer;
28 | private swapBuffers;
29 | private drawBufferToConsole;
30 | private clearBuffer;
31 | private draw;
32 | private connectAndDraw;
33 | private drawLine;
34 | prerun(widget: app.Iwidget): void;
35 | }
36 |
--------------------------------------------------------------------------------
/dist/scripts/TCG origin.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.TCG = void 0;
30 | const chalk_1 = __importDefault(require("chalk"));
31 | const app = __importStar(require("../src/lib/CLIApplication"));
32 | class TCG {
33 | constructor(objects, props) {
34 | this.data = {
35 | "type": "tcg",
36 | "properties": {
37 | "accepts": ["accepts", "paths", "global", "styles", "events", "defaultEvents", "text", "placeholder", "checked"],
38 | "paths": [],
39 | "global": "",
40 | "styles": {
41 | "x": 1,
42 | "y": 1,
43 | "visible": true
44 | },
45 | "events": {},
46 | "defaultEvents": {}
47 | }
48 | };
49 | this.camera = { x: 1, y: -1, z: 0 };
50 | this.objects = [];
51 | objects = objects.map(e => {
52 | e.buffer = { buffer1: [], buffer2: [], buffer3: [], currentBuffer: [] };
53 | return e;
54 | });
55 | this.objects = this.objects.concat(objects);
56 | if (props)
57 | this.data.properties = app.setProps(props, this.data.properties);
58 | }
59 | rotateX(point, angle, center) {
60 | const y = (point.y - center.y) * Math.cos(angle) - (point.z - center.z) * Math.sin(angle) + center.y;
61 | const z = (point.y - center.y) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
62 | return Object.assign(Object.assign({}, point), { y, z });
63 | }
64 | rotateY(point, angle, center) {
65 | const x = (point.x - center.x) * Math.cos(angle) + (point.z - center.z) * Math.sin(angle) + center.x;
66 | const z = -(point.x - center.x) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
67 | return Object.assign(Object.assign({}, point), { x, z });
68 | }
69 | rotateZ(point, angle, center) {
70 | const x = (point.x - center.x) * Math.cos(angle) - (point.y - center.y) * Math.sin(angle) + center.x;
71 | const y = (point.x - center.x) * Math.sin(angle) + (point.y - center.y) * Math.cos(angle) + center.y;
72 | return Object.assign(Object.assign({}, point), { x, y });
73 | }
74 | drawToBuffer(buffer, x, y, char) {
75 | if (!buffer[y])
76 | buffer[y] = [];
77 | buffer[y][x] = char;
78 | }
79 | swapBuffers(object) {
80 | if (object.buffer.currentBuffer === object.buffer.buffer1) {
81 | object.buffer.currentBuffer = object.buffer.buffer2;
82 | }
83 | else if (object.buffer.currentBuffer === object.buffer.buffer2) {
84 | object.buffer.currentBuffer = object.buffer.buffer3;
85 | }
86 | else {
87 | object.buffer.currentBuffer = object.buffer.buffer1;
88 | }
89 | }
90 | drawBufferToConsole(buffer) {
91 | for (let row of buffer)
92 | if (row)
93 | process.stdout.write(row.join('') + '\n');
94 | }
95 | clearBuffer(buffer) {
96 | for (let i = 0; i < buffer.length; i++)
97 | buffer[i] = [];
98 | }
99 | draw() {
100 | process.stdout.write('\x1Bc');
101 | this.objects.forEach(object => {
102 | if (!object.buffer)
103 | object.buffer = { buffer1: [], buffer2: [], buffer3: [], currentBuffer: [] };
104 | this.clearBuffer(object.buffer.currentBuffer);
105 | let rotatedVertices = object.vertices.map(point => this.rotateX(this.rotateY(this.rotateZ(point, object.rotation.z, object.center), object.rotation.y, object.center), object.rotation.x, object.center));
106 | let translatedVertices = rotatedVertices.map(point => ({
107 | x: point.x - this.camera.x,
108 | y: point.y - this.camera.y,
109 | z: point.z - this.camera.z
110 | }));
111 | this.connectAndDraw([0, 1, 3, 2], translatedVertices);
112 | this.connectAndDraw([4, 5, 7, 6], translatedVertices);
113 | this.connectAndDraw([0, 1, 5, 4], translatedVertices);
114 | this.connectAndDraw([2, 3, 7, 6], translatedVertices);
115 | this.connectAndDraw([0, 2, 6, 4], translatedVertices);
116 | this.connectAndDraw([1, 3, 7, 5], translatedVertices);
117 | this.swapBuffers(object);
118 | this.drawBufferToConsole(object.buffer.currentBuffer);
119 | });
120 | }
121 | connectAndDraw(faceVertices, vertices) {
122 | for (let i = 0; i < faceVertices.length; i++) {
123 | const start = faceVertices[i];
124 | const end = faceVertices[(i + 1) % faceVertices.length];
125 | const startPoint = vertices[start];
126 | const endPoint = vertices[end];
127 | const startScreenX = Math.round(startPoint.x * 10) + 40;
128 | const startScreenY = Math.round(startPoint.y * 10) + 5;
129 | const endScreenX = Math.round(endPoint.x * 10) + 40;
130 | const endScreenY = Math.round(endPoint.y * 10) + 5;
131 | this.drawLine(startScreenX, startScreenY, endScreenX, endScreenY);
132 | }
133 | }
134 | drawLine(x0, y0, x1, y1) {
135 | const dx = Math.abs(x1 - x0);
136 | const dy = Math.abs(y1 - y0);
137 | const sx = x0 < x1 ? 1 : -1;
138 | const sy = y0 < y1 ? 1 : -1;
139 | let err = dx - dy;
140 | while (true) {
141 | process.stdout.cursorTo(x0 - 20, y0 - 10);
142 | process.stdout.write(chalk_1.default.white('█'));
143 | if (x0 === x1 && y0 === y1)
144 | break;
145 | const e2 = 2 * err;
146 | if (e2 > -dy) {
147 | err -= dy;
148 | x0 += sx;
149 | }
150 | if (e2 < dx) {
151 | err += dx;
152 | y0 += sy;
153 | }
154 | }
155 | }
156 | prerun(widget) {
157 | // console.log("Objects:", this.objects);
158 | var _a;
159 | const { events } = widget.data.properties;
160 | (_a = events.onFrame) === null || _a === void 0 ? void 0 : _a.call(events, this.objects, this.camera);
161 | this.draw();
162 | }
163 | }
164 | exports.TCG = TCG;
165 |
--------------------------------------------------------------------------------
/dist/scripts/TCG.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from '../src/lib/CLIApplication';
2 | export interface Iobject {
3 | id: string;
4 | center: Iposition;
5 | rotation: Iposition;
6 | vertices: Iposition[];
7 | }
8 | export interface Iposition {
9 | x: number;
10 | y: number;
11 | z: number;
12 | }
13 | export declare class TCG {
14 | data: app.Idata;
15 | camera: Iposition;
16 | objects: Iobject[];
17 | constructor(objects: Iobject[], props?: app.Iproperties);
18 | private rotateX;
19 | private rotateY;
20 | private rotateZ;
21 | private draw;
22 | private connectAndDraw;
23 | private drawLine;
24 | prerun(widget: app.Iwidget): void;
25 | }
26 |
--------------------------------------------------------------------------------
/dist/scripts/TCG.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.TCG = void 0;
30 | const chalk_1 = __importDefault(require("chalk"));
31 | const app = __importStar(require("../src/lib/CLIApplication"));
32 | class TCG {
33 | constructor(objects, props) {
34 | this.data = {
35 | "type": "tcg",
36 | "properties": {
37 | "accepts": ["accepts", "paths", "global", "styles", "events", "defaultEvents", "text", "placeholder", "checked"],
38 | "paths": [],
39 | "global": "",
40 | "styles": {
41 | "x": 1,
42 | "y": 1,
43 | "visible": true
44 | },
45 | "events": {},
46 | "defaultEvents": {}
47 | }
48 | };
49 | this.camera = { x: 1, y: -1, z: 0 };
50 | this.objects = [];
51 | this.objects = this.objects.concat(objects);
52 | if (props)
53 | this.data.properties = app.setProps(props, this.data.properties);
54 | }
55 | rotateX(point, angle, center) {
56 | const y = (point.y - center.y) * Math.cos(angle) - (point.z - center.z) * Math.sin(angle) + center.y;
57 | const z = (point.y - center.y) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
58 | return Object.assign(Object.assign({}, point), { y, z });
59 | }
60 | rotateY(point, angle, center) {
61 | const x = (point.x - center.x) * Math.cos(angle) + (point.z - center.z) * Math.sin(angle) + center.x;
62 | const z = -(point.x - center.x) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
63 | return Object.assign(Object.assign({}, point), { x, z });
64 | }
65 | rotateZ(point, angle, center) {
66 | const x = (point.x - center.x) * Math.cos(angle) - (point.y - center.y) * Math.sin(angle) + center.x;
67 | const y = (point.x - center.x) * Math.sin(angle) + (point.y - center.y) * Math.cos(angle) + center.y;
68 | return Object.assign(Object.assign({}, point), { x, y });
69 | }
70 | draw() {
71 | process.stdout.write('\x1Bc');
72 | this.objects.forEach(object => {
73 | let rotatedVertices = object.vertices.map(point => this.rotateX(this.rotateY(this.rotateZ(point, object.rotation.z, object.center), object.rotation.y, object.center), object.rotation.x, object.center));
74 | let translatedVertices = rotatedVertices.map(point => ({
75 | x: point.x - this.camera.x,
76 | y: point.y - this.camera.y,
77 | z: point.z - this.camera.z
78 | }));
79 | this.connectAndDraw([0, 1, 3, 2], translatedVertices);
80 | this.connectAndDraw([4, 5, 7, 6], translatedVertices);
81 | this.connectAndDraw([0, 1, 5, 4], translatedVertices);
82 | this.connectAndDraw([2, 3, 7, 6], translatedVertices);
83 | this.connectAndDraw([0, 2, 6, 4], translatedVertices);
84 | this.connectAndDraw([1, 3, 7, 5], translatedVertices);
85 | });
86 | }
87 | connectAndDraw(faceVertices, vertices) {
88 | for (let i = 0; i < faceVertices.length; i++) {
89 | const start = faceVertices[i];
90 | const end = faceVertices[(i + 1) % faceVertices.length];
91 | const startPoint = vertices[start];
92 | const endPoint = vertices[end];
93 | const startScreenX = Math.round(startPoint.x * 10) + 40;
94 | const startScreenY = Math.round(startPoint.y * 10) + 5;
95 | const endScreenX = Math.round(endPoint.x * 10) + 40;
96 | const endScreenY = Math.round(endPoint.y * 10) + 5;
97 | this.drawLine(startScreenX, startScreenY, endScreenX, endScreenY);
98 | }
99 | }
100 | drawLine(x0, y0, x1, y1) {
101 | const dx = Math.abs(x1 - x0);
102 | const dy = Math.abs(y1 - y0);
103 | const sx = x0 < x1 ? 1 : -1;
104 | const sy = y0 < y1 ? 1 : -1;
105 | let err = dx - dy;
106 | while (true) {
107 | process.stdout.cursorTo(x0 - 20, y0 - 10);
108 | process.stdout.write(chalk_1.default.white('█'));
109 | if (x0 === x1 && y0 === y1)
110 | break;
111 | const e2 = 2 * err;
112 | if (e2 > -dy) {
113 | err -= dy;
114 | x0 += sx;
115 | }
116 | if (e2 < dx) {
117 | err += dx;
118 | y0 += sy;
119 | }
120 | }
121 | }
122 | prerun(widget) {
123 | var _a;
124 | const { events } = widget.data.properties;
125 | (_a = events.onFrame) === null || _a === void 0 ? void 0 : _a.call(events, this.objects, this.camera);
126 | this.draw();
127 | }
128 | }
129 | exports.TCG = TCG;
130 |
--------------------------------------------------------------------------------
/dist/scripts/global.d.ts:
--------------------------------------------------------------------------------
1 | export { TCG } from './TCG';
2 |
--------------------------------------------------------------------------------
/dist/scripts/global.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.TCG = void 0;
4 | var TCG_1 = require("./TCG");
5 | Object.defineProperty(exports, "TCG", { enumerable: true, get: function () { return TCG_1.TCG; } });
6 |
--------------------------------------------------------------------------------
/dist/src/index.d.ts:
--------------------------------------------------------------------------------
1 | export { CLIApplication } from "./lib/CLIApplication";
2 | export { CLIPanel } from "./lib/CLIWidgets/CLIPanel";
3 | export { CLILabel } from "./lib/CLIWidgets/CLILabel";
4 | export { CLIButton } from "./lib/CLIWidgets/CLIButton";
5 | export { CLICheckbox } from "./lib/CLIWidgets/CLICheckbox";
6 | export { CLIRadio } from "./lib/CLIWidgets/CLIRadio";
7 | export { CLIImage } from "./lib/CLIWidgets/CLIImage";
8 | export { CLITextbox } from './lib/CLIWidgets/CLITextbox';
9 | export { CLIWebview } from "./lib/CLIWidgets/CLIWebview";
10 | export { CLICanvas } from "./lib/CLIWidgets/CLICanvas";
11 | export { CLICustom } from "./lib/CLIWidgets/CLICustom";
12 |
--------------------------------------------------------------------------------
/dist/src/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.CLICustom = exports.CLICanvas = exports.CLIWebview = exports.CLITextbox = exports.CLIImage = exports.CLIRadio = exports.CLICheckbox = exports.CLIButton = exports.CLILabel = exports.CLIPanel = exports.CLIApplication = void 0;
4 | var CLIApplication_1 = require("./lib/CLIApplication");
5 | Object.defineProperty(exports, "CLIApplication", { enumerable: true, get: function () { return CLIApplication_1.CLIApplication; } });
6 | var CLIPanel_1 = require("./lib/CLIWidgets/CLIPanel");
7 | Object.defineProperty(exports, "CLIPanel", { enumerable: true, get: function () { return CLIPanel_1.CLIPanel; } });
8 | var CLILabel_1 = require("./lib/CLIWidgets/CLILabel");
9 | Object.defineProperty(exports, "CLILabel", { enumerable: true, get: function () { return CLILabel_1.CLILabel; } });
10 | var CLIButton_1 = require("./lib/CLIWidgets/CLIButton");
11 | Object.defineProperty(exports, "CLIButton", { enumerable: true, get: function () { return CLIButton_1.CLIButton; } });
12 | var CLICheckbox_1 = require("./lib/CLIWidgets/CLICheckbox");
13 | Object.defineProperty(exports, "CLICheckbox", { enumerable: true, get: function () { return CLICheckbox_1.CLICheckbox; } });
14 | var CLIRadio_1 = require("./lib/CLIWidgets/CLIRadio");
15 | Object.defineProperty(exports, "CLIRadio", { enumerable: true, get: function () { return CLIRadio_1.CLIRadio; } });
16 | var CLIImage_1 = require("./lib/CLIWidgets/CLIImage");
17 | Object.defineProperty(exports, "CLIImage", { enumerable: true, get: function () { return CLIImage_1.CLIImage; } });
18 | var CLITextbox_1 = require("./lib/CLIWidgets/CLITextbox");
19 | Object.defineProperty(exports, "CLITextbox", { enumerable: true, get: function () { return CLITextbox_1.CLITextbox; } });
20 | var CLIWebview_1 = require("./lib/CLIWidgets/CLIWebview");
21 | Object.defineProperty(exports, "CLIWebview", { enumerable: true, get: function () { return CLIWebview_1.CLIWebview; } });
22 | var CLICanvas_1 = require("./lib/CLIWidgets/CLICanvas");
23 | Object.defineProperty(exports, "CLICanvas", { enumerable: true, get: function () { return CLICanvas_1.CLICanvas; } });
24 | var CLICustom_1 = require("./lib/CLIWidgets/CLICustom");
25 | Object.defineProperty(exports, "CLICustom", { enumerable: true, get: function () { return CLICustom_1.CLICustom; } });
26 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIApplication.d.ts:
--------------------------------------------------------------------------------
1 | export interface Iwidget {
2 | data: Idata;
3 | prerun: Function;
4 | isTyping?: boolean;
5 | }
6 | export interface Idata {
7 | type: string;
8 | properties: Iproperties;
9 | }
10 | export interface Iproperties {
11 | accepts: Array;
12 | paths: Array;
13 | global: string;
14 | styles: Istyles;
15 | events: Ievents;
16 | defaultEvents: Ievents;
17 | canvasChilds?: Array;
18 | text?: string;
19 | placeholder?: string;
20 | checked?: boolean;
21 | [key: string]: any;
22 | }
23 | export interface IcanvasChild {
24 | type: string;
25 | x: number;
26 | y: number;
27 | toX?: number;
28 | toY?: number;
29 | centerX?: number;
30 | centerY?: number;
31 | fill: string;
32 | radius?: number;
33 | width?: number;
34 | height?: number;
35 | private?: Iresult[];
36 | }
37 | export interface Iresult {
38 | x: number;
39 | y: number;
40 | fill: string;
41 | }
42 | export interface Istyles {
43 | x: number;
44 | y: number;
45 | width?: number;
46 | height?: number;
47 | fill?: string;
48 | "background-color"?: string;
49 | "text-color"?: string;
50 | "placeholder-color"?: string;
51 | visible: boolean;
52 | check?: Array;
53 | img?: string;
54 | page?: string;
55 | "img-pixels"?: (string | Array);
56 | }
57 | export interface Ievents {
58 | onEnter?: Function;
59 | onPut?: Function;
60 | onLeave?: Function;
61 | onChange?: Function;
62 | onConnect?: (object);
63 | onFrame?: Function;
64 | }
65 | export declare class CLIApplication {
66 | private debug;
67 | private widgets;
68 | private Vwidgets;
69 | private curlocs;
70 | constructor(option?: any);
71 | append(...widgets: Array): void;
72 | private event;
73 | isOverLapping(widget: Iwidget, props: Istyles): boolean | "" | 0 | undefined;
74 | hexbn(hex: string, brightness: number): string;
75 | show(frame: number): void;
76 | find(path: string): Iwidget | undefined;
77 | modify(path: string, props: Iproperties): void;
78 | }
79 | export declare function setProps(get: Iproperties, origin: Iproperties): Iproperties;
80 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIApplication.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
4 | };
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | exports.setProps = exports.CLIApplication = void 0;
7 | const chalk_1 = __importDefault(require("chalk"));
8 | class CLIApplication {
9 | constructor(option) {
10 | this.debug = false;
11 | this.widgets = [];
12 | this.Vwidgets = [];
13 | this.curlocs = {
14 | tab: 0,
15 | textloc: 0
16 | };
17 | this.widgets = [];
18 | this.curlocs = {
19 | tab: 0,
20 | textloc: 0
21 | };
22 | if (option === null || option === void 0 ? void 0 : option.debug)
23 | this.debug = true;
24 | }
25 | append(...widgets) {
26 | let exists = [];
27 | widgets.forEach((widget) => {
28 | widget.data.properties.paths.forEach((path) => {
29 | if (exists.includes(path))
30 | throw new Error(`[unique.path] ${path} is already exists`);
31 | exists.push(path);
32 | if (this.find(path)) {
33 | throw new Error(`[unique.path] ${path} is already exists`);
34 | }
35 | });
36 | });
37 | this.widgets = this.widgets.concat(widgets);
38 | }
39 | event() {
40 | process.stdin.setRawMode(true);
41 | process.stdin.setEncoding(`utf-8`);
42 | process.stdin.on(`data`, (key) => {
43 | var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
44 | if (key === `\u0003`) {
45 | process.stdout.write(`\x1b[${process.stdout.rows - 1};${process.stdout.columns}H`);
46 | process.exit();
47 | }
48 | const selected = this.Vwidgets[this.curlocs.tab];
49 | if (selected.isTyping && selected.data.type === `textbox`) {
50 | if (selected.data.properties.text && (this.curlocs.textloc < selected.data.properties.text.length) && key === `\u001b[C`)
51 | this.curlocs.textloc += 1;
52 | if (this.curlocs.textloc > 0 && key === `\u001b[D`)
53 | this.curlocs.textloc -= 1;
54 | if (![`\u001b[D`, `\u001b[C`, `\u0008`, `\r`, `\n`].includes(key)) {
55 | selected.data.properties.text = `${(_a = selected.data.properties.text) === null || _a === void 0 ? void 0 : _a.substring(0, this.curlocs.textloc)}${key}${(_b = selected.data.properties.text) === null || _b === void 0 ? void 0 : _b.substring(this.curlocs.textloc, selected.data.properties.text.length)}`;
56 | this.curlocs.textloc += 1;
57 | }
58 | if (key === `\r` || key === `\n`) {
59 | (_d = (_c = selected.data.properties.defaultEvents) === null || _c === void 0 ? void 0 : _c.onEnter) === null || _d === void 0 ? void 0 : _d.call(_c);
60 | (_f = (_e = selected.data.properties.events) === null || _e === void 0 ? void 0 : _e.onEnter) === null || _f === void 0 ? void 0 : _f.call(_e);
61 | (_h = (_g = selected.data.properties.defaultEvents).onChange) === null || _h === void 0 ? void 0 : _h.call(_g);
62 | (_k = (_j = selected.data.properties.events).onChange) === null || _k === void 0 ? void 0 : _k.call(_j);
63 | }
64 | if (key === `\u0008` && this.curlocs.textloc > 0) {
65 | selected.data.properties.text = `${(_l = selected.data.properties.text) === null || _l === void 0 ? void 0 : _l.substring(0, this.curlocs.textloc - 1)}${(_m = selected.data.properties.text) === null || _m === void 0 ? void 0 : _m.substring(this.curlocs.textloc, selected.data.properties.text.length)}`;
66 | this.curlocs.textloc -= 1;
67 | }
68 | }
69 | else {
70 | if (key === `\u001b[C`)
71 | this.curlocs.tab += 1;
72 | if (key === `\u001b[D`)
73 | this.curlocs.tab -= 1;
74 | if (key === `\u001b[C` || key === `\u001b[D`) {
75 | this.curlocs.textloc = 0;
76 | (_p = (_o = selected.data.properties.events) === null || _o === void 0 ? void 0 : _o.onLeave) === null || _p === void 0 ? void 0 : _p.call(_o);
77 | (_r = (_q = selected.data.properties.defaultEvents) === null || _q === void 0 ? void 0 : _q.onLeave) === null || _r === void 0 ? void 0 : _r.call(_q);
78 | }
79 | if (key === `\r` || key === `\n`) {
80 | this.curlocs.textloc = selected.data.properties.text ? selected.data.properties.text.length : 0;
81 | let result = (_t = (_s = selected.data.properties.defaultEvents) === null || _s === void 0 ? void 0 : _s.onEnter) === null || _t === void 0 ? void 0 : _t.call(_s);
82 | (_v = (_u = selected.data.properties.events) === null || _u === void 0 ? void 0 : _u.onEnter) === null || _v === void 0 ? void 0 : _v.call(_u);
83 | if (selected.data.type === `radio`)
84 | this.widgets = result;
85 | }
86 | }
87 | if (this.curlocs.tab >= this.Vwidgets.length)
88 | this.curlocs.tab = this.Vwidgets.length - 1;
89 | if (this.curlocs.tab < 0)
90 | this.curlocs.tab = 0;
91 | if (selected.data.properties.styles.height !== process.stdout.rows) {
92 | (_x = (_w = selected.data.properties.events) === null || _w === void 0 ? void 0 : _w.onPut) === null || _x === void 0 ? void 0 : _x.call(_w);
93 | (_z = (_y = selected.data.properties.defaultEvents) === null || _y === void 0 ? void 0 : _y.onPut) === null || _z === void 0 ? void 0 : _z.call(_y);
94 | }
95 | });
96 | process.stdout.write(`\x1B[?25l`);
97 | }
98 | isOverLapping(widget, props) {
99 | const { styles } = widget.data.properties;
100 | return ((styles === null || styles === void 0 ? void 0 : styles.width) &&
101 | (styles === null || styles === void 0 ? void 0 : styles.height) &&
102 | (styles === null || styles === void 0 ? void 0 : styles["background-color"]) &&
103 | (props.x >= styles.x && props.x <= styles.x + styles.width) &&
104 | (props.y >= styles.y && props.y <= styles.y + styles.height));
105 | }
106 | hexbn(hex, brightness) {
107 | hex = hex.replace(/^#/, ``);
108 | if (!/^(?:[0-9a-fA-F]{3}){1,2}$/.test(hex))
109 | return ``;
110 | let bigint = parseInt(hex, 16);
111 | let rgb = [(bigint >> 16) & 255, (bigint >> 8) & 255, bigint & 255];
112 | rgb = rgb.map(e => e -= brightness);
113 | rgb = rgb.map(e => Math.max(0, Math.min(255, e)));
114 | let res = rgb.map(e => e.toString(16).padStart(2, `0`));
115 | const hexColor = `#${res.join(``)}`;
116 | return hexColor;
117 | }
118 | show(frame) {
119 | this.event();
120 | setInterval(() => {
121 | console.clear();
122 | if (this.curlocs.tab >= this.Vwidgets.length)
123 | this.curlocs.tab = this.Vwidgets.length - 1;
124 | if (this.curlocs.tab < 0)
125 | this.curlocs.tab = 0;
126 | this.Vwidgets = this.widgets.filter(e => e.data.properties.styles.visible);
127 | this.Vwidgets.forEach((widget, idx) => {
128 | const { type } = widget.data;
129 | const { styles } = widget.data.properties;
130 | let focus = ``;
131 | if (styles.height !== process.stdout.rows && this.curlocs.tab === idx)
132 | focus = chalk_1.default.bgHex(this.hexbn(styles[`background-color`] || styles[`text-color`] || `#ffffff`, 25))(` `);
133 | if (styles.visible && type === `panel`)
134 | widget.prerun(widget, focus);
135 | if (styles.visible && type === `label`)
136 | widget.prerun(this.widgets, widget, this.isOverLapping, focus);
137 | if (styles.visible && type === `button`)
138 | widget.prerun(widget, focus);
139 | if (styles.visible && type === `checkbox`)
140 | widget.prerun(this.widgets, widget, this.isOverLapping, focus);
141 | if (styles.visible && type === `radio`)
142 | widget.prerun(this.widgets, widget, this.isOverLapping, focus);
143 | if (styles.visible && type === `image`)
144 | widget.prerun(widget);
145 | if (styles.visible && type === `textbox`)
146 | widget.prerun(widget, focus, this.curlocs.textloc);
147 | if (styles.visible && type === `canvas`)
148 | widget.prerun(widget);
149 | if (styles.visible && type === `custom`)
150 | widget.prerun(widget, focus, this.widgets, this.isOverLapping, this.curlocs);
151 | if (styles.visible && type === `tcg`)
152 | widget.prerun(widget);
153 | });
154 | if (this.debug) {
155 | process.stdout.write(`\x1b[1;1H`);
156 | console.log(this.curlocs.tab);
157 | }
158 | }, 1000 / frame);
159 | }
160 | find(path) {
161 | return this.widgets.find(value => value.data.properties.paths.includes(path));
162 | }
163 | modify(path, props) {
164 | const widgetIdx = this.widgets.findIndex(value => value.data.properties.paths.includes(path));
165 | this.widgets[widgetIdx].data.properties = setProps(props, this.widgets[widgetIdx].data.properties);
166 | }
167 | }
168 | exports.CLIApplication = CLIApplication;
169 | function setProps(get, origin) {
170 | if (get)
171 | Object.keys(get).forEach((prop) => {
172 | if ((origin === null || origin === void 0 ? void 0 : origin.accepts) && !origin.accepts.includes(prop) && origin.accepts.length !== 0)
173 | return;
174 | if (!Array.isArray(origin[prop]) && typeof origin[prop] === `object`) {
175 | origin[prop] = setProps(get[prop], origin[prop]);
176 | }
177 | else {
178 | const value = get[prop];
179 | origin[prop] = value;
180 | }
181 | });
182 | return origin;
183 | }
184 | exports.setProps = setProps;
185 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLIButton.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 | export declare class CLIButton {
3 | data: app.Idata;
4 | constructor(props?: app.Iproperties);
5 | prerun(widget: app.Iwidget, focus: string): void;
6 | }
7 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLIButton.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.CLIButton = void 0;
30 | const chalk_1 = __importDefault(require("chalk"));
31 | const app = __importStar(require("../CLIApplication"));
32 | class CLIButton {
33 | constructor(props) {
34 | this.data = {
35 | "type": "button",
36 | "properties": {
37 | "text": "lorem ipsum",
38 | "accepts": ["paths", "styles", "events", "text", "global"],
39 | "paths": [],
40 | "global": "",
41 | "styles": {
42 | "x": 1,
43 | "y": 1,
44 | "text-color": "#ffffff",
45 | "visible": true
46 | },
47 | "events": {},
48 | "defaultEvents": {}
49 | }
50 | };
51 | if (props)
52 | this.data.properties = app.setProps(props, this.data.properties);
53 | }
54 | prerun(widget, focus) {
55 | const { styles, text } = widget.data.properties;
56 | if (!styles.fill)
57 | styles.fill = `█`;
58 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
59 | if (styles.width)
60 | console.log(focus + chalk_1.default.hex(styles[`background-color`] ? styles[`background-color`] : `#ffffff`)(styles.fill.repeat(styles.width)));
61 | if (styles.height)
62 | for (let i = 0; i < styles.height; i++) {
63 | process.stdout.write(`\x1b[${styles.y + i};${styles.x}H`);
64 | if (styles.width)
65 | console.log(focus + chalk_1.default.hex(styles[`background-color`] ? styles[`background-color`] : `#ffffff`)(styles.fill.repeat(styles.width)));
66 | }
67 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
68 | console.log(focus + chalk_1.default.bgHex((styles === null || styles === void 0 ? void 0 : styles[`background-color`]) ? styles[`background-color`] : `#000000`).hex((styles === null || styles === void 0 ? void 0 : styles[`text-color`]) ? styles[`text-color`] : `#ffffff`)(text));
69 | }
70 | }
71 | exports.CLIButton = CLIButton;
72 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLICanvas.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 | export declare class CLICanvas {
3 | private lines;
4 | private circles;
5 | private rectangles;
6 | private line;
7 | private circle;
8 | private rectangle;
9 | data: app.Idata;
10 | constructor(props?: app.Iproperties);
11 | prerun(widget: app.Iwidget): void;
12 | }
13 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLICanvas.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | Object.defineProperty(exports, "__esModule", { value: true });
26 | exports.CLICanvas = void 0;
27 | const app = __importStar(require("../CLIApplication"));
28 | class CLICanvas {
29 | line(object) {
30 | if (!object.toX || !object.toY)
31 | return;
32 | let result = [];
33 | const deltaX = object.toX - object.x;
34 | const deltaY = object.toY - object.y;
35 | const steps = Math.max(Math.abs(deltaX), Math.abs(deltaY));
36 | for (let i = 0; i <= steps; i++) {
37 | let x, y;
38 | if (deltaX >= 0 && deltaY >= 0) {
39 | x = Math.round(object.x + (i / steps) * Math.abs(deltaX));
40 | y = Math.round(object.y + (i / steps) * Math.abs(deltaY));
41 | }
42 | else if (deltaX < 0 && deltaY >= 0) {
43 | x = Math.round(object.x - (i / steps) * Math.abs(deltaX));
44 | y = Math.round(object.y + (i / steps) * Math.abs(deltaY));
45 | }
46 | else if (deltaX >= 0 && deltaY < 0) {
47 | x = Math.round(object.x + (i / steps) * Math.abs(deltaX));
48 | y = Math.round(object.y - (i / steps) * Math.abs(deltaY));
49 | }
50 | else { // deltaX < 0 && deltaY < 0
51 | x = Math.round(object.x - (i / steps) * Math.abs(deltaX));
52 | y = Math.round(object.y - (i / steps) * Math.abs(deltaY));
53 | }
54 | process.stdout.write(`\x1b[${y};${x}H`);
55 | console.log(object.fill);
56 | result.push({ fill: object.fill, x: x, y: y });
57 | }
58 | return result;
59 | }
60 | circle(object) {
61 | if (!object.centerX || !object.centerY || !object.radius)
62 | return;
63 | let result = [];
64 | for (let y = object.centerY - object.radius; y <= object.centerY + object.radius; y++) {
65 | for (let x = object.centerX - object.radius; x <= object.centerX + object.radius; x++) {
66 | const distance = Math.sqrt((x - object.centerX) ** 2 + (y - object.centerY) ** 2);
67 | if (distance <= object.radius) {
68 | process.stdout.write(`\x1b[${y};${x}H`);
69 | console.log(object.fill);
70 | result.push({ fill: object.fill, x: x, y: y });
71 | }
72 | }
73 | }
74 | return result;
75 | }
76 | rectangle(object) {
77 | if (!object.height || !object.width)
78 | return;
79 | let result = [];
80 | for (let i = object.y; i < object.y + object.height; i++) {
81 | for (let j = object.x; j < object.x + object.width; j++) {
82 | process.stdout.write(`\x1b[${i};${j}H`);
83 | console.log(object.fill);
84 | result.push({ fill: object.fill, x: j, y: i });
85 | }
86 | }
87 | return result;
88 | }
89 | constructor(props) {
90 | this.lines = [];
91 | this.circles = [];
92 | this.rectangles = [];
93 | this.data = {
94 | "type": "canvas",
95 | "properties": {
96 | "canvasChilds": [],
97 | "accepts": ["paths", "global", "styles", "events", "defaultEvents", "canvasChilds"],
98 | "paths": [],
99 | "global": "",
100 | "styles": {
101 | "x": 1,
102 | "y": 1,
103 | "width": 20,
104 | "height": 10,
105 | "visible": true
106 | },
107 | "events": {},
108 | "defaultEvents": {}
109 | }
110 | };
111 | if (props)
112 | this.data.properties = app.setProps(props, this.data.properties);
113 | }
114 | prerun(widget) {
115 | var _a;
116 | (_a = widget.data.properties.canvasChilds) === null || _a === void 0 ? void 0 : _a.forEach((child) => {
117 | var _a, _b, _c;
118 | if (child.type === `line`) {
119 | if (this.lines.includes(child)) {
120 | const idx = this.lines.findIndex(e => e === child);
121 | (_a = this.lines[idx].private) === null || _a === void 0 ? void 0 : _a.forEach(_private => {
122 | if (!_private.x || !_private.y)
123 | return;
124 | process.stdout.write(`\x1b[${_private.y};${_private.x}H`);
125 | console.log(_private.fill);
126 | });
127 | }
128 | else {
129 | child.private = this.line(child);
130 | this.lines.push(child);
131 | }
132 | }
133 | else if (child.type === `rectangle`) {
134 | if (this.rectangles.includes(child)) {
135 | const idx = this.rectangles.findIndex(e => e === child);
136 | (_b = this.rectangles[idx].private) === null || _b === void 0 ? void 0 : _b.forEach(_private => {
137 | if (!_private.x || !_private.y)
138 | return;
139 | process.stdout.write(`\x1b[${_private.y};${_private.x}H`);
140 | console.log(_private.fill);
141 | });
142 | }
143 | else {
144 | child.private = this.rectangle(child);
145 | this.rectangles.push(child);
146 | }
147 | }
148 | else if (child.type === `circle`) {
149 | if (this.circles.includes(child)) {
150 | const idx = this.circles.findIndex(e => e === child);
151 | (_c = this.circles[idx].private) === null || _c === void 0 ? void 0 : _c.forEach(_private => {
152 | if (!_private.x || !_private.y)
153 | return;
154 | process.stdout.write(`\x1b[${_private.y};${_private.x}H`);
155 | console.log(_private.fill);
156 | });
157 | }
158 | else {
159 | child.private = this.circle(child);
160 | this.circles.push(child);
161 | }
162 | }
163 | });
164 | }
165 | }
166 | exports.CLICanvas = CLICanvas;
167 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLICheckbox.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 | export declare class CLICheckbox {
3 | data: app.Idata;
4 | constructor(props?: app.Iproperties);
5 | prerun(widgets: Array, widget: app.Iwidget, func: Function, focus: string): void;
6 | }
7 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLICheckbox.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.CLICheckbox = void 0;
30 | const chalk_1 = __importDefault(require("chalk"));
31 | const app = __importStar(require("../CLIApplication"));
32 | class CLICheckbox {
33 | constructor(props) {
34 | this.data = {
35 | "type": "checkbox",
36 | "properties": {
37 | "text": "lorem ipsum",
38 | "checked": false,
39 | "accepts": ["paths", "styles", "text", "events", "checked", "global"],
40 | "paths": [],
41 | "global": "",
42 | "styles": {
43 | "x": 1,
44 | "y": 1,
45 | "text-color": "#ffffff",
46 | "visible": true,
47 | "check": ["✅ ", "❌ "]
48 | },
49 | "events": {},
50 | "defaultEvents": {
51 | "onEnter": () => {
52 | this.data.properties.checked = !this.data.properties.checked;
53 | }
54 | }
55 | }
56 | };
57 | if (props)
58 | this.data.properties = app.setProps(props, this.data.properties);
59 | }
60 | prerun(widgets, widget, func, focus) {
61 | var _a, _b;
62 | const { styles, text } = widget.data.properties;
63 | let isOverLapping = false;
64 | widgets.forEach((_widget) => {
65 | var _a, _b;
66 | if (func(_widget, styles)) {
67 | isOverLapping = true;
68 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
69 | const backgroundColor = _widget.data.properties.styles["background-color"] || `#000000`;
70 | const textColor = styles["text-color"] || _widget.data.properties.styles["text-color"] || `#ffffff`;
71 | console.log(focus + (this.data.properties.checked ? (_a = styles.check) === null || _a === void 0 ? void 0 : _a[0] : (_b = styles.check) === null || _b === void 0 ? void 0 : _b[1]) + chalk_1.default.bgHex(backgroundColor)(chalk_1.default.hex(textColor)(text)));
72 | }
73 | });
74 | if (!isOverLapping) {
75 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
76 | const backgroundColor = `#000000`;
77 | const textColor = styles["text-color"] || `#ffffff`;
78 | console.log(focus + (this.data.properties.checked ? (_a = styles.check) === null || _a === void 0 ? void 0 : _a[0] : (_b = styles.check) === null || _b === void 0 ? void 0 : _b[1]) + chalk_1.default.bgHex(backgroundColor)(chalk_1.default.hex(textColor)(text)));
79 | }
80 | }
81 | }
82 | exports.CLICheckbox = CLICheckbox;
83 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLICustom.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 | export declare class CLICustom {
3 | data: app.Idata;
4 | constructor(props?: app.Iproperties);
5 | prerun(widget: app.Iwidget, focus: string, widgets: Array, func: Function, object: any): void;
6 | }
7 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLICustom.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | Object.defineProperty(exports, "__esModule", { value: true });
26 | exports.CLICustom = void 0;
27 | const app = __importStar(require("../CLIApplication"));
28 | class CLICustom {
29 | constructor(props) {
30 | this.data = {
31 | "type": "custom",
32 | "properties": {
33 | "accepts": ["accepts", "paths", "global", "styles", "events", "defaultEvents", "text", "placeholder", "checked"],
34 | "paths": [],
35 | "global": "",
36 | "styles": {
37 | "x": 1,
38 | "y": 1,
39 | "visible": true
40 | },
41 | "events": {},
42 | "defaultEvents": {}
43 | }
44 | };
45 | if (props)
46 | this.data.properties = app.setProps(props, this.data.properties);
47 | }
48 | prerun(widget, focus, widgets, func, object) { }
49 | }
50 | exports.CLICustom = CLICustom;
51 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLIImage.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 | export declare class CLIImage {
3 | private text;
4 | private isDoing;
5 | data: app.Idata;
6 | constructor(props?: app.Iproperties);
7 | prerun(widget: app.Iwidget): void;
8 | }
9 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLIImage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.CLIImage = void 0;
30 | const image_to_ascii_1 = __importDefault(require("image-to-ascii"));
31 | const app = __importStar(require("../CLIApplication"));
32 | class CLIImage {
33 | constructor(props) {
34 | this.text = ``;
35 | this.isDoing = false;
36 | this.data = {
37 | "type": "image",
38 | "properties": {
39 | "accepts": ["paths", "styles", "global"],
40 | "paths": [],
41 | "global": "",
42 | "styles": {
43 | "x": 1,
44 | "y": 1,
45 | "width": 50,
46 | "height": 50,
47 | "visible": true,
48 | "img": "",
49 | "img-pixels": " "
50 | },
51 | "events": {},
52 | "defaultEvents": {}
53 | }
54 | };
55 | if (props)
56 | this.data.properties = app.setProps(props, this.data.properties);
57 | }
58 | prerun(widget) {
59 | const { styles } = widget.data.properties;
60 | if (this.text !== ``) {
61 | this.text.split(`\n`).forEach((line, idx) => {
62 | process.stdout.write(`\x1b[${styles.y + idx};${styles.x}H`);
63 | console.log(line);
64 | });
65 | }
66 | else if (!this.isDoing) {
67 | this.isDoing = true;
68 | (0, image_to_ascii_1.default)(styles.img, {
69 | size: {
70 | width: styles.width,
71 | height: styles.height
72 | },
73 | bg: true,
74 | fg: false,
75 | pixels: styles["img-pixels"]
76 | }, (err, converted) => {
77 | if (err)
78 | throw new Error(err);
79 | this.text = converted;
80 | });
81 | }
82 | }
83 | }
84 | exports.CLIImage = CLIImage;
85 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLILabel.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 | export declare class CLILabel {
3 | data: app.Idata;
4 | constructor(props?: app.Iproperties);
5 | prerun(widgets: Array, widget: app.Iwidget, func: Function, focus: string): void;
6 | }
7 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLILabel.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.CLILabel = void 0;
30 | const chalk_1 = __importDefault(require("chalk"));
31 | const app = __importStar(require("../CLIApplication"));
32 | class CLILabel {
33 | constructor(props) {
34 | this.data = {
35 | "type": "label",
36 | "properties": {
37 | "text": "lorem ipsum",
38 | "accepts": ["paths", "styles", "text", "global"],
39 | "paths": [],
40 | "global": "",
41 | "styles": {
42 | "x": 1,
43 | "y": 1,
44 | "text-color": "#ffffff",
45 | "visible": true
46 | },
47 | "events": {},
48 | "defaultEvents": {}
49 | }
50 | };
51 | if (props)
52 | this.data.properties = app.setProps(props, this.data.properties);
53 | }
54 | prerun(widgets, widget, func, focus) {
55 | const { styles, text } = widget.data.properties;
56 | let isOverLapping = false;
57 | widgets.forEach((_widget) => {
58 | if (func(_widget, styles)) {
59 | isOverLapping = true;
60 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
61 | const backgroundColor = _widget.data.properties.styles["background-color"] || `#000000`;
62 | const textColor = styles["text-color"] || _widget.data.properties.styles["text-color"] || `#ffffff`;
63 | console.log(focus + chalk_1.default.bgHex(backgroundColor)(chalk_1.default.hex(textColor)(text)));
64 | }
65 | });
66 | if (!isOverLapping) {
67 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
68 | const backgroundColor = `#000000`;
69 | const textColor = styles["text-color"] || `#ffffff`;
70 | console.log(focus + chalk_1.default.bgHex(backgroundColor)(chalk_1.default.hex(textColor)(text)));
71 | }
72 | }
73 | }
74 | exports.CLILabel = CLILabel;
75 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLIPanel.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 | export declare class CLIPanel {
3 | data: app.Idata;
4 | constructor(props?: app.Iproperties);
5 | prerun(widget: app.Iwidget, focus: string): void;
6 | }
7 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLIPanel.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.CLIPanel = void 0;
30 | const chalk_1 = __importDefault(require("chalk"));
31 | const app = __importStar(require("../CLIApplication"));
32 | class CLIPanel {
33 | constructor(props) {
34 | this.data = {
35 | "type": "panel",
36 | "properties": {
37 | "accepts": ["paths", "styles", "global"],
38 | "paths": [],
39 | "global": "",
40 | "styles": {
41 | "x": 0,
42 | "y": 0,
43 | "width": process.stdout.columns,
44 | "height": process.stdout.rows,
45 | "fill": "█",
46 | "background-color": "#000000",
47 | "text-color": "#ffffff",
48 | "visible": true
49 | },
50 | "events": {},
51 | "defaultEvents": {}
52 | }
53 | };
54 | if (props)
55 | this.data.properties = app.setProps(props, this.data.properties);
56 | }
57 | prerun(widget, focus) {
58 | const { styles } = widget.data.properties;
59 | if (!styles.fill)
60 | styles.fill = `█`;
61 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
62 | if (styles.width)
63 | console.log(focus + chalk_1.default.hex(styles[`background-color`] ? styles[`background-color`] : `#ffffff`)(styles.fill.repeat(styles.width)));
64 | if (styles.height)
65 | for (let i = 0; i < styles.height; i++) {
66 | process.stdout.write(`\x1b[${styles.y + i};${styles.x}H`);
67 | if (styles.width)
68 | console.log(focus + chalk_1.default.hex(styles[`background-color`] ? styles[`background-color`] : `#ffffff`)(styles.fill.repeat(styles.width)));
69 | }
70 | }
71 | }
72 | exports.CLIPanel = CLIPanel;
73 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLIRadio.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 | export declare class CLIRadio {
3 | private widgets;
4 | data: app.Idata;
5 | constructor(props?: app.Iproperties);
6 | prerun(widgets: Array, widget: app.Iwidget, func: Function, focus: string): void;
7 | }
8 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLIRadio.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.CLIRadio = void 0;
30 | const chalk_1 = __importDefault(require("chalk"));
31 | const app = __importStar(require("../CLIApplication"));
32 | class CLIRadio {
33 | constructor(props) {
34 | this.widgets = [];
35 | this.data = {
36 | "type": "radio",
37 | "properties": {
38 | "text": "lorem ipsum",
39 | "checked": false,
40 | "accepts": ["paths", "styles", "text", "events", "checked", "global"],
41 | "paths": [],
42 | "global": "default",
43 | "styles": {
44 | "x": 1,
45 | "y": 1,
46 | "text-color": "#ffffff",
47 | "visible": true,
48 | "check": ["⚪ ", "⚫ "]
49 | },
50 | "events": {},
51 | "defaultEvents": {
52 | "onEnter": () => {
53 | this.widgets.map((e) => e.data.properties.checked = e.data.properties.global === this.data.properties.global ? false : e.data.properties.checked);
54 | this.data.properties.checked = !this.data.properties.checked;
55 | return this.widgets;
56 | }
57 | }
58 | }
59 | };
60 | if (props)
61 | this.data.properties = app.setProps(props, this.data.properties);
62 | }
63 | prerun(widgets, widget, func, focus) {
64 | var _a, _b;
65 | const { styles, text } = widget.data.properties;
66 | this.widgets = widgets;
67 | let isOverLapping = false;
68 | widgets.forEach((_widget) => {
69 | var _a, _b;
70 | if (func(_widget, styles)) {
71 | isOverLapping = true;
72 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
73 | const backgroundColor = _widget.data.properties.styles["background-color"] || `#000000`;
74 | const textColor = styles["text-color"] || _widget.data.properties.styles["text-color"] || `#ffffff`;
75 | console.log(focus + (this.data.properties.checked ? (_a = styles.check) === null || _a === void 0 ? void 0 : _a[0] : (_b = styles.check) === null || _b === void 0 ? void 0 : _b[1]) + chalk_1.default.bgHex(backgroundColor)(chalk_1.default.hex(textColor)(text)));
76 | }
77 | });
78 | if (!isOverLapping) {
79 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
80 | const backgroundColor = `#000000`;
81 | const textColor = styles["text-color"] || `#ffffff`;
82 | console.log(focus + (this.data.properties.checked ? (_a = styles.check) === null || _a === void 0 ? void 0 : _a[0] : (_b = styles.check) === null || _b === void 0 ? void 0 : _b[1]) + chalk_1.default.bgHex(backgroundColor)(chalk_1.default.hex(textColor)(text)));
83 | }
84 | }
85 | }
86 | exports.CLIRadio = CLIRadio;
87 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLITextbox.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 | export declare class CLITextbox {
3 | isTyping: boolean;
4 | data: app.Idata;
5 | constructor(props?: app.Iproperties);
6 | prerun(widget: app.Iwidget, focus: string, textloc: number): void;
7 | }
8 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLITextbox.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.CLITextbox = void 0;
30 | const chalk_1 = __importDefault(require("chalk"));
31 | const app = __importStar(require("../CLIApplication"));
32 | class CLITextbox {
33 | constructor(props) {
34 | this.isTyping = false;
35 | this.data = {
36 | "type": "textbox",
37 | "properties": {
38 | "text": "",
39 | "placeholder": "",
40 | "accepts": ["paths", "styles", "global", "text", "placeholder", "events"],
41 | "paths": [],
42 | "global": "",
43 | "styles": {
44 | "x": 1,
45 | "y": 1,
46 | "background-color": "#ffffff",
47 | "placeholder-color": "#777777",
48 | "text-color": "#000000",
49 | "visible": true
50 | },
51 | "events": {},
52 | "defaultEvents": {
53 | "onEnter": () => {
54 | this.isTyping = !this.isTyping;
55 | }
56 | }
57 | }
58 | };
59 | if (props)
60 | this.data.properties = app.setProps(props, this.data.properties);
61 | }
62 | prerun(widget, focus, textloc) {
63 | const { styles, text, placeholder } = widget.data.properties;
64 | const backgroundColor = styles["background-color"] || `#ffffff`;
65 | const placeholderColor = styles["placeholder-color"] || `#777777`;
66 | const textColor = styles["text-color"] || `#000000`;
67 | if (this.isTyping) {
68 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
69 | console.log(focus + (text === `` ? chalk_1.default.bgHex(backgroundColor)(chalk_1.default.hex(placeholderColor)(placeholder)) : chalk_1.default.bgHex(backgroundColor)(chalk_1.default.hex(textColor)(`${text === null || text === void 0 ? void 0 : text.substring(0, textloc)}|${text === null || text === void 0 ? void 0 : text.substring(textloc, text.length)}`))));
70 | }
71 | else {
72 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
73 | console.log(focus + (text === `` ? chalk_1.default.bgHex(backgroundColor)(chalk_1.default.hex(placeholderColor)(placeholder)) : chalk_1.default.bgHex(backgroundColor)(chalk_1.default.hex(textColor)(text))));
74 | }
75 | }
76 | }
77 | exports.CLITextbox = CLITextbox;
78 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLIWebview.d.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 | export declare class CLIWebview {
3 | private text;
4 | private isDoing;
5 | data: app.Idata;
6 | constructor(props?: app.Iproperties);
7 | prerun(widget: app.Iwidget): void;
8 | }
9 |
--------------------------------------------------------------------------------
/dist/src/lib/CLIWidgets/CLIWebview.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
15 | }) : function(o, v) {
16 | o["default"] = v;
17 | });
18 | var __importStar = (this && this.__importStar) || function (mod) {
19 | if (mod && mod.__esModule) return mod;
20 | var result = {};
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22 | __setModuleDefault(result, mod);
23 | return result;
24 | };
25 | var __importDefault = (this && this.__importDefault) || function (mod) {
26 | return (mod && mod.__esModule) ? mod : { "default": mod };
27 | };
28 | Object.defineProperty(exports, "__esModule", { value: true });
29 | exports.CLIWebview = void 0;
30 | const puppeteer_1 = __importDefault(require("puppeteer"));
31 | const image_to_ascii_1 = __importDefault(require("image-to-ascii"));
32 | const app = __importStar(require("../CLIApplication"));
33 | class CLIWebview {
34 | constructor(props) {
35 | this.text = ``;
36 | this.isDoing = false;
37 | this.data = {
38 | "type": "image",
39 | "properties": {
40 | "accepts": ["paths", "styles", "global"],
41 | "paths": [],
42 | "global": "",
43 | "styles": {
44 | "x": 1,
45 | "y": 1,
46 | "visible": true,
47 | "img": "",
48 | "img-pixels": " ",
49 | "page": "https://www.google.com"
50 | },
51 | "events": {},
52 | "defaultEvents": {}
53 | }
54 | };
55 | if (props)
56 | this.data.properties = app.setProps(props, this.data.properties);
57 | }
58 | prerun(widget) {
59 | const { styles, events } = widget.data.properties;
60 | if (this.text !== ``) {
61 | this.text.split(`\n`).forEach((line, idx) => {
62 | process.stdout.write(`\x1b[${styles.y + idx};${styles.x}H`);
63 | console.log(line);
64 | });
65 | }
66 | else if (!this.isDoing) {
67 | this.isDoing = true;
68 | const browser = puppeteer_1.default.launch();
69 | const page = browser.then(value => value.newPage());
70 | page.then(value => {
71 | var _a;
72 | if (typeof events.onConnect === `function`)
73 | (_a = events.onConnect) === null || _a === void 0 ? void 0 : _a.call(events, value, () => {
74 | if (this.text === ``) {
75 | value.waitForTimeout(2000).then(() => {
76 | value.screenshot({ path: `browse.png` }).then(() => {
77 | styles.img = `browse.png`;
78 | (0, image_to_ascii_1.default)(styles.img, {
79 | size: {
80 | width: styles.width,
81 | height: styles.height
82 | },
83 | bg: true,
84 | fg: false,
85 | pixels: styles["img-pixels"]
86 | }, (err, converted) => {
87 | if (err)
88 | throw new Error(err);
89 | this.text = converted;
90 | });
91 | });
92 | });
93 | }
94 | });
95 | // if (styles.page) value.goto(styles.page).then(() => {
96 | // value.type(`textarea[type="search"]`, `sans`).then(() => {
97 | // value.click(`body > div > div > form > div:nth-child(1) > div > div > center > input`).then(() => {
98 | // value.waitForTimeout(2000).then(() => {
99 | // value.screenshot({ path: `browse.png` }).then(() => {
100 | // styles.img = `browse.png`;
101 | // imageToAscii(styles.img, {
102 | // size: {
103 | // width: styles.width,
104 | // height: styles.height
105 | // },
106 | // bg: true,
107 | // fg: false,
108 | // pixels: styles["img-pixels"]
109 | // }, (err: string, converted: string) => {
110 | // if (err) throw new Error(err);
111 | // this.text = converted;
112 | // });
113 | // });
114 | // });
115 | // });
116 | // });
117 | // });
118 | });
119 | }
120 | }
121 | }
122 | exports.CLIWebview = CLIWebview;
123 |
--------------------------------------------------------------------------------
/imgs/dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICe1BotMaker/linterf/31a5ba11c5bbf7bfb9c43a8d2f89cec32a6269be/imgs/dog.jpg
--------------------------------------------------------------------------------
/imgs/tcg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICe1BotMaker/linterf/31a5ba11c5bbf7bfb9c43a8d2f89cec32a6269be/imgs/tcg.gif
--------------------------------------------------------------------------------
/imgs/video.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICe1BotMaker/linterf/31a5ba11c5bbf7bfb9c43a8d2f89cec32a6269be/imgs/video.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "linterf",
3 | "version": "3.0.25",
4 | "description": "Line interface for easier use of cli",
5 | "main": "dist/src/index.js",
6 | "author": "ice1",
7 | "license": "Apache-2.0",
8 | "dependencies": {
9 | "@typescript-eslint/parser": "^6.11.0",
10 | "chalk": "^4.1.2",
11 | "eslint": "^8.53.0",
12 | "image-to-ascii": "^3.2.0",
13 | "puppeteer": "^21.5.1",
14 | "typescript": "^5.2.2"
15 | },
16 | "devDependencies": {
17 | "@babel/cli": "^7.23.0",
18 | "@babel/core": "^7.23.2",
19 | "@babel/plugin-syntax-jsx": "^7.22.5",
20 | "@babel/plugin-transform-react-jsx": "^7.22.15",
21 | "@babel/preset-env": "^7.23.2",
22 | "@babel/preset-react": "^7.22.15",
23 | "@types/ascii-art": "^1.4.3"
24 | },
25 | "scripts": {
26 | "test": "npx babel tests --out-dir tests"
27 | },
28 | "publishConfig": {
29 | "@ice1:registry": "https://npm.pkg.github.com"
30 | },
31 | "repository": "https://github.com/ICe1BotMaker/linterf",
32 | "keywords": [
33 | "linterf",
34 | "cli",
35 | "3d",
36 | "argument",
37 | "argv",
38 | "args"
39 | ]
40 | }
41 |
--------------------------------------------------------------------------------
/scripts/TCG nobuffer.ts:
--------------------------------------------------------------------------------
1 | import chalk from "chalk";
2 | import * as app from '../src/lib/CLIApplication';
3 |
4 | export interface Iobject {
5 | id: string;
6 | center: Iposition;
7 | rotation: Iposition;
8 | vertices: Iposition[];
9 | }
10 |
11 | export interface Iposition {
12 | x: number;
13 | y: number;
14 | z: number;
15 | }
16 |
17 | export class TCG {
18 | public data: app.Idata = {
19 | "type": "tcg",
20 | "properties": {
21 | "accepts": ["accepts", "paths", "global", "styles", "events", "defaultEvents", "text", "placeholder", "checked"],
22 | "paths": [],
23 | "global": "",
24 | "styles": {
25 | "x": 1,
26 | "y": 1,
27 | "visible": true
28 | },
29 | "events": {},
30 | "defaultEvents": {}
31 | }
32 | };
33 |
34 | public camera: Iposition = { x: 1, y: -1, z: 0 };
35 | public objects: Iobject[] = [];
36 |
37 | public constructor(objects: Iobject[], props?: app.Iproperties) {
38 | this.objects = this.objects.concat(objects);
39 |
40 | if (props) this.data.properties = app.setProps(props, this.data.properties);
41 | }
42 |
43 | private rotateX(point: Iposition, angle: number, center: Iposition): Iposition {
44 | const y = (point.y - center.y) * Math.cos(angle) - (point.z - center.z) * Math.sin(angle) + center.y;
45 | const z = (point.y - center.y) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
46 | return { ...point, y, z };
47 | }
48 |
49 | private rotateY(point: Iposition, angle: number, center: Iposition): Iposition {
50 | const x = (point.x - center.x) * Math.cos(angle) + (point.z - center.z) * Math.sin(angle) + center.x;
51 | const z = -(point.x - center.x) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
52 | return { ...point, x, z };
53 | }
54 |
55 | private rotateZ(point: Iposition, angle: number, center: Iposition): Iposition {
56 | const x = (point.x - center.x) * Math.cos(angle) - (point.y - center.y) * Math.sin(angle) + center.x;
57 | const y = (point.x - center.x) * Math.sin(angle) + (point.y - center.y) * Math.cos(angle) + center.y;
58 | return { ...point, x, y };
59 | }
60 |
61 | private draw() {
62 | process.stdout.write('\x1Bc');
63 |
64 | this.objects.forEach(object => {
65 | let rotatedVertices = object.vertices.map(point =>
66 | this.rotateX(this.rotateY(this.rotateZ(point, object.rotation.z, object.center), object.rotation.y, object.center), object.rotation.x, object.center)
67 | );
68 |
69 | let translatedVertices = rotatedVertices.map(point => ({
70 | x: point.x - this.camera.x,
71 | y: point.y - this.camera.y,
72 | z: point.z - this.camera.z
73 | }));
74 |
75 | this.connectAndDraw([0, 1, 3, 2], translatedVertices);
76 | this.connectAndDraw([4, 5, 7, 6], translatedVertices);
77 | this.connectAndDraw([0, 1, 5, 4], translatedVertices);
78 | this.connectAndDraw([2, 3, 7, 6], translatedVertices);
79 | this.connectAndDraw([0, 2, 6, 4], translatedVertices);
80 | this.connectAndDraw([1, 3, 7, 5], translatedVertices);
81 | });
82 | }
83 |
84 | private connectAndDraw(faceVertices: any, vertices: any) {
85 | for (let i = 0; i < faceVertices.length; i++) {
86 | const start = faceVertices[i];
87 | const end = faceVertices[(i + 1) % faceVertices.length];
88 |
89 | const startPoint = vertices[start];
90 | const endPoint = vertices[end];
91 |
92 | const startScreenX = Math.round(startPoint.x * 10) + 40;
93 | const startScreenY = Math.round(startPoint.y * 10) + 5;
94 | const endScreenX = Math.round(endPoint.x * 10) + 40;
95 | const endScreenY = Math.round(endPoint.y * 10) + 5;
96 |
97 | this.drawLine(startScreenX, startScreenY, endScreenX, endScreenY);
98 | }
99 | }
100 |
101 | private drawLine(x0: number, y0: number, x1: number, y1: number) {
102 | const dx = Math.abs(x1 - x0);
103 | const dy = Math.abs(y1 - y0);
104 | const sx = x0 < x1 ? 1 : -1;
105 | const sy = y0 < y1 ? 1 : -1;
106 | let err = dx - dy;
107 |
108 | while (true) {
109 | process.stdout.cursorTo(x0 - 20, y0 - 10);
110 | process.stdout.write(chalk.white('█'));
111 |
112 | if (x0 === x1 && y0 === y1) break;
113 | const e2 = 2 * err;
114 | if (e2 > -dy) {
115 | err -= dy;
116 | x0 += sx;
117 | }
118 | if (e2 < dx) {
119 | err += dx;
120 | y0 += sy;
121 | }
122 | }
123 | }
124 |
125 | public prerun(widget: app.Iwidget) {
126 | const { events } = widget.data.properties;
127 | events.onFrame?.(this.objects, this.camera);
128 | this.draw();
129 | }
130 | }
--------------------------------------------------------------------------------
/scripts/TCG origin.ts:
--------------------------------------------------------------------------------
1 | import chalk from "chalk";
2 | import * as app from '../src/lib/CLIApplication';
3 |
4 | export interface Iobject {
5 | id: string;
6 | center: Iposition;
7 | rotation: Iposition;
8 | vertices: Iposition[];
9 |
10 | buffer: {
11 | buffer1: any[];
12 | buffer2: any[];
13 | buffer3: any[];
14 | currentBuffer: any[];
15 | };
16 | }
17 |
18 | export interface Iposition {
19 | x: number;
20 | y: number;
21 | z: number;
22 | }
23 |
24 | export class TCG {
25 | public data: app.Idata = {
26 | "type": "tcg",
27 | "properties": {
28 | "accepts": ["accepts", "paths", "global", "styles", "events", "defaultEvents", "text", "placeholder", "checked"],
29 | "paths": [],
30 | "global": "",
31 | "styles": {
32 | "x": 1,
33 | "y": 1,
34 | "visible": true
35 | },
36 | "events": {},
37 | "defaultEvents": {}
38 | }
39 | };
40 |
41 | public camera: Iposition = { x: 1, y: -1, z: 0 };
42 | public objects: Iobject[] = [];
43 |
44 | public constructor(objects: Iobject[], props?: app.Iproperties) {
45 | objects = objects.map(e => {
46 | e.buffer = { buffer1: [], buffer2: [], buffer3: [], currentBuffer: [] };
47 | return e;
48 | });
49 |
50 | this.objects = this.objects.concat(objects);
51 |
52 | if (props) this.data.properties = app.setProps(props, this.data.properties);
53 | }
54 |
55 | private rotateX(point: Iposition, angle: number, center: Iposition): Iposition {
56 | const y = (point.y - center.y) * Math.cos(angle) - (point.z - center.z) * Math.sin(angle) + center.y;
57 | const z = (point.y - center.y) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
58 | return { ...point, y, z };
59 | }
60 |
61 | private rotateY(point: Iposition, angle: number, center: Iposition): Iposition {
62 | const x = (point.x - center.x) * Math.cos(angle) + (point.z - center.z) * Math.sin(angle) + center.x;
63 | const z = -(point.x - center.x) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
64 | return { ...point, x, z };
65 | }
66 |
67 | private rotateZ(point: Iposition, angle: number, center: Iposition): Iposition {
68 | const x = (point.x - center.x) * Math.cos(angle) - (point.y - center.y) * Math.sin(angle) + center.x;
69 | const y = (point.x - center.x) * Math.sin(angle) + (point.y - center.y) * Math.cos(angle) + center.y;
70 | return { ...point, x, y };
71 | }
72 |
73 | private drawToBuffer(buffer: any[], x: number, y: number, char: any) {
74 | if (!buffer[y]) buffer[y] = [];
75 | buffer[y][x] = char;
76 | }
77 |
78 | private swapBuffers(object: Iobject) {
79 | if (object.buffer.currentBuffer === object.buffer.buffer1) {
80 | object.buffer.currentBuffer = object.buffer.buffer2;
81 | } else if (object.buffer.currentBuffer === object.buffer.buffer2) {
82 | object.buffer.currentBuffer = object.buffer.buffer3;
83 | } else {
84 | object.buffer.currentBuffer = object.buffer.buffer1;
85 | }
86 | }
87 |
88 | private drawBufferToConsole(buffer: any[]) {
89 | for (let row of buffer) if (row) process.stdout.write(row.join('') + '\n');
90 | }
91 |
92 | private clearBuffer(buffer: any[]) {
93 | for (let i = 0; i < buffer.length; i++) buffer[i] = [];
94 | }
95 |
96 | private draw() {
97 | process.stdout.write('\x1Bc');
98 |
99 | this.objects.forEach(object => {
100 | if (!object.buffer) object.buffer = { buffer1: [], buffer2: [], buffer3: [], currentBuffer: [] };
101 |
102 | this.clearBuffer(object.buffer.currentBuffer);
103 |
104 | let rotatedVertices = object.vertices.map(point =>
105 | this.rotateX(this.rotateY(this.rotateZ(point, object.rotation.z, object.center), object.rotation.y, object.center), object.rotation.x, object.center)
106 | );
107 |
108 | let translatedVertices = rotatedVertices.map(point => ({
109 | x: point.x - this.camera.x,
110 | y: point.y - this.camera.y,
111 | z: point.z - this.camera.z
112 | }));
113 |
114 | this.connectAndDraw([0, 1, 3, 2], translatedVertices);
115 | this.connectAndDraw([4, 5, 7, 6], translatedVertices);
116 | this.connectAndDraw([0, 1, 5, 4], translatedVertices);
117 | this.connectAndDraw([2, 3, 7, 6], translatedVertices);
118 | this.connectAndDraw([0, 2, 6, 4], translatedVertices);
119 | this.connectAndDraw([1, 3, 7, 5], translatedVertices);
120 |
121 | this.swapBuffers(object);
122 | this.drawBufferToConsole(object.buffer.currentBuffer);
123 | });
124 | }
125 |
126 | private connectAndDraw(faceVertices: any, vertices: any) {
127 | for (let i = 0; i < faceVertices.length; i++) {
128 | const start = faceVertices[i];
129 | const end = faceVertices[(i + 1) % faceVertices.length];
130 |
131 | const startPoint = vertices[start];
132 | const endPoint = vertices[end];
133 |
134 | const startScreenX = Math.round(startPoint.x * 10) + 40;
135 | const startScreenY = Math.round(startPoint.y * 10) + 5;
136 | const endScreenX = Math.round(endPoint.x * 10) + 40;
137 | const endScreenY = Math.round(endPoint.y * 10) + 5;
138 |
139 | this.drawLine(startScreenX, startScreenY, endScreenX, endScreenY);
140 | }
141 | }
142 |
143 | private drawLine(x0: number, y0: number, x1: number, y1: number) {
144 | const dx = Math.abs(x1 - x0);
145 | const dy = Math.abs(y1 - y0);
146 | const sx = x0 < x1 ? 1 : -1;
147 | const sy = y0 < y1 ? 1 : -1;
148 | let err = dx - dy;
149 |
150 | while (true) {
151 | process.stdout.cursorTo(x0 - 20, y0 - 10);
152 | process.stdout.write(chalk.white('█'));
153 |
154 | if (x0 === x1 && y0 === y1) break;
155 | const e2 = 2 * err;
156 | if (e2 > -dy) {
157 | err -= dy;
158 | x0 += sx;
159 | }
160 | if (e2 < dx) {
161 | err += dx;
162 | y0 += sy;
163 | }
164 | }
165 | }
166 |
167 | public prerun(widget: app.Iwidget) {
168 | // console.log("Objects:", this.objects);
169 |
170 | const { events } = widget.data.properties;
171 | events.onFrame?.(this.objects, this.camera);
172 | this.draw();
173 | }
174 | }
--------------------------------------------------------------------------------
/scripts/TCG.ts:
--------------------------------------------------------------------------------
1 | import chalk from "chalk";
2 | import * as app from '../src/lib/CLIApplication';
3 |
4 | export interface Iobject {
5 | id: string;
6 | center: Iposition;
7 | rotation: Iposition;
8 | vertices: Iposition[];
9 | }
10 |
11 | export interface Iposition {
12 | x: number;
13 | y: number;
14 | z: number;
15 | }
16 |
17 | export class TCG {
18 | public data: app.Idata = {
19 | "type": "tcg",
20 | "properties": {
21 | "accepts": ["accepts", "paths", "global", "styles", "events", "defaultEvents", "text", "placeholder", "checked"],
22 | "paths": [],
23 | "global": "",
24 | "styles": {
25 | "x": 1,
26 | "y": 1,
27 | "visible": true
28 | },
29 | "events": {},
30 | "defaultEvents": {}
31 | }
32 | };
33 |
34 | public camera: Iposition = { x: 1, y: -1, z: 0 };
35 | public objects: Iobject[] = [];
36 |
37 | public constructor(objects: Iobject[], props?: app.Iproperties) {
38 | this.objects = this.objects.concat(objects);
39 |
40 | if (props) this.data.properties = app.setProps(props, this.data.properties);
41 | }
42 |
43 | private rotateX(point: Iposition, angle: number, center: Iposition): Iposition {
44 | const y = (point.y - center.y) * Math.cos(angle) - (point.z - center.z) * Math.sin(angle) + center.y;
45 | const z = (point.y - center.y) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
46 | return { ...point, y, z };
47 | }
48 |
49 | private rotateY(point: Iposition, angle: number, center: Iposition): Iposition {
50 | const x = (point.x - center.x) * Math.cos(angle) + (point.z - center.z) * Math.sin(angle) + center.x;
51 | const z = -(point.x - center.x) * Math.sin(angle) + (point.z - center.z) * Math.cos(angle) + center.z;
52 | return { ...point, x, z };
53 | }
54 |
55 | private rotateZ(point: Iposition, angle: number, center: Iposition): Iposition {
56 | const x = (point.x - center.x) * Math.cos(angle) - (point.y - center.y) * Math.sin(angle) + center.x;
57 | const y = (point.x - center.x) * Math.sin(angle) + (point.y - center.y) * Math.cos(angle) + center.y;
58 | return { ...point, x, y };
59 | }
60 |
61 | private draw() {
62 | process.stdout.write('\x1Bc');
63 |
64 | this.objects.forEach(object => {
65 | let rotatedVertices = object.vertices.map(point =>
66 | this.rotateX(this.rotateY(this.rotateZ(point, object.rotation.z, object.center), object.rotation.y, object.center), object.rotation.x, object.center)
67 | );
68 |
69 | let translatedVertices = rotatedVertices.map(point => ({
70 | x: point.x - this.camera.x,
71 | y: point.y - this.camera.y,
72 | z: point.z - this.camera.z
73 | }));
74 |
75 | this.connectAndDraw([0, 1, 3, 2], translatedVertices);
76 | this.connectAndDraw([4, 5, 7, 6], translatedVertices);
77 | this.connectAndDraw([0, 1, 5, 4], translatedVertices);
78 | this.connectAndDraw([2, 3, 7, 6], translatedVertices);
79 | this.connectAndDraw([0, 2, 6, 4], translatedVertices);
80 | this.connectAndDraw([1, 3, 7, 5], translatedVertices);
81 | });
82 | }
83 |
84 | private connectAndDraw(faceVertices: any, vertices: any) {
85 | for (let i = 0; i < faceVertices.length; i++) {
86 | const start = faceVertices[i];
87 | const end = faceVertices[(i + 1) % faceVertices.length];
88 |
89 | const startPoint = vertices[start];
90 | const endPoint = vertices[end];
91 |
92 | const startScreenX = Math.round(startPoint.x * 10) + 40;
93 | const startScreenY = Math.round(startPoint.y * 10) + 5;
94 | const endScreenX = Math.round(endPoint.x * 10) + 40;
95 | const endScreenY = Math.round(endPoint.y * 10) + 5;
96 |
97 | this.drawLine(startScreenX, startScreenY, endScreenX, endScreenY);
98 | }
99 | }
100 |
101 | private drawLine(x0: number, y0: number, x1: number, y1: number) {
102 | const dx = Math.abs(x1 - x0);
103 | const dy = Math.abs(y1 - y0);
104 | const sx = x0 < x1 ? 1 : -1;
105 | const sy = y0 < y1 ? 1 : -1;
106 | let err = dx - dy;
107 |
108 | while (true) {
109 | process.stdout.cursorTo(x0 - 20, y0 - 10);
110 | process.stdout.write(chalk.white('█'));
111 |
112 | if (x0 === x1 && y0 === y1) break;
113 | const e2 = 2 * err;
114 | if (e2 > -dy) {
115 | err -= dy;
116 | x0 += sx;
117 | }
118 | if (e2 < dx) {
119 | err += dx;
120 | y0 += sy;
121 | }
122 | }
123 | }
124 |
125 | public prerun(widget: app.Iwidget) {
126 | const { events } = widget.data.properties;
127 | events.onFrame?.(this.objects, this.camera);
128 | this.draw();
129 | }
130 | }
--------------------------------------------------------------------------------
/scripts/global.ts:
--------------------------------------------------------------------------------
1 | export { TCG } from './TCG';
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { CLIApplication } from "./lib/CLIApplication";
2 |
3 | export { CLIPanel } from "./lib/CLIWidgets/CLIPanel";
4 | export { CLILabel } from "./lib/CLIWidgets/CLILabel";
5 | export { CLIButton } from "./lib/CLIWidgets/CLIButton";
6 | export { CLICheckbox } from "./lib/CLIWidgets/CLICheckbox";
7 | export { CLIRadio } from "./lib/CLIWidgets/CLIRadio";
8 | export { CLIImage } from "./lib/CLIWidgets/CLIImage";
9 | export { CLITextbox } from './lib/CLIWidgets/CLITextbox'
10 | export { CLIWebview } from "./lib/CLIWidgets/CLIWebview";
11 | export { CLICanvas } from "./lib/CLIWidgets/CLICanvas";
12 |
13 | export { CLICustom } from "./lib/CLIWidgets/CLICustom";
--------------------------------------------------------------------------------
/src/lib/CLIApplication.ts:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk';
2 |
3 | export interface Iwidget {
4 | data: Idata;
5 | prerun: Function;
6 | isTyping?: boolean;
7 | }
8 |
9 | export interface Idata {
10 | type: string;
11 | properties: Iproperties;
12 | }
13 |
14 | export interface Iproperties {
15 | accepts: Array;
16 | paths: Array;
17 | global: string;
18 | styles: Istyles;
19 | events: Ievents;
20 | defaultEvents: Ievents;
21 |
22 | canvasChilds?: Array;
23 |
24 | text?: string;
25 | placeholder?: string;
26 |
27 | checked?: boolean;
28 |
29 | [key: string]: any;
30 | }
31 |
32 | export interface IcanvasChild {
33 | type: string;
34 |
35 | x: number;
36 | y: number;
37 | toX?: number;
38 | toY?: number;
39 | centerX?: number;
40 | centerY?: number,
41 |
42 | fill: string;
43 |
44 | radius?: number;
45 |
46 | width?: number;
47 | height?: number;
48 |
49 | private?: Iresult[];
50 | }
51 |
52 | export interface Iresult {
53 | x: number;
54 | y: number;
55 |
56 | fill: string;
57 | }
58 |
59 | export interface Istyles {
60 | x: number;
61 | y: number;
62 |
63 | width?: number;
64 | height?: number;
65 |
66 | fill?: string;
67 | "background-color"?: string;
68 |
69 | "text-color"?: string;
70 | "placeholder-color"?: string;
71 |
72 | visible: boolean;
73 |
74 | check?: Array;
75 |
76 | img?: string;
77 | page?: string;
78 | "img-pixels"?: (string | Array);
79 | }
80 |
81 | export interface Ievents {
82 | onEnter?: Function;
83 | onPut?: Function;
84 | onLeave?: Function;
85 | onChange?: Function;
86 | onConnect?: (object);
87 |
88 | onFrame?: Function;
89 | }
90 |
91 | export class CLIApplication {
92 | private debug: boolean = false;
93 | private widgets: Array = [];
94 | private Vwidgets: Array = [];
95 | private curlocs = {
96 | tab: 0,
97 | textloc: 0
98 | };
99 |
100 | public constructor(option?: any) {
101 | this.widgets = [];
102 | this.curlocs = {
103 | tab: 0,
104 | textloc: 0
105 | };
106 |
107 | if (option?.debug) this.debug = true;
108 | }
109 |
110 | public append(...widgets: Array) {
111 | let exists: Array = [];
112 |
113 | widgets.forEach((widget: Iwidget) => {
114 | widget.data.properties.paths.forEach((path: string) => {
115 | if (exists.includes(path)) throw new Error(`[unique.path] ${path} is already exists`);
116 | exists.push(path);
117 |
118 | if (this.find(path)) {
119 | throw new Error(`[unique.path] ${path} is already exists`);
120 | }
121 | });
122 | });
123 |
124 | this.widgets = this.widgets.concat(widgets);
125 | }
126 |
127 | private event() {
128 | process.stdin.setRawMode(true);
129 | process.stdin.setEncoding(`utf-8`);
130 |
131 | process.stdin.on(`data`, (key: string) => {
132 | if (key === `\u0003`) {
133 | process.stdout.write(`\x1b[${process.stdout.rows - 1};${process.stdout.columns}H`);
134 | process.exit();
135 | }
136 |
137 | const selected = this.Vwidgets[this.curlocs.tab];
138 |
139 | if (selected.isTyping && selected.data.type === `textbox`) {
140 | if (selected.data.properties.text && (this.curlocs.textloc < selected.data.properties.text.length) && key === `\u001b[C`) this.curlocs.textloc += 1;
141 | if (this.curlocs.textloc !> 0 && key === `\u001b[D`) this.curlocs.textloc -= 1;
142 |
143 | if (![`\u001b[D`, `\u001b[C`, `\u0008`, `\r`, `\n`].includes(key)) {
144 | selected.data.properties.text = `${selected.data.properties.text?.substring(0, this.curlocs.textloc)}${key}${selected.data.properties.text?.substring(this.curlocs.textloc, selected.data.properties.text.length)}`;
145 | this.curlocs.textloc += 1;
146 | }
147 |
148 | if (key === `\r` || key === `\n`) {
149 | selected.data.properties.defaultEvents?.onEnter?.();
150 | selected.data.properties.events?.onEnter?.();
151 |
152 | selected.data.properties.defaultEvents.onChange?.();
153 | selected.data.properties.events.onChange?.();
154 | }
155 |
156 | if (key === `\u0008` && this.curlocs.textloc > 0) {
157 | selected.data.properties.text = `${selected.data.properties.text?.substring(0, this.curlocs.textloc - 1)}${selected.data.properties.text?.substring(this.curlocs.textloc, selected.data.properties.text.length)}`;
158 | this.curlocs.textloc -= 1;
159 | }
160 | } else {
161 | if (key === `\u001b[C`) this.curlocs.tab += 1;
162 | if (key === `\u001b[D`) this.curlocs.tab -= 1;
163 |
164 | if (key === `\u001b[C` || key === `\u001b[D`) {
165 | this.curlocs.textloc = 0;
166 | selected.data.properties.events?.onLeave?.();
167 | selected.data.properties.defaultEvents?.onLeave?.();
168 | }
169 |
170 | if (key === `\r` || key === `\n`) {
171 | this.curlocs.textloc = selected.data.properties.text ? selected.data.properties.text.length : 0;
172 |
173 | let result = selected.data.properties.defaultEvents?.onEnter?.();
174 | selected.data.properties.events?.onEnter?.();
175 |
176 | if (selected.data.type === `radio`) this.widgets = result;
177 | }
178 | }
179 |
180 | if (this.curlocs.tab >= this.Vwidgets.length) this.curlocs.tab = this.Vwidgets.length - 1;
181 | if (this.curlocs.tab < 0) this.curlocs.tab = 0;
182 |
183 | if (selected.data.properties.styles.height !== process.stdout.rows) {
184 | selected.data.properties.events?.onPut?.();
185 | selected.data.properties.defaultEvents?.onPut?.();
186 | }
187 | });
188 |
189 | process.stdout.write(`\x1B[?25l`);
190 | }
191 |
192 | public isOverLapping(widget: Iwidget, props: Istyles) {
193 | const { styles } = widget.data.properties;
194 |
195 | return (
196 | styles?.width &&
197 | styles?.height &&
198 | styles?.["background-color"] &&
199 | (props.x >= styles.x && props.x <= styles.x + styles.width) &&
200 | (props.y >= styles.y && props.y <= styles.y + styles.height)
201 | );
202 | }
203 |
204 | public hexbn(hex: string, brightness: number) {
205 | hex = hex.replace(/^#/, ``);
206 | if (!/^(?:[0-9a-fA-F]{3}){1,2}$/.test(hex)) return ``;
207 | let bigint = parseInt(hex, 16);
208 | let rgb = [(bigint >> 16) & 255, (bigint >> 8) & 255, bigint & 255];
209 | rgb = rgb.map(e => e -= brightness);
210 | rgb = rgb.map(e => Math.max(0, Math.min(255, e)));
211 | let res = rgb.map(e => e.toString(16).padStart(2, `0`));
212 | const hexColor = `#${res.join(``)}`;
213 | return hexColor;
214 | }
215 |
216 | public show(frame: number) {
217 | this.event();
218 |
219 | setInterval(() => {
220 | console.clear();
221 |
222 | if (this.curlocs.tab >= this.Vwidgets.length) this.curlocs.tab = this.Vwidgets.length - 1;
223 | if (this.curlocs.tab < 0) this.curlocs.tab = 0;
224 |
225 | this.Vwidgets = this.widgets.filter(e => e.data.properties.styles.visible);
226 |
227 | this.Vwidgets.forEach((widget: Iwidget, idx: number) => {
228 | const { type } = widget.data;
229 | const { styles } = widget.data.properties;
230 |
231 | let focus: string = ``;
232 | if (styles.height !== process.stdout.rows && this.curlocs.tab === idx) focus = chalk.bgHex(this.hexbn(styles[`background-color`] || styles[`text-color`] || `#ffffff`, 25))(` `);
233 |
234 | if (styles.visible && type === `panel`) widget.prerun(widget, focus);
235 | if (styles.visible && type === `label`) widget.prerun(this.widgets, widget, this.isOverLapping, focus);
236 | if (styles.visible && type === `button`) widget.prerun(widget, focus);
237 | if (styles.visible && type === `checkbox`) widget.prerun(this.widgets, widget, this.isOverLapping, focus);
238 | if (styles.visible && type === `radio`) widget.prerun(this.widgets, widget, this.isOverLapping, focus);
239 | if (styles.visible && type === `image`) widget.prerun(widget);
240 | if (styles.visible && type === `textbox`) widget.prerun(widget, focus, this.curlocs.textloc);
241 | if (styles.visible && type === `canvas`) widget.prerun(widget);
242 |
243 | if (styles.visible && type === `custom`) widget.prerun(widget, focus, this.widgets, this.isOverLapping, this.curlocs);
244 |
245 | if (styles.visible && type === `tcg`) widget.prerun(widget);
246 | });
247 |
248 | if (this.debug) {
249 | process.stdout.write(`\x1b[1;1H`);
250 | console.log(this.curlocs.tab);
251 | }
252 | }, 1000 / frame);
253 | }
254 |
255 | public find(path: string) {
256 | return this.widgets.find(value => value.data.properties.paths.includes(path));
257 | }
258 |
259 | public modify(path: string, props: Iproperties) {
260 | const widgetIdx = this.widgets.findIndex(value => value.data.properties.paths.includes(path));
261 | this.widgets[widgetIdx].data.properties = setProps(props, this.widgets[widgetIdx].data.properties);
262 | }
263 | }
264 |
265 | export function setProps(get: Iproperties, origin: Iproperties): Iproperties {
266 | if (get) Object.keys(get).forEach((prop: string) => {
267 | if (origin?.accepts && !origin.accepts.includes(prop) && origin.accepts.length !== 0) return;
268 |
269 | if (!Array.isArray(origin[prop]) && typeof origin[prop] === `object`) {
270 | origin[prop] = setProps(get[prop], origin[prop]);
271 | } else {
272 | const value = get[prop];
273 | origin[prop] = value;
274 | }
275 | });
276 |
277 | return origin;
278 | }
279 |
--------------------------------------------------------------------------------
/src/lib/CLIWidgets/CLIButton.ts:
--------------------------------------------------------------------------------
1 | import chalk from "chalk";
2 | import * as app from "../CLIApplication";
3 |
4 | export class CLIButton {
5 | public data: app.Idata = {
6 | "type": "button",
7 | "properties": {
8 | "text": "lorem ipsum",
9 | "accepts": ["paths", "styles", "events", "text", "global"],
10 | "paths": [],
11 | "global": "",
12 | "styles": {
13 | "x": 1,
14 | "y": 1,
15 | "text-color": "#ffffff",
16 | "visible": true
17 | },
18 | "events": {},
19 | "defaultEvents": {}
20 | }
21 | };
22 |
23 | public constructor(props?: app.Iproperties) {
24 | if (props) this.data.properties = app.setProps(props, this.data.properties);
25 | }
26 |
27 | public prerun(widget: app.Iwidget, focus: string) {
28 | const { styles, text } = widget.data.properties;
29 |
30 | if (!styles.fill) styles.fill = `█`;
31 |
32 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
33 | if (styles.width) console.log(focus + chalk.hex(styles[`background-color`] ? styles[`background-color`] : `#ffffff`)(styles.fill.repeat(styles.width)));
34 |
35 | if (styles.height) for (let i = 0; i < styles.height; i++) {
36 | process.stdout.write(`\x1b[${styles.y + i};${styles.x}H`);
37 | if (styles.width) console.log(focus + chalk.hex(styles[`background-color`] ? styles[`background-color`] : `#ffffff`)(styles.fill.repeat(styles.width)));
38 | }
39 |
40 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
41 | console.log(focus + chalk.bgHex(styles?.[`background-color`] ? styles[`background-color`] : `#000000`).hex(styles?.[`text-color`] ? styles[`text-color`] : `#ffffff`)(text));
42 | }
43 | }
--------------------------------------------------------------------------------
/src/lib/CLIWidgets/CLICanvas.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 |
3 | export class CLICanvas {
4 | private lines: app.IcanvasChild[] = [];
5 | private circles: app.IcanvasChild[] = [];
6 | private rectangles: app.IcanvasChild[] = [];
7 |
8 | private line(object: app.IcanvasChild): (app.Iresult[] | undefined) {
9 | if (!object.toX || !object.toY) return;
10 |
11 | let result: app.Iresult[] = [];
12 |
13 | const deltaX = object.toX - object.x;
14 | const deltaY = object.toY - object.y;
15 | const steps = Math.max(Math.abs(deltaX), Math.abs(deltaY));
16 |
17 | for (let i = 0; i <= steps; i++) {
18 | let x: number, y: number;
19 |
20 | if (deltaX >= 0 && deltaY >= 0) {
21 | x = Math.round(object.x + (i / steps) * Math.abs(deltaX));
22 | y = Math.round(object.y + (i / steps) * Math.abs(deltaY));
23 | } else if (deltaX < 0 && deltaY >= 0) {
24 | x = Math.round(object.x - (i / steps) * Math.abs(deltaX));
25 | y = Math.round(object.y + (i / steps) * Math.abs(deltaY));
26 | } else if (deltaX >= 0 && deltaY < 0) {
27 | x = Math.round(object.x + (i / steps) * Math.abs(deltaX));
28 | y = Math.round(object.y - (i / steps) * Math.abs(deltaY));
29 | } else { // deltaX < 0 && deltaY < 0
30 | x = Math.round(object.x - (i / steps) * Math.abs(deltaX));
31 | y = Math.round(object.y - (i / steps) * Math.abs(deltaY));
32 | }
33 |
34 | process.stdout.write(`\x1b[${y};${x}H`);
35 | console.log(object.fill);
36 |
37 | result.push({ fill: object.fill, x: x, y: y });
38 | }
39 |
40 | return result;
41 | }
42 |
43 | private circle(object: app.IcanvasChild): (app.Iresult[] | undefined) {
44 | if (!object.centerX || !object.centerY || !object.radius) return;
45 |
46 | let result: app.Iresult[] = [];
47 |
48 | for (let y = object.centerY - object.radius; y <= object.centerY + object.radius; y++) {
49 | for (let x = object.centerX - object.radius; x <= object.centerX + object.radius; x++) {
50 | const distance = Math.sqrt((x - object.centerX) ** 2 + (y - object.centerY) ** 2);
51 |
52 | if (distance <= object.radius) {
53 | process.stdout.write(`\x1b[${y};${x}H`);
54 | console.log(object.fill);
55 |
56 | result.push({ fill: object.fill, x: x, y: y });
57 | }
58 | }
59 | }
60 |
61 | return result;
62 | }
63 |
64 | private rectangle(object: app.IcanvasChild): (app.Iresult[] | undefined) {
65 | if (!object.height || !object.width) return;
66 |
67 | let result: app.Iresult[] = [];
68 |
69 | for (let i = object.y; i < object.y + object.height; i++) {
70 | for (let j = object.x; j < object.x + object.width; j++) {
71 | process.stdout.write(`\x1b[${i};${j}H`);
72 | console.log(object.fill);
73 |
74 | result.push({ fill: object.fill, x: j, y: i });
75 | }
76 | }
77 |
78 | return result;
79 | }
80 |
81 | public data: app.Idata = {
82 | "type": "canvas",
83 | "properties": {
84 | "canvasChilds": [],
85 | "accepts": ["paths", "global", "styles", "events", "defaultEvents", "canvasChilds"],
86 | "paths": [],
87 | "global": "",
88 | "styles": {
89 | "x": 1,
90 | "y": 1,
91 | "width": 20,
92 | "height": 10,
93 | "visible": true
94 | },
95 | "events": {},
96 | "defaultEvents": {}
97 | }
98 | };
99 |
100 | public constructor(props?: app.Iproperties) {
101 | if (props) this.data.properties = app.setProps(props, this.data.properties);
102 | }
103 |
104 | public prerun(widget: app.Iwidget) {
105 | widget.data.properties.canvasChilds?.forEach((child: app.IcanvasChild) => {
106 | if (child.type === `line`) {
107 | if (this.lines.includes(child)) {
108 | const idx = this.lines.findIndex(e => e === child);
109 |
110 | this.lines[idx].private?.forEach(_private => {
111 | if (!_private.x || !_private.y) return;
112 | process.stdout.write(`\x1b[${_private.y};${_private.x}H`);
113 | console.log(_private.fill);
114 | });
115 | } else {
116 | child.private = this.line(child);
117 | this.lines.push(child);
118 | }
119 | } else if (child.type === `rectangle`) {
120 | if (this.rectangles.includes(child)) {
121 | const idx = this.rectangles.findIndex(e => e === child);
122 |
123 | this.rectangles[idx].private?.forEach(_private => {
124 | if (!_private.x || !_private.y) return;
125 | process.stdout.write(`\x1b[${_private.y};${_private.x}H`);
126 | console.log(_private.fill);
127 | });
128 | } else {
129 | child.private = this.rectangle(child);
130 | this.rectangles.push(child);
131 | }
132 | } else if (child.type === `circle`) {
133 | if (this.circles.includes(child)) {
134 | const idx = this.circles.findIndex(e => e === child);
135 |
136 | this.circles[idx].private?.forEach(_private => {
137 | if (!_private.x || !_private.y) return;
138 | process.stdout.write(`\x1b[${_private.y};${_private.x}H`);
139 | console.log(_private.fill);
140 | });
141 | } else {
142 | child.private = this.circle(child);
143 | this.circles.push(child);
144 | }
145 | }
146 | });
147 | }
148 | }
--------------------------------------------------------------------------------
/src/lib/CLIWidgets/CLICheckbox.ts:
--------------------------------------------------------------------------------
1 | import chalk from "chalk";
2 | import * as app from "../CLIApplication";
3 |
4 | export class CLICheckbox {
5 | public data: app.Idata = {
6 | "type": "checkbox",
7 | "properties": {
8 | "text": "lorem ipsum",
9 | "checked": false,
10 | "accepts": ["paths", "styles", "text", "events", "checked", "global"],
11 | "paths": [],
12 | "global": "",
13 | "styles": {
14 | "x": 1,
15 | "y": 1,
16 | "text-color": "#ffffff",
17 | "visible": true,
18 | "check": ["✅ ", "❌ "]
19 | },
20 | "events": {},
21 | "defaultEvents": {
22 | "onEnter": () => {
23 | this.data.properties.checked = !this.data.properties.checked;
24 | }
25 | }
26 | }
27 | };
28 |
29 | public constructor(props?: app.Iproperties) {
30 | if (props) this.data.properties = app.setProps(props, this.data.properties);
31 | }
32 |
33 | public prerun(widgets: Array, widget: app.Iwidget, func: Function, focus: string) {
34 | const { styles, text } = widget.data.properties;
35 |
36 | let isOverLapping: boolean = false;
37 | widgets.forEach((_widget: app.Iwidget) => {
38 | if (func(_widget, styles)) {
39 | isOverLapping = true;
40 |
41 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
42 |
43 | const backgroundColor = _widget.data.properties.styles["background-color"] || `#000000`;
44 | const textColor = styles["text-color"] || _widget.data.properties.styles["text-color"] || `#ffffff`;
45 |
46 | console.log(focus + (this.data.properties.checked ? styles.check?.[0] : styles.check?.[1]) + chalk.bgHex(backgroundColor)(chalk.hex(textColor)(text)));
47 | }
48 | });
49 |
50 | if (!isOverLapping) {
51 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
52 |
53 | const backgroundColor = `#000000`;
54 | const textColor = styles["text-color"] || `#ffffff`;
55 |
56 | console.log(focus + (this.data.properties.checked ? styles.check?.[0] : styles.check?.[1]) + chalk.bgHex(backgroundColor)(chalk.hex(textColor)(text)));
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/src/lib/CLIWidgets/CLICustom.ts:
--------------------------------------------------------------------------------
1 | import * as app from "../CLIApplication";
2 |
3 | export class CLICustom {
4 | public data: app.Idata = {
5 | "type": "custom",
6 | "properties": {
7 | "accepts": ["accepts", "paths", "global", "styles", "events", "defaultEvents", "text", "placeholder", "checked"],
8 | "paths": [],
9 | "global": "",
10 | "styles": {
11 | "x": 1,
12 | "y": 1,
13 | "visible": true
14 | },
15 | "events": {},
16 | "defaultEvents": {}
17 | }
18 | };
19 |
20 | public constructor(props?: app.Iproperties) {
21 | if (props) this.data.properties = app.setProps(props, this.data.properties);
22 | }
23 |
24 | public prerun(widget: app.Iwidget, focus: string, widgets: Array, func: Function, object: any) {}
25 | }
--------------------------------------------------------------------------------
/src/lib/CLIWidgets/CLIImage.ts:
--------------------------------------------------------------------------------
1 | import imageToAscii from 'image-to-ascii';
2 | import * as app from "../CLIApplication";
3 |
4 | export class CLIImage {
5 | private text: string = ``;
6 | private isDoing: boolean = false;
7 |
8 | public data: app.Idata = {
9 | "type": "image",
10 | "properties": {
11 | "accepts": ["paths", "styles", "global"],
12 | "paths": [],
13 | "global": "",
14 | "styles": {
15 | "x": 1,
16 | "y": 1,
17 | "width": 50,
18 | "height": 50,
19 | "visible": true,
20 | "img": "",
21 | "img-pixels": " "
22 | },
23 | "events": {},
24 | "defaultEvents": {}
25 | }
26 | };
27 |
28 | public constructor(props?: app.Iproperties) {
29 | if (props) this.data.properties = app.setProps(props, this.data.properties);
30 | }
31 |
32 | public prerun(widget: app.Iwidget) {
33 | const { styles } = widget.data.properties;
34 |
35 | if (this.text !== ``) {
36 | this.text.split(`\n`).forEach((line: string, idx: number) => {
37 | process.stdout.write(`\x1b[${styles.y + idx};${styles.x}H`);
38 | console.log(line);
39 | })
40 | } else if (!this.isDoing) {
41 | this.isDoing = true;
42 | imageToAscii(styles.img, {
43 | size: {
44 | width: styles.width,
45 | height: styles.height
46 | },
47 | bg: true,
48 | fg: false,
49 | pixels: styles["img-pixels"]
50 | }, (err: string, converted: string) => {
51 | if (err) throw new Error(err);
52 | this.text = converted;
53 | });
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/lib/CLIWidgets/CLILabel.ts:
--------------------------------------------------------------------------------
1 | import chalk from "chalk";
2 | import * as app from "../CLIApplication";
3 |
4 | export class CLILabel {
5 | public data: app.Idata = {
6 | "type": "label",
7 | "properties": {
8 | "text": "lorem ipsum",
9 | "accepts": ["paths", "styles", "text", "global"],
10 | "paths": [],
11 | "global": "",
12 | "styles": {
13 | "x": 1,
14 | "y": 1,
15 | "text-color": "#ffffff",
16 | "visible": true
17 | },
18 | "events": {},
19 | "defaultEvents": {}
20 | }
21 | };
22 |
23 | public constructor(props?: app.Iproperties) {
24 | if (props) this.data.properties = app.setProps(props, this.data.properties);
25 | }
26 |
27 | public prerun(widgets: Array, widget: app.Iwidget, func: Function, focus: string) {
28 | const { styles, text } = widget.data.properties;
29 |
30 | let isOverLapping: boolean = false;
31 | widgets.forEach((_widget: app.Iwidget) => {
32 | if (func(_widget, styles)) {
33 | isOverLapping = true;
34 |
35 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
36 |
37 | const backgroundColor = _widget.data.properties.styles["background-color"] || `#000000`;
38 | const textColor = styles["text-color"] || _widget.data.properties.styles["text-color"] || `#ffffff`;
39 |
40 | console.log(focus + chalk.bgHex(backgroundColor)(chalk.hex(textColor)(text)));
41 | }
42 | });
43 |
44 | if (!isOverLapping) {
45 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
46 |
47 | const backgroundColor = `#000000`;
48 | const textColor = styles["text-color"] || `#ffffff`;
49 |
50 | console.log(focus + chalk.bgHex(backgroundColor)(chalk.hex(textColor)(text)));
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/src/lib/CLIWidgets/CLIPanel.ts:
--------------------------------------------------------------------------------
1 | import chalk from "chalk";
2 | import * as app from "../CLIApplication";
3 |
4 | export class CLIPanel {
5 | public data: app.Idata = {
6 | "type": "panel",
7 | "properties": {
8 | "accepts": ["paths", "styles", "global"],
9 | "paths": [],
10 | "global": "",
11 | "styles": {
12 | "x": 0,
13 | "y": 0,
14 | "width": process.stdout.columns,
15 | "height": process.stdout.rows,
16 | "fill": "█",
17 | "background-color": "#000000",
18 | "text-color": "#ffffff",
19 | "visible": true
20 | },
21 | "events": {},
22 | "defaultEvents": {}
23 | }
24 | };
25 |
26 | public constructor(props?: app.Iproperties) {
27 | if (props) this.data.properties = app.setProps(props, this.data.properties);
28 | }
29 |
30 | public prerun(widget: app.Iwidget, focus: string) {
31 | const { styles } = widget.data.properties;
32 |
33 | if (!styles.fill) styles.fill = `█`;
34 |
35 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
36 | if (styles.width) console.log(focus + chalk.hex(styles[`background-color`] ? styles[`background-color`] : `#ffffff`)(styles.fill.repeat(styles.width)));
37 |
38 | if (styles.height) for (let i = 0; i < styles.height; i++) {
39 | process.stdout.write(`\x1b[${styles.y + i};${styles.x}H`);
40 | if (styles.width) console.log(focus + chalk.hex(styles[`background-color`] ? styles[`background-color`] : `#ffffff`)(styles.fill.repeat(styles.width)));
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/src/lib/CLIWidgets/CLIRadio.ts:
--------------------------------------------------------------------------------
1 | import chalk from "chalk";
2 | import * as app from "../CLIApplication";
3 |
4 | export class CLIRadio {
5 | private widgets: Array = [];
6 |
7 | public data: app.Idata = {
8 | "type": "radio",
9 | "properties": {
10 | "text": "lorem ipsum",
11 | "checked": false,
12 | "accepts": ["paths", "styles", "text", "events", "checked", "global"],
13 | "paths": [],
14 | "global": "default",
15 | "styles": {
16 | "x": 1,
17 | "y": 1,
18 | "text-color": "#ffffff",
19 | "visible": true,
20 | "check": ["⚪ ", "⚫ "]
21 | },
22 | "events": {},
23 | "defaultEvents": {
24 | "onEnter": () => {
25 | this.widgets.map((e: app.Iwidget) => e.data.properties.checked = e.data.properties.global === this.data.properties.global ? false : e.data.properties.checked);
26 | this.data.properties.checked = !this.data.properties.checked;
27 |
28 | return this.widgets;
29 | }
30 | }
31 | }
32 | };
33 |
34 | public constructor(props?: app.Iproperties) {
35 | if (props) this.data.properties = app.setProps(props, this.data.properties);
36 | }
37 |
38 | public prerun(widgets: Array, widget: app.Iwidget, func: Function, focus: string) {
39 | const { styles, text } = widget.data.properties;
40 |
41 | this.widgets = widgets;
42 |
43 | let isOverLapping: boolean = false;
44 | widgets.forEach((_widget: app.Iwidget) => {
45 | if (func(_widget, styles)) {
46 | isOverLapping = true;
47 |
48 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
49 |
50 | const backgroundColor = _widget.data.properties.styles["background-color"] || `#000000`;
51 | const textColor = styles["text-color"] || _widget.data.properties.styles["text-color"] || `#ffffff`;
52 |
53 | console.log(focus + (this.data.properties.checked ? styles.check?.[0] : styles.check?.[1]) + chalk.bgHex(backgroundColor)(chalk.hex(textColor)(text)));
54 | }
55 | });
56 |
57 | if (!isOverLapping) {
58 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
59 |
60 | const backgroundColor = `#000000`;
61 | const textColor = styles["text-color"] || `#ffffff`;
62 |
63 | console.log(focus + (this.data.properties.checked ? styles.check?.[0] : styles.check?.[1]) + chalk.bgHex(backgroundColor)(chalk.hex(textColor)(text)));
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/src/lib/CLIWidgets/CLITextbox.ts:
--------------------------------------------------------------------------------
1 | import chalk from "chalk";
2 | import * as app from "../CLIApplication";
3 |
4 | export class CLITextbox {
5 | public isTyping: boolean = false;
6 |
7 | public data: app.Idata = {
8 | "type": "textbox",
9 | "properties": {
10 | "text": "",
11 | "placeholder": "",
12 | "accepts": ["paths", "styles", "global", "text", "placeholder", "events"],
13 | "paths": [],
14 | "global": "",
15 | "styles": {
16 | "x": 1,
17 | "y": 1,
18 | "background-color": "#ffffff",
19 | "placeholder-color": "#777777",
20 | "text-color": "#000000",
21 | "visible": true
22 | },
23 | "events": {},
24 | "defaultEvents": {
25 | "onEnter": () => {
26 | this.isTyping = !this.isTyping;
27 | }
28 | }
29 | }
30 | };
31 |
32 | public constructor(props?: app.Iproperties) {
33 | if (props) this.data.properties = app.setProps(props, this.data.properties);
34 | }
35 |
36 | public prerun(widget: app.Iwidget, focus: string, textloc: number) {
37 | const { styles, text, placeholder } = widget.data.properties;
38 |
39 | const backgroundColor = styles["background-color"] || `#ffffff`;
40 | const placeholderColor = styles["placeholder-color"] || `#777777`;
41 | const textColor = styles["text-color"] || `#000000`;
42 |
43 | if (this.isTyping) {
44 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
45 | console.log(focus + (text === `` ? chalk.bgHex(backgroundColor)(chalk.hex(placeholderColor)(placeholder)) : chalk.bgHex(backgroundColor)(chalk.hex(textColor)(`${text?.substring(0, textloc)}|${text?.substring(textloc, text.length)}`))));
46 | } else {
47 | process.stdout.write(`\x1b[${styles.y};${styles.x}H`);
48 | console.log(focus + (text === `` ? chalk.bgHex(backgroundColor)(chalk.hex(placeholderColor)(placeholder)) : chalk.bgHex(backgroundColor)(chalk.hex(textColor)(text))));
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/lib/CLIWidgets/CLIWebview.ts:
--------------------------------------------------------------------------------
1 | import puppeteer from 'puppeteer';
2 | import imageToAscii from 'image-to-ascii';
3 | import * as app from "../CLIApplication";
4 |
5 | export class CLIWebview {
6 | private text: string = ``;
7 | private isDoing: boolean = false;
8 |
9 | public data: app.Idata = {
10 | "type": "image",
11 | "properties": {
12 | "accepts": ["paths", "styles", "global"],
13 | "paths": [],
14 | "global": "",
15 | "styles": {
16 | "x": 1,
17 | "y": 1,
18 | "visible": true,
19 | "img": "",
20 | "img-pixels": " ",
21 | "page": "https://www.google.com"
22 | },
23 | "events": {},
24 | "defaultEvents": {}
25 | }
26 | };
27 |
28 | public constructor(props?: app.Iproperties) {
29 | if (props) this.data.properties = app.setProps(props, this.data.properties);
30 | }
31 |
32 | public prerun(widget: app.Iwidget) {
33 | const { styles, events } = widget.data.properties;
34 |
35 | if (this.text !== ``) {
36 | this.text.split(`\n`).forEach((line: string, idx: number) => {
37 | process.stdout.write(`\x1b[${styles.y + idx};${styles.x}H`);
38 | console.log(line);
39 | });
40 | } else if (!this.isDoing) {
41 | this.isDoing = true;
42 |
43 | const browser = puppeteer.launch();
44 | const page = browser.then(value => value.newPage());
45 |
46 | page.then(value => {
47 | if (typeof events.onConnect === `function`) events.onConnect?.(value, () => {
48 | if (this.text === ``) {
49 | value.waitForTimeout(2000).then(() => {
50 | value.screenshot({ path: `browse.png` }).then(() => {
51 | styles.img = `browse.png`;
52 |
53 | imageToAscii(styles.img, {
54 | size: {
55 | width: styles.width,
56 | height: styles.height
57 | },
58 | bg: true,
59 | fg: false,
60 | pixels: styles["img-pixels"]
61 | }, (err: string, converted: string) => {
62 | if (err) throw new Error(err);
63 | this.text = converted;
64 | });
65 | });
66 | });
67 | }
68 | });
69 |
70 | // if (styles.page) value.goto(styles.page).then(() => {
71 | // value.type(`textarea[type="search"]`, `sans`).then(() => {
72 | // value.click(`body > div > div > form > div:nth-child(1) > div > div > center > input`).then(() => {
73 | // value.waitForTimeout(2000).then(() => {
74 | // value.screenshot({ path: `browse.png` }).then(() => {
75 | // styles.img = `browse.png`;
76 |
77 | // imageToAscii(styles.img, {
78 | // size: {
79 | // width: styles.width,
80 | // height: styles.height
81 | // },
82 | // bg: true,
83 | // fg: false,
84 | // pixels: styles["img-pixels"]
85 | // }, (err: string, converted: string) => {
86 | // if (err) throw new Error(err);
87 | // this.text = converted;
88 | // });
89 | // });
90 | // });
91 | // });
92 | // });
93 | // });
94 | });
95 | }
96 | }
97 | }
--------------------------------------------------------------------------------
/tests/default.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _require = require("../"),
4 | CLIApplication = _require.CLIApplication,
5 | CLIPanel = _require.CLIPanel,
6 | CLILabel = _require.CLILabel,
7 | CLIButton = _require.CLIButton;
8 | var app = new CLIApplication();
9 | var background = new CLIPanel({
10 | "styles": {
11 | "background-color": "#EEEEEE"
12 | }
13 | });
14 | var title = new CLILabel({
15 | "text": "simple-modal-app",
16 | "styles": {
17 | "text-color": "#222831",
18 | x: 4,
19 | y: 2
20 | }
21 | });
22 | var label1 = new CLILabel({
23 | "paths": ["root/label1"],
24 | "text": "open-modal",
25 | "styles": {
26 | "text-color": "#00ADB5",
27 | x: 4,
28 | y: 3,
29 | visible: false
30 | }
31 | });
32 | var timeout;
33 | var button1 = new CLIButton({
34 | "text": " button ",
35 | "styles": {
36 | "background-color": "#222831",
37 | "text-color": "#EEEEEE",
38 | x: 4,
39 | y: 4,
40 | width: 8,
41 | height: 1
42 | },
43 | "events": {
44 | "onPut": function onPut() {
45 | timeout = setTimeout(function () {
46 | app.modify("root/label1", {
47 | styles: {
48 | visible: true
49 | }
50 | });
51 | }, 500);
52 | },
53 | "onLeave": function onLeave() {
54 | clearTimeout(timeout);
55 | app.modify("root/label1", {
56 | styles: {
57 | visible: false
58 | }
59 | });
60 | },
61 | "onEnter": function onEnter() {
62 | app.modify("root/modalp", {
63 | styles: {
64 | visible: true
65 | }
66 | });
67 | app.modify("root/modall", {
68 | styles: {
69 | visible: true
70 | }
71 | });
72 | app.modify("root/modalb", {
73 | styles: {
74 | visible: true
75 | }
76 | });
77 | }
78 | }
79 | });
80 | var modalPanel = new CLIPanel({
81 | "paths": ["root/modalp"],
82 | "styles": {
83 | "background-color": "#222831",
84 | "visible": false,
85 | x: 8,
86 | y: 2,
87 | "width": 50,
88 | "height": 10
89 | }
90 | });
91 | var modalLabel = new CLILabel({
92 | "paths": ["root/modall"],
93 | "text": "modal-title",
94 | "styles": {
95 | "text-color": "#EEEEEE",
96 | x: 12,
97 | y: 3,
98 | "visible": false
99 | }
100 | });
101 | var modalButton = new CLIButton({
102 | "paths": ["root/modalb"],
103 | "text": " close ",
104 | "styles": {
105 | "background-color": "#EEEEEE",
106 | "text-color": "#222831",
107 | x: 12,
108 | y: 4,
109 | width: 6,
110 | height: 1,
111 | visible: false
112 | },
113 | "events": {
114 | "onEnter": function onEnter() {
115 | app.modify("root/modalp", {
116 | styles: {
117 | visible: false
118 | }
119 | });
120 | app.modify("root/modall", {
121 | styles: {
122 | visible: false
123 | }
124 | });
125 | app.modify("root/modalb", {
126 | styles: {
127 | visible: false
128 | }
129 | });
130 | }
131 | }
132 | });
133 | app.append(background, title, label1, button1, modalPanel, modalLabel, modalButton);
134 | app.show(30);
135 |
136 | // const siu =
137 | //
138 |
139 | //
140 | // {
142 | // timeout = setTimeout(() => {
143 | // app.modify(`root/label1`, { styles: { visible: true } });
144 | // }, 500);
145 | // },
146 | // "onLeave": () => {
147 | // clearTimeout(timeout);
148 | // app.modify(`root/label1`, { styles: { visible: false } });
149 | // },
150 | // "onEnter": () => {
151 | // app.modify(`root/modalp`, { styles: { visible: true } });
152 | // app.modify(`root/modall`, { styles: { visible: true } });
153 | // app.modify(`root/modalb`, { styles: { visible: true } });
154 | // }
155 | // }} />
156 |
157 | //
158 | //
159 | // {
161 | // app.modify(`root/modalp`, { styles: { visible: false } });
162 | // app.modify(`root/modall`, { styles: { visible: false } });
163 | // app.modify(`root/modalb`, { styles: { visible: false } });
164 | // }
165 | // }} />
166 | //
167 | // ;
168 |
169 | // app.append(siu);
--------------------------------------------------------------------------------
/tests/default.jsx:
--------------------------------------------------------------------------------
1 | const { CLIApplication, CLIPanel, CLILabel, CLIButton } = require(`../`);
2 |
3 | const app = new CLIApplication();
4 |
5 | const background = ;
6 | const title = ;
7 |
8 | const label1 = ;
9 | let timeout;
10 | const button1 = {
12 | timeout = setTimeout(() => {
13 | app.modify(`root/label1`, { styles: { visible: true } });
14 | }, 500);
15 | },
16 | "onLeave": () => {
17 | clearTimeout(timeout);
18 | app.modify(`root/label1`, { styles: { visible: false } });
19 | },
20 | "onEnter": () => {
21 | app.modify(`root/modalp`, { styles: { visible: true } });
22 | app.modify(`root/modall`, { styles: { visible: true } });
23 | app.modify(`root/modalb`, { styles: { visible: true } });
24 | }
25 | }} />;
26 |
27 | const modalPanel = ;
28 | const modalLabel = ;
29 | const modalButton = {
31 | app.modify(`root/modalp`, { styles: { visible: false } });
32 | app.modify(`root/modall`, { styles: { visible: false } });
33 | app.modify(`root/modalb`, { styles: { visible: false } });
34 | }
35 | }} />;
36 |
37 | app.append(background, title, label1, button1, modalPanel, modalLabel, modalButton);
38 | app.show(30);
39 |
40 |
41 |
42 |
43 | // const siu =
44 | //
45 |
46 | //
47 | // {
49 | // timeout = setTimeout(() => {
50 | // app.modify(`root/label1`, { styles: { visible: true } });
51 | // }, 500);
52 | // },
53 | // "onLeave": () => {
54 | // clearTimeout(timeout);
55 | // app.modify(`root/label1`, { styles: { visible: false } });
56 | // },
57 | // "onEnter": () => {
58 | // app.modify(`root/modalp`, { styles: { visible: true } });
59 | // app.modify(`root/modall`, { styles: { visible: true } });
60 | // app.modify(`root/modalb`, { styles: { visible: true } });
61 | // }
62 | // }} />
63 |
64 | //
65 | //
66 | // {
68 | // app.modify(`root/modalp`, { styles: { visible: false } });
69 | // app.modify(`root/modall`, { styles: { visible: false } });
70 | // app.modify(`root/modalb`, { styles: { visible: false } });
71 | // }
72 | // }} />
73 | //
74 | // ;
75 |
76 | // app.append(siu);
--------------------------------------------------------------------------------
/tests/normal.js:
--------------------------------------------------------------------------------
1 | const { CLIApplication, CLICanvas, CLITextbox } = require(`../`);
2 |
3 | const app = new CLIApplication();
4 |
5 | const canvas = new CLICanvas({
6 | canvasChilds: [
7 | {
8 | type: `rectangle`,
9 | x: 1,
10 | y: 1,
11 | width: 10,
12 | height: 5,
13 | fill: `█`
14 | },
15 | {
16 | type: `circle`,
17 | centerX: 20,
18 | centerY: 6,
19 | radius: 5,
20 | fill: `█`
21 | },
22 | {
23 | type: `line`,
24 | x: 1,
25 | y: 7,
26 | toX: 10,
27 | toY: 11,
28 | fill: `█`
29 | }
30 | ]
31 | });
32 |
33 | const textbox = new CLITextbox({
34 | placeholder: `sans`,
35 | styles: {
36 | y: 9
37 | }
38 | })
39 |
40 | app.append(canvas, textbox);
41 | app.show(30);
--------------------------------------------------------------------------------
/tests/tcg.js:
--------------------------------------------------------------------------------
1 | const { CLIApplication } = require(`../`);
2 | const global = require(`../dist/scripts/global`);
3 |
4 | const app = new CLIApplication();
5 |
6 | const tcg = new global.TCG([
7 | {
8 | id: `cube`,
9 | center: { x: .5, y: .8, z: .5 },
10 | rotation: { x: .5, y: .5, z: 0 },
11 | vertices: [
12 | { x: 0, y: .7, z: 0 },
13 | { x: 1, y: .7, z: 0 },
14 | { x: 0, y: 1.3, z: 0 },
15 | { x: 1, y: 1.3, z: 0 },
16 | { x: 0, y: .7, z: 1 },
17 | { x: 1, y: .7, z: 1 },
18 | { x: 0, y: 1.3, z: 1 },
19 | { x: 1, y: 1.3, z: 1 },
20 | ]
21 | }
22 | ], { events: {
23 | onFrame: (objects, camera) => {
24 | const playerFirstX = objects[0].vertices[0].x;
25 | const playerFirstY = objects[0].vertices[0].y;
26 | const playerFirstZ = objects[0].vertices[0].z;
27 | const playerSecondX = objects[0].vertices[2].x;
28 | const playerSecondY = objects[0].vertices[2].y;
29 | const playerSecondZ = objects[0].vertices[3].z;
30 | const playerWidth = objects[0].vertices[1].x - objects[0].vertices[0].x;
31 | const playerHeight = objects[0].vertices[1].y - objects[0].vertices[0].y;
32 |
33 | const objectFirstX = objects[1].vertices[0].x;
34 | const objectFirstY = objects[1].vertices[0].y;
35 | const objectFirstZ = objects[1].vertices[0].z;
36 | const objectSecondX = objects[1].vertices[2].x;
37 | const objectSecondY = objects[1].vertices[2].y;
38 | const objectSecondZ = objects[1].vertices[3].z;
39 | const objectWidth = objects[1].vertices[1].x - objects[1].vertices[0].x;
40 | const objectHeight = objects[1].vertices[1].y - objects[1].vertices[0].y;
41 |
42 | if (
43 | (playerFirstX >= 5.5 && playerFirstX <= 9) && (
44 | (Math.floor(playerFirstY + playerSecondZ) === Math.floor(objectFirstY + objectSecondZ)) ||
45 | (Math.floor(playerFirstY + playerSecondZ) === Math.floor(objectFirstY + objectSecondZ))
46 | )
47 | ) {
48 | process.exit();
49 | }
50 |
51 | if (playerFirstX * 10 >= process.stdout.columns) {
52 | const idx = tcg.objects.findIndex(e => e.id.includes(`pyramid`));
53 | if (idx !== -1) tcg.objects.splice(idx, 1);
54 | createObstacles();
55 |
56 | objects[0].center.x = .5;
57 | objects[0].center.z = .5;
58 | objects[0].rotation.y = .5;
59 | objects[0].vertices.forEach((e, idx) => e.x = (idx + 1) % 2 === 0 ? 1 : 0);
60 | objects[0].vertices.forEach((e, idx) => e.z = idx >= 4 ? 1 : 0);
61 | }
62 |
63 | objects[0].center.x += .05 + .1;
64 | objects[0].rotation.y += .1 + .1;
65 | objects[0].vertices.map(e => e.x += .05 + .1);
66 | }
67 | } });
68 |
69 | const createObstacles = () => {
70 | const location = { x: 7, y: Math.floor(Math.random() * 2) };
71 |
72 | tcg.objects.push({
73 | id: `pyramid-${Math.random().toString(36).substring(2)}`,
74 | center: { x: .5 + location.x, y: .5 + location.y, z: .5 },
75 | rotation: { x: -.5, y: .5, z: 0 },
76 | vertices: [
77 | { x: 0 + location.x, y: 0 + location.y, z: 0 },
78 | { x: 1 + location.x, y: 0 + location.y, z: 0 },
79 | { x: 0 + location.x, y: 1 + location.y, z: 0 },
80 | { x: 1 + location.x, y: 1 + location.y, z: 0 },
81 | { x: .5 + location.x, y: .5 + location.y, z: 1 },
82 | { x: .5 + location.x, y: .5 + location.y, z: 1 },
83 | { x: .5 + location.x, y: .5 + location.y, z: 1 },
84 | { x: .5 + location.x, y: .5 + location.y, z: 1 },
85 | ]
86 | });
87 | };
88 |
89 | createObstacles();
90 |
91 | process.stdin.on(`data`, key => {
92 | if (key === `w`) {
93 | tcg.objects[0].vertices.map(e => e.y -= .1);
94 | tcg.objects[0].center.y -= .1;
95 | }
96 |
97 | if (key === `s`) {
98 | tcg.objects[0].vertices.map(e => e.y += .1);
99 | tcg.objects[0].center.y += .1;
100 | }
101 |
102 | if (key === `d`) {
103 | tcg.objects[0].vertices.map(e => e.x += .2);
104 | tcg.objects[0].center.x += .2;
105 | }
106 | });
107 |
108 | app.append(tcg);
109 | app.show(30);
--------------------------------------------------------------------------------
/tests/tcg2.js:
--------------------------------------------------------------------------------
1 | const { CLIApplication } = require(`../`);
2 | const global = require(`../dist/scripts/TCG`);
3 |
4 | const app = new CLIApplication({ debug: true });
5 |
6 | const tcg = new global.TCG([
7 | {
8 | id: `cube`,
9 | center: { x: 1, y: 1, z: 1 },
10 | rotation: { x: 0, y: 0, z: 0 },
11 | vertices: [
12 | { x: 0, y: 0, z: 0 },
13 | { x: 2, y: 0, z: 0 },
14 | { x: 0, y: 2, z: 0 },
15 | { x: 2, y: 2, z: 0 },
16 | { x: 0, y: 0, z: 2 },
17 | { x: 2, y: 0, z: 2 },
18 | { x: 0, y: 2, z: 2 },
19 | { x: 2, y: 2, z: 2 },
20 | ]
21 | }
22 | ], { events: {
23 | onFrame: (objects, camera) => {
24 | objects[0].rotation.x += .1;
25 | objects[0].rotation.y += .1;
26 | objects[0].rotation.z += .1;
27 | }
28 | } });
29 |
30 | app.append(tcg);
31 | app.show(30);
--------------------------------------------------------------------------------
/tests/tcg3.js:
--------------------------------------------------------------------------------
1 | const { CLIApplication } = require(`../`);
2 | const global = require(`../dist/scripts/global`);
3 |
4 | const app = new CLIApplication();
5 |
6 | const tcg = new global.TCG([
7 | {
8 | id: `cube`,
9 | center: { x: .5, y: .8, z: .5 },
10 | rotation: { x: .5, y: .5, z: 0 },
11 | vertices: [
12 | { x: 0, y: .7, z: 0 },
13 | { x: 1, y: .7, z: 0 },
14 | { x: 0, y: 1.3, z: 0 },
15 | { x: 1, y: 1.3, z: 0 },
16 | { x: 0, y: .7, z: 1 },
17 | { x: 1, y: .7, z: 1 },
18 | { x: 0, y: 1.3, z: 1 },
19 | { x: 1, y: 1.3, z: 1 },
20 | ]
21 | }
22 | ], { events: {
23 | onFrame: (objects, camera) => {
24 | if (objects[0].vertices[0].x >= 5) {
25 | objects[0].center.x = .5;
26 | objects[0].vertices.map((e, idx) => e.x = (((idx + 1) % 2) === 0));
27 | }
28 |
29 | objects[0].center.x += .15;
30 | objects[0].rotation.y += .2;
31 | objects[0].vertices.map(e => e.x += .15);
32 | }
33 | } });
34 |
35 | app.append(tcg);
36 | app.show(24);
--------------------------------------------------------------------------------
/transform-jsx-syntax.js:
--------------------------------------------------------------------------------
1 | module.exports = function(babel) {
2 | const { types: t } = babel;
3 |
4 | const supportedElements = ['CLILabel', 'CLIButton', 'CLIPanel', 'CLICheckbox', 'CLIRadio', 'CLIImage', 'CLITextbox', 'CLIWebview', 'CLICanvas', 'CLICustom'];
5 |
6 | return {
7 | name: 'transform-jsx-syntax',
8 | visitor: {
9 | JSXElement(path) {
10 | const elementName = path.node.openingElement.name.name;
11 |
12 | if (supportedElements.includes(elementName)) {
13 | const pathAttr = path.node.openingElement.attributes;
14 | const pathProps = pathAttr.map((attr) => {
15 | const key = attr.name.name;
16 | let value;
17 |
18 | if (t.isJSXExpressionContainer(attr.value)) value = attr.value.expression;
19 | else value = attr.value;
20 |
21 | return t.objectProperty(t.stringLiteral(key), value);
22 | });
23 |
24 | const newElement = t.newExpression(t.identifier(elementName), [
25 | t.objectExpression(pathProps),
26 | ]);
27 |
28 | path.replaceWith(newElement);
29 | }
30 | },
31 | },
32 | };
33 | };
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2016",
4 | "module": "commonjs",
5 | "esModuleInterop": true,
6 | "forceConsistentCasingInFileNames": true,
7 | "strict": true,
8 | "skipLibCheck": true,
9 | "outDir": "./dist",
10 | "declaration": true,
11 | "noImplicitAny": false
12 | },
13 | "include": ["src/**/*", "scripts/**/*"],
14 | "exclude": ["node_modules"]
15 | }
--------------------------------------------------------------------------------