novac 2.0.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1574 -597
  3. package/bin/novac +468 -171
  4. package/bin/nvc +522 -0
  5. package/bin/nvml +78 -17
  6. package/demo.nv +0 -0
  7. package/demo_builtins.nv +0 -0
  8. package/demo_http.nv +0 -0
  9. package/examples/bf.nv +69 -0
  10. package/examples/math.nv +21 -0
  11. package/kits/birdAPI/kitdef.js +954 -0
  12. package/kits/kitRNG/kitdef.js +740 -0
  13. package/kits/kitSSH/kitdef.js +1272 -0
  14. package/kits/kitadb/kitdef.js +606 -0
  15. package/kits/kitai/kitdef.js +2185 -0
  16. package/kits/kitansi/kitdef.js +1402 -0
  17. package/kits/kitcanvas/kitdef.js +914 -0
  18. package/kits/kitclippy/kitdef.js +925 -0
  19. package/kits/kitformat/kitdef.js +1485 -0
  20. package/kits/kitgps/kitdef.js +1862 -0
  21. package/kits/kitlibproc/kitdef.js +3 -2
  22. package/kits/kitmatrix/ex.js +19 -0
  23. package/kits/kitmatrix/kitdef.js +960 -0
  24. package/kits/kitmorse/kitdef.js +229 -0
  25. package/kits/kitmpatch/kitdef.js +906 -0
  26. package/kits/kitnet/kitdef.js +1401 -0
  27. package/kits/kitnovacweb/README.md +1416 -143
  28. package/kits/kitnovacweb/kitdef.js +92 -2
  29. package/kits/kitnovacweb/nvml/executor.js +578 -176
  30. package/kits/kitnovacweb/nvml/index.js +2 -2
  31. package/kits/kitnovacweb/nvml/lexer.js +72 -69
  32. package/kits/kitnovacweb/nvml/parser.js +328 -159
  33. package/kits/kitnovacweb/nvml/renderer.js +770 -270
  34. package/kits/kitparse/kitdef.js +1688 -0
  35. package/kits/kitproto/kitdef.js +613 -0
  36. package/kits/kitqr/kitdef.js +637 -0
  37. package/kits/kitregex++/kitdef.js +1353 -0
  38. package/kits/kitrequire/kitdef.js +1599 -0
  39. package/kits/kitx11/kitdef.js +1 -0
  40. package/kits/kitx11/kitx11.js +2472 -0
  41. package/kits/kitx11/kitx11_conn.js +948 -0
  42. package/kits/kitx11/kitx11_worker.js +121 -0
  43. package/kits/libtea/kitdef.js +2691 -0
  44. package/kits/libterm/ex.js +285 -0
  45. package/kits/libterm/kitdef.js +1927 -0
  46. package/novac/LICENSE +21 -0
  47. package/novac/README.md +1823 -0
  48. package/novac/bin/novac +950 -0
  49. package/novac/bin/nvc +522 -0
  50. package/novac/bin/nvml +542 -0
  51. package/novac/demo.nv +245 -0
  52. package/novac/demo_builtins.nv +209 -0
  53. package/novac/demo_http.nv +62 -0
  54. package/novac/examples/bf.nv +69 -0
  55. package/novac/examples/math.nv +21 -0
  56. package/novac/kits/kitai/kitdef.js +2185 -0
  57. package/novac/kits/kitansi/kitdef.js +1402 -0
  58. package/novac/kits/kitformat/kitdef.js +1485 -0
  59. package/novac/kits/kitgps/kitdef.js +1862 -0
  60. package/novac/kits/kitlibfs/kitdef.js +231 -0
  61. package/{examples/example-project/nova_modules → novac/kits}/kitlibproc/kitdef.js +3 -2
  62. package/novac/kits/kitmatrix/ex.js +19 -0
  63. package/novac/kits/kitmatrix/kitdef.js +960 -0
  64. package/novac/kits/kitmpatch/kitdef.js +906 -0
  65. package/novac/kits/kitnovacweb/README.md +1572 -0
  66. package/novac/kits/kitnovacweb/demo.nv +12 -0
  67. package/novac/kits/kitnovacweb/demo.nvml +71 -0
  68. package/novac/kits/kitnovacweb/index.nova +12 -0
  69. package/novac/kits/kitnovacweb/kitdef.js +692 -0
  70. package/novac/kits/kitnovacweb/nova.kit.json +8 -0
  71. package/novac/kits/kitnovacweb/nvml/executor.js +739 -0
  72. package/novac/kits/kitnovacweb/nvml/index.js +67 -0
  73. package/novac/kits/kitnovacweb/nvml/lexer.js +263 -0
  74. package/novac/kits/kitnovacweb/nvml/parser.js +508 -0
  75. package/novac/kits/kitnovacweb/nvml/renderer.js +924 -0
  76. package/novac/kits/kitparse/kitdef.js +1688 -0
  77. package/novac/kits/kitregex++/kitdef.js +1353 -0
  78. package/novac/kits/kitrequire/kitdef.js +1599 -0
  79. package/novac/kits/kitx11/kitdef.js +1 -0
  80. package/novac/kits/kitx11/kitx11.js +2472 -0
  81. package/novac/kits/kitx11/kitx11_conn.js +948 -0
  82. package/novac/kits/kitx11/kitx11_worker.js +121 -0
  83. package/novac/kits/libtea/tf.js +2691 -0
  84. package/novac/kits/libterm/ex.js +285 -0
  85. package/novac/kits/libterm/kitdef.js +1927 -0
  86. package/novac/node_modules/chalk/license +9 -0
  87. package/novac/node_modules/chalk/package.json +83 -0
  88. package/novac/node_modules/chalk/readme.md +297 -0
  89. package/novac/node_modules/chalk/source/index.d.ts +325 -0
  90. package/novac/node_modules/chalk/source/index.js +225 -0
  91. package/novac/node_modules/chalk/source/utilities.js +33 -0
  92. package/novac/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
  93. package/novac/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
  94. package/novac/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
  95. package/novac/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
  96. package/novac/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
  97. package/novac/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
  98. package/novac/node_modules/commander/LICENSE +22 -0
  99. package/novac/node_modules/commander/Readme.md +1176 -0
  100. package/novac/node_modules/commander/esm.mjs +16 -0
  101. package/novac/node_modules/commander/index.js +24 -0
  102. package/novac/node_modules/commander/lib/argument.js +150 -0
  103. package/novac/node_modules/commander/lib/command.js +2777 -0
  104. package/novac/node_modules/commander/lib/error.js +39 -0
  105. package/novac/node_modules/commander/lib/help.js +747 -0
  106. package/novac/node_modules/commander/lib/option.js +380 -0
  107. package/novac/node_modules/commander/lib/suggestSimilar.js +101 -0
  108. package/novac/node_modules/commander/package-support.json +19 -0
  109. package/novac/node_modules/commander/package.json +82 -0
  110. package/novac/node_modules/commander/typings/esm.d.mts +3 -0
  111. package/novac/node_modules/commander/typings/index.d.ts +1113 -0
  112. package/novac/node_modules/node-addon-api/LICENSE.md +9 -0
  113. package/novac/node_modules/node-addon-api/README.md +95 -0
  114. package/novac/node_modules/node-addon-api/common.gypi +21 -0
  115. package/novac/node_modules/node-addon-api/except.gypi +25 -0
  116. package/novac/node_modules/node-addon-api/index.js +14 -0
  117. package/novac/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
  118. package/novac/node_modules/node-addon-api/napi-inl.h +7165 -0
  119. package/novac/node_modules/node-addon-api/napi.h +3364 -0
  120. package/novac/node_modules/node-addon-api/node_addon_api.gyp +42 -0
  121. package/novac/node_modules/node-addon-api/node_api.gyp +9 -0
  122. package/novac/node_modules/node-addon-api/noexcept.gypi +26 -0
  123. package/novac/node_modules/node-addon-api/package-support.json +21 -0
  124. package/novac/node_modules/node-addon-api/package.json +480 -0
  125. package/novac/node_modules/node-addon-api/tools/README.md +73 -0
  126. package/novac/node_modules/node-addon-api/tools/check-napi.js +99 -0
  127. package/novac/node_modules/node-addon-api/tools/clang-format.js +71 -0
  128. package/novac/node_modules/node-addon-api/tools/conversion.js +301 -0
  129. package/novac/node_modules/serialize-javascript/LICENSE +27 -0
  130. package/novac/node_modules/serialize-javascript/README.md +149 -0
  131. package/novac/node_modules/serialize-javascript/index.js +297 -0
  132. package/novac/node_modules/serialize-javascript/package.json +33 -0
  133. package/novac/package.json +27 -0
  134. package/novac/scripts/update-bin.js +24 -0
  135. package/novac/src/core/bstd.js +1035 -0
  136. package/novac/src/core/config.js +155 -0
  137. package/novac/src/core/describe.js +187 -0
  138. package/novac/src/core/emitter.js +499 -0
  139. package/novac/src/core/error.js +86 -0
  140. package/novac/src/core/executor.js +5606 -0
  141. package/novac/src/core/formatter.js +686 -0
  142. package/novac/src/core/lexer.js +1026 -0
  143. package/novac/src/core/nova_builtins.js +717 -0
  144. package/novac/src/core/nova_thread_worker.js +166 -0
  145. package/novac/src/core/parser.js +2181 -0
  146. package/novac/src/core/types.js +112 -0
  147. package/novac/src/index.js +28 -0
  148. package/novac/src/runtime/stdlib.js +244 -0
  149. package/package.json +6 -3
  150. package/scripts/update-bin.js +0 -0
  151. package/src/core/bstd.js +838 -362
  152. package/src/core/executor.js +2578 -170
  153. package/src/core/lexer.js +502 -54
  154. package/src/core/nova_builtins.js +21 -3
  155. package/src/core/parser.js +413 -72
  156. package/src/core/types.js +30 -2
  157. package/src/index.js +0 -0
  158. package/examples/example-project/README.md +0 -3
  159. package/examples/example-project/src/main.nova +0 -3
  160. package/src/core/environment.js +0 -0
  161. /package/{examples/example-project/bin/example-project.nv → novac/node_modules/node-addon-api/nothing.c} +0 -0
@@ -0,0 +1,2472 @@
1
+ 'use strict';
2
+
3
+ // ============================================================
4
+ // kitx11.js — Full X11 / Xlib reference in JavaScript
5
+ // Every constant, every atom, every keysym, every color.
6
+ //
7
+ // Cross-platform fixes applied:
8
+ // 1. Runtime byte-order detection — works on big-endian hosts.
9
+ // 2. buildConnectionRequest supports MIT-MAGIC-COOKIE-1 auth.
10
+ // 3. Extension negotiation helper (queryExtension / assertExtension).
11
+ // 4. Dual CJS + ESM export shim — works in Node.js and browsers.
12
+ //
13
+ // Exports (CJS): const { kitdef } = require('./kitx11.js')
14
+ // Exports (ESM): import { kitdef } from './kitx11.js'
15
+ // ============================================================
16
+
17
+ // ────────────────────────────────────────────────────────────
18
+ // SECTION 1: PROTOCOL FUNDAMENTALS
19
+ // ────────────────────────────────────────────────────────────
20
+
21
+ /** X11 protocol version */
22
+ const PROTOCOL = { MAJOR: 11, MINOR: 0 };
23
+
24
+ /** X11 connection byte order markers */
25
+ const ByteOrder = { LSB_FIRST: 0x6C, MSB_FIRST: 0x42 }; // 'l' and 'B'
26
+
27
+ /** Special resource IDs */
28
+ const XID = {
29
+ NONE: 0,
30
+ COPY_FROM_PARENT: 0,
31
+ PARENT_RELATIVE: 1,
32
+ ALL_TEMPORARY: 2,
33
+ };
34
+
35
+ /** Boolean constants */
36
+ const XBool = { FALSE: 0, TRUE: 1 };
37
+
38
+ /** Time constants */
39
+ const Time = {
40
+ CURRENT_TIME: 0,
41
+ LAST_KNOWN_TIME:1,
42
+ };
43
+
44
+ // ────────────────────────────────────────────────────────────
45
+ // SECTION 2: EVENT TYPES
46
+ // ────────────────────────────────────────────────────────────
47
+
48
+ const EventType = {
49
+ KEY_PRESS: 2,
50
+ KEY_RELEASE: 3,
51
+ BUTTON_PRESS: 4,
52
+ BUTTON_RELEASE: 5,
53
+ MOTION_NOTIFY: 6,
54
+ ENTER_NOTIFY: 7,
55
+ LEAVE_NOTIFY: 8,
56
+ FOCUS_IN: 9,
57
+ FOCUS_OUT: 10,
58
+ KEYMAP_NOTIFY: 11,
59
+ EXPOSE: 12,
60
+ GRAPHICS_EXPOSE: 13,
61
+ NO_EXPOSE: 14,
62
+ VISIBILITY_NOTIFY: 15,
63
+ CREATE_NOTIFY: 16,
64
+ DESTROY_NOTIFY: 17,
65
+ UNMAP_NOTIFY: 18,
66
+ MAP_NOTIFY: 19,
67
+ MAP_REQUEST: 20,
68
+ REPARENT_NOTIFY: 21,
69
+ CONFIGURE_NOTIFY: 22,
70
+ CONFIGURE_REQUEST: 23,
71
+ GRAVITY_NOTIFY: 24,
72
+ RESIZE_REQUEST: 25,
73
+ CIRCULATE_NOTIFY: 26,
74
+ CIRCULATE_REQUEST: 27,
75
+ PROPERTY_NOTIFY: 28,
76
+ SELECTION_CLEAR: 29,
77
+ SELECTION_REQUEST: 30,
78
+ SELECTION_NOTIFY: 31,
79
+ COLORMAP_NOTIFY: 32,
80
+ CLIENT_MESSAGE: 33,
81
+ MAPPING_NOTIFY: 34,
82
+ GENERIC_EVENT: 35,
83
+ LAST_EVENT: 36,
84
+ };
85
+
86
+ /** Reverse map: event number → name */
87
+ const EventTypeName = Object.fromEntries(Object.entries(EventType).map(([k,v])=>[v,k]));
88
+
89
+ // ────────────────────────────────────────────────────────────
90
+ // SECTION 3: EVENT MASKS
91
+ // ────────────────────────────────────────────────────────────
92
+
93
+ const EventMask = {
94
+ NO_EVENT_MASK: 0,
95
+ KEY_PRESS_MASK: (1 << 0),
96
+ KEY_RELEASE_MASK: (1 << 1),
97
+ BUTTON_PRESS_MASK: (1 << 2),
98
+ BUTTON_RELEASE_MASK: (1 << 3),
99
+ ENTER_WINDOW_MASK: (1 << 4),
100
+ LEAVE_WINDOW_MASK: (1 << 5),
101
+ POINTER_MOTION_MASK: (1 << 6),
102
+ POINTER_MOTION_HINT_MASK: (1 << 7),
103
+ BUTTON1_MOTION_MASK: (1 << 8),
104
+ BUTTON2_MOTION_MASK: (1 << 9),
105
+ BUTTON3_MOTION_MASK: (1 << 10),
106
+ BUTTON4_MOTION_MASK: (1 << 11),
107
+ BUTTON5_MOTION_MASK: (1 << 12),
108
+ BUTTON_MOTION_MASK: (1 << 13),
109
+ KEYMAP_STATE_MASK: (1 << 14),
110
+ EXPOSURE_MASK: (1 << 15),
111
+ VISIBILITY_CHANGE_MASK: (1 << 16),
112
+ STRUCTURE_NOTIFY_MASK: (1 << 17),
113
+ RESIZE_REDIRECT_MASK: (1 << 18),
114
+ SUBSTRUCTURE_NOTIFY_MASK: (1 << 19),
115
+ SUBSTRUCTURE_REDIRECT_MASK: (1 << 20),
116
+ FOCUS_CHANGE_MASK: (1 << 21),
117
+ PROPERTY_CHANGE_MASK: (1 << 22),
118
+ COLORMAP_CHANGE_MASK: (1 << 23),
119
+ OWNER_GRAB_BUTTON_MASK: (1 << 24),
120
+ };
121
+
122
+ /** Decode an event mask bitmask into an array of flag names */
123
+ function decodeEventMask(mask) {
124
+ return Object.entries(EventMask).filter(([,v]) => v && (mask & v) === v).map(([k]) => k);
125
+ }
126
+
127
+ // ────────────────────────────────────────────────────────────
128
+ // SECTION 4: REQUEST OPCODES
129
+ // ────────────────────────────────────────────────────────────
130
+
131
+ const Request = {
132
+ CREATE_WINDOW: 1,
133
+ CHANGE_WINDOW_ATTRIBUTES: 2,
134
+ GET_WINDOW_ATTRIBUTES: 3,
135
+ DESTROY_WINDOW: 4,
136
+ DESTROY_SUBWINDOWS: 5,
137
+ CHANGE_SAVE_SET: 6,
138
+ REPARENT_WINDOW: 7,
139
+ MAP_WINDOW: 8,
140
+ MAP_SUBWINDOWS: 9,
141
+ UNMAP_WINDOW: 10,
142
+ UNMAP_SUBWINDOWS: 11,
143
+ CONFIGURE_WINDOW: 12,
144
+ CIRCULATE_WINDOW: 13,
145
+ GET_GEOMETRY: 14,
146
+ QUERY_TREE: 15,
147
+ INTERN_ATOM: 16,
148
+ GET_ATOM_NAME: 17,
149
+ CHANGE_PROPERTY: 18,
150
+ DELETE_PROPERTY: 19,
151
+ GET_PROPERTY: 20,
152
+ LIST_PROPERTIES: 21,
153
+ SET_SELECTION_OWNER: 22,
154
+ GET_SELECTION_OWNER: 23,
155
+ CONVERT_SELECTION: 24,
156
+ SEND_EVENT: 25,
157
+ GRAB_POINTER: 26,
158
+ UNGRAB_POINTER: 27,
159
+ GRAB_BUTTON: 28,
160
+ UNGRAB_BUTTON: 29,
161
+ CHANGE_ACTIVE_POINTER_GRAB: 30,
162
+ GRAB_KEYBOARD: 31,
163
+ UNGRAB_KEYBOARD: 32,
164
+ GRAB_KEY: 33,
165
+ UNGRAB_KEY: 34,
166
+ ALLOW_EVENTS: 35,
167
+ GRAB_SERVER: 36,
168
+ UNGRAB_SERVER: 37,
169
+ QUERY_POINTER: 38,
170
+ GET_MOTION_EVENTS: 39,
171
+ TRANSLATE_COORDINATES: 40,
172
+ WARP_POINTER: 41,
173
+ SET_INPUT_FOCUS: 42,
174
+ GET_INPUT_FOCUS: 43,
175
+ QUERY_KEYMAP: 44,
176
+ OPEN_FONT: 45,
177
+ CLOSE_FONT: 46,
178
+ QUERY_FONT: 47,
179
+ QUERY_TEXT_EXTENTS: 48,
180
+ LIST_FONTS: 49,
181
+ LIST_FONTS_WITH_INFO: 50,
182
+ SET_FONT_PATH: 51,
183
+ GET_FONT_PATH: 52,
184
+ CREATE_PIXMAP: 53,
185
+ FREE_PIXMAP: 54,
186
+ CREATE_GC: 55,
187
+ CHANGE_GC: 56,
188
+ COPY_GC: 57,
189
+ SET_DASHES: 58,
190
+ SET_CLIP_RECTANGLES: 59,
191
+ FREE_GC: 60,
192
+ CLEAR_AREA: 61,
193
+ COPY_AREA: 62,
194
+ COPY_PLANE: 63,
195
+ POLY_POINT: 64,
196
+ POLY_LINE: 65,
197
+ POLY_SEGMENT: 66,
198
+ POLY_RECTANGLE: 67,
199
+ POLY_ARC: 68,
200
+ FILL_POLY: 69,
201
+ POLY_FILL_RECTANGLE: 70,
202
+ POLY_FILL_ARC: 71,
203
+ PUT_IMAGE: 72,
204
+ GET_IMAGE: 73,
205
+ POLY_TEXT_8: 74,
206
+ POLY_TEXT_16: 75,
207
+ IMAGE_TEXT_8: 76,
208
+ IMAGE_TEXT_16: 77,
209
+ CREATE_COLORMAP: 78,
210
+ FREE_COLORMAP: 79,
211
+ COPY_COLORMAP_AND_FREE: 80,
212
+ INSTALL_COLORMAP: 81,
213
+ UNINSTALL_COLORMAP: 82,
214
+ LIST_INSTALLED_COLORMAPS: 83,
215
+ ALLOC_COLOR: 84,
216
+ ALLOC_NAMED_COLOR: 85,
217
+ ALLOC_COLOR_CELLS: 86,
218
+ ALLOC_COLOR_PLANES: 87,
219
+ FREE_COLORS: 88,
220
+ STORE_COLORS: 89,
221
+ STORE_NAMED_COLOR: 90,
222
+ QUERY_COLORS: 91,
223
+ LOOKUP_COLOR: 92,
224
+ CREATE_CURSOR: 93,
225
+ CREATE_GLYPH_CURSOR: 94,
226
+ FREE_CURSOR: 95,
227
+ RECOLOR_CURSOR: 96,
228
+ QUERY_BEST_SIZE: 97,
229
+ QUERY_EXTENSION: 98,
230
+ LIST_EXTENSIONS: 99,
231
+ CHANGE_KEYBOARD_MAPPING: 100,
232
+ GET_KEYBOARD_MAPPING: 101,
233
+ CHANGE_KEYBOARD_CONTROL: 102,
234
+ GET_KEYBOARD_CONTROL: 103,
235
+ BELL: 104,
236
+ CHANGE_POINTER_CONTROL: 105,
237
+ GET_POINTER_CONTROL: 106,
238
+ SET_SCREEN_SAVER: 107,
239
+ GET_SCREEN_SAVER: 108,
240
+ CHANGE_HOSTS: 109,
241
+ LIST_HOSTS: 110,
242
+ SET_ACCESS_CONTROL: 111,
243
+ SET_CLOSE_DOWN_MODE: 112,
244
+ KILL_CLIENT: 113,
245
+ ROTATE_PROPERTIES: 114,
246
+ FORCE_SCREEN_SAVER: 115,
247
+ SET_POINTER_MAPPING: 116,
248
+ GET_POINTER_MAPPING: 117,
249
+ SET_MODIFIER_MAPPING: 118,
250
+ GET_MODIFIER_MAPPING: 119,
251
+ NO_OPERATION: 127,
252
+ };
253
+
254
+ const RequestName = Object.fromEntries(Object.entries(Request).map(([k,v])=>[v,k]));
255
+
256
+ // ────────────────────────────────────────────────────────────
257
+ // SECTION 5: ERROR CODES
258
+ // ────────────────────────────────────────────────────────────
259
+
260
+ const ErrorCode = {
261
+ SUCCESS: 0,
262
+ BAD_REQUEST: 1,
263
+ BAD_VALUE: 2,
264
+ BAD_WINDOW: 3,
265
+ BAD_PIXMAP: 4,
266
+ BAD_ATOM: 5,
267
+ BAD_CURSOR: 6,
268
+ BAD_FONT: 7,
269
+ BAD_MATCH: 8,
270
+ BAD_DRAWABLE: 9,
271
+ BAD_ACCESS: 10,
272
+ BAD_ALLOC: 11,
273
+ BAD_COLOR: 12,
274
+ BAD_GC: 13,
275
+ BAD_ID_CHOICE: 14,
276
+ BAD_NAME: 15,
277
+ BAD_LENGTH: 16,
278
+ BAD_IMPLEMENTATION:17,
279
+ FIRST_EXTENSION_ERROR: 128,
280
+ LAST_EXTENSION_ERROR: 255,
281
+ };
282
+
283
+ const ErrorName = Object.fromEntries(Object.entries(ErrorCode).map(([k,v])=>[v,k]));
284
+
285
+ // ────────────────────────────────────────────────────────────
286
+ // SECTION 6: WINDOW ATTRIBUTES & VALUES
287
+ // ────────────────────────────────────────────────────────────
288
+
289
+ /** Window attribute value masks (CW_ flags) */
290
+ const CW = {
291
+ BACK_PIXMAP: (1 << 0),
292
+ BACK_PIXEL: (1 << 1),
293
+ BORDER_PIXMAP: (1 << 2),
294
+ BORDER_PIXEL: (1 << 3),
295
+ BIT_GRAVITY: (1 << 4),
296
+ WIN_GRAVITY: (1 << 5),
297
+ BACKING_STORE: (1 << 6),
298
+ BACKING_PLANES: (1 << 7),
299
+ BACKING_PIXEL: (1 << 8),
300
+ OVERRIDE_REDIRECT: (1 << 9),
301
+ SAVE_UNDER: (1 << 10),
302
+ EVENT_MASK: (1 << 11),
303
+ DONT_PROPAGATE: (1 << 12),
304
+ COLORMAP: (1 << 13),
305
+ CURSOR: (1 << 14),
306
+ };
307
+
308
+ /** Window classes */
309
+ const WindowClass = {
310
+ COPY_FROM_PARENT: 0,
311
+ INPUT_OUTPUT: 1,
312
+ INPUT_ONLY: 2,
313
+ };
314
+
315
+ /** Map state */
316
+ const MapState = {
317
+ IS_UNMAPPED: 0,
318
+ IS_UNVIEWABLE: 1,
319
+ IS_VIEWABLE: 2,
320
+ };
321
+
322
+ /** Backing store */
323
+ const BackingStore = {
324
+ NOT_USEFUL: 0,
325
+ WHEN_MAPPED: 1,
326
+ ALWAYS: 2,
327
+ };
328
+
329
+ /** Bit gravity */
330
+ const BitGravity = {
331
+ FORGET: 0,
332
+ NORTH_WEST:1,
333
+ NORTH: 2,
334
+ NORTH_EAST:3,
335
+ WEST: 4,
336
+ CENTER: 5,
337
+ EAST: 6,
338
+ SOUTH_WEST:7,
339
+ SOUTH: 8,
340
+ SOUTH_EAST:9,
341
+ STATIC: 10,
342
+ };
343
+
344
+ /** Window gravity */
345
+ const WinGravity = {
346
+ UNMAP: 0,
347
+ NORTH_WEST:1,
348
+ NORTH: 2,
349
+ NORTH_EAST:3,
350
+ WEST: 4,
351
+ CENTER: 5,
352
+ EAST: 6,
353
+ SOUTH_WEST:7,
354
+ SOUTH: 8,
355
+ SOUTH_EAST:9,
356
+ STATIC: 10,
357
+ };
358
+
359
+ // ────────────────────────────────────────────────────────────
360
+ // SECTION 7: GC (GRAPHICS CONTEXT) VALUES
361
+ // ────────────────────────────────────────────────────────────
362
+
363
+ /** GC value masks */
364
+ const GCMask = {
365
+ FUNCTION: (1 << 0),
366
+ PLANE_MASK: (1 << 1),
367
+ FOREGROUND: (1 << 2),
368
+ BACKGROUND: (1 << 3),
369
+ LINE_WIDTH: (1 << 4),
370
+ LINE_STYLE: (1 << 5),
371
+ CAP_STYLE: (1 << 6),
372
+ JOIN_STYLE: (1 << 7),
373
+ FILL_STYLE: (1 << 8),
374
+ FILL_RULE: (1 << 9),
375
+ TILE: (1 << 10),
376
+ STIPPLE: (1 << 11),
377
+ TILE_STIPPLE_X_ORIGIN:(1 << 12),
378
+ TILE_STIPPLE_Y_ORIGIN:(1 << 13),
379
+ FONT: (1 << 14),
380
+ SUBWINDOW_MODE: (1 << 15),
381
+ GRAPHICS_EXPOSURES: (1 << 16),
382
+ CLIP_X_ORIGIN: (1 << 17),
383
+ CLIP_Y_ORIGIN: (1 << 18),
384
+ CLIP_MASK: (1 << 19),
385
+ DASH_OFFSET: (1 << 20),
386
+ DASH_LIST: (1 << 21),
387
+ ARC_MODE: (1 << 22),
388
+ LAST_GC: (1 << 23),
389
+ };
390
+
391
+ /** GC function (logical drawing operations) */
392
+ const GCFunction = {
393
+ CLEAR: 0, // 0
394
+ AND: 1, // src AND dst
395
+ AND_REVERSE: 2, // src AND NOT dst
396
+ COPY: 3, // src
397
+ AND_INVERTED: 4, // NOT src AND dst
398
+ NOOP: 5, // dst
399
+ XOR: 6, // src XOR dst
400
+ OR: 7, // src OR dst
401
+ NOR: 8, // NOT (src OR dst)
402
+ EQUIV: 9, // NOT (src XOR dst)
403
+ INVERT: 10, // NOT dst
404
+ OR_REVERSE: 11, // src OR NOT dst
405
+ COPY_INVERTED: 12, // NOT src
406
+ OR_INVERTED: 13, // NOT src OR dst
407
+ NAND: 14, // NOT (src AND dst)
408
+ SET: 15, // 1
409
+ };
410
+
411
+ /** Line style */
412
+ const LineStyle = {
413
+ SOLID: 0,
414
+ ON_OFF_DASH: 1,
415
+ DOUBLE_DASH: 2,
416
+ };
417
+
418
+ /** Cap style */
419
+ const CapStyle = {
420
+ NOT_LAST: 0,
421
+ BUTT: 1,
422
+ ROUND: 2,
423
+ PROJECTING:3,
424
+ };
425
+
426
+ /** Join style */
427
+ const JoinStyle = {
428
+ MITER: 0,
429
+ ROUND: 1,
430
+ BEVEL: 2,
431
+ };
432
+
433
+ /** Fill style */
434
+ const FillStyle = {
435
+ SOLID: 0,
436
+ TILED: 1,
437
+ STIPPLED: 2,
438
+ OPAQUE_STIPPLED:3,
439
+ };
440
+
441
+ /** Fill rule */
442
+ const FillRule = {
443
+ EVEN_ODD_RULE: 0,
444
+ WINDING_RULE: 1,
445
+ };
446
+
447
+ /** Arc mode */
448
+ const ArcMode = {
449
+ CHORD: 0,
450
+ PIE_SLICE: 1,
451
+ };
452
+
453
+ /** Subwindow mode */
454
+ const SubwindowMode = {
455
+ CLIP_BY_CHILDREN: 0,
456
+ INCLUDE_INFERIORS: 1,
457
+ };
458
+
459
+ // ────────────────────────────────────────────────────────────
460
+ // SECTION 8: POINTER / KEYBOARD / INPUT
461
+ // ────────────────────────────────────────────────────────────
462
+
463
+ /** Modifier key masks */
464
+ const ModifierMask = {
465
+ SHIFT_MASK: (1 << 0),
466
+ LOCK_MASK: (1 << 1),
467
+ CONTROL_MASK: (1 << 2),
468
+ MOD1_MASK: (1 << 3), // usually Alt
469
+ MOD2_MASK: (1 << 4), // usually NumLock
470
+ MOD3_MASK: (1 << 5),
471
+ MOD4_MASK: (1 << 6), // usually Super/Win
472
+ MOD5_MASK: (1 << 7), // usually AltGr
473
+ BUTTON1_MASK: (1 << 8),
474
+ BUTTON2_MASK: (1 << 9),
475
+ BUTTON3_MASK: (1 << 10),
476
+ BUTTON4_MASK: (1 << 11),
477
+ BUTTON5_MASK: (1 << 12),
478
+ ANY_MODIFIER: 0x8000,
479
+ };
480
+
481
+ /** Mouse button numbers */
482
+ const Button = { B1: 1, B2: 2, B3: 3, B4: 4, B5: 5, ANY: 0 };
483
+
484
+ /** Input focus modes */
485
+ const FocusMode = {
486
+ NORMAL: 0,
487
+ GRAB: 1,
488
+ UNGRAB: 2,
489
+ WHILE_GRABBED: 3,
490
+ };
491
+
492
+ /** Input focus revert-to */
493
+ const RevertTo = {
494
+ NONE: 0,
495
+ POINTER_ROOT: 1,
496
+ PARENT: 2,
497
+ };
498
+
499
+ /** Grab modes */
500
+ const GrabMode = {
501
+ SYNC: 0,
502
+ ASYNC: 1,
503
+ };
504
+
505
+ /** Grab status */
506
+ const GrabStatus = {
507
+ GRAB_SUCCESS: 0,
508
+ ALREADY_GRABBED: 1,
509
+ GRAB_INVALID_TIME:2,
510
+ GRAB_NOT_VIEWABLE:3,
511
+ GRAB_FROZEN: 4,
512
+ };
513
+
514
+ /** Allow-events modes */
515
+ const AllowEvents = {
516
+ ASYNC_POINTER: 0,
517
+ SYNC_POINTER: 1,
518
+ REPLAY_POINTER: 2,
519
+ ASYNC_KEYBOARD: 3,
520
+ SYNC_KEYBOARD: 4,
521
+ REPLAY_KEYBOARD: 5,
522
+ ASYNC_BOTH: 6,
523
+ SYNC_BOTH: 7,
524
+ };
525
+
526
+ /** Notify modes (EnterNotify, FocusIn, etc.) */
527
+ const NotifyMode = {
528
+ NORMAL: 0,
529
+ GRAB: 1,
530
+ UNGRAB: 2,
531
+ WHILE_GRABBED: 3,
532
+ };
533
+
534
+ /** Notify detail */
535
+ const NotifyDetail = {
536
+ ANCESTOR: 0,
537
+ VIRTUAL: 1,
538
+ INFERIOR: 2,
539
+ NONLINEAR: 3,
540
+ NONLINEAR_VIRTUAL: 4,
541
+ POINTER: 5,
542
+ POINTER_ROOT: 6,
543
+ DETAIL_NONE: 7,
544
+ };
545
+
546
+ /** Visibility state */
547
+ const Visibility = {
548
+ UNOBSCURED: 0,
549
+ PARTIALLY_OBSCURED:1,
550
+ FULLY_OBSCURED: 2,
551
+ };
552
+
553
+ /** Circulate direction */
554
+ const Circulate = {
555
+ RAISE_LOWEST: 0,
556
+ LOWER_HIGHEST: 1,
557
+ };
558
+
559
+ /** Property state (PropertyNotify) */
560
+ const PropertyState = {
561
+ NEW_VALUE: 0,
562
+ DELETED: 1,
563
+ };
564
+
565
+ /** Colormap state */
566
+ const ColormapState = {
567
+ UNINSTALLED: 0,
568
+ INSTALLED: 1,
569
+ };
570
+
571
+ /** Mapping request */
572
+ const MappingRequest = {
573
+ MODIFIER: 0,
574
+ KEYBOARD: 1,
575
+ POINTER: 2,
576
+ };
577
+
578
+ // ────────────────────────────────────────────────────────────
579
+ // SECTION 9: SCREEN SAVER & POWER
580
+ // ────────────────────────────────────────────────────────────
581
+
582
+ const ScreenSaver = {
583
+ RESET: 0,
584
+ ACTIVE: 1,
585
+ };
586
+
587
+ const ScreenSaverState = {
588
+ OFF: 0,
589
+ ON: 1,
590
+ CYCLE: 2,
591
+ DISABLED: 3,
592
+ };
593
+
594
+ const ScreenSaverKind = {
595
+ BLANKED: 0,
596
+ INTERNAL: 1,
597
+ EXTERNAL: 2,
598
+ };
599
+
600
+ const Blanking = {
601
+ DONT_PREFER_BLANKING: 0,
602
+ PREFER_BLANKING: 1,
603
+ DEFAULT_BLANKING: 2,
604
+ };
605
+
606
+ const Exposures = {
607
+ DONT_ALLOW_EXPOSURES: 0,
608
+ ALLOW_EXPOSURES: 1,
609
+ DEFAULT_EXPOSURES: 2,
610
+ };
611
+
612
+ // ────────────────────────────────────────────────────────────
613
+ // SECTION 10: HOST ACCESS
614
+ // ────────────────────────────────────────────────────────────
615
+
616
+ const HostFamily = {
617
+ INTERNET: 0,
618
+ DECnet: 1,
619
+ CHAOS: 2,
620
+ SERVER_INTERPRETED: 5,
621
+ INTERNET6: 6,
622
+ };
623
+
624
+ const AccessControl = {
625
+ DISABLE: 0,
626
+ ENABLE: 1,
627
+ };
628
+
629
+ const CloseDownMode = {
630
+ DESTROY_ALL: 0,
631
+ RETAIN_PERMANENT: 1,
632
+ RETAIN_TEMPORARY: 2,
633
+ };
634
+
635
+ // ────────────────────────────────────────────────────────────
636
+ // SECTION 11: COLORMAP
637
+ // ────────────────────────────────────────────────────────────
638
+
639
+ const ColormapAlloc = {
640
+ ALLOC_NONE: 0,
641
+ ALLOC_ALL: 1,
642
+ };
643
+
644
+ const VisualClass = {
645
+ STATIC_GRAY: 0,
646
+ GRAY_SCALE: 1,
647
+ STATIC_COLOR: 2,
648
+ PSEUDO_COLOR: 3,
649
+ TRUE_COLOR: 4,
650
+ DIRECT_COLOR: 5,
651
+ };
652
+
653
+ // ────────────────────────────────────────────────────────────
654
+ // SECTION 12: IMAGE / PIXMAP
655
+ // ────────────────────────────────────────────────────────────
656
+
657
+ const ImageFormat = {
658
+ XY_BITMAP: 0,
659
+ XY_PIXMAP: 1,
660
+ Z_PIXMAP: 2,
661
+ };
662
+
663
+ const BitmapBitOrder = {
664
+ LSB_FIRST: 0,
665
+ MSB_FIRST: 1,
666
+ };
667
+
668
+ const ByteOrderConst = {
669
+ LSB_FIRST: 0,
670
+ MSB_FIRST: 1,
671
+ };
672
+
673
+ const QueryBestSizeClass = {
674
+ CURSOR: 0,
675
+ TILE: 1,
676
+ STIPPLE:2,
677
+ };
678
+
679
+ // ────────────────────────────────────────────────────────────
680
+ // SECTION 13: BUILT-IN ATOMS
681
+ // ────────────────────────────────────────────────────────────
682
+
683
+ /** Predefined atom IDs (XA_ constants) */
684
+ const Atom = {
685
+ NONE: 0,
686
+ ANY: 0,
687
+ PRIMARY: 1,
688
+ SECONDARY: 2,
689
+ ARC: 3,
690
+ ATOM: 4,
691
+ BITMAP: 5,
692
+ CARDINAL: 6,
693
+ COLORMAP: 7,
694
+ CURSOR: 8,
695
+ CUT_BUFFER0: 9,
696
+ CUT_BUFFER1: 10,
697
+ CUT_BUFFER2: 11,
698
+ CUT_BUFFER3: 12,
699
+ CUT_BUFFER4: 13,
700
+ CUT_BUFFER5: 14,
701
+ CUT_BUFFER6: 15,
702
+ CUT_BUFFER7: 16,
703
+ DRAWABLE: 17,
704
+ FONT: 18,
705
+ INTEGER: 19,
706
+ PIXMAP: 20,
707
+ POINT: 21,
708
+ RECTANGLE: 22,
709
+ RESOURCE_MANAGER: 23,
710
+ RGB_COLOR_MAP: 24,
711
+ RGB_BEST_MAP: 25,
712
+ RGB_BLUE_MAP: 26,
713
+ RGB_DEFAULT_MAP: 27,
714
+ RGB_GRAY_MAP: 28,
715
+ RGB_GREEN_MAP: 29,
716
+ RGB_RED_MAP: 30,
717
+ STRING: 31,
718
+ VISUALID: 32,
719
+ WINDOW: 33,
720
+ WM_COMMAND: 34,
721
+ WM_HINTS: 35,
722
+ WM_CLIENT_MACHINE: 36,
723
+ WM_ICON_NAME: 37,
724
+ WM_ICON_SIZE: 38,
725
+ WM_NAME: 39,
726
+ WM_NORMAL_HINTS: 40,
727
+ WM_SIZE_HINTS: 41,
728
+ WM_ZOOM_HINTS: 42,
729
+ MIN_SPACE: 43,
730
+ NORM_SPACE: 44,
731
+ MAX_SPACE: 45,
732
+ END_SPACE: 46,
733
+ SUPERSCRIPT_X: 47,
734
+ SUPERSCRIPT_Y: 48,
735
+ SUBSCRIPT_X: 49,
736
+ SUBSCRIPT_Y: 50,
737
+ UNDERLINE_POSITION: 51,
738
+ UNDERLINE_THICKNESS:52,
739
+ STRIKEOUT_ASCENT: 53,
740
+ STRIKEOUT_DESCENT: 54,
741
+ ITALIC_ANGLE: 55,
742
+ X_HEIGHT: 56,
743
+ QUAD_WIDTH: 57,
744
+ WEIGHT: 58,
745
+ POINT_SIZE: 59,
746
+ RESOLUTION: 60,
747
+ COPYRIGHT: 61,
748
+ NOTICE: 62,
749
+ FONT_NAME: 63,
750
+ FAMILY_NAME: 64,
751
+ FULL_NAME: 65,
752
+ CAP_HEIGHT: 66,
753
+ WM_CLASS: 67,
754
+ WM_TRANSIENT_FOR: 68,
755
+ LAST_PREDEFINED: 68,
756
+ };
757
+
758
+ const AtomName = Object.fromEntries(Object.entries(Atom).map(([k,v])=>[v,k]));
759
+
760
+ // ────────────────────────────────────────────────────────────
761
+ // SECTION 14: ICCCM PROPERTY NAMES
762
+ // ────────────────────────────────────────────────────────────
763
+
764
+ /** ICCCM (Inter-Client Communication Conventions Manual) atom name strings */
765
+ const ICCCM = {
766
+ // WM Protocols
767
+ WM_PROTOCOLS: 'WM_PROTOCOLS',
768
+ WM_DELETE_WINDOW: 'WM_DELETE_WINDOW',
769
+ WM_TAKE_FOCUS: 'WM_TAKE_FOCUS',
770
+ WM_SAVE_YOURSELF: 'WM_SAVE_YOURSELF',
771
+
772
+ // Window manager hints
773
+ WM_NAME: 'WM_NAME',
774
+ WM_ICON_NAME: 'WM_ICON_NAME',
775
+ WM_NORMAL_HINTS: 'WM_NORMAL_HINTS',
776
+ WM_HINTS: 'WM_HINTS',
777
+ WM_CLASS: 'WM_CLASS',
778
+ WM_TRANSIENT_FOR: 'WM_TRANSIENT_FOR',
779
+ WM_COMMAND: 'WM_COMMAND',
780
+ WM_CLIENT_MACHINE: 'WM_CLIENT_MACHINE',
781
+ WM_ICON_SIZE: 'WM_ICON_SIZE',
782
+ WM_STATE: 'WM_STATE',
783
+ WM_CHANGE_STATE: 'WM_CHANGE_STATE',
784
+ WM_COLORMAP_WINDOWS: 'WM_COLORMAP_WINDOWS',
785
+ WM_COLORMAP_NOTIFY: 'WM_COLORMAP_NOTIFY',
786
+ WM_CLIENT_LEADER: 'WM_CLIENT_LEADER',
787
+ WM_WINDOW_ROLE: 'WM_WINDOW_ROLE',
788
+
789
+ // Selections
790
+ PRIMARY: 'PRIMARY',
791
+ SECONDARY: 'SECONDARY',
792
+ CLIPBOARD: 'CLIPBOARD',
793
+ CLIPBOARD_MANAGER: 'CLIPBOARD_MANAGER',
794
+ SAVE_TARGETS: 'SAVE_TARGETS',
795
+
796
+ // Selection targets
797
+ TARGETS: 'TARGETS',
798
+ MULTIPLE: 'MULTIPLE',
799
+ TIMESTAMP: 'TIMESTAMP',
800
+ INCR: 'INCR',
801
+ TEXT: 'TEXT',
802
+ COMPOUND_TEXT: 'COMPOUND_TEXT',
803
+ UTF8_STRING: 'UTF8_STRING',
804
+ STRING: 'STRING',
805
+
806
+ // Cut buffers
807
+ CUT_BUFFER0: 'CUT_BUFFER0',
808
+ CUT_BUFFER1: 'CUT_BUFFER1',
809
+ CUT_BUFFER2: 'CUT_BUFFER2',
810
+ CUT_BUFFER3: 'CUT_BUFFER3',
811
+ CUT_BUFFER4: 'CUT_BUFFER4',
812
+ CUT_BUFFER5: 'CUT_BUFFER5',
813
+ CUT_BUFFER6: 'CUT_BUFFER6',
814
+ CUT_BUFFER7: 'CUT_BUFFER7',
815
+
816
+ // Types
817
+ ATOM: 'ATOM',
818
+ CARDINAL: 'CARDINAL',
819
+ INTEGER: 'INTEGER',
820
+ WINDOW: 'WINDOW',
821
+ PIXMAP: 'PIXMAP',
822
+ BITMAP: 'BITMAP',
823
+ STRING: 'STRING',
824
+ };
825
+
826
+ /** WM_STATE values */
827
+ const WMState = {
828
+ WITHDRAWN: 0,
829
+ NORMAL: 1,
830
+ ICONIC: 3,
831
+ };
832
+
833
+ /** WM_HINTS flags */
834
+ const WMHints = {
835
+ INPUT_HINT: (1 << 0),
836
+ STATE_HINT: (1 << 1),
837
+ ICON_PIXMAP_HINT: (1 << 2),
838
+ ICON_WINDOW_HINT: (1 << 3),
839
+ ICON_POSITION_HINT: (1 << 4),
840
+ ICON_MASK_HINT: (1 << 5),
841
+ WINDOW_GROUP_HINT: (1 << 6),
842
+ MESSAGE_HINT: (1 << 7),
843
+ URGENCY_HINT: (1 << 8),
844
+ };
845
+
846
+ /** WM_SIZE_HINTS / WM_NORMAL_HINTS flags */
847
+ const SizeHints = {
848
+ US_POSITION: (1 << 0),
849
+ US_SIZE: (1 << 1),
850
+ P_POSITION: (1 << 2),
851
+ P_SIZE: (1 << 3),
852
+ P_MIN_SIZE: (1 << 4),
853
+ P_MAX_SIZE: (1 << 5),
854
+ P_RESIZE_INC: (1 << 6),
855
+ P_ASPECT: (1 << 7),
856
+ P_BASE_SIZE: (1 << 8),
857
+ P_WIN_GRAVITY: (1 << 9),
858
+ };
859
+
860
+ // ────────────────────────────────────────────────────────────
861
+ // SECTION 15: EWMH (_NET_) PROPERTY NAMES
862
+ // ────────────────────────────────────────────────────────────
863
+
864
+ /** Extended Window Manager Hints (EWMH / _NET_ atoms) */
865
+ const EWMH = {
866
+ // Root window properties
867
+ _NET_SUPPORTED: '_NET_SUPPORTED',
868
+ _NET_CLIENT_LIST: '_NET_CLIENT_LIST',
869
+ _NET_CLIENT_LIST_STACKING: '_NET_CLIENT_LIST_STACKING',
870
+ _NET_NUMBER_OF_DESKTOPS: '_NET_NUMBER_OF_DESKTOPS',
871
+ _NET_DESKTOP_GEOMETRY: '_NET_DESKTOP_GEOMETRY',
872
+ _NET_DESKTOP_VIEWPORT: '_NET_DESKTOP_VIEWPORT',
873
+ _NET_CURRENT_DESKTOP: '_NET_CURRENT_DESKTOP',
874
+ _NET_DESKTOP_NAMES: '_NET_DESKTOP_NAMES',
875
+ _NET_ACTIVE_WINDOW: '_NET_ACTIVE_WINDOW',
876
+ _NET_WORKAREA: '_NET_WORKAREA',
877
+ _NET_SUPPORTING_WM_CHECK: '_NET_SUPPORTING_WM_CHECK',
878
+ _NET_VIRTUAL_ROOTS: '_NET_VIRTUAL_ROOTS',
879
+ _NET_DESKTOP_LAYOUT: '_NET_DESKTOP_LAYOUT',
880
+ _NET_SHOWING_DESKTOP: '_NET_SHOWING_DESKTOP',
881
+
882
+ // Root window messages
883
+ _NET_CLOSE_WINDOW: '_NET_CLOSE_WINDOW',
884
+ _NET_MOVERESIZE_WINDOW: '_NET_MOVERESIZE_WINDOW',
885
+ _NET_WM_MOVERESIZE: '_NET_WM_MOVERESIZE',
886
+ _NET_RESTACK_WINDOW: '_NET_RESTACK_WINDOW',
887
+ _NET_REQUEST_FRAME_EXTENTS: '_NET_REQUEST_FRAME_EXTENTS',
888
+
889
+ // Application window properties
890
+ _NET_WM_NAME: '_NET_WM_NAME',
891
+ _NET_WM_VISIBLE_NAME: '_NET_WM_VISIBLE_NAME',
892
+ _NET_WM_ICON_NAME: '_NET_WM_ICON_NAME',
893
+ _NET_WM_VISIBLE_ICON_NAME: '_NET_WM_VISIBLE_ICON_NAME',
894
+ _NET_WM_DESKTOP: '_NET_WM_DESKTOP',
895
+ _NET_WM_WINDOW_TYPE: '_NET_WM_WINDOW_TYPE',
896
+ _NET_WM_STATE: '_NET_WM_STATE',
897
+ _NET_WM_ALLOWED_ACTIONS: '_NET_WM_ALLOWED_ACTIONS',
898
+ _NET_WM_STRUT: '_NET_WM_STRUT',
899
+ _NET_WM_STRUT_PARTIAL: '_NET_WM_STRUT_PARTIAL',
900
+ _NET_WM_ICON_GEOMETRY: '_NET_WM_ICON_GEOMETRY',
901
+ _NET_WM_ICON: '_NET_WM_ICON',
902
+ _NET_WM_PID: '_NET_WM_PID',
903
+ _NET_WM_HANDLED_ICONS: '_NET_WM_HANDLED_ICONS',
904
+ _NET_WM_USER_TIME: '_NET_WM_USER_TIME',
905
+ _NET_WM_USER_TIME_WINDOW: '_NET_WM_USER_TIME_WINDOW',
906
+ _NET_FRAME_EXTENTS: '_NET_FRAME_EXTENTS',
907
+ _NET_WM_OPAQUE_REGION: '_NET_WM_OPAQUE_REGION',
908
+ _NET_WM_BYPASS_COMPOSITOR: '_NET_WM_BYPASS_COMPOSITOR',
909
+
910
+ // Window types
911
+ _NET_WM_WINDOW_TYPE_DESKTOP: '_NET_WM_WINDOW_TYPE_DESKTOP',
912
+ _NET_WM_WINDOW_TYPE_DOCK: '_NET_WM_WINDOW_TYPE_DOCK',
913
+ _NET_WM_WINDOW_TYPE_TOOLBAR: '_NET_WM_WINDOW_TYPE_TOOLBAR',
914
+ _NET_WM_WINDOW_TYPE_MENU: '_NET_WM_WINDOW_TYPE_MENU',
915
+ _NET_WM_WINDOW_TYPE_UTILITY: '_NET_WM_WINDOW_TYPE_UTILITY',
916
+ _NET_WM_WINDOW_TYPE_SPLASH: '_NET_WM_WINDOW_TYPE_SPLASH',
917
+ _NET_WM_WINDOW_TYPE_DIALOG: '_NET_WM_WINDOW_TYPE_DIALOG',
918
+ _NET_WM_WINDOW_TYPE_DROPDOWN_MENU: '_NET_WM_WINDOW_TYPE_DROPDOWN_MENU',
919
+ _NET_WM_WINDOW_TYPE_POPUP_MENU:'_NET_WM_WINDOW_TYPE_POPUP_MENU',
920
+ _NET_WM_WINDOW_TYPE_TOOLTIP: '_NET_WM_WINDOW_TYPE_TOOLTIP',
921
+ _NET_WM_WINDOW_TYPE_NOTIFICATION:'_NET_WM_WINDOW_TYPE_NOTIFICATION',
922
+ _NET_WM_WINDOW_TYPE_COMBO: '_NET_WM_WINDOW_TYPE_COMBO',
923
+ _NET_WM_WINDOW_TYPE_DND: '_NET_WM_WINDOW_TYPE_DND',
924
+ _NET_WM_WINDOW_TYPE_NORMAL: '_NET_WM_WINDOW_TYPE_NORMAL',
925
+
926
+ // Window states
927
+ _NET_WM_STATE_MODAL: '_NET_WM_STATE_MODAL',
928
+ _NET_WM_STATE_STICKY: '_NET_WM_STATE_STICKY',
929
+ _NET_WM_STATE_MAXIMIZED_VERT: '_NET_WM_STATE_MAXIMIZED_VERT',
930
+ _NET_WM_STATE_MAXIMIZED_HORZ: '_NET_WM_STATE_MAXIMIZED_HORZ',
931
+ _NET_WM_STATE_SHADED: '_NET_WM_STATE_SHADED',
932
+ _NET_WM_STATE_SKIP_TASKBAR: '_NET_WM_STATE_SKIP_TASKBAR',
933
+ _NET_WM_STATE_SKIP_PAGER: '_NET_WM_STATE_SKIP_PAGER',
934
+ _NET_WM_STATE_HIDDEN: '_NET_WM_STATE_HIDDEN',
935
+ _NET_WM_STATE_FULLSCREEN: '_NET_WM_STATE_FULLSCREEN',
936
+ _NET_WM_STATE_ABOVE: '_NET_WM_STATE_ABOVE',
937
+ _NET_WM_STATE_BELOW: '_NET_WM_STATE_BELOW',
938
+ _NET_WM_STATE_DEMANDS_ATTENTION:'_NET_WM_STATE_DEMANDS_ATTENTION',
939
+ _NET_WM_STATE_FOCUSED: '_NET_WM_STATE_FOCUSED',
940
+
941
+ // Allowed actions
942
+ _NET_WM_ACTION_MOVE: '_NET_WM_ACTION_MOVE',
943
+ _NET_WM_ACTION_RESIZE: '_NET_WM_ACTION_RESIZE',
944
+ _NET_WM_ACTION_MINIMIZE: '_NET_WM_ACTION_MINIMIZE',
945
+ _NET_WM_ACTION_SHADE: '_NET_WM_ACTION_SHADE',
946
+ _NET_WM_ACTION_STICK: '_NET_WM_ACTION_STICK',
947
+ _NET_WM_ACTION_MAXIMIZE_HORZ: '_NET_WM_ACTION_MAXIMIZE_HORZ',
948
+ _NET_WM_ACTION_MAXIMIZE_VERT: '_NET_WM_ACTION_MAXIMIZE_VERT',
949
+ _NET_WM_ACTION_FULLSCREEN: '_NET_WM_ACTION_FULLSCREEN',
950
+ _NET_WM_ACTION_CHANGE_DESKTOP: '_NET_WM_ACTION_CHANGE_DESKTOP',
951
+ _NET_WM_ACTION_CLOSE: '_NET_WM_ACTION_CLOSE',
952
+ _NET_WM_ACTION_ABOVE: '_NET_WM_ACTION_ABOVE',
953
+ _NET_WM_ACTION_BELOW: '_NET_WM_ACTION_BELOW',
954
+
955
+ // WM identification
956
+ _NET_WM_FULL_PLACEMENT: '_NET_WM_FULL_PLACEMENT',
957
+ _NET_WM_PING: '_NET_WM_PING',
958
+ _NET_WM_SYNC_REQUEST: '_NET_WM_SYNC_REQUEST',
959
+ _NET_WM_SYNC_REQUEST_COUNTER: '_NET_WM_SYNC_REQUEST_COUNTER',
960
+ _NET_WM_FULLSCREEN_MONITORS: '_NET_WM_FULLSCREEN_MONITORS',
961
+
962
+ // Startup notification
963
+ _NET_STARTUP_ID: '_NET_STARTUP_ID',
964
+ _NET_STARTUP_INFO: '_NET_STARTUP_INFO',
965
+ _NET_STARTUP_INFO_BEGIN: '_NET_STARTUP_INFO_BEGIN',
966
+
967
+ // System tray
968
+ _NET_SYSTEM_TRAY_OPCODE: '_NET_SYSTEM_TRAY_OPCODE',
969
+ _NET_SYSTEM_TRAY_VISUAL: '_NET_SYSTEM_TRAY_VISUAL',
970
+ _NET_SYSTEM_TRAY_ORIENTATION: '_NET_SYSTEM_TRAY_ORIENTATION',
971
+
972
+ // Desktop layout
973
+ _NET_DESKTOP_LAYOUT_ORIENTATION_HORZ: '_NET_DESKTOP_LAYOUT_ORIENTATION_HORZ',
974
+ _NET_DESKTOP_LAYOUT_ORIENTATION_VERT: '_NET_DESKTOP_LAYOUT_ORIENTATION_VERT',
975
+ _NET_DESKTOP_LAYOUT_TOPLEFT: '_NET_DESKTOP_LAYOUT_TOPLEFT',
976
+ _NET_DESKTOP_LAYOUT_TOPRIGHT: '_NET_DESKTOP_LAYOUT_TOPRIGHT',
977
+ _NET_DESKTOP_LAYOUT_BOTTOMRIGHT:'_NET_DESKTOP_LAYOUT_BOTTOMRIGHT',
978
+ _NET_DESKTOP_LAYOUT_BOTTOMLEFT:'_NET_DESKTOP_LAYOUT_BOTTOMLEFT',
979
+ };
980
+
981
+ /** _NET_WM_STATE action values */
982
+ const EWMHStateAction = {
983
+ REMOVE: 0,
984
+ ADD: 1,
985
+ TOGGLE: 2,
986
+ };
987
+
988
+ /** _NET_WM_MOVERESIZE direction values */
989
+ const MoveResizeDirection = {
990
+ SIZE_TOPLEFT: 0,
991
+ SIZE_TOP: 1,
992
+ SIZE_TOPRIGHT: 2,
993
+ SIZE_RIGHT: 3,
994
+ SIZE_BOTTOMRIGHT: 4,
995
+ SIZE_BOTTOM: 5,
996
+ SIZE_BOTTOMLEFT: 6,
997
+ SIZE_LEFT: 7,
998
+ MOVE: 8,
999
+ SIZE_KEYBOARD: 9,
1000
+ MOVE_KEYBOARD: 10,
1001
+ CANCEL: 11,
1002
+ };
1003
+
1004
+ // ────────────────────────────────────────────────────────────
1005
+ // SECTION 16: SELECTION / PROPERTY TYPES
1006
+ // ────────────────────────────────────────────────────────────
1007
+
1008
+ const SelectionType = {
1009
+ PRIMARY: 'PRIMARY',
1010
+ SECONDARY: 'SECONDARY',
1011
+ CLIPBOARD: 'CLIPBOARD',
1012
+ };
1013
+
1014
+ /** Property change modes */
1015
+ const PropMode = {
1016
+ REPLACE: 0,
1017
+ PREPEND: 1,
1018
+ APPEND: 2,
1019
+ };
1020
+
1021
+ /** Property format sizes */
1022
+ const PropFormat = { F8: 8, F16: 16, F32: 32 };
1023
+
1024
+ // ────────────────────────────────────────────────────────────
1025
+ // SECTION 17: KEYSYM TABLE
1026
+ // Full XK_ keysym constants (X11/keysymdef.h)
1027
+ // ────────────────────────────────────────────────────────────
1028
+
1029
+ const Keysym = {
1030
+ // ── Void / special ──────────────────────────────────────
1031
+ XK_VoidSymbol: 0xFFFFFF,
1032
+
1033
+ // ── TTY functions ────────────────────────────────────────
1034
+ XK_BackSpace: 0xFF08,
1035
+ XK_Tab: 0xFF09,
1036
+ XK_Linefeed: 0xFF0A,
1037
+ XK_Clear: 0xFF0B,
1038
+ XK_Return: 0xFF0D,
1039
+ XK_Pause: 0xFF13,
1040
+ XK_Scroll_Lock: 0xFF14,
1041
+ XK_Sys_Req: 0xFF15,
1042
+ XK_Escape: 0xFF1B,
1043
+ XK_Delete: 0xFFFF,
1044
+
1045
+ // ── Cursor control ────────────────────────────────────────
1046
+ XK_Home: 0xFF50,
1047
+ XK_Left: 0xFF51,
1048
+ XK_Up: 0xFF52,
1049
+ XK_Right: 0xFF53,
1050
+ XK_Down: 0xFF54,
1051
+ XK_Prior: 0xFF55, // Page Up
1052
+ XK_Page_Up: 0xFF55,
1053
+ XK_Next: 0xFF56, // Page Down
1054
+ XK_Page_Down: 0xFF56,
1055
+ XK_End: 0xFF57,
1056
+ XK_Begin: 0xFF58,
1057
+
1058
+ // ── Misc functions ────────────────────────────────────────
1059
+ XK_Select: 0xFF60,
1060
+ XK_Print: 0xFF61,
1061
+ XK_Execute: 0xFF62,
1062
+ XK_Insert: 0xFF63,
1063
+ XK_Undo: 0xFF65,
1064
+ XK_Redo: 0xFF66,
1065
+ XK_Menu: 0xFF67,
1066
+ XK_Find: 0xFF68,
1067
+ XK_Cancel: 0xFF69,
1068
+ XK_Help: 0xFF6A,
1069
+ XK_Break: 0xFF6B,
1070
+ XK_Mode_switch: 0xFF7E,
1071
+ XK_script_switch: 0xFF7E,
1072
+ XK_Num_Lock: 0xFF7F,
1073
+
1074
+ // ── Keypad ────────────────────────────────────────────────
1075
+ XK_KP_Space: 0xFF80,
1076
+ XK_KP_Tab: 0xFF89,
1077
+ XK_KP_Enter: 0xFF8D,
1078
+ XK_KP_F1: 0xFF91,
1079
+ XK_KP_F2: 0xFF92,
1080
+ XK_KP_F3: 0xFF93,
1081
+ XK_KP_F4: 0xFF94,
1082
+ XK_KP_Home: 0xFF95,
1083
+ XK_KP_Left: 0xFF96,
1084
+ XK_KP_Up: 0xFF97,
1085
+ XK_KP_Right: 0xFF98,
1086
+ XK_KP_Down: 0xFF99,
1087
+ XK_KP_Prior: 0xFF9A,
1088
+ XK_KP_Page_Up: 0xFF9A,
1089
+ XK_KP_Next: 0xFF9B,
1090
+ XK_KP_Page_Down: 0xFF9B,
1091
+ XK_KP_End: 0xFF9C,
1092
+ XK_KP_Begin: 0xFF9D,
1093
+ XK_KP_Insert: 0xFF9E,
1094
+ XK_KP_Delete: 0xFF9F,
1095
+ XK_KP_Equal: 0xFFBD,
1096
+ XK_KP_Multiply: 0xFFAA,
1097
+ XK_KP_Add: 0xFFAB,
1098
+ XK_KP_Separator: 0xFFAC,
1099
+ XK_KP_Subtract: 0xFFAD,
1100
+ XK_KP_Decimal: 0xFFAE,
1101
+ XK_KP_Divide: 0xFFAF,
1102
+ XK_KP_0: 0xFFB0,
1103
+ XK_KP_1: 0xFFB1,
1104
+ XK_KP_2: 0xFFB2,
1105
+ XK_KP_3: 0xFFB3,
1106
+ XK_KP_4: 0xFFB4,
1107
+ XK_KP_5: 0xFFB5,
1108
+ XK_KP_6: 0xFFB6,
1109
+ XK_KP_7: 0xFFB7,
1110
+ XK_KP_8: 0xFFB8,
1111
+ XK_KP_9: 0xFFB9,
1112
+
1113
+ // ── Function keys ─────────────────────────────────────────
1114
+ XK_F1: 0xFFBE, XK_F2: 0xFFBF, XK_F3: 0xFFC0, XK_F4: 0xFFC1,
1115
+ XK_F5: 0xFFC2, XK_F6: 0xFFC3, XK_F7: 0xFFC4, XK_F8: 0xFFC5,
1116
+ XK_F9: 0xFFC6, XK_F10: 0xFFC7, XK_F11: 0xFFC8, XK_F12: 0xFFC9,
1117
+ XK_F13: 0xFFCA, XK_F14: 0xFFCB, XK_F15: 0xFFCC, XK_F16: 0xFFCD,
1118
+ XK_F17: 0xFFCE, XK_F18: 0xFFCF, XK_F19: 0xFFD0, XK_F20: 0xFFD1,
1119
+ XK_F21: 0xFFD2, XK_F22: 0xFFD3, XK_F23: 0xFFD4, XK_F24: 0xFFD5,
1120
+ XK_F25: 0xFFD6, XK_F26: 0xFFD7, XK_F27: 0xFFD8, XK_F28: 0xFFD9,
1121
+ XK_F29: 0xFFDA, XK_F30: 0xFFDB, XK_F31: 0xFFDC, XK_F32: 0xFFDD,
1122
+ XK_F33: 0xFFDE, XK_F34: 0xFFDF, XK_F35: 0xFFE0,
1123
+
1124
+ // ── Modifier keys ─────────────────────────────────────────
1125
+ XK_Shift_L: 0xFFE1,
1126
+ XK_Shift_R: 0xFFE2,
1127
+ XK_Control_L: 0xFFE3,
1128
+ XK_Control_R: 0xFFE4,
1129
+ XK_Caps_Lock: 0xFFE5,
1130
+ XK_Shift_Lock: 0xFFE6,
1131
+ XK_Meta_L: 0xFFE7,
1132
+ XK_Meta_R: 0xFFE8,
1133
+ XK_Alt_L: 0xFFE9,
1134
+ XK_Alt_R: 0xFFEA,
1135
+ XK_Super_L: 0xFFEB,
1136
+ XK_Super_R: 0xFFEC,
1137
+ XK_Hyper_L: 0xFFED,
1138
+ XK_Hyper_R: 0xFFEE,
1139
+
1140
+ // ── ISO keys ──────────────────────────────────────────────
1141
+ XK_ISO_Lock: 0xFE01,
1142
+ XK_ISO_Level2_Latch: 0xFE02,
1143
+ XK_ISO_Level3_Shift: 0xFE03,
1144
+ XK_ISO_Level3_Latch: 0xFE04,
1145
+ XK_ISO_Level3_Lock: 0xFE05,
1146
+ XK_ISO_Group_Shift: 0xFF7E,
1147
+ XK_ISO_Group_Latch: 0xFE06,
1148
+ XK_ISO_Group_Lock: 0xFE07,
1149
+ XK_ISO_Next_Group: 0xFE08,
1150
+ XK_ISO_Next_Group_Lock: 0xFE09,
1151
+ XK_ISO_Prev_Group: 0xFE0A,
1152
+ XK_ISO_Prev_Group_Lock: 0xFE0B,
1153
+ XK_ISO_First_Group: 0xFE0C,
1154
+ XK_ISO_First_Group_Lock: 0xFE0D,
1155
+ XK_ISO_Last_Group: 0xFE0E,
1156
+ XK_ISO_Last_Group_Lock: 0xFE0F,
1157
+ XK_ISO_Left_Tab: 0xFE20,
1158
+ XK_ISO_Move_Line_Up: 0xFE21,
1159
+ XK_ISO_Move_Line_Down: 0xFE22,
1160
+ XK_ISO_Partial_Line_Up: 0xFE23,
1161
+ XK_ISO_Partial_Line_Down: 0xFE24,
1162
+ XK_ISO_Partial_Space_Left:0xFE25,
1163
+ XK_ISO_Partial_Space_Right:0xFE26,
1164
+ XK_ISO_Set_Margin_Left: 0xFE27,
1165
+ XK_ISO_Set_Margin_Right: 0xFE28,
1166
+ XK_ISO_Release_Margin_Left:0xFE29,
1167
+ XK_ISO_Release_Margin_Right:0xFE2A,
1168
+ XK_ISO_Release_Both_Margins:0xFE2B,
1169
+ XK_ISO_Fast_Cursor_Left: 0xFE2C,
1170
+ XK_ISO_Fast_Cursor_Right: 0xFE2D,
1171
+ XK_ISO_Fast_Cursor_Up: 0xFE2E,
1172
+ XK_ISO_Fast_Cursor_Down: 0xFE2F,
1173
+ XK_ISO_Continuous_Underline:0xFE30,
1174
+ XK_ISO_Discontinuous_Underline:0xFE31,
1175
+ XK_ISO_Emphasize: 0xFE32,
1176
+ XK_ISO_Center_Object: 0xFE33,
1177
+ XK_ISO_Enter: 0xFE34,
1178
+
1179
+ // ── Latin-1 (0x0020-0x00FF) ──────────────────────────────
1180
+ XK_space: 0x0020, XK_exclam: 0x0021, XK_quotedbl: 0x0022,
1181
+ XK_numbersign: 0x0023, XK_dollar: 0x0024, XK_percent: 0x0025,
1182
+ XK_ampersand: 0x0026, XK_apostrophe: 0x0027, XK_quoteright: 0x0027,
1183
+ XK_parenleft: 0x0028, XK_parenright: 0x0029, XK_asterisk: 0x002A,
1184
+ XK_plus: 0x002B, XK_comma: 0x002C, XK_minus: 0x002D,
1185
+ XK_period: 0x002E, XK_slash: 0x002F,
1186
+ XK_0: 0x0030, XK_1: 0x0031, XK_2: 0x0032, XK_3: 0x0033,
1187
+ XK_4: 0x0034, XK_5: 0x0035, XK_6: 0x0036, XK_7: 0x0037,
1188
+ XK_8: 0x0038, XK_9: 0x0039,
1189
+ XK_colon: 0x003A, XK_semicolon: 0x003B, XK_less: 0x003C,
1190
+ XK_equal: 0x003D, XK_greater: 0x003E, XK_question: 0x003F,
1191
+ XK_at: 0x0040,
1192
+ XK_A: 0x0041, XK_B: 0x0042, XK_C: 0x0043, XK_D: 0x0044,
1193
+ XK_E: 0x0045, XK_F: 0x0046, XK_G: 0x0047, XK_H: 0x0048,
1194
+ XK_I: 0x0049, XK_J: 0x004A, XK_K: 0x004B, XK_L: 0x004C,
1195
+ XK_M: 0x004D, XK_N: 0x004E, XK_O: 0x004F, XK_P: 0x0050,
1196
+ XK_Q: 0x0051, XK_R: 0x0052, XK_S: 0x0053, XK_T: 0x0054,
1197
+ XK_U: 0x0055, XK_V: 0x0056, XK_W: 0x0057, XK_X: 0x0058,
1198
+ XK_Y: 0x0059, XK_Z: 0x005A,
1199
+ XK_bracketleft: 0x005B, XK_backslash: 0x005C, XK_bracketright:0x005D,
1200
+ XK_asciicircum: 0x005E, XK_underscore: 0x005F, XK_grave: 0x0060,
1201
+ XK_quoteleft: 0x0060,
1202
+ XK_a: 0x0061, XK_b: 0x0062, XK_c: 0x0063, XK_d: 0x0064,
1203
+ XK_e: 0x0065, XK_f: 0x0066, XK_g: 0x0067, XK_h: 0x0068,
1204
+ XK_i: 0x0069, XK_j: 0x006A, XK_k: 0x006B, XK_l: 0x006C,
1205
+ XK_m: 0x006D, XK_n: 0x006E, XK_o: 0x006F, XK_p: 0x0070,
1206
+ XK_q: 0x0071, XK_r: 0x0072, XK_s: 0x0073, XK_t: 0x0074,
1207
+ XK_u: 0x0075, XK_v: 0x0076, XK_w: 0x0077, XK_x: 0x0078,
1208
+ XK_y: 0x0079, XK_z: 0x007A,
1209
+ XK_braceleft: 0x007B, XK_bar: 0x007C, XK_braceright: 0x007D,
1210
+ XK_asciitilde: 0x007E,
1211
+
1212
+ // ── Latin-1 extended ──────────────────────────────────────
1213
+ XK_nobreakspace: 0x00A0, XK_exclamdown: 0x00A1, XK_cent: 0x00A2,
1214
+ XK_sterling: 0x00A3, XK_currency: 0x00A4, XK_yen: 0x00A5,
1215
+ XK_brokenbar: 0x00A6, XK_section: 0x00A7, XK_diaeresis: 0x00A8,
1216
+ XK_copyright: 0x00A9, XK_ordfeminine: 0x00AA, XK_guillemotleft: 0x00AB,
1217
+ XK_notsign: 0x00AC, XK_hyphen: 0x00AD, XK_registered: 0x00AE,
1218
+ XK_macron: 0x00AF, XK_degree: 0x00B0, XK_plusminus: 0x00B1,
1219
+ XK_twosuperior: 0x00B2, XK_threesuperior: 0x00B3, XK_acute: 0x00B4,
1220
+ XK_mu: 0x00B5, XK_paragraph: 0x00B6, XK_periodcentered:0x00B7,
1221
+ XK_cedilla: 0x00B8, XK_onesuperior: 0x00B9, XK_masculine: 0x00BA,
1222
+ XK_guillemotright: 0x00BB, XK_onequarter: 0x00BC, XK_onehalf: 0x00BD,
1223
+ XK_threequarters: 0x00BE, XK_questiondown: 0x00BF,
1224
+ XK_Agrave: 0x00C0, XK_Aacute: 0x00C1, XK_Acircumflex: 0x00C2,
1225
+ XK_Atilde: 0x00C3, XK_Adiaeresis: 0x00C4, XK_Aring: 0x00C5,
1226
+ XK_AE: 0x00C6, XK_Ccedilla: 0x00C7,
1227
+ XK_Egrave: 0x00C8, XK_Eacute: 0x00C9, XK_Ecircumflex: 0x00CA, XK_Ediaeresis: 0x00CB,
1228
+ XK_Igrave: 0x00CC, XK_Iacute: 0x00CD, XK_Icircumflex: 0x00CE, XK_Idiaeresis: 0x00CF,
1229
+ XK_ETH: 0x00D0, XK_Ntilde: 0x00D1,
1230
+ XK_Ograve: 0x00D2, XK_Oacute: 0x00D3, XK_Ocircumflex: 0x00D4,
1231
+ XK_Otilde: 0x00D5, XK_Odiaeresis: 0x00D6, XK_multiply: 0x00D7,
1232
+ XK_Ooblique: 0x00D8, XK_Oslash: 0x00D8,
1233
+ XK_Ugrave: 0x00D9, XK_Uacute: 0x00DA, XK_Ucircumflex: 0x00DB, XK_Udiaeresis: 0x00DC,
1234
+ XK_Yacute: 0x00DD, XK_THORN: 0x00DE, XK_ssharp: 0x00DF,
1235
+ XK_agrave: 0x00E0, XK_aacute: 0x00E1, XK_acircumflex: 0x00E2,
1236
+ XK_atilde: 0x00E3, XK_adiaeresis: 0x00E4, XK_aring: 0x00E5,
1237
+ XK_ae: 0x00E6, XK_ccedilla: 0x00E7,
1238
+ XK_egrave: 0x00E8, XK_eacute: 0x00E9, XK_ecircumflex: 0x00EA, XK_ediaeresis: 0x00EB,
1239
+ XK_igrave: 0x00EC, XK_iacute: 0x00ED, XK_icircumflex: 0x00EE, XK_idiaeresis: 0x00EF,
1240
+ XK_eth: 0x00F0, XK_ntilde: 0x00F1,
1241
+ XK_ograve: 0x00F2, XK_oacute: 0x00F3, XK_ocircumflex: 0x00F4,
1242
+ XK_otilde: 0x00F5, XK_odiaeresis: 0x00F6, XK_division: 0x00F7,
1243
+ XK_oslash: 0x00F8, XK_ooblique: 0x00F8,
1244
+ XK_ugrave: 0x00F9, XK_uacute: 0x00FA, XK_ucircumflex: 0x00FB, XK_udiaeresis: 0x00FC,
1245
+ XK_yacute: 0x00FD, XK_thorn: 0x00FE, XK_ydiaeresis: 0x00FF,
1246
+
1247
+ // ── XF86 / multimedia keys ───────────────────────────────
1248
+ XF86XK_ModeLock: 0x1008FF01,
1249
+ XF86XK_MonBrightnessUp: 0x1008FF02,
1250
+ XF86XK_MonBrightnessDown: 0x1008FF03,
1251
+ XF86XK_KbdLightOnOff: 0x1008FF04,
1252
+ XF86XK_KbdBrightnessUp: 0x1008FF05,
1253
+ XF86XK_KbdBrightnessDown: 0x1008FF06,
1254
+ XF86XK_Standby: 0x1008FF10,
1255
+ XF86XK_AudioLowerVolume: 0x1008FF11,
1256
+ XF86XK_AudioMute: 0x1008FF12,
1257
+ XF86XK_AudioRaiseVolume: 0x1008FF13,
1258
+ XF86XK_AudioPlay: 0x1008FF14,
1259
+ XF86XK_AudioStop: 0x1008FF15,
1260
+ XF86XK_AudioPrev: 0x1008FF16,
1261
+ XF86XK_AudioNext: 0x1008FF17,
1262
+ XF86XK_HomePage: 0x1008FF18,
1263
+ XF86XK_Mail: 0x1008FF19,
1264
+ XF86XK_Start: 0x1008FF1A,
1265
+ XF86XK_Search: 0x1008FF1B,
1266
+ XF86XK_AudioRecord: 0x1008FF1C,
1267
+ XF86XK_Calculator: 0x1008FF1D,
1268
+ XF86XK_Memo: 0x1008FF1E,
1269
+ XF86XK_ToDoList: 0x1008FF1F,
1270
+ XF86XK_Calendar: 0x1008FF20,
1271
+ XF86XK_PowerDown: 0x1008FF21,
1272
+ XF86XK_ContrastAdjust: 0x1008FF22,
1273
+ XF86XK_RockerUp: 0x1008FF23,
1274
+ XF86XK_RockerDown: 0x1008FF24,
1275
+ XF86XK_RockerEnter: 0x1008FF25,
1276
+ XF86XK_Back: 0x1008FF26,
1277
+ XF86XK_Forward: 0x1008FF27,
1278
+ XF86XK_Stop: 0x1008FF28,
1279
+ XF86XK_Refresh: 0x1008FF29,
1280
+ XF86XK_PowerOff: 0x1008FF2A,
1281
+ XF86XK_WakeUp: 0x1008FF2B,
1282
+ XF86XK_Eject: 0x1008FF2C,
1283
+ XF86XK_ScreenSaver: 0x1008FF2D,
1284
+ XF86XK_WWW: 0x1008FF2E,
1285
+ XF86XK_Sleep: 0x1008FF2F,
1286
+ XF86XK_Favorites: 0x1008FF30,
1287
+ XF86XK_AudioPause: 0x1008FF31,
1288
+ XF86XK_AudioMedia: 0x1008FF32,
1289
+ XF86XK_MyComputer: 0x1008FF33,
1290
+ XF86XK_VendorHome: 0x1008FF34,
1291
+ XF86XK_LightBulb: 0x1008FF35,
1292
+ XF86XK_Shop: 0x1008FF36,
1293
+ XF86XK_History: 0x1008FF37,
1294
+ XF86XK_OpenURL: 0x1008FF38,
1295
+ XF86XK_AddFavorite: 0x1008FF39,
1296
+ XF86XK_HotLinks: 0x1008FF3A,
1297
+ XF86XK_BrightnessAdjust: 0x1008FF3B,
1298
+ XF86XK_Finance: 0x1008FF3C,
1299
+ XF86XK_Community: 0x1008FF3D,
1300
+ XF86XK_AudioRewind: 0x1008FF3E,
1301
+ XF86XK_BackForward: 0x1008FF3F,
1302
+ XF86XK_Launch0: 0x1008FF40,
1303
+ XF86XK_Launch1: 0x1008FF41,
1304
+ XF86XK_Launch2: 0x1008FF42,
1305
+ XF86XK_Launch3: 0x1008FF43,
1306
+ XF86XK_Launch4: 0x1008FF44,
1307
+ XF86XK_Launch5: 0x1008FF45,
1308
+ XF86XK_Launch6: 0x1008FF46,
1309
+ XF86XK_Launch7: 0x1008FF47,
1310
+ XF86XK_Launch8: 0x1008FF48,
1311
+ XF86XK_Launch9: 0x1008FF49,
1312
+ XF86XK_LaunchA: 0x1008FF4A,
1313
+ XF86XK_LaunchB: 0x1008FF4B,
1314
+ XF86XK_LaunchC: 0x1008FF4C,
1315
+ XF86XK_LaunchD: 0x1008FF4D,
1316
+ XF86XK_LaunchE: 0x1008FF4E,
1317
+ XF86XK_LaunchF: 0x1008FF4F,
1318
+ XF86XK_ApplicationLeft: 0x1008FF50,
1319
+ XF86XK_ApplicationRight: 0x1008FF51,
1320
+ XF86XK_Book: 0x1008FF52,
1321
+ XF86XK_CD: 0x1008FF53,
1322
+ XF86XK_Calculater: 0x1008FF54,
1323
+ XF86XK_Clear: 0x1008FF55,
1324
+ XF86XK_Close: 0x1008FF56,
1325
+ XF86XK_Copy: 0x1008FF57,
1326
+ XF86XK_Cut: 0x1008FF58,
1327
+ XF86XK_Display: 0x1008FF59,
1328
+ XF86XK_DOS: 0x1008FF5A,
1329
+ XF86XK_Documents: 0x1008FF5B,
1330
+ XF86XK_Excel: 0x1008FF5C,
1331
+ XF86XK_Explorer: 0x1008FF5D,
1332
+ XF86XK_Game: 0x1008FF5E,
1333
+ XF86XK_Go: 0x1008FF5F,
1334
+ XF86XK_iTouch: 0x1008FF60,
1335
+ XF86XK_LogOff: 0x1008FF61,
1336
+ XF86XK_Market: 0x1008FF62,
1337
+ XF86XK_Meeting: 0x1008FF63,
1338
+ XF86XK_MenuKB: 0x1008FF65,
1339
+ XF86XK_MenuPB: 0x1008FF66,
1340
+ XF86XK_MySites: 0x1008FF67,
1341
+ XF86XK_New: 0x1008FF68,
1342
+ XF86XK_News: 0x1008FF69,
1343
+ XF86XK_OfficeHome: 0x1008FF6A,
1344
+ XF86XK_Open: 0x1008FF6B,
1345
+ XF86XK_Option: 0x1008FF6C,
1346
+ XF86XK_Paste: 0x1008FF6D,
1347
+ XF86XK_Phone: 0x1008FF6E,
1348
+ XF86XK_Q: 0x1008FF70,
1349
+ XF86XK_Reply: 0x1008FF72,
1350
+ XF86XK_Reload: 0x1008FF73,
1351
+ XF86XK_RotateWindows: 0x1008FF74,
1352
+ XF86XK_RotationPB: 0x1008FF75,
1353
+ XF86XK_RotationKB: 0x1008FF76,
1354
+ XF86XK_Save: 0x1008FF77,
1355
+ XF86XK_ScrollUp: 0x1008FF78,
1356
+ XF86XK_ScrollDown: 0x1008FF79,
1357
+ XF86XK_ScrollClick: 0x1008FF7A,
1358
+ XF86XK_Send: 0x1008FF7B,
1359
+ XF86XK_Spell: 0x1008FF7C,
1360
+ XF86XK_SplitScreen: 0x1008FF7D,
1361
+ XF86XK_Support: 0x1008FF7E,
1362
+ XF86XK_TaskPane: 0x1008FF7F,
1363
+ XF86XK_Terminal: 0x1008FF80,
1364
+ XF86XK_Tools: 0x1008FF81,
1365
+ XF86XK_Travel: 0x1008FF82,
1366
+ XF86XK_UserPB: 0x1008FF84,
1367
+ XF86XK_User1KB: 0x1008FF85,
1368
+ XF86XK_User2KB: 0x1008FF86,
1369
+ XF86XK_Video: 0x1008FF87,
1370
+ XF86XK_WheelButton: 0x1008FF88,
1371
+ XF86XK_Word: 0x1008FF89,
1372
+ XF86XK_Xfer: 0x1008FF8A,
1373
+ XF86XK_ZoomIn: 0x1008FF8B,
1374
+ XF86XK_ZoomOut: 0x1008FF8C,
1375
+ XF86XK_Away: 0x1008FF8D,
1376
+ XF86XK_Messenger: 0x1008FF8E,
1377
+ XF86XK_WebCam: 0x1008FF8F,
1378
+ XF86XK_MailForward: 0x1008FF90,
1379
+ XF86XK_Pictures: 0x1008FF91,
1380
+ XF86XK_Music: 0x1008FF92,
1381
+ XF86XK_Battery: 0x1008FF93,
1382
+ XF86XK_Bluetooth: 0x1008FF94,
1383
+ XF86XK_WLAN: 0x1008FF95,
1384
+ XF86XK_UWB: 0x1008FF96,
1385
+ XF86XK_AudioForward: 0x1008FF97,
1386
+ XF86XK_AudioRepeat: 0x1008FF98,
1387
+ XF86XK_AudioRandomPlay: 0x1008FF99,
1388
+ XF86XK_Subtitle: 0x1008FF9A,
1389
+ XF86XK_AudioCycleTrack: 0x1008FF9B,
1390
+ XF86XK_CycleAngle: 0x1008FF9C,
1391
+ XF86XK_FrameBack: 0x1008FF9D,
1392
+ XF86XK_FrameForward: 0x1008FF9E,
1393
+ XF86XK_Time: 0x1008FF9F,
1394
+ XF86XK_Select: 0x1008FFA0,
1395
+ XF86XK_View: 0x1008FFA1,
1396
+ XF86XK_TopMenu: 0x1008FFA2,
1397
+ XF86XK_SuspendVide: 0x1008FFA7,
1398
+ XF86XK_Hibernate: 0x1008FFA8,
1399
+ XF86XK_TouchpadToggle: 0x1008FFA9,
1400
+ XF86XK_TouchpadOn: 0x1008FFB0,
1401
+ XF86XK_TouchpadOff: 0x1008FFB1,
1402
+ XF86XK_AudioMicMute: 0x1008FFB2,
1403
+ XF86XK_Switch_VT_1: 0x1008FE01,
1404
+ XF86XK_Switch_VT_2: 0x1008FE02,
1405
+ XF86XK_Switch_VT_3: 0x1008FE03,
1406
+ XF86XK_Switch_VT_4: 0x1008FE04,
1407
+ XF86XK_Switch_VT_5: 0x1008FE05,
1408
+ XF86XK_Switch_VT_6: 0x1008FE06,
1409
+ XF86XK_Switch_VT_7: 0x1008FE07,
1410
+ XF86XK_Switch_VT_8: 0x1008FE08,
1411
+ XF86XK_Switch_VT_9: 0x1008FE09,
1412
+ XF86XK_Switch_VT_10: 0x1008FE0A,
1413
+ XF86XK_Switch_VT_11: 0x1008FE0B,
1414
+ XF86XK_Switch_VT_12: 0x1008FE0C,
1415
+ XF86XK_Ungrab: 0x1008FE20,
1416
+ XF86XK_ClearGrab: 0x1008FE21,
1417
+ XF86XK_Next_VMode: 0x1008FE22,
1418
+ XF86XK_Prev_VMode: 0x1008FE23,
1419
+ XF86XK_LogWindowTree: 0x1008FE24,
1420
+ XF86XK_LogGrabInfo: 0x1008FE25,
1421
+ };
1422
+
1423
+ /** Reverse map: keysym code → name */
1424
+ const KeysymName = Object.fromEntries(
1425
+ Object.entries(Keysym).map(([k,v]) => [v, k])
1426
+ );
1427
+
1428
+ // ────────────────────────────────────────────────────────────
1429
+ // SECTION 18: KEYSYM UTILITIES
1430
+ // ────────────────────────────────────────────────────────────
1431
+
1432
+ /**
1433
+ * Look up a keysym code by name (XK_ prefix optional).
1434
+ * @param {string} name
1435
+ * @returns {number|undefined}
1436
+ */
1437
+ function keysymByName(name) {
1438
+ if (Keysym[name] !== undefined) return Keysym[name];
1439
+ const withPrefix = 'XK_' + name;
1440
+ return Keysym[withPrefix];
1441
+ }
1442
+
1443
+ /**
1444
+ * Look up a keysym name by code.
1445
+ * @param {number} code
1446
+ * @returns {string|undefined}
1447
+ */
1448
+ function keysymToName(code) {
1449
+ return KeysymName[code];
1450
+ }
1451
+
1452
+ /**
1453
+ * Convert a keysym to its Unicode code point (for Latin-1 and Unicode keysyms).
1454
+ * @param {number} keysym
1455
+ * @returns {number|null}
1456
+ */
1457
+ function keysymToUnicode(keysym) {
1458
+ // Direct Latin-1
1459
+ if (keysym >= 0x0020 && keysym <= 0x00FF) return keysym;
1460
+ // Unicode keysyms (0x01000000 + codepoint)
1461
+ if ((keysym & 0xFF000000) === 0x01000000) return keysym & 0x00FFFFFF;
1462
+ return null;
1463
+ }
1464
+
1465
+ /**
1466
+ * Convert a keysym to a character string (if printable).
1467
+ * @param {number} keysym
1468
+ * @returns {string|null}
1469
+ */
1470
+ function keysymToChar(keysym) {
1471
+ const cp = keysymToUnicode(keysym);
1472
+ if (cp !== null && cp >= 0x0020) return String.fromCodePoint(cp);
1473
+ return null;
1474
+ }
1475
+
1476
+ /**
1477
+ * Get a Unicode code point's corresponding keysym.
1478
+ * @param {number} codepoint
1479
+ * @returns {number}
1480
+ */
1481
+ function unicodeToKeysym(codepoint) {
1482
+ if (codepoint >= 0x0020 && codepoint <= 0x00FF) return codepoint;
1483
+ return 0x01000000 | codepoint;
1484
+ }
1485
+
1486
+ /**
1487
+ * Test if a keysym is a modifier key.
1488
+ * @param {number} keysym
1489
+ * @returns {boolean}
1490
+ */
1491
+ function isModifierKeysym(keysym) {
1492
+ return keysym >= 0xFFE1 && keysym <= 0xFFEE;
1493
+ }
1494
+
1495
+ /**
1496
+ * Test if a keysym is a function key (F1–F35).
1497
+ * @param {number} keysym
1498
+ * @returns {boolean}
1499
+ */
1500
+ function isFunctionKeysym(keysym) {
1501
+ return keysym >= 0xFFBE && keysym <= 0xFFE0;
1502
+ }
1503
+
1504
+ /**
1505
+ * Test if a keysym is a keypad key.
1506
+ */
1507
+ function isKeypadKeysym(keysym) {
1508
+ return keysym >= 0xFF80 && keysym <= 0xFFBD;
1509
+ }
1510
+
1511
+ /**
1512
+ * Test if a keysym is printable (has a character).
1513
+ */
1514
+ function isPrintableKeysym(keysym) {
1515
+ return keysymToChar(keysym) !== null;
1516
+ }
1517
+
1518
+ // ────────────────────────────────────────────────────────────
1519
+ // SECTION 19: X11 NAMED COLORS (rgb.txt — full list)
1520
+ // ────────────────────────────────────────────────────────────
1521
+
1522
+ /**
1523
+ * Full X11 named color table.
1524
+ * Keys are lowercase names (spaces removed), values are [r, g, b].
1525
+ */
1526
+ const X11Colors = {
1527
+ aliceblue: [240,248,255], antiquewhite: [250,235,215],
1528
+ antiquewhite1: [255,239,219], antiquewhite2: [238,223,204],
1529
+ antiquewhite3: [205,192,176], antiquewhite4: [139,131,120],
1530
+ aquamarine: [127,255,212], aquamarine1: [127,255,212],
1531
+ aquamarine2: [118,238,198], aquamarine3: [102,205,170],
1532
+ aquamarine4: [69,139,116], azure: [240,255,255],
1533
+ azure1: [240,255,255], azure2: [224,238,238],
1534
+ azure3: [193,205,205], azure4: [131,139,139],
1535
+ beige: [245,245,220], bisque: [255,228,196],
1536
+ bisque1: [255,228,196], bisque2: [238,213,183],
1537
+ bisque3: [205,183,158], bisque4: [139,125,107],
1538
+ black: [0,0,0], blanchedalmond: [255,235,205],
1539
+ blue: [0,0,255], blue1: [0,0,255],
1540
+ blue2: [0,0,238], blue3: [0,0,205],
1541
+ blue4: [0,0,139], blueviolet: [138,43,226],
1542
+ brown: [165,42,42], brown1: [255,64,64],
1543
+ brown2: [238,59,59], brown3: [205,51,51],
1544
+ brown4: [139,35,35], burlywood: [222,184,135],
1545
+ burlywood1: [255,211,155], burlywood2: [238,197,145],
1546
+ burlywood3: [205,170,125], burlywood4: [139,115,85],
1547
+ cadetblue: [95,158,160], cadetblue1: [152,245,255],
1548
+ cadetblue2: [142,229,238], cadetblue3: [122,197,205],
1549
+ cadetblue4: [83,134,139], chartreuse: [127,255,0],
1550
+ chartreuse1: [127,255,0], chartreuse2: [118,238,0],
1551
+ chartreuse3: [102,205,0], chartreuse4: [69,139,0],
1552
+ chocolate: [210,105,30], chocolate1: [255,127,36],
1553
+ chocolate2: [238,118,33], chocolate3: [205,102,29],
1554
+ chocolate4: [139,69,19], coral: [255,127,80],
1555
+ coral1: [255,114,86], coral2: [238,106,80],
1556
+ coral3: [205,91,69], coral4: [139,62,47],
1557
+ cornflowerblue: [100,149,237], cornsilk: [255,248,220],
1558
+ cornsilk1: [255,248,220], cornsilk2: [238,232,205],
1559
+ cornsilk3: [205,200,177], cornsilk4: [139,136,120],
1560
+ cyan: [0,255,255], cyan1: [0,255,255],
1561
+ cyan2: [0,238,238], cyan3: [0,205,205],
1562
+ cyan4: [0,139,139], darkblue: [0,0,139],
1563
+ darkcyan: [0,139,139], darkgoldenrod: [184,134,11],
1564
+ darkgoldenrod1: [255,185,15], darkgoldenrod2: [238,173,14],
1565
+ darkgoldenrod3: [205,149,12], darkgoldenrod4: [139,101,8],
1566
+ darkgray: [169,169,169], darkgreen: [0,100,0],
1567
+ darkgrey: [169,169,169], darkkhaki: [189,183,107],
1568
+ darkmagenta: [139,0,139], darkolivegreen: [85,107,47],
1569
+ darkolivegreen1: [202,255,112], darkolivegreen2: [188,238,104],
1570
+ darkolivegreen3: [162,205,90], darkolivegreen4: [110,139,61],
1571
+ darkorange: [255,140,0], darkorange1: [255,127,0],
1572
+ darkorange2: [238,118,0], darkorange3: [205,102,0],
1573
+ darkorange4: [139,69,0], darkorchid: [153,50,204],
1574
+ darkorchid1: [191,62,255], darkorchid2: [178,58,238],
1575
+ darkorchid3: [154,50,205], darkorchid4: [104,34,139],
1576
+ darkred: [139,0,0], darksalmon: [233,150,122],
1577
+ darkseagreen: [143,188,143], darkseagreen1: [193,255,193],
1578
+ darkseagreen2: [180,238,180], darkseagreen3: [155,205,155],
1579
+ darkseagreen4: [105,139,105], darkslateblue: [72,61,139],
1580
+ darkslategray: [47,79,79], darkslategray1: [151,255,255],
1581
+ darkslategray2: [141,238,238], darkslategray3: [121,205,205],
1582
+ darkslategray4: [82,139,139], darkslategrey: [47,79,79],
1583
+ darkturquoise: [0,206,209], darkviolet: [148,0,211],
1584
+ deeppink: [255,20,147], deeppink1: [255,20,147],
1585
+ deeppink2: [238,18,137], deeppink3: [205,16,118],
1586
+ deeppink4: [139,10,80], deepskyblue: [0,191,255],
1587
+ deepskyblue1: [0,191,255], deepskyblue2: [0,178,238],
1588
+ deepskyblue3: [0,154,205], deepskyblue4: [0,104,139],
1589
+ dimgray: [105,105,105], dimgrey: [105,105,105],
1590
+ dodgerblue: [30,144,255], dodgerblue1: [30,144,255],
1591
+ dodgerblue2: [28,134,238], dodgerblue3: [24,116,205],
1592
+ dodgerblue4: [16,78,139], firebrick: [178,34,34],
1593
+ firebrick1: [255,48,48], firebrick2: [238,44,44],
1594
+ firebrick3: [205,38,38], firebrick4: [139,26,26],
1595
+ floralwhite: [255,250,240], forestgreen: [34,139,34],
1596
+ gainsboro: [220,220,220], ghostwhite: [248,248,255],
1597
+ gold: [255,215,0], gold1: [255,215,0],
1598
+ gold2: [238,201,0], gold3: [205,173,0],
1599
+ gold4: [139,117,0], goldenrod: [218,165,32],
1600
+ goldenrod1: [255,193,37], goldenrod2: [238,180,34],
1601
+ goldenrod3: [205,155,29], goldenrod4: [139,105,20],
1602
+ gray: [190,190,190], gray0: [0,0,0],
1603
+ gray1: [3,3,3], gray2: [5,5,5],
1604
+ gray3: [8,8,8], gray4: [10,10,10],
1605
+ gray5: [13,13,13], gray6: [15,15,15],
1606
+ gray7: [18,18,18], gray8: [20,20,20],
1607
+ gray9: [23,23,23], gray10: [26,26,26],
1608
+ gray11: [28,28,28], gray12: [31,31,31],
1609
+ gray13: [33,33,33], gray14: [36,36,36],
1610
+ gray15: [38,38,38], gray16: [41,41,41],
1611
+ gray17: [43,43,43], gray18: [46,46,46],
1612
+ gray19: [48,48,48], gray20: [51,51,51],
1613
+ gray21: [54,54,54], gray22: [56,56,56],
1614
+ gray23: [59,59,59], gray24: [61,61,61],
1615
+ gray25: [64,64,64], gray26: [66,66,66],
1616
+ gray27: [69,69,69], gray28: [71,71,71],
1617
+ gray29: [74,74,74], gray30: [77,77,77],
1618
+ gray31: [79,79,79], gray32: [82,82,82],
1619
+ gray33: [84,84,84], gray34: [87,87,87],
1620
+ gray35: [89,89,89], gray36: [92,92,92],
1621
+ gray37: [94,94,94], gray38: [97,97,97],
1622
+ gray39: [99,99,99], gray40: [102,102,102],
1623
+ gray41: [105,105,105], gray42: [107,107,107],
1624
+ gray43: [110,110,110], gray44: [112,112,112],
1625
+ gray45: [115,115,115], gray46: [117,117,117],
1626
+ gray47: [120,120,120], gray48: [122,122,122],
1627
+ gray49: [125,125,125], gray50: [127,127,127],
1628
+ gray51: [130,130,130], gray52: [133,133,133],
1629
+ gray53: [135,135,135], gray54: [138,138,138],
1630
+ gray55: [140,140,140], gray56: [143,143,143],
1631
+ gray57: [145,145,145], gray58: [148,148,148],
1632
+ gray59: [150,150,150], gray60: [153,153,153],
1633
+ gray61: [156,156,156], gray62: [158,158,158],
1634
+ gray63: [161,161,161], gray64: [163,163,163],
1635
+ gray65: [166,166,166], gray66: [168,168,168],
1636
+ gray67: [171,171,171], gray68: [173,173,173],
1637
+ gray69: [176,176,176], gray70: [179,179,179],
1638
+ gray71: [181,181,181], gray72: [184,184,184],
1639
+ gray73: [186,186,186], gray74: [189,189,189],
1640
+ gray75: [191,191,191], gray76: [194,194,194],
1641
+ gray77: [196,196,196], gray78: [199,199,199],
1642
+ gray79: [201,201,201], gray80: [204,204,204],
1643
+ gray81: [207,207,207], gray82: [209,209,209],
1644
+ gray83: [212,212,212], gray84: [214,214,214],
1645
+ gray85: [217,217,217], gray86: [219,219,219],
1646
+ gray87: [222,222,222], gray88: [224,224,224],
1647
+ gray89: [227,227,227], gray90: [229,229,229],
1648
+ gray91: [232,232,232], gray92: [235,235,235],
1649
+ gray93: [237,237,237], gray94: [240,240,240],
1650
+ gray95: [242,242,242], gray96: [245,245,245],
1651
+ gray97: [247,247,247], gray98: [250,250,250],
1652
+ gray99: [252,252,252], gray100: [255,255,255],
1653
+ green: [0,255,0], green1: [0,255,0],
1654
+ green2: [0,238,0], green3: [0,205,0],
1655
+ green4: [0,139,0], greenyellow: [173,255,47],
1656
+ grey: [190,190,190], honeydew: [240,255,240],
1657
+ honeydew1: [240,255,240], honeydew2: [224,238,224],
1658
+ honeydew3: [193,205,193], honeydew4: [131,139,131],
1659
+ hotpink: [255,105,180], hotpink1: [255,110,180],
1660
+ hotpink2: [238,106,167], hotpink3: [205,96,144],
1661
+ hotpink4: [139,58,98], indianred: [205,92,92],
1662
+ indianred1: [255,106,106], indianred2: [238,99,99],
1663
+ indianred3: [205,85,85], indianred4: [139,58,58],
1664
+ ivory: [255,255,240], ivory1: [255,255,240],
1665
+ ivory2: [238,238,224], ivory3: [205,205,193],
1666
+ ivory4: [139,139,131], khaki: [240,230,140],
1667
+ khaki1: [255,246,143], khaki2: [238,230,133],
1668
+ khaki3: [205,198,115], khaki4: [139,134,78],
1669
+ lavender: [230,230,250], lavenderblush: [255,240,245],
1670
+ lavenderblush1: [255,240,245], lavenderblush2: [238,224,229],
1671
+ lavenderblush3: [205,193,197], lavenderblush4: [139,131,134],
1672
+ lawngreen: [124,252,0], lemonchiffon: [255,250,205],
1673
+ lemonchiffon1: [255,250,205], lemonchiffon2: [238,233,191],
1674
+ lemonchiffon3: [205,201,165], lemonchiffon4: [139,137,112],
1675
+ lightblue: [173,216,230], lightblue1: [191,239,255],
1676
+ lightblue2: [178,223,238], lightblue3: [154,192,205],
1677
+ lightblue4: [104,131,139], lightcoral: [240,128,128],
1678
+ lightcyan: [224,255,255], lightcyan1: [224,255,255],
1679
+ lightcyan2: [209,238,238], lightcyan3: [180,205,205],
1680
+ lightcyan4: [122,139,139], lightgoldenrod: [238,221,130],
1681
+ lightgoldenrod1: [255,236,139], lightgoldenrod2: [238,220,130],
1682
+ lightgoldenrod3: [205,190,112], lightgoldenrod4: [139,129,76],
1683
+ lightgoldenrodyellow: [250,250,210], lightgray: [211,211,211],
1684
+ lightgreen: [144,238,144], lightgrey: [211,211,211],
1685
+ lightpink: [255,182,193], lightpink1: [255,174,185],
1686
+ lightpink2: [238,162,173], lightpink3: [205,140,149],
1687
+ lightpink4: [139,95,101], lightsalmon: [255,160,122],
1688
+ lightsalmon1: [255,160,122], lightsalmon2: [238,149,114],
1689
+ lightsalmon3: [205,129,98], lightsalmon4: [139,87,66],
1690
+ lightseagreen: [32,178,170], lightskyblue: [135,206,250],
1691
+ lightskyblue1: [176,226,255], lightskyblue2: [164,211,238],
1692
+ lightskyblue3: [141,182,205], lightskyblue4: [96,123,139],
1693
+ lightslateblue: [132,112,255], lightslategray: [119,136,153],
1694
+ lightslategrey: [119,136,153], lightsteelblue: [176,196,222],
1695
+ lightsteelblue1: [202,225,255], lightsteelblue2: [188,210,238],
1696
+ lightsteelblue3: [162,181,205], lightsteelblue4: [110,123,139],
1697
+ lightyellow: [255,255,224], lightyellow1: [255,255,224],
1698
+ lightyellow2: [238,238,209], lightyellow3: [205,205,180],
1699
+ lightyellow4: [139,139,122], limegreen: [50,205,50],
1700
+ linen: [250,240,230], magenta: [255,0,255],
1701
+ magenta1: [255,0,255], magenta2: [238,0,238],
1702
+ magenta3: [205,0,205], magenta4: [139,0,139],
1703
+ maroon: [176,48,96], maroon1: [255,52,179],
1704
+ maroon2: [238,48,167], maroon3: [205,41,144],
1705
+ maroon4: [139,28,98], mediumaquamarine: [102,205,170],
1706
+ mediumblue: [0,0,205], mediumorchid: [186,85,211],
1707
+ mediumorchid1: [224,102,255], mediumorchid2: [209,95,238],
1708
+ mediumorchid3: [180,82,205], mediumorchid4: [122,55,139],
1709
+ mediumpurple: [147,112,219], mediumpurple1: [171,130,255],
1710
+ mediumpurple2: [159,121,238], mediumpurple3: [137,104,205],
1711
+ mediumpurple4: [93,71,139], mediumseagreen: [60,179,113],
1712
+ mediumslateblue: [123,104,238], mediumspringgreen: [0,250,154],
1713
+ mediumturquoise: [72,209,204], mediumvioletred: [199,21,133],
1714
+ midnightblue: [25,25,112], mintcream: [245,255,250],
1715
+ mistyrose: [255,228,225], mistyrose1: [255,228,225],
1716
+ mistyrose2: [238,213,210], mistyrose3: [205,183,181],
1717
+ mistyrose4: [139,125,123], moccasin: [255,228,181],
1718
+ navajowhite: [255,222,173], navajowhite1: [255,222,173],
1719
+ navajowhite2: [238,207,161], navajowhite3: [205,179,139],
1720
+ navajowhite4: [139,121,94], navy: [0,0,128],
1721
+ navyblue: [0,0,128], oldlace: [253,245,230],
1722
+ olivedrab: [107,142,35], olivedrab1: [192,255,62],
1723
+ olivedrab2: [179,238,58], olivedrab3: [154,205,50],
1724
+ olivedrab4: [105,139,34], orange: [255,165,0],
1725
+ orange1: [255,165,0], orange2: [238,154,0],
1726
+ orange3: [205,133,0], orange4: [139,90,0],
1727
+ orangered: [255,69,0], orangered1: [255,69,0],
1728
+ orangered2: [238,64,0], orangered3: [205,55,0],
1729
+ orangered4: [139,37,0], orchid: [218,112,214],
1730
+ orchid1: [255,131,250], orchid2: [238,122,233],
1731
+ orchid3: [205,105,201], orchid4: [139,71,137],
1732
+ palegoldenrod: [238,232,170], palegreen: [152,251,152],
1733
+ palegreen1: [154,255,154], palegreen2: [144,238,144],
1734
+ palegreen3: [124,205,124], palegreen4: [84,139,84],
1735
+ paleturquoise: [175,238,238], paleturquoise1: [187,255,255],
1736
+ paleturquoise2: [174,238,238], paleturquoise3: [150,205,205],
1737
+ paleturquoise4: [102,139,139], palevioletred: [219,112,147],
1738
+ palevioletred1: [255,130,171], palevioletred2: [238,121,159],
1739
+ palevioletred3: [205,104,137], palevioletred4: [139,71,93],
1740
+ papayawhip: [255,239,213], peachpuff: [255,218,185],
1741
+ peachpuff1: [255,218,185], peachpuff2: [238,203,173],
1742
+ peachpuff3: [205,175,149], peachpuff4: [139,119,101],
1743
+ peru: [205,133,63], pink: [255,192,203],
1744
+ pink1: [255,181,197], pink2: [238,169,184],
1745
+ pink3: [205,145,158], pink4: [139,99,108],
1746
+ plum: [221,160,221], plum1: [255,187,255],
1747
+ plum2: [238,174,238], plum3: [205,150,205],
1748
+ plum4: [139,102,139], powderblue: [176,224,230],
1749
+ purple: [160,32,240], purple1: [155,48,255],
1750
+ purple2: [145,44,238], purple3: [125,38,205],
1751
+ purple4: [85,26,139], red: [255,0,0],
1752
+ red1: [255,0,0], red2: [238,0,0],
1753
+ red3: [205,0,0], red4: [139,0,0],
1754
+ rosybrown: [188,143,143], rosybrown1: [255,193,193],
1755
+ rosybrown2: [238,180,180], rosybrown3: [205,155,155],
1756
+ rosybrown4: [139,105,105], royalblue: [65,105,225],
1757
+ royalblue1: [72,118,255], royalblue2: [67,110,238],
1758
+ royalblue3: [58,95,205], royalblue4: [39,64,139],
1759
+ saddlebrown: [139,69,19], salmon: [250,128,114],
1760
+ salmon1: [255,140,105], salmon2: [238,130,98],
1761
+ salmon3: [205,112,84], salmon4: [139,76,57],
1762
+ sandybrown: [244,164,96], seagreen: [46,139,87],
1763
+ seagreen1: [84,255,159], seagreen2: [78,238,148],
1764
+ seagreen3: [67,205,128], seagreen4: [46,139,87],
1765
+ seashell: [255,245,238], seashell1: [255,245,238],
1766
+ seashell2: [238,229,222], seashell3: [205,197,191],
1767
+ seashell4: [139,134,130], sienna: [160,82,45],
1768
+ sienna1: [255,130,71], sienna2: [238,121,66],
1769
+ sienna3: [205,104,57], sienna4: [139,71,38],
1770
+ skyblue: [135,206,235], skyblue1: [135,206,255],
1771
+ skyblue2: [126,192,238], skyblue3: [108,166,205],
1772
+ skyblue4: [74,112,139], slateblue: [106,90,205],
1773
+ slateblue1: [131,111,255], slateblue2: [122,103,238],
1774
+ slateblue3: [105,89,205], slateblue4: [71,60,139],
1775
+ slategray: [112,128,144], slategray1: [198,226,255],
1776
+ slategray2: [185,211,238], slategray3: [159,182,205],
1777
+ slategray4: [108,123,139], slategrey: [112,128,144],
1778
+ snow: [255,250,250], snow1: [255,250,250],
1779
+ snow2: [238,233,233], snow3: [205,201,201],
1780
+ snow4: [139,137,137], springgreen: [0,255,127],
1781
+ springgreen1: [0,255,127], springgreen2: [0,238,118],
1782
+ springgreen3: [0,205,102], springgreen4: [0,139,69],
1783
+ steelblue: [70,130,180], steelblue1: [99,184,255],
1784
+ steelblue2: [92,172,238], steelblue3: [79,148,205],
1785
+ steelblue4: [54,100,139], tan: [210,180,140],
1786
+ tan1: [255,165,79], tan2: [238,154,73],
1787
+ tan3: [205,133,63], tan4: [139,90,43],
1788
+ thistle: [216,191,216], thistle1: [255,225,255],
1789
+ thistle2: [238,210,238], thistle3: [205,181,205],
1790
+ thistle4: [139,123,139], tomato: [255,99,71],
1791
+ tomato1: [255,99,71], tomato2: [238,92,66],
1792
+ tomato3: [205,79,57], tomato4: [139,54,38],
1793
+ turquoise: [64,224,208], turquoise1: [0,245,255],
1794
+ turquoise2: [0,229,238], turquoise3: [0,197,205],
1795
+ turquoise4: [0,134,139], violet: [238,130,238],
1796
+ violetred: [208,32,144], violetred1: [255,62,150],
1797
+ violetred2: [238,58,140], violetred3: [205,50,120],
1798
+ violetred4: [139,34,82], wheat: [245,222,179],
1799
+ wheat1: [255,231,186], wheat2: [238,216,174],
1800
+ wheat3: [205,186,150], wheat4: [139,126,102],
1801
+ white: [255,255,255], whitesmoke: [245,245,245],
1802
+ yellow: [255,255,0], yellow1: [255,255,0],
1803
+ yellow2: [238,238,0], yellow3: [205,205,0],
1804
+ yellow4: [139,139,0], yellowgreen: [154,205,50],
1805
+ };
1806
+
1807
+ // ────────────────────────────────────────────────────────────
1808
+ // SECTION 20: COLOR UTILITIES
1809
+ // ────────────────────────────────────────────────────────────
1810
+
1811
+ /**
1812
+ * Normalize an X11 color name (lowercase, remove spaces/hyphens).
1813
+ */
1814
+ function _normColorName(name) {
1815
+ return name.toLowerCase().replace(/[\s\-_]/g, '');
1816
+ }
1817
+
1818
+ /**
1819
+ * Look up an X11 named color. Returns [r,g,b] or null.
1820
+ * @param {string} name
1821
+ * @returns {[number,number,number]|null}
1822
+ */
1823
+ function colorByName(name) {
1824
+ return X11Colors[_normColorName(name)] || null;
1825
+ }
1826
+
1827
+ /**
1828
+ * Look up an X11 color name by exact [r,g,b] values.
1829
+ * @param {number} r
1830
+ * @param {number} g
1831
+ * @param {number} b
1832
+ * @returns {string|null}
1833
+ */
1834
+ function colorNameByRGB(r, g, b) {
1835
+ for (const [name, [cr,cg,cb]] of Object.entries(X11Colors)) {
1836
+ if (cr === r && cg === g && cb === b) return name;
1837
+ }
1838
+ return null;
1839
+ }
1840
+
1841
+ /**
1842
+ * Find the closest X11 named color to an [r,g,b] value.
1843
+ * @param {number} r
1844
+ * @param {number} g
1845
+ * @param {number} b
1846
+ * @returns {{ name: string, rgb: [number,number,number], distance: number }}
1847
+ */
1848
+ function closestColor(r, g, b) {
1849
+ let best = null, bestDist = Infinity;
1850
+ for (const [name, [cr,cg,cb]] of Object.entries(X11Colors)) {
1851
+ const d = (r-cr)**2 + (g-cg)**2 + (b-cb)**2;
1852
+ if (d < bestDist) { bestDist = d; best = { name, rgb: [cr,cg,cb], distance: Math.sqrt(d) }; }
1853
+ }
1854
+ return best;
1855
+ }
1856
+
1857
+ /**
1858
+ * Parse a color string in any common format:
1859
+ * '#RGB', '#RRGGBB', 'rgb(r,g,b)', 'X11 name'
1860
+ * Returns { r, g, b } or null.
1861
+ * @param {string} str
1862
+ * @returns {{r:number, g:number, b:number}|null}
1863
+ */
1864
+ function parseColor(str) {
1865
+ str = str.trim();
1866
+ // #RGB
1867
+ if (/^#[0-9a-fA-F]{3}$/.test(str)) {
1868
+ const [,r,g,b] = str.match(/^#(.)(.)(.)$/);
1869
+ return { r: parseInt(r+r,16), g: parseInt(g+g,16), b: parseInt(b+b,16) };
1870
+ }
1871
+ // #RRGGBB
1872
+ if (/^#[0-9a-fA-F]{6}$/.test(str)) {
1873
+ return { r: parseInt(str.slice(1,3),16), g: parseInt(str.slice(3,5),16), b: parseInt(str.slice(5,7),16) };
1874
+ }
1875
+ // rgb(r,g,b)
1876
+ const rgbMatch = str.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
1877
+ if (rgbMatch) return { r: +rgbMatch[1], g: +rgbMatch[2], b: +rgbMatch[3] };
1878
+ // X11 name
1879
+ const named = colorByName(str);
1880
+ if (named) return { r: named[0], g: named[1], b: named[2] };
1881
+ return null;
1882
+ }
1883
+
1884
+ /**
1885
+ * Convert [r,g,b] to hex string.
1886
+ * @param {number} r @param {number} g @param {number} b
1887
+ * @returns {string}
1888
+ */
1889
+ function rgbToHex(r, g, b) {
1890
+ return '#' + [r,g,b].map(v => Math.max(0,Math.min(255,v)).toString(16).padStart(2,'0').toUpperCase()).join('');
1891
+ }
1892
+
1893
+ /**
1894
+ * Convert [r,g,b] to HSL { h, s, l } (h: 0-360, s/l: 0-100).
1895
+ */
1896
+ function rgbToHSL(r, g, b) {
1897
+ r /= 255; g /= 255; b /= 255;
1898
+ const max = Math.max(r,g,b), min = Math.min(r,g,b);
1899
+ const l = (max+min)/2;
1900
+ if (max === min) return { h:0, s:0, l: Math.round(l*100) };
1901
+ const d = max - min;
1902
+ const s = l > 0.5 ? d/(2-max-min) : d/(max+min);
1903
+ let h;
1904
+ if (max===r) h = ((g-b)/d + (g<b?6:0))/6;
1905
+ else if (max===g) h = ((b-r)/d+2)/6;
1906
+ else h = ((r-g)/d+4)/6;
1907
+ return { h: Math.round(h*360), s: Math.round(s*100), l: Math.round(l*100) };
1908
+ }
1909
+
1910
+ /**
1911
+ * Convert HSL { h, s, l } to [r, g, b].
1912
+ */
1913
+ function hslToRGB(h, s, l) {
1914
+ s /= 100; l /= 100;
1915
+ const c = (1 - Math.abs(2*l-1)) * s;
1916
+ const x = c * (1 - Math.abs((h/60)%2 - 1));
1917
+ const m = l - c/2;
1918
+ let r=0,g=0,b=0;
1919
+ if (h<60) { r=c; g=x; }
1920
+ else if (h<120) { r=x; g=c; }
1921
+ else if (h<180) { g=c; b=x; }
1922
+ else if (h<240) { g=x; b=c; }
1923
+ else if (h<300) { r=x; b=c; }
1924
+ else { r=c; b=x; }
1925
+ return [Math.round((r+m)*255), Math.round((g+m)*255), Math.round((b+m)*255)];
1926
+ }
1927
+
1928
+ /**
1929
+ * Convert [r,g,b] to HSV { h, s, v } (h: 0-360, s/v: 0-100).
1930
+ */
1931
+ function rgbToHSV(r, g, b) {
1932
+ r /= 255; g /= 255; b /= 255;
1933
+ const max = Math.max(r,g,b), min = Math.min(r,g,b), d = max-min;
1934
+ const v = max;
1935
+ const s = max === 0 ? 0 : d/max;
1936
+ let h = 0;
1937
+ if (d !== 0) {
1938
+ if (max===r) h = ((g-b)/d)%6;
1939
+ else if (max===g) h = (b-r)/d+2;
1940
+ else h = (r-g)/d+4;
1941
+ h = h/6;
1942
+ if (h<0) h+=1;
1943
+ }
1944
+ return { h: Math.round(h*360), s: Math.round(s*100), v: Math.round(v*100) };
1945
+ }
1946
+
1947
+ /**
1948
+ * Convert HSV to [r,g,b].
1949
+ */
1950
+ function hsvToRGB(h, s, v) {
1951
+ s /= 100; v /= 100;
1952
+ const c = v*s, x = c*(1-Math.abs((h/60)%2-1)), m = v-c;
1953
+ let r=0,g=0,b=0;
1954
+ if (h<60) { r=c; g=x; }
1955
+ else if (h<120) { r=x; g=c; }
1956
+ else if (h<180) { g=c; b=x; }
1957
+ else if (h<240) { g=x; b=c; }
1958
+ else if (h<300) { r=x; b=c; }
1959
+ else { r=c; b=x; }
1960
+ return [Math.round((r+m)*255), Math.round((g+m)*255), Math.round((b+m)*255)];
1961
+ }
1962
+
1963
+ /**
1964
+ * Convert [r,g,b] to X11 16-bit format (0–65535 per channel).
1965
+ */
1966
+ function rgbToX11(r, g, b) {
1967
+ return { r: r*257, g: g*257, b: b*257 };
1968
+ }
1969
+
1970
+ /**
1971
+ * Convert X11 16-bit format to [r,g,b] (0–255).
1972
+ */
1973
+ function x11ToRGB(r, g, b) {
1974
+ return [Math.round(r/257), Math.round(g/257), Math.round(b/257)];
1975
+ }
1976
+
1977
+ /**
1978
+ * Calculate relative luminance (WCAG).
1979
+ */
1980
+ function luminance(r, g, b) {
1981
+ const c = [r,g,b].map(v => { v /= 255; return v <= 0.03928 ? v/12.92 : ((v+0.055)/1.055)**2.4; });
1982
+ return 0.2126*c[0] + 0.7152*c[1] + 0.0722*c[2];
1983
+ }
1984
+
1985
+ /**
1986
+ * Calculate WCAG contrast ratio between two colors.
1987
+ * @param {[number,number,number]} c1
1988
+ * @param {[number,number,number]} c2
1989
+ * @returns {number} ratio (1-21)
1990
+ */
1991
+ function contrastRatio(c1, c2) {
1992
+ const l1 = luminance(...c1), l2 = luminance(...c2);
1993
+ return (Math.max(l1,l2)+0.05) / (Math.min(l1,l2)+0.05);
1994
+ }
1995
+
1996
+ /**
1997
+ * Check WCAG accessibility level.
1998
+ * @returns {'AAA'|'AA'|'AA Large'|'Fail'}
1999
+ */
2000
+ function wcagLevel(c1, c2) {
2001
+ const r = contrastRatio(c1, c2);
2002
+ if (r >= 7) return 'AAA';
2003
+ if (r >= 4.5) return 'AA';
2004
+ if (r >= 3) return 'AA Large';
2005
+ return 'Fail';
2006
+ }
2007
+
2008
+ /**
2009
+ * Mix two [r,g,b] colors.
2010
+ * @param {[number,number,number]} c1
2011
+ * @param {[number,number,number]} c2
2012
+ * @param {number} [t=0.5] mix factor 0=c1, 1=c2
2013
+ * @returns {[number,number,number]}
2014
+ */
2015
+ function mixColors(c1, c2, t = 0.5) {
2016
+ return c1.map((v,i) => Math.round(v + (c2[i]-v)*t));
2017
+ }
2018
+
2019
+ /**
2020
+ * Search X11 colors by partial name.
2021
+ * @param {string} query
2022
+ * @returns {Array<{name:string, rgb:[number,number,number]}>}
2023
+ */
2024
+ function searchColors(query) {
2025
+ const q = _normColorName(query);
2026
+ return Object.entries(X11Colors)
2027
+ .filter(([name]) => name.includes(q))
2028
+ .map(([name, rgb]) => ({ name, rgb }));
2029
+ }
2030
+
2031
+ // ────────────────────────────────────────────────────────────
2032
+ // SECTION 21: PROTOCOL MESSAGE BUILDERS
2033
+ // ────────────────────────────────────────────────────────────
2034
+
2035
+ // ── FIX 1: Runtime byte-order detection ──────────────────────
2036
+ // The X11 protocol lets the client declare its native byte order.
2037
+ // We detect it at load time instead of hard-coding little-endian,
2038
+ // so the same code works on big-endian hosts (SPARC, PowerPC, etc.).
2039
+ const _hostIsLE = (() => {
2040
+ const b = new Uint8Array(2);
2041
+ new DataView(b.buffer).setUint16(0, 1, true); // write 1 as LE
2042
+ return b[0] === 1; // true if host is LE
2043
+ })();
2044
+
2045
+ const _byteOrderMarker = _hostIsLE ? 0x6C /* 'l' */ : 0x42 /* 'B' */;
2046
+
2047
+ /**
2048
+ * Write a uint16 / uint32 in the host's native byte order.
2049
+ * @internal
2050
+ */
2051
+ function _setU16(view, offset, val) { view.setUint16(offset, val, _hostIsLE); }
2052
+ function _setU32(view, offset, val) { view.setUint32(offset, val, _hostIsLE); }
2053
+ function _setI16(view, offset, val) { view.setInt16(offset, val, _hostIsLE); }
2054
+
2055
+ // ── FIX 2: Auth-aware connection request ─────────────────────
2056
+ /**
2057
+ * Build an X11 connection setup request (RFC / Xlib §8).
2058
+ *
2059
+ * The packet includes optional MIT-MAGIC-COOKIE-1 authorisation data so
2060
+ * that callers can connect to servers that require authentication (i.e.
2061
+ * virtually every real display server).
2062
+ *
2063
+ * @param {object} [opts]
2064
+ * @param {number} [opts.majorVersion=11] Protocol major version
2065
+ * @param {number} [opts.minorVersion=0] Protocol minor version
2066
+ * @param {string} [opts.authName=''] e.g. 'MIT-MAGIC-COOKIE-1'
2067
+ * @param {Uint8Array} [opts.authData] Raw auth data bytes
2068
+ * @returns {Uint8Array} Ready-to-send connection setup packet
2069
+ *
2070
+ * @example
2071
+ * // No auth (e.g. Xvfb with -nolisten tcp and xhost +)
2072
+ * buildConnectionRequest();
2073
+ *
2074
+ * // MIT-MAGIC-COOKIE-1 (read from ~/.Xauthority via the 'xauth' package)
2075
+ * buildConnectionRequest({
2076
+ * authName: 'MIT-MAGIC-COOKIE-1',
2077
+ * authData: Uint8Array.from(Buffer.from(cookieHex, 'hex')),
2078
+ * });
2079
+ */
2080
+ function buildConnectionRequest(opts = {}) {
2081
+ const major = opts.majorVersion ?? 11;
2082
+ const minor = opts.minorVersion ?? 0;
2083
+ const authName = opts.authName ?? '';
2084
+ const authData = opts.authData ?? new Uint8Array(0);
2085
+
2086
+ const enc = new TextEncoder();
2087
+ const nameBytes = enc.encode(authName);
2088
+ const namePad = (4 - (nameBytes.length % 4)) % 4;
2089
+ const dataPad = (4 - (authData.length % 4)) % 4;
2090
+
2091
+ const totalLen = 12 + nameBytes.length + namePad + authData.length + dataPad;
2092
+ const buf = new Uint8Array(totalLen);
2093
+ const view = new DataView(buf.buffer);
2094
+
2095
+ view.setUint8(0, _byteOrderMarker); // byte-order (host-native)
2096
+ view.setUint8(1, 0); // unused
2097
+ _setU16(view, 2, major); // protocol-major-version
2098
+ _setU16(view, 4, minor); // protocol-minor-version
2099
+ _setU16(view, 6, nameBytes.length); // auth-proto-name-length
2100
+ _setU16(view, 8, authData.length); // auth-proto-data-length
2101
+ _setU16(view, 10, 0); // unused
2102
+
2103
+ let off = 12;
2104
+ buf.set(nameBytes, off); off += nameBytes.length + namePad;
2105
+ buf.set(authData, off);
2106
+
2107
+ return buf;
2108
+ }
2109
+
2110
+ /**
2111
+ * Build a CreateWindow request buffer.
2112
+ * @param {object} attrs
2113
+ * @returns {Uint8Array}
2114
+ */
2115
+ function buildCreateWindowRequest(attrs) {
2116
+ const {
2117
+ wid, parent, x=0, y=0, width=100, height=100,
2118
+ borderWidth=0, windowClass=WindowClass.INPUT_OUTPUT,
2119
+ visual=0, valueMask=0, values=[]
2120
+ } = attrs;
2121
+ const len = 8 + values.length;
2122
+ const buf = new Uint8Array(len * 4);
2123
+ const v = new DataView(buf.buffer);
2124
+ v.setUint8(0, Request.CREATE_WINDOW);
2125
+ v.setUint8(1, 0); // depth
2126
+ _setU16(v, 2, len);
2127
+ _setU32(v, 4, wid);
2128
+ _setU32(v, 8, parent);
2129
+ _setI16(v, 12, x);
2130
+ _setI16(v, 14, y);
2131
+ _setU16(v, 16, width);
2132
+ _setU16(v, 18, height);
2133
+ _setU16(v, 20, borderWidth);
2134
+ _setU16(v, 22, windowClass);
2135
+ _setU32(v, 24, visual);
2136
+ _setU32(v, 28, valueMask);
2137
+ values.forEach((val, i) => _setU32(v, 32 + i*4, val));
2138
+ return buf;
2139
+ }
2140
+
2141
+ /**
2142
+ * Build a MapWindow request.
2143
+ * @param {number} wid
2144
+ * @returns {Uint8Array}
2145
+ */
2146
+ function buildMapWindowRequest(wid) {
2147
+ const buf = new Uint8Array(8);
2148
+ const v = new DataView(buf.buffer);
2149
+ v.setUint8(0, Request.MAP_WINDOW);
2150
+ v.setUint8(1, 0);
2151
+ _setU16(v, 2, 2);
2152
+ _setU32(v, 4, wid);
2153
+ return buf;
2154
+ }
2155
+
2156
+ /**
2157
+ * Build a ChangeProperty request.
2158
+ * @param {object} attrs
2159
+ * @returns {Uint8Array}
2160
+ */
2161
+ function buildChangePropertyRequest(attrs) {
2162
+ const { wid, mode=PropMode.REPLACE, property, type, format=PropFormat.F32, data=[] } = attrs;
2163
+ const dataBytes = format === 8 ? data.length : format === 16 ? data.length*2 : data.length*4;
2164
+ const padded = Math.ceil(dataBytes / 4) * 4;
2165
+ const len = 6 + padded/4;
2166
+ const buf = new Uint8Array(len * 4);
2167
+ const v = new DataView(buf.buffer);
2168
+ v.setUint8(0, Request.CHANGE_PROPERTY);
2169
+ v.setUint8(1, mode);
2170
+ _setU16(v, 2, len);
2171
+ _setU32(v, 4, wid);
2172
+ _setU32(v, 8, property);
2173
+ _setU32(v, 12, type);
2174
+ v.setUint8(16, format);
2175
+ // bytes 17-19: unused
2176
+ _setU32(v, 20, data.length);
2177
+ data.forEach((val, i) => {
2178
+ if (format === 8) v.setUint8(24+i, val);
2179
+ else if (format === 16) _setU16(v, 24+i*2, val);
2180
+ else _setU32(v, 24+i*4, val);
2181
+ });
2182
+ return buf;
2183
+ }
2184
+
2185
+ /**
2186
+ * Build an InternAtom request.
2187
+ * @param {string} name
2188
+ * @param {boolean} [onlyIfExists=false]
2189
+ * @returns {Uint8Array}
2190
+ */
2191
+ function buildInternAtomRequest(name, onlyIfExists = false) {
2192
+ const encoded = new TextEncoder().encode(name);
2193
+ const padded = Math.ceil(encoded.length / 4) * 4;
2194
+ const len = 2 + padded/4;
2195
+ const buf = new Uint8Array(len * 4);
2196
+ const v = new DataView(buf.buffer);
2197
+ v.setUint8(0, Request.INTERN_ATOM);
2198
+ v.setUint8(1, onlyIfExists ? 1 : 0);
2199
+ _setU16(v, 2, len);
2200
+ _setU16(v, 4, encoded.length);
2201
+ buf.set(encoded, 8);
2202
+ return buf;
2203
+ }
2204
+
2205
+ // ── FIX 3: Extension negotiation helper ──────────────────────
2206
+ /**
2207
+ * Build a QueryExtension request for the given extension name string.
2208
+ * Use this to probe whether a given extension is available before
2209
+ * sending any extension-specific requests.
2210
+ *
2211
+ * @param {string} name e.g. Extension.RANDR ('RANDR')
2212
+ * @returns {Uint8Array}
2213
+ *
2214
+ * @example
2215
+ * // Node.js with a raw socket to the X11 display:
2216
+ * socket.write(buildQueryExtensionRequest(Extension.RANDR));
2217
+ * // Parse the reply: reply[8] is 'present' (1 = yes, 0 = not present)
2218
+ */
2219
+ function buildQueryExtensionRequest(name) {
2220
+ const encoded = new TextEncoder().encode(name);
2221
+ const padded = Math.ceil(encoded.length / 4) * 4;
2222
+ const len = 2 + padded / 4;
2223
+ const buf = new Uint8Array(len * 4);
2224
+ const v = new DataView(buf.buffer);
2225
+ v.setUint8(0, Request.QUERY_EXTENSION);
2226
+ v.setUint8(1, 0);
2227
+ _setU16(v, 2, len);
2228
+ _setU16(v, 4, encoded.length);
2229
+ // bytes 6-7: unused
2230
+ buf.set(encoded, 8);
2231
+ return buf;
2232
+ }
2233
+
2234
+ /**
2235
+ * Parse a QueryExtension reply (32-byte fixed-size reply).
2236
+ * Call this with the raw reply Uint8Array received from the server.
2237
+ *
2238
+ * @param {Uint8Array} reply
2239
+ * @returns {{ present: boolean, majorOpcode: number, firstEvent: number, firstError: number }}
2240
+ */
2241
+ function parseQueryExtensionReply(reply) {
2242
+ if (reply.length < 32) throw new RangeError('QueryExtension reply must be ≥ 32 bytes');
2243
+ const v = new DataView(reply.buffer, reply.byteOffset, reply.byteLength);
2244
+ return {
2245
+ present: v.getUint8(8) === 1,
2246
+ majorOpcode: v.getUint8(9),
2247
+ firstEvent: v.getUint8(10),
2248
+ firstError: v.getUint8(11),
2249
+ };
2250
+ }
2251
+
2252
+ /**
2253
+ * Convenience: throw a clear error when an extension is not present.
2254
+ * Call this after parsing the QueryExtension reply for a required extension.
2255
+ *
2256
+ * @param {string} name Extension name (for the error message)
2257
+ * @param {ReturnType<parseQueryExtensionReply>} reply
2258
+ * @throws {Error} if reply.present is false
2259
+ */
2260
+ function assertExtension(name, reply) {
2261
+ if (!reply.present) {
2262
+ throw new Error(
2263
+ `X11 extension "${name}" is not available on this server. ` +
2264
+ `Check server capabilities with buildQueryExtensionRequest() before use.`
2265
+ );
2266
+ }
2267
+ }
2268
+
2269
+ // ────────────────────────────────────────────────────────────
2270
+ // SECTION 22: EXTENSION CONSTANTS
2271
+ // ────────────────────────────────────────────────────────────
2272
+
2273
+ /** Common X11 extension names */
2274
+ const Extension = {
2275
+ BIGREQ: 'BIG-REQUESTS',
2276
+ COMPOSITE: 'Composite',
2277
+ DAMAGE: 'DAMAGE',
2278
+ DPMS: 'DPMS',
2279
+ DRI2: 'DRI2',
2280
+ DRI3: 'DRI3',
2281
+ FIXES: 'XFIXES',
2282
+ GENERIC_EVENT:'Generic Event Extension',
2283
+ GLX: 'GLX',
2284
+ INPUT: 'XInputExtension',
2285
+ PRESENT: 'Present',
2286
+ RANDR: 'RANDR',
2287
+ RECORD: 'RECORD',
2288
+ RENDER: 'RENDER',
2289
+ RESOURCE: 'X-Resource',
2290
+ SCREENSAVER: 'MIT-SCREEN-SAVER',
2291
+ SHAPE: 'SHAPE',
2292
+ SHM: 'MIT-SHM',
2293
+ SYNC: 'SYNC',
2294
+ TEST: 'XTEST',
2295
+ VIDEO: 'XVideo',
2296
+ XINERAMA: 'XINERAMA',
2297
+ XKB: 'XKEYBOARD',
2298
+ XPRINT: 'XpExtension',
2299
+ };
2300
+
2301
+ /** XRANDR rotation/reflection flags */
2302
+ const RandrRotation = {
2303
+ ROTATE_0: 1,
2304
+ ROTATE_90: 2,
2305
+ ROTATE_180: 4,
2306
+ ROTATE_270: 8,
2307
+ REFLECT_X: 16,
2308
+ REFLECT_Y: 32,
2309
+ };
2310
+
2311
+ /** XRANDR connection status */
2312
+ const RandrConnection = {
2313
+ CONNECTED: 0,
2314
+ DISCONNECTED: 1,
2315
+ UNKNOWN_CONNECTION:2,
2316
+ };
2317
+
2318
+ /** XRender picture format types */
2319
+ const PictType = {
2320
+ INDEXED: 0,
2321
+ DIRECT: 1,
2322
+ };
2323
+
2324
+ /** XRender repeat types */
2325
+ const RepeatType = {
2326
+ NONE: 0,
2327
+ NORMAL: 1,
2328
+ PAD: 2,
2329
+ REFLECT: 3,
2330
+ };
2331
+
2332
+ /** XInput2 device types */
2333
+ const XIDeviceType = {
2334
+ MASTER_POINTER: 1,
2335
+ MASTER_KEYBOARD: 2,
2336
+ SLAVE_POINTER: 3,
2337
+ SLAVE_KEYBOARD: 4,
2338
+ FLOATING_SLAVE: 5,
2339
+ };
2340
+
2341
+ /** XFIXES region operations */
2342
+ const FixesRegionOp = {
2343
+ SET: 0,
2344
+ UNION: 1,
2345
+ INTERSECT: 2,
2346
+ SUBTRACT: 3,
2347
+ INVERT: 4,
2348
+ };
2349
+
2350
+ /** XSync counter value sign */
2351
+ const SyncValueType = {
2352
+ ABSOLUTE: 0,
2353
+ RELATIVE: 1,
2354
+ };
2355
+
2356
+ /** COMPOSITE redirect modes */
2357
+ const CompositeRedirect = {
2358
+ AUTOMATIC: 0,
2359
+ MANUAL: 1,
2360
+ };
2361
+
2362
+ // ────────────────────────────────────────────────────────────
2363
+ // EXPORTS
2364
+ // ────────────────────────────────────────────────────────────
2365
+ // EXPORTS (FIX 4: dual CJS + ESM shim)
2366
+ // ────────────────────────────────────────────────────────────
2367
+
2368
+ const kitdef = {
2369
+ // ── Host byte-order (runtime) ────────────────────
2370
+ hostIsLittleEndian: _hostIsLE,
2371
+ byteOrderMarker: _byteOrderMarker,
2372
+
2373
+ // ── Protocol fundamentals ────────────────────────
2374
+ PROTOCOL, ByteOrder, XID, XBool, Time,
2375
+
2376
+ // ── Events ───────────────────────────────────────
2377
+ EventType, EventTypeName, EventMask, decodeEventMask,
2378
+
2379
+ // ── Requests ─────────────────────────────────────
2380
+ Request, RequestName,
2381
+
2382
+ // ── Errors ───────────────────────────────────────
2383
+ ErrorCode, ErrorName,
2384
+
2385
+ // ── Window ───────────────────────────────────────
2386
+ CW, WindowClass, MapState, BackingStore, BitGravity, WinGravity,
2387
+
2388
+ // ── Graphics Context ─────────────────────────────
2389
+ GCMask, GCFunction, LineStyle, CapStyle, JoinStyle,
2390
+ FillStyle, FillRule, ArcMode, SubwindowMode,
2391
+
2392
+ // ── Input ────────────────────────────────────────
2393
+ ModifierMask, Button, FocusMode, RevertTo, GrabMode, GrabStatus,
2394
+ AllowEvents, NotifyMode, NotifyDetail, Visibility, Circulate,
2395
+ PropertyState, ColormapState, MappingRequest,
2396
+
2397
+ // ── Screen / Power ───────────────────────────────
2398
+ ScreenSaver, ScreenSaverState, ScreenSaverKind, Blanking, Exposures,
2399
+
2400
+ // ── Host / Access ────────────────────────────────
2401
+ HostFamily, AccessControl, CloseDownMode,
2402
+
2403
+ // ── Colormap / Visual ────────────────────────────
2404
+ ColormapAlloc, VisualClass,
2405
+
2406
+ // ── Image ────────────────────────────────────────
2407
+ ImageFormat, BitmapBitOrder, ByteOrderConst, QueryBestSizeClass,
2408
+
2409
+ // ── Atoms ────────────────────────────────────────
2410
+ Atom, AtomName,
2411
+
2412
+ // ── ICCCM ────────────────────────────────────────
2413
+ ICCCM, WMState, WMHints, SizeHints,
2414
+
2415
+ // ── EWMH ─────────────────────────────────────────
2416
+ EWMH, EWMHStateAction, MoveResizeDirection,
2417
+
2418
+ // ── Selections / Properties ──────────────────────
2419
+ SelectionType, PropMode, PropFormat,
2420
+
2421
+ // ── Keysyms ──────────────────────────────────────
2422
+ Keysym, KeysymName,
2423
+ keysymByName, keysymToName, keysymToUnicode, keysymToChar,
2424
+ unicodeToKeysym, isModifierKeysym, isFunctionKeysym,
2425
+ isKeypadKeysym, isPrintableKeysym,
2426
+
2427
+ // ── X11 Colors ───────────────────────────────────
2428
+ X11Colors,
2429
+ colorByName, colorNameByRGB, closestColor,
2430
+ parseColor, rgbToHex,
2431
+ rgbToHSL, hslToRGB, rgbToHSV, hsvToRGB,
2432
+ rgbToX11, x11ToRGB,
2433
+ luminance, contrastRatio, wcagLevel,
2434
+ mixColors, searchColors,
2435
+
2436
+ // ── Protocol message builders ────────────────────
2437
+ buildConnectionRequest, // FIX 1+2: endian-aware + auth support
2438
+ buildCreateWindowRequest, // FIX 1: endian-aware
2439
+ buildMapWindowRequest, // FIX 1: endian-aware
2440
+ buildChangePropertyRequest, // FIX 1: endian-aware
2441
+ buildInternAtomRequest, // FIX 1: endian-aware
2442
+
2443
+ // ── Extension negotiation (FIX 3) ────────────────
2444
+ buildQueryExtensionRequest,
2445
+ parseQueryExtensionReply,
2446
+ assertExtension,
2447
+
2448
+ // ── Extensions ───────────────────────────────────
2449
+ Extension,
2450
+ RandrRotation, RandrConnection,
2451
+ PictType, RepeatType,
2452
+ XIDeviceType,
2453
+ FixesRegionOp,
2454
+ SyncValueType,
2455
+ CompositeRedirect,
2456
+ };
2457
+
2458
+ // FIX 4: Dual CommonJS + ESM export shim.
2459
+ //
2460
+ // CJS (Node.js require): const { kitdef } = require('./kitx11.js')
2461
+ // ESM (import / browser): import { kitdef } from './kitx11.js'
2462
+ //
2463
+ // The 'typeof' guard is evaluated at runtime so bundlers targeting
2464
+ // pure-ESM environments can tree-shake the CJS branch away.
2465
+ if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
2466
+ // CommonJS (Node.js)
2467
+ module.exports = { kitdef };
2468
+ } else if (typeof globalThis !== 'undefined') {
2469
+ // Browser global fallback (no bundler, no module system)
2470
+ globalThis.kitx11 = { kitdef };
2471
+ }
2472
+