├── LICENSE
├── README
├── example
└── index.html
├── fonts
└── ansilove_font_pc_80x25.png
└── src
├── Term.js
├── parser
├── AnsiParser.js
├── ByteArray.js
├── CharacterCodes.js
├── EscapeSequencer.js
├── Keyboard.js
├── NVTCodes.js
├── SixteenColors.js
└── Telnet.js
├── telnet
├── Session.js
└── Socket.js
└── viewer
├── AnsiViewer.js
├── Cursor.js
├── Font.js
└── Point.js
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010 Peter Nitsch
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pnitsch/jsTerm/ba18c505ea969a331c890b203b0a6f0ac2e789d3/README
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | jsTerm Example
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | - Bookmarks -
54 | towel.blinkenlights.nl
55 | vert.synchro.net
56 | bbs.pharcyde.org
57 | d1st.org
58 | bbs.electronicchicken.com
59 | entropybbs.co.nz
60 | lunatic.zapto.org
61 | bbs.roughneckbbs.com
62 | masqueradebbs.com
63 | alecoexp.dyndns.org
64 | bluewavebbs.dyndns.org
65 | bbs.akroncdnr.com
66 | cbliss.synchro.net
67 | ds69bbs.com
68 | bbs.defcon.no
69 | bbs.dmine.net
70 | bbs.diskshop.ca
71 | eotd.com
72 | flashpointbbs.no-ip.org
73 | fjbbs.gotdns.com
74 | isisunveiled.no-ip.org
75 | bbs.zeusdev.co.uk
76 | musicstation.spb.ru
77 | phybbs.dyndns.org
78 | rdfig.net
79 | redhill.net.nz
80 | bbs.dxrw.org
81 | bbs.scansoutheasternmass.com
82 | thechangeosp.nl
83 | darkside.dtdns.net
84 | white-squirrel.dnsalias.net
85 | wildcatcastle.gotdns.com
86 | bbs.zzap.org
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/fonts/ansilove_font_pc_80x25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pnitsch/jsTerm/ba18c505ea969a331c890b203b0a6f0ac2e789d3/fonts/ansilove_font_pc_80x25.png
--------------------------------------------------------------------------------
/src/Term.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Peter Nitsch
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | *
22 | * @author Peter Nitsch
23 | * http://jsterm.com
24 | * http://www.peternitsch.net
25 | */
26 |
27 | var TERM = TERM || {
28 | socket : null,
29 | SERVER_URL : "174.143.154.166", // Your node.js server IP
30 | SERVER_PORT : "8000", // Your node.js server port
31 | VERSION : "0.1 alpha"
32 | };
--------------------------------------------------------------------------------
/src/parser/AnsiParser.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Peter Nitsch
3 | */
4 |
5 | TERM.AnsiParser = function (viewer){
6 |
7 | var viewer = viewer;
8 | var escapeCommand = [];
9 | var bufferEscapeCommand = false;
10 |
11 | this.escapeCommands = new TERM.EscapeSequencer(viewer);
12 | this._bytes;
13 |
14 | this.parse = function (bytes) {
15 |
16 | if( bytes != null ) this._bytes = new TERM.ByteArray(bytes);
17 |
18 | while( this._bytes.bytesAvailable > 0 ){
19 | var result = this._bytes.readUnsignedByte();
20 |
21 | if( result == SUBSTITUTE) {
22 | break;
23 | } else {
24 | this.readByte( result );
25 | }
26 | }
27 |
28 | this._bytes.position = 0;
29 | };
30 |
31 | this._exceptionsLib = [];
32 | this._exceptions = [];
33 |
34 | this.hasException = function( code ) {
35 | if( this._exceptions.indexOf(code) != -1 )
36 | return true;
37 | return false;
38 | };
39 |
40 | this.writeException = function( code, callback ) {
41 | if( !this.hasException(code) ){
42 | this._exceptionsLib[code] = callback;
43 | this._exceptions.push(code);
44 | }
45 | };
46 |
47 | this.readByte = function (b) {
48 |
49 | if(b == ESCAPE) {
50 | escapeCommand = [];
51 | escapeCommand.push(b);
52 | bufferEscapeCommand = true;
53 | } else {
54 | if(bufferEscapeCommand){
55 | escapeCommand.push(b);
56 | if( this.escapeCommands.checkCommandAction(escapeCommand.length, b) ) {
57 | this.escapeCommands.executeCommand(escapeCommand);
58 | bufferEscapeCommand = false;
59 | }
60 | } else if( this.hasException(b) ) {
61 | this._exceptionsLib[b]( b, this._bytes );
62 | } else if(b >= SPACE) {
63 | viewer.drawCharacter(b);
64 | } else {
65 | switch(b) {
66 | case BACKSPACE:
67 | viewer.moveBackward(1, true);
68 | break;
69 |
70 | case LINE_FEED:
71 | viewer.carriageReturn();
72 | viewer.moveDown(1);
73 | break;
74 |
75 | case CARRIAGE_RETURN:
76 | viewer.carriageReturn();
77 | break;
78 |
79 | case FORM_FEED:
80 | viewer.eraseScreen();
81 | viewer.reposition(0, 0);
82 | break;
83 | }
84 | }
85 | }
86 | };
87 |
88 | };
--------------------------------------------------------------------------------
/src/parser/ByteArray.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Peter Nitsch
3 | */
4 |
5 | TERM.ByteArray = function (bytes){
6 |
7 | this.position = 0;
8 | this.stringdata = bytes;
9 |
10 | this.readUnsignedByte = function(){
11 | var b = this.stringdata.charCodeAt(this.position);
12 | if(this.position!=this.stringdata.length) this.position++;
13 | return b;
14 | };
15 |
16 | this.writeByte = function(){
17 | // TO DO
18 | };
19 |
20 | };
21 |
22 | TERM.ByteArray.prototype = {
23 |
24 | get bytesAvailable (){
25 | return this.stringdata.length - this.position;
26 | },
27 | get length (){
28 | return this.stringdata.length;
29 | }
30 |
31 | };
32 |
33 |
--------------------------------------------------------------------------------
/src/parser/CharacterCodes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Peter Nitsch
3 | */
4 |
5 | const NULL = 0
6 | const START_OF_HEADING = 1;
7 | const START_OF_TEXT = 2;
8 | const END_OF_TEXT = 3;
9 | const END_OF_TRANSMISSION = 4;
10 | const ENQUIRY = 5;
11 | const ACKNOWLEDGE = 6;
12 | const BELL = 7;
13 | const BACKSPACE = 8;
14 | const HORIZONTAL_TABULATION = 9;
15 | const LINE_FEED = 10;
16 | const VERTICAL_TABULATION = 11;
17 | const FORM_FEED = 12;
18 | const CARRIAGE_RETURN = 13;
19 | const SHIFT_OUT = 14;
20 | const SHIFT_IN = 15;
21 | const DATA_LINK_ESCAPE = 16;
22 | const DEVICE_CONTROL_ONE = 17;
23 | const DEVICE_CONTROL_TWO = 18;
24 | const DEVICE_CONTROL_THREE = 19;
25 | const DEVICE_CONTROL_FOUR = 20;
26 | const NEGATIVE_ACKNOWLEDGE = 21;
27 | const SYNCHRONOUS_IDLE = 22;
28 | const END_OF_TRANSMISSION_BLOCK = 23;
29 | const CANCEL = 24;
30 | const END_OF_MEDIUM = 25;
31 | const SUBSTITUTE = 26;
32 | const ESCAPE = 27;
33 | const FILE_SEPARATOR = 28;
34 | const GROUP_SEPARATOR = 29;
35 | const RECORD_SEPARATOR = 30;
36 | const UNIT_SEPARATOR = 31;
37 | const SPACE = 32;
38 | const EXCLAMATION_MARK = 33;
39 | const QUOTATION_MARK = 34;
40 | const uint_SIGN = 35;
41 | const DOLLAR_SIGN = 36;
42 | const PERCENT_SIGN = 37;
43 | const AMPERSAND = 38;
44 | const APOSTROPHE = 39;
45 | const LEFT_PARENTHESIS = 40;
46 | const RIGHT_PARENTHESIS = 41;
47 | const ASTERISK = 42;
48 | const PLUS_SIGN = 43;
49 | const COMMA = 44;
50 | const HYPHEN_MINUS = 45;
51 | const FULL_STOP = 46;
52 | const SOLIDUS = 47;
53 | const DIGIT_ZERO = 48;
54 | const DIGIT_ONE = 49;
55 | const DIGIT_TWO = 50;
56 | const DIGIT_THREE = 51;
57 | const DIGIT_FOUR = 52;
58 | const DIGIT_FIVE = 53;
59 | const DIGIT_SIX = 54;
60 | const DIGIT_SEVEN = 55;
61 | const DIGIT_EIGHT = 56;
62 | const DIGIT_NINE = 57;
63 | const COLON = 58;
64 | const SEMICOLON = 59;
65 | const LESS_THAN_SIGN = 60;
66 | const EQUALS_SIGN = 61;
67 | const GREATER_THAN_SIGN = 62;
68 | const QUESTION_MARK = 63;
69 | const COMMERCIAL_AT = 64;
70 | const LATIN_CAPITAL_LETTER_A = 65;
71 | const LATIN_CAPITAL_LETTER_B = 66;
72 | const LATIN_CAPITAL_LETTER_C = 67;
73 | const LATIN_CAPITAL_LETTER_D = 68;
74 | const LATIN_CAPITAL_LETTER_E = 69;
75 | const LATIN_CAPITAL_LETTER_F = 70;
76 | const LATIN_CAPITAL_LETTER_G = 71;
77 | const LATIN_CAPITAL_LETTER_H = 72;
78 | const LATIN_CAPITAL_LETTER_I = 73;
79 | const LATIN_CAPITAL_LETTER_J = 74;
80 | const LATIN_CAPITAL_LETTER_K = 75;
81 | const LATIN_CAPITAL_LETTER_L = 76;
82 | const LATIN_CAPITAL_LETTER_M = 77;
83 | const LATIN_CAPITAL_LETTER_N = 78;
84 | const LATIN_CAPITAL_LETTER_O = 79;
85 | const LATIN_CAPITAL_LETTER_P = 80;
86 | const LATIN_CAPITAL_LETTER_Q = 81;
87 | const LATIN_CAPITAL_LETTER_R = 82;
88 | const LATIN_CAPITAL_LETTER_S = 83;
89 | const LATIN_CAPITAL_LETTER_T = 84;
90 | const LATIN_CAPITAL_LETTER_U = 85;
91 | const LATIN_CAPITAL_LETTER_V = 86;
92 | const LATIN_CAPITAL_LETTER_W = 87;
93 | const LATIN_CAPITAL_LETTER_X = 88;
94 | const LATIN_CAPITAL_LETTER_Y = 89;
95 | const LATIN_CAPITAL_LETTER_Z = 90;
96 | const LEFT_SQUARE_BRACKET = 91;
97 | const REVERSE_SOLIDUS = 92;
98 | const RIGHT_SQUARE_BRACKET = 93;
99 | const CIRCUMFLEX_ACCENT = 94;
100 | const LOW_LINE = 95;
101 | const GRAVE_ACCENT = 96;
102 | const LATIN_SMALL_LETTER_A = 97;
103 | const LATIN_SMALL_LETTER_B = 98;
104 | const LATIN_SMALL_LETTER_C = 99;
105 | const LATIN_SMALL_LETTER_D = 100;
106 | const LATIN_SMALL_LETTER_E = 101;
107 | const LATIN_SMALL_LETTER_F = 102;
108 | const LATIN_SMALL_LETTER_G = 103;
109 | const LATIN_SMALL_LETTER_H = 104;
110 | const LATIN_SMALL_LETTER_I = 105;
111 | const LATIN_SMALL_LETTER_J = 106;
112 | const LATIN_SMALL_LETTER_K = 107;
113 | const LATIN_SMALL_LETTER_L = 108;
114 | const LATIN_SMALL_LETTER_M = 109;
115 | const LATIN_SMALL_LETTER_N = 110;
116 | const LATIN_SMALL_LETTER_O = 111;
117 | const LATIN_SMALL_LETTER_P = 112;
118 | const LATIN_SMALL_LETTER_Q = 113;
119 | const LATIN_SMALL_LETTER_R = 114;
120 | const LATIN_SMALL_LETTER_S = 115;
121 | const LATIN_SMALL_LETTER_T = 116;
122 | const LATIN_SMALL_LETTER_U = 117;
123 | const LATIN_SMALL_LETTER_V = 118;
124 | const LATIN_SMALL_LETTER_W = 119;
125 | const LATIN_SMALL_LETTER_X = 120;
126 | const LATIN_SMALL_LETTER_Y = 121;
127 | const LATIN_SMALL_LETTER_Z = 122;
128 | const LEFT_CURLY_BRACKET = 123;
129 | const VERTICAL_LINE = 124;
130 | const RIGHT_CURLY_BRACKET = 125;
131 | const TILDE = 126;
132 | const DELETE = 127;
133 | const LATIN_CAPITAL_LETTER_C_WITH_CEDILLA = 128;
134 | const LATIN_SMALL_LETTER_U_WITH_DIAERESIS = 129;
135 | const LATIN_SMALL_LETTER_E_WITH_ACUTE = 130;
136 | const LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX = 131;
137 | const LATIN_SMALL_LETTER_A_WITH_DIAERESIS = 132;
138 | const LATIN_SMALL_LETTER_A_WITH_GRAVE = 133;
139 | const LATIN_SMALL_LETTER_A_WITH_RING_ABOVE = 134;
140 | const LATIN_SMALL_LETTER_C_WITH_CEDILLA = 135;
141 | const LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX = 136;
142 | const LATIN_SMALL_LETTER_E_WITH_DIAERESIS = 137;
143 | const LATIN_SMALL_LETTER_E_WITH_GRAVE = 138;
144 | const LATIN_SMALL_LETTER_I_WITH_DIAERESIS = 139;
145 | const LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX = 140;
146 | const LATIN_SMALL_LETTER_I_WITH_GRAVE = 141;
147 | const LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS = 142;
148 | const LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE = 143;
149 | const LATIN_CAPITAL_LETTER_E_WITH_ACUTE = 144;
150 | const LATIN_SMALL_LETTER_AE = 145;
151 | const LATIN_CAPITAL_LETTER_AE = 146;
152 | const LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX = 147;
153 | const LATIN_SMALL_LETTER_O_WITH_DIAERESIS = 148;
154 | const LATIN_SMALL_LETTER_O_WITH_GRAVE = 149;
155 | const LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX = 150;
156 | const LATIN_SMALL_LETTER_U_WITH_GRAVE = 151;
157 | const LATIN_SMALL_LETTER_Y_WITH_DIAERESIS = 152;
158 | const LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS = 153;
159 | const LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS = 154;
160 | const CENT_SIGN = 155;
161 | const POUND_SIGN = 156;
162 | const YEN_SIGN = 157;
163 | const PESETA_SIGN = 158;
164 | const LATIN_SMALL_LETTER_F_WITH_HOOK = 159;
165 | const LATIN_SMALL_LETTER_A_WITH_ACUTE = 160;
166 | const LATIN_SMALL_LETTER_I_WITH_ACUTE = 161;
167 | const LATIN_SMALL_LETTER_O_WITH_ACUTE = 162;
168 | const LATIN_SMALL_LETTER_U_WITH_ACUTE = 163;
169 | const LATIN_SMALL_LETTER_N_WITH_TILDE = 164;
170 | const LATIN_CAPITAL_LETTER_N_WITH_TILDE = 165;
171 | const FEMININE_ORDINAL_INDICATOR = 166;
172 | const MASCULINE_ORDINAL_INDICATOR = 167;
173 | const INVERTED_QUESTION_MARK = 168;
174 | const REVERSED_NOT_SIGN = 169;
175 | const NOT_SIGN = 170;
176 | const VULGAR_FRACTION_ONE_HALF = 171;
177 | const VULGAR_FRACTION_ONE_QUARTER = 172;
178 | const INVERTED_EXCLAMATION_MARK = 173;
179 | const LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK = 174;
180 | const RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK = 175;
181 | const LIGHT_SHADE = 176;
182 | const MEDIUM_SHADE = 177;
183 | const DARK_SHADE = 178;
184 | const BOX_DRAWINGS_LIGHT_VERTICAL = 179;
185 | const BOX_DRAWINGS_LIGHT_VERTICAL_AND_LEFT = 180;
186 | const BOX_DRAWINGS_VERTICAL_SINGLE_AND_LEFT_DOUBLE = 181;
187 | const BOX_DRAWINGS_VERTICAL_DOUBLE_AND_LEFT_SINGLE = 182;
188 | const BOX_DRAWINGS_DOWN_DOUBLE_AND_LEFT_SINGLE = 183;
189 | const BOX_DRAWINGS_DOWN_SINGLE_AND_LEFT_DOUBLE = 184;
190 | const BOX_DRAWINGS_DOUBLE_VERTICAL_AND_LEFT = 185;
191 | const BOX_DRAWINGS_DOUBLE_VERTICAL = 186;
192 | const BOX_DRAWINGS_DOUBLE_DOWN_AND_LEFT = 187;
193 | const BOX_DRAWINGS_DOUBLE_UP_AND_LEFT = 188;
194 | const BOX_DRAWINGS_UP_DOUBLE_AND_LEFT_SINGLE = 189;
195 | const BOX_DRAWINGS_UP_SINGLE_AND_LEFT_DOUBLE = 190;
196 | const BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT = 191;
197 | const BOX_DRAWINGS_LIGHT_UP_AND_RIGHT = 192;
198 | const BOX_DRAWINGS_LIGHT_UP_AND_HORIZONTAL = 193;
199 | const BOX_DRAWINGS_LIGHT_DOWN_AND_HORIZONTAL = 194;
200 | const BOX_DRAWINGS_LIGHT_VERTICAL_AND_RIGHT = 195;
201 | const BOX_DRAWINGS_LIGHT_HORIZONTAL = 196;
202 | const BOX_DRAWINGS_LIGHT_VERTICAL_AND_HORIZONTAL = 197;
203 | const BOX_DRAWINGS_VERTICAL_SINGLE_AND_RIGHT_DOUBLE = 198;
204 | const BOX_DRAWINGS_VERTICAL_DOUBLE_AND_RIGHT_SINGLE = 199;
205 | const BOX_DRAWINGS_DOUBLE_UP_AND_RIGHT = 200;
206 | const BOX_DRAWINGS_DOUBLE_DOWN_AND_RIGHT = 201;
207 | const BOX_DRAWINGS_DOUBLE_UP_AND_HORIZONTAL = 202;
208 | const BOX_DRAWINGS_DOUBLE_DOWN_AND_HORIZONTAL = 203;
209 | const BOX_DRAWINGS_DOUBLE_VERTICAL_AND_RIGHT = 204;
210 | const BOX_DRAWINGS_DOUBLE_HORIZONTAL = 205;
211 | const BOX_DRAWINGS_DOUBLE_VERTICAL_AND_HORIZONTAL = 206;
212 | const BOX_DRAWINGS_UP_SINGLE_AND_HORIZONTAL_DOUBLE = 207;
213 | const BOX_DRAWINGS_UP_DOUBLE_AND_HORIZONTAL_SINGLE = 208;
214 | const BOX_DRAWINGS_DOWN_SINGLE_AND_HORIZONTAL_DOUBLE = 209;
215 | const BOX_DRAWINGS_DOWN_DOUBLE_AND_HORIZONTAL_SINGLE = 210;
216 | const BOX_DRAWINGS_UP_DOUBLE_AND_RIGHT_SINGLE = 211;
217 | const BOX_DRAWINGS_UP_SINGLE_AND_RIGHT_DOUBLE = 212;
218 | const BOX_DRAWINGS_DOWN_SINGLE_AND_RIGHT_DOUBLE = 213;
219 | const BOX_DRAWINGS_DOWN_DOUBLE_AND_RIGHT_SINGLE = 214;
220 | const BOX_DRAWINGS_VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE = 215;
221 | const BOX_DRAWINGS_VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE = 216;
222 | const BOX_DRAWINGS_LIGHT_UP_AND_LEFT = 217;
223 | const BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT = 218;
224 | const FULL_BLOCK = 219;
225 | const LOWER_HALF_BLOCK = 220;
226 | const LEFT_HALF_BLOCK = 221;
227 | const RIGHT_HALF_BLOCK = 222;
228 | const UPPER_HALF_BLOCK = 223;
229 | const GREEK_SMALL_LETTER_ALPHA = 224;
230 | const LATIN_SMALL_LETTER_SHARP_S = 225;
231 | const GREEK_CAPITAL_LETTER_GAMMA = 226;
232 | const GREEK_SMALL_LETTER_PI = 227;
233 | const GREEK_CAPITAL_LETTER_SIGMA = 228;
234 | const GREEK_SMALL_LETTER_SIGMA = 229;
235 | const MICRO_SIGN = 230;
236 | const GREEK_SMALL_LETTER_TAU = 231;
237 | const GREEK_CAPITAL_LETTER_PHI = 232;
238 | const GREEK_CAPITAL_LETTER_THETA = 233;
239 | const GREEK_CAPITAL_LETTER_OMEGA = 234;
240 | const GREEK_SMALL_LETTER_DELTA = 235;
241 | const INFINITY = 236;
242 | const GREEK_SMALL_LETTER_PHI = 237;
243 | const GREEK_SMALL_LETTER_EPSILON = 238;
244 | const INTERSECTION = 239;
245 | const IDENTICAL_TO = 240;
246 | const PLUS_MINUS_SIGN = 241;
247 | const GREATER_THAN_OR_EQUAL_TO = 242;
248 | const LESS_THAN_OR_EQUAL_TO = 243;
249 | const TOP_HALF_INTEGRAL = 244;
250 | const BOTTOM_HALF_INTEGRAL = 245;
251 | const DIVISION_SIGN = 246;
252 | const ALMOST_EQUAL_TO = 247;
253 | const DEGREE_SIGN = 248;
254 | const BULLET_OPERATOR = 249;
255 | const MIDDLE_DOT = 250;
256 | const SQUARE_ROOT = 251;
257 | const SUPERSCRIPT_LATIN_SMALL_LETTER_N = 252;
258 | const SUPERSCRIPT_TWO = 253;
259 | const BLACK_SQUARE = 254;
260 | const NO_BREAK_SPACE = 255;
--------------------------------------------------------------------------------
/src/parser/EscapeSequencer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Peter Nitsch
3 | */
4 |
5 | TERM.EscapeSequencer = function (viewer){
6 |
7 | var viewer = viewer;
8 | var telnet;
9 |
10 | var _customCommand;
11 | var _currentCustomCommand = {};
12 |
13 | this.actionCharacterLib = [];
14 |
15 | this.init = function() {
16 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_H ] = this.cursorPosition;
17 | this.actionCharacterLib[ LATIN_SMALL_LETTER_F ] = this.cursorPosition;
18 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_A ] = this.cursorUp;
19 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_B ] = this.cursorDown;
20 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_C] = this.cursorForward;
21 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_D ] = this.cursorBackward;
22 | this.actionCharacterLib[ LATIN_SMALL_LETTER_S ] = this.saveCursorPosition;
23 | this.actionCharacterLib[ LATIN_SMALL_LETTER_U ] = this.restoreCursorPosition;
24 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_K ] = this.eraseLine;
25 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_J ] = this.eraseDisplay;
26 | this.actionCharacterLib[ LATIN_SMALL_LETTER_N ] = this.deviceRequest;
27 | this.actionCharacterLib[ LATIN_SMALL_LETTER_M ] = this.setGraphicsMode;
28 | this.actionCharacterLib[ LATIN_SMALL_LETTER_H ] = this.setMode;
29 | this.actionCharacterLib[ LATIN_SMALL_LETTER_L ] = this.resetMode;
30 | this.actionCharacterLib[ LATIN_SMALL_LETTER_P ] = this.setKeyboardStrings;
31 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_M ] = this.scrollUp;
32 | this.actionCharacterLib[ LATIN_SMALL_LETTER_R ] = this.scrollScreen;
33 |
34 | // TO DO
35 | this.actionCharacterLib[ LATIN_SMALL_LETTER_A ] = this.unused;
36 | this.actionCharacterLib[ LATIN_SMALL_LETTER_D ] = this.unused;
37 | this.actionCharacterLib[ LATIN_SMALL_LETTER_E ] = this.unused;
38 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_L ] = this.unused;
39 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_P ] = this.unused;
40 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_E ] = this.unused;
41 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_F ] = this.unused;
42 | this.actionCharacterLib[ LATIN_CAPITAL_LETTER_X ] = this.unused;
43 |
44 | };
45 |
46 | this.executeCommand = function(command) {
47 | try {
48 | this.actionCharacterLib[ command[command.length-1] ]( command );
49 | } catch(error) {
50 | console.log(error);
51 | }
52 | };
53 |
54 | this.checkCommandAction = function(position, character) {
55 | if( this.actionCharacterLib[character] != undefined )
56 | return true;
57 |
58 | return false;
59 | };
60 |
61 | this.unused = function(params) {
62 | // EMPTY
63 | };
64 |
65 | this.deviceRequest = function(params) {
66 | if( params[2]==DIGIT_FIVE ){
67 | TERM.socket.writeByte(ESCAPE);
68 | TERM.socket.writeByte(LEFT_SQUARE_BRACKET);
69 | TERM.socket.writeByte(DIGIT_ZERO);
70 | TERM.socket.writeByte(LATIN_SMALL_LETTER_N);
71 | } else if( params[2]==DIGIT_SIX ) {
72 | var i;
73 | var rows = "" + viewer.cursor.y;
74 | var cols = "" + viewer.cursor.x;
75 |
76 | TERM.socket.writeByte(ESCAPE);
77 | TERM.socket.writeByte(LEFT_SQUARE_BRACKET);
78 | for(i=0;i 0){
120 | lineArray = params.slice(2, params.length-1);
121 | for( i=0; i0) ? column-1 : 0;
128 | line = (line>0) ? line-1 : 0;
129 |
130 | viewer.reposition(column, line);
131 | }
132 | };
133 |
134 | this.cursorUp = function(params) {
135 | var valueArray = params.slice(2, params.length-1);
136 | var valueStr = "";
137 | for( i=0; i 0) ? parseInt(valueStr) : 1;
141 |
142 | viewer.moveUp(value);
143 | };
144 |
145 | this.cursorDown = function(params) {
146 | var valueArray = params.slice(2, params.length-1);
147 | var valueStr = "";
148 | for( i=0; i 0) ? parseInt(valueStr) : 1;
152 |
153 | viewer.moveDown(value);
154 | };
155 |
156 | this.cursorForward = function(params) {
157 | var valueArray = params.slice(2, params.length-1);
158 | var valueStr = "";
159 | for( i=0; i 0) ? parseInt(valueStr) : 1;
163 |
164 | viewer.moveForward(value);
165 | };
166 |
167 | this.cursorBackward = function(params) {
168 | var valueArray = params.slice(2, params.length-1);
169 | var valueStr = "";
170 | for( i=0; i 0) ? parseInt(valueStr) : 1;
174 |
175 | viewer.moveBackward(value);
176 | };
177 |
178 | this.saveCursorPosition = function(params) {
179 | viewer.savePosition();
180 | };
181 |
182 | this.restoreCursorPosition = function(params) {
183 | viewer.restorePosition();
184 | };
185 |
186 | // Set Graphic Mode functions
187 | var _bold = false;
188 | var _reverse = false;
189 |
190 | var _boldColors = [BLACK_BOLD, RED_BOLD, GREEN_BOLD, YELLOW_BOLD, BLUE_BOLD, MAGENTA_BOLD, CYAN_BOLD, WHITE_BOLD];
191 | var _normalColors = [BLACK_NORMAL, RED_NORMAL, GREEN_NORMAL, YELLOW_NORMAL, BLUE_NORMAL, MAGENTA_NORMAL, CYAN_NORMAL, WHITE_NORMAL];
192 |
193 | var _currentForegroundColor = WHITE_NORMAL;
194 | var _currentBackgroundColor = BLACK_NORMAL;
195 |
196 | this.setGraphicsMode = function(params) {
197 | for( i=2; i= NE_VAR_NAME_MAXLENGTH) {
385 | return NE_IN_ERROR;
386 | } else {
387 | sbuf.concat(i);
388 | }
389 | }
390 | } while (true);
391 |
392 | return i;
393 | };
394 |
395 | function readNEVariableValue(sbuf) {
396 | var i = bytes.readUnsignedByte();
397 | if (i == -1) {
398 | return NE_IN_ERROR;
399 | } else if (i == IAC) {
400 | i = bytes.readUnsignedByte();
401 | if (i == IAC) {
402 | return NE_VAR_DEFINED_EMPTY;
403 | } else if (i == SE) {
404 | return NE_IN_END;
405 | } else {
406 | return NE_IN_ERROR;
407 | }
408 | } else if (i == NE_VAR || i == NE_USERVAR) {
409 | return NE_VAR_DEFINED_EMPTY;
410 | } else if (i == NE_ESC) {
411 | i = bytes.readUnsignedByte();
412 | if (i == NE_ESC || i == NE_VAR || i == NE_USERVAR || i == NE_VALUE) {
413 | sbuf.concat(i);
414 | } else {
415 | return NE_IN_ERROR;
416 | }
417 | } else {
418 | sbuf.concat(i);
419 | }
420 |
421 | do {
422 | i = bytes.readUnsignedByte();
423 | if (i == -1) {
424 | return NE_IN_ERROR;
425 | } else if (i == IAC) {
426 | i = bytes.readUnsignedByte();
427 | if (i == IAC) {
428 | sbuf.concat(i);
429 | } else if (i == SE) {
430 | return NE_IN_END;
431 | } else {
432 | return NE_IN_ERROR;
433 | }
434 | } else if (i == NE_ESC) {
435 | i = bytes.readUnsignedByte();
436 | if (i == NE_ESC || i == NE_VAR || i == NE_USERVAR || i == NE_VALUE) {
437 | sbuf.concat(i);
438 | } else {
439 | return NE_IN_ERROR;
440 | }
441 | } else if (i == NE_VAR || i == NE_USERVAR) {
442 | return NE_VAR_OK;
443 | } else {
444 | if (sbuf.length > NE_VAR_VALUE_MAXLENGTH) {
445 | return NE_IN_ERROR;
446 | } else {
447 | sbuf.concat(i);
448 | }
449 | }
450 | } while (true);
451 |
452 | return i;
453 | };
454 |
455 |
456 | function readNEVariables() {
457 | var sbuf = "";
458 | var i = bytes.readUnsignedByte();
459 | if (i == IAC) {
460 | skipToSE();
461 | console.log("readNEVariables()::INVALID VARIABLE");
462 | return;
463 | }
464 | var cont = true;
465 | if (i == NE_VAR || i == NE_USERVAR) {
466 | do {
467 | switch (readNEVariableName(sbuf)) {
468 | case NE_IN_ERROR:
469 | console.log("readNEVariables()::NE_IN_ERROR");
470 | return;
471 | case NE_IN_END:
472 | console.log("readNEVariables()::NE_IN_END");
473 | return;
474 | case NE_VAR_DEFINED:
475 | console.log("readNEVariables()::NE_VAR_DEFINED");
476 | var str = sbuf;
477 | sbuf = "";
478 | switch (readNEVariableValue(sbuf)) {
479 | case NE_IN_ERROR:
480 | console.log("readNEVariables()::NE_IN_ERROR");
481 | return;
482 | case NE_IN_END:
483 | console.log("readNEVariables()::NE_IN_END");
484 | return;
485 | case NE_VAR_DEFINED_EMPTY:
486 | console.log("readNEVariables()::NE_VAR_DEFINED_EMPTY");
487 | break;
488 | case NE_VAR_OK:
489 | console.log("readNEVariables()::NE_VAR_OK:VAR=" + str + " VAL=" + sbuf.toString());
490 | sbuf = "";
491 | break;
492 | }
493 | break;
494 | case NE_VAR_UNDEFINED:
495 | console.log("readNEVariables()::NE_VAR_UNDEFINED");
496 | break;
497 | }
498 | } while (cont);
499 | }
500 | };
501 |
502 | function handleNEIs() {
503 | if (isEnabled(NEWENV)) {
504 | readNEVariables();
505 | }
506 | };
507 |
508 | function handleNEInfo() {
509 | if (isEnabled(NEWENV)) {
510 | readNEVariables();
511 | }
512 | };
513 |
514 | function getTTYPE() {
515 | if (isEnabled(TTYPE)) {
516 | TERM.socket.writeByte(IAC);
517 | TERM.socket.writeByte(SB);
518 | TERM.socket.writeByte(TTYPE);
519 | TERM.socket.writeByte(SEND);
520 | TERM.socket.writeByte(IAC);
521 | TERM.socket.writeByte(SE);
522 | }
523 | };
524 |
525 | function negotiateLineMode() {
526 | if (isEnabled(LINEMODE)) {
527 | TERM.socket.writeByte(IAC);
528 | TERM.socket.writeByte(SB);
529 | TERM.socket.writeByte(LINEMODE);
530 | TERM.socket.writeByte(LM_MODE);
531 | TERM.socket.writeByte(LM_EDIT | LM_TRAPSIG);
532 | TERM.socket.writeByte(IAC);
533 | TERM.socket.writeByte(SE);
534 | WAIT_LM_MODE_ACK = true;
535 |
536 | TERM.socket.writeByte(IAC);
537 | TERM.socket.writeByte(SB);
538 | TERM.socket.writeByte(LINEMODE);
539 | TERM.socket.writeByte(DONT);
540 | TERM.socket.writeByte(LM_FORWARDMASK);
541 | TERM.socket.writeByte(IAC);
542 | TERM.socket.writeByte(SE);
543 | WAIT_LM_DO_REPLY_FORWARDMASK = true;
544 | }
545 | };
546 |
547 | function negotiateEnvironment() {
548 | if (isEnabled(NEWENV)) {
549 | ba.TERM.socket.writeByte(IAC);
550 | ba.TERM.socket.writeByte(SB);
551 | ba.TERM.socket.writeByte(NEWENV);
552 | ba.TERM.socket.writeByte(SEND);
553 | ba.TERM.socket.writeByte(NE_VAR);
554 | ba.TERM.socket.writeByte(NE_USERVAR);
555 | ba.TERM.socket.writeByte(IAC);
556 | ba.TERM.socket.writeByte(SE);
557 | WAIT_NE_SEND_REPLY = true;
558 | }
559 | };
560 |
561 | function skipToSE() {
562 | while (bytes.readUnsignedByte() != SE) ;
563 | };
564 |
565 | function readTriple(triple) {
566 | triple[0] = bytes.readUnsignedByte();
567 | triple[1] = bytes.readUnsignedByte();
568 | if ((triple[0] == IAC) && (triple[1] == SE)) {
569 | return false;
570 | } else {
571 | triple[2] = bytes.readUnsignedByte();
572 | return true;
573 | }
574 |
575 | return false;
576 | };
577 |
578 |
579 | function readIACSETerminatedString(maxlength) {
580 | var where = 0;
581 | var cbuf = [];
582 | var b = ' ';
583 | var cont = true;
584 |
585 | do {
586 | var i;
587 | i = bytes.readUnsignedByte();
588 | switch (i) {
589 | case IAC:
590 | i = bytes.readUnsignedByte();
591 | if (i == SE) {
592 | cont = false;
593 | }
594 | break;
595 | case -1:
596 | return ("default");
597 | default:
598 | }
599 | if (cont) {
600 | b = i.toString();
601 | if (b == '\n' || b == '\r' || where == maxlength) {
602 | cont = false;
603 | } else {
604 | cbuf[where++] = b;
605 | }
606 | }
607 | } while (cont);
608 |
609 | var str = "";
610 | for(var j=0; j this.cursor.maxColumnwidth * this.cursor.columnwidth){
57 | this.moveDown(1);
58 | this.cursor.carriageReturn();
59 | }
60 | };
61 |
62 | this.draw = function(charCode) {
63 | //console.log(charCode +" "+ this.cursor.x +" "+ this.cursor.y)
64 |
65 | ctx.fillStyle = this.cursor.backgroundColor;
66 | ctx.fillRect(this.cursor.x, this.cursor.y, font.width, font.height);
67 |
68 | ctx.drawImage(fontmap,
69 | charCode*(font.width+1), this.colorTable(this.cursor.foregroundColor)*font.height, font.width, font.height,
70 | this.cursor.x, this.cursor.y, font.width, font.height);
71 | };
72 |
73 | this.carriageReturn = function() {
74 | this.cursor.carriageReturn();
75 | };
76 |
77 | this.formFeed = function() {
78 | this.cursor.x = 0;
79 | this.cursor.y = 0;
80 | };
81 |
82 | this.moveBackward = function(val, erase) {
83 | var movements = val;
84 |
85 | while( movements > 0 ) {
86 | this.cursor.moveBackward(1);
87 | if(erase) this.draw(SPACE);
88 | movements--;
89 | }
90 | };
91 |
92 | this.moveDown = function(val) {
93 | if(this.cursor.y >= this.cursor.lineheight*(botMargin-1) && scroll){
94 | this.scrollUp(1);
95 | } else {
96 | this.cursor.moveDown(val);
97 | }
98 | };
99 |
100 | this.moveForward = function(val) {
101 | this.cursor.moveForward(val);
102 | };
103 |
104 | this.moveUp = function(val) {
105 | this.cursor.moveUp(val);
106 | };
107 |
108 | this.reposition = function(x, y) {
109 | this.cursor.x = x * this.cursor.columnwidth;
110 | this.cursor.y = y * this.cursor.lineheight;
111 | };
112 |
113 | this.restorePosition = function() {
114 | this.cursor.x = _savedPosition.x;
115 | this.cursor.y = _savedPosition.y;
116 | };
117 |
118 | this.savePosition = function() {
119 | _savedPosition.x = this.cursor.x;
120 | _savedPosition.y = this.cursor.y;
121 | };
122 |
123 | this.displayCleared = function() {
124 | ctx.fillStyle = BLACK_NORMAL;
125 | ctx.fillRect(0, 0, this.cursor.maxColumnwidth * this.cursor.columnwidth, this.cursor.maxLineheight * this.cursor.lineheight);
126 | };
127 |
128 | this.eraseUp = function() {
129 | ctx.fillStyle = BLACK_NORMAL;
130 | ctx.fillRect(0, 0, this.cursor.maxColumnwidth * this.cursor.columnwidth, this.cursor.y);
131 | };
132 |
133 | this.eraseScreen = function() {
134 | ctx.fillStyle = this.cursor.backgroundColor;
135 | ctx.fillRect(0, 0, this.cursor.maxColumnwidth * this.cursor.columnwidth, this.cursor.maxLineheight * this.cursor.lineheight);
136 | };
137 |
138 | this.eraseDown = function() {
139 | ctx.fillStyle = BLACK_NORMAL;
140 | ctx.fillRect(0, this.cursor.y, this.cursor.maxColumnwidth * this.cursor.columnwidth, (this.cursor.maxLineheight * this.cursor.lineheight) - this.cursor.y);
141 | };
142 |
143 | this.eraseEndOfLine = function() {
144 | ctx.fillStyle = BLACK_NORMAL;
145 | var w = (this.cursor.maxColumnwidth * this.cursor.columnwidth) - (this.cursor.x - this.cursor.columnwidth);
146 | ctx.fillRect(this.cursor.x, this.cursor.y, w, this.cursor.lineheight);
147 | };
148 |
149 | this.eraseStartOfLine = function() {
150 | ctx.fillStyle = BLACK_NORMAL;
151 | ctx.fillRect(0, this.cursor.y, this.cursor.x, this.cursor.lineheight);
152 | };
153 |
154 | this.eraseLine = function() {
155 | ctx.fillStyle = BLACK_NORMAL;
156 | ctx.fillRect(0, this.cursor.y, this.cursor.maxColumnwidth * this.cursor.columnwidth, this.cursor.lineheight);
157 | };
158 |
159 | this.backgroundColorChanged = function(color) {
160 | this.cursor.backgroundColor = color;
161 | };
162 |
163 | this.foregroundColorChanged = function(color) {
164 | this.cursor.foregroundColor = color;
165 | };
166 |
167 | this.home = function() {
168 | this.cursor.x = 0;
169 | this.cursor.y = (topMargin-1) * this.cursor.maxLineHeight;
170 | };
171 |
172 | this.scrollScreen = function(start, end) {
173 | topMargin = start;
174 | botMargin = end;
175 |
176 | handleHome();
177 | };
178 |
179 | this.scrollUp = function(val) {
180 | var canvasData = ctx.getImageData(0, topMargin * this.cursor.lineheight, this.cursor.maxColumnwidth*this.cursor.columnwidth, this.cursor.lineheight * (botMargin-topMargin));
181 | this.displayCleared();
182 | ctx.putImageData(canvasData, 0, this.cursor.lineheight*(topMargin-1));
183 | };
184 |
185 | this.clearCanvas();
186 |
187 | };
--------------------------------------------------------------------------------
/src/viewer/Cursor.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Peter Nitsch
3 | */
4 |
5 | TERM.Cursor = function (){
6 |
7 | this.foregroundColor = WHITE_NORMAL;
8 | this.backgroundColor = BLACK_NORMAL;
9 | this.position = new TERM.Point();
10 | this.maxColumnWidth = 80;
11 | this.maxLineHeight = 25;
12 | this.columnWidth = 8;
13 | this.lineHeight = 16;
14 | this.maxColumns = 80;
15 | this.infiniteWidth = false;
16 | this.infiniteHeight = false;
17 |
18 | this.moveForward = function(columns) {
19 | if( this.position.x + (columns*this.columnWidth) <= this.maxColumns * this.columnWidth )
20 | this.position.x = this.position.x + (columns*this.columnWidth);
21 | else
22 | this.position.x = (this.maxColumns * this.columnWidth) - this.columnWidth;
23 | };
24 |
25 | this.moveBackward = function(columns) {
26 | if( this.position.x - (columns*this.columnWidth) >= 0 )
27 | this.position.x = this.position.x - (columns*this.columnWidth);
28 | else
29 | this.position.x = 0;
30 | };
31 |
32 | this.moveDown = function(lines) {
33 | this.position.y = this.position.y + (lines*this.lineHeight);
34 | };
35 |
36 | this.moveUp = function(lines) {
37 | if( this.position.y - (lines*this.lineHeight) >= 0 )
38 | this.position.y = this.position.y - (lines*this.lineHeight);
39 | else
40 | this.position.y = 0;
41 | };
42 |
43 | this.carriageReturn = function() {
44 | this.position.x = 0;
45 | };
46 |
47 | };
48 |
49 | TERM.Cursor.prototype = {
50 |
51 | get x (){
52 | return this.position.x;
53 | },
54 | set x (val){
55 | this.position.x = val;
56 | },
57 |
58 | get y (){
59 | return this.position.y;
60 | },
61 | set y (val){
62 | this.position.y = val;
63 | }
64 |
65 | };
--------------------------------------------------------------------------------
/src/viewer/Font.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Peter Nitsch
3 | */
4 |
5 | TERM.Font = function() {
6 |
7 | this.width = 8;
8 | this.height = 16;
9 | this.lineHeight = 23;
10 |
11 | };
--------------------------------------------------------------------------------
/src/viewer/Point.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Peter Nitsch
3 | */
4 |
5 | TERM.Point = function() {
6 |
7 | this.x = 0;
8 | this.y = 0;
9 |
10 | };
--------------------------------------------------------------------------------