diff --git a/bin/keyboard_layouts.mjs b/bin/keyboard_layouts.mjs
deleted file mode 100644
index 4f8aa64eb..000000000
--- a/bin/keyboard_layouts.mjs
+++ /dev/null
@@ -1,38 +0,0 @@
-import fs from 'node:fs';
-import path from 'node:path';
-
-const DATA = {};
-
-for (let i = 2; i < process.argv.length; ++i) {
- const filename = process.argv[i];
- const key = path.basename(filename).split('.')[0];
- const value = JSON.parse(fs.readFileSync(filename));
- DATA[key] = value;
-}
-
-let keys = [];
-for (const map in DATA) {
- keys = keys.concat(Object.keys(DATA[map]));
-}
-const KEYS = Array.from(new Set(keys)).sort();
-const ACC = Object.fromEntries(Object.keys(DATA).map((el, i) => [el, i]));
-const MAP = Object.fromEntries(KEYS.map(el => [el, []]));
-for (const key of KEYS) {
- for (const map in ACC) {
- MAP[key].push(DATA[map][key]);
- }
-}
-
-// minify if all entries are of length 1
-for (const key in MAP) {
- for (const c of MAP[key]) {
- if (!c || c.length !== 1)
- break;
- }
- MAP[key] = MAP[key].join('');
-}
-
-const FINAL = {acc: ACC, map: MAP};
-
-console.log(FINAL);
-console.log(JSON.stringify(FINAL).length);
diff --git a/fixtures/keyboard_layout.html b/fixtures/keyboard_layout.html
deleted file mode 100644
index 9ac068863..000000000
--- a/fixtures/keyboard_layout.html
+++ /dev/null
@@ -1,270 +0,0 @@
-
-
-
-
-
-
- Keyboard Layout
-
-
-
-
Keyboard Base Layout
-
- To record your keyboard base layout (unshifted), press all keys from left to right.
- While you can record most keys with this helper, it is enough to press all character producing keys.
-
- Esc deletes last key except itself.
- Enter starts new key row (Enter itself gets not shown as key).
-
-
-
- Esc
-
-
-
-
-
-
-
-
-
-
-
diff --git a/fixtures/keyboard_layouts/DE.json b/fixtures/keyboard_layouts/DE.json
deleted file mode 100644
index 1623cab94..000000000
--- a/fixtures/keyboard_layouts/DE.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "Backquote": "^",
- "Backslash": "#",
- "BracketLeft": "ü",
- "BracketRight": "+",
- "Comma": ",",
- "Digit0": "0",
- "Digit1": "1",
- "Digit2": "2",
- "Digit3": "3",
- "Digit4": "4",
- "Digit5": "5",
- "Digit6": "6",
- "Digit7": "7",
- "Digit8": "8",
- "Digit9": "9",
- "Equal": "´",
- "IntlBackslash": "<",
- "KeyA": "a",
- "KeyB": "b",
- "KeyC": "c",
- "KeyD": "d",
- "KeyE": "e",
- "KeyF": "f",
- "KeyG": "g",
- "KeyH": "h",
- "KeyI": "i",
- "KeyJ": "j",
- "KeyK": "k",
- "KeyL": "l",
- "KeyM": "m",
- "KeyN": "n",
- "KeyO": "o",
- "KeyP": "p",
- "KeyQ": "q",
- "KeyR": "r",
- "KeyS": "s",
- "KeyT": "t",
- "KeyU": "u",
- "KeyV": "v",
- "KeyW": "w",
- "KeyX": "x",
- "KeyY": "z",
- "KeyZ": "y",
- "Minus": "ß",
- "Period": ".",
- "Quote": "ä",
- "Semicolon": "ö",
- "Slash": "-"
-}
\ No newline at end of file
diff --git a/fixtures/keyboard_layouts/ES.json b/fixtures/keyboard_layouts/ES.json
deleted file mode 100644
index 130be6d3d..000000000
--- a/fixtures/keyboard_layouts/ES.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "Backquote": "º",
- "Backslash": "ç",
- "BracketLeft": "`",
- "BracketRight": "+",
- "Comma": ",",
- "Digit0": "0",
- "Digit1": "1",
- "Digit2": "2",
- "Digit3": "3",
- "Digit4": "4",
- "Digit5": "5",
- "Digit6": "6",
- "Digit7": "7",
- "Digit8": "8",
- "Digit9": "9",
- "Equal": "¡",
- "IntlBackslash": "<",
- "KeyA": "a",
- "KeyB": "b",
- "KeyC": "c",
- "KeyD": "d",
- "KeyE": "e",
- "KeyF": "f",
- "KeyG": "g",
- "KeyH": "h",
- "KeyI": "i",
- "KeyJ": "j",
- "KeyK": "k",
- "KeyL": "l",
- "KeyM": "m",
- "KeyN": "n",
- "KeyO": "o",
- "KeyP": "p",
- "KeyQ": "q",
- "KeyR": "r",
- "KeyS": "s",
- "KeyT": "t",
- "KeyU": "u",
- "KeyV": "v",
- "KeyW": "w",
- "KeyX": "x",
- "KeyY": "y",
- "KeyZ": "z",
- "Minus": "'",
- "Period": ".",
- "Quote": "´",
- "Semicolon": "ñ",
- "Slash": "-"
-}
\ No newline at end of file
diff --git a/fixtures/keyboard_layouts/ES_LA.json b/fixtures/keyboard_layouts/ES_LA.json
deleted file mode 100644
index 7178f4355..000000000
--- a/fixtures/keyboard_layouts/ES_LA.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "Backquote": "|",
- "Backslash": "}",
- "BracketLeft": "´",
- "BracketRight": "+",
- "Comma": ",",
- "Digit0": "0",
- "Digit1": "1",
- "Digit2": "2",
- "Digit3": "3",
- "Digit4": "4",
- "Digit5": "5",
- "Digit6": "6",
- "Digit7": "7",
- "Digit8": "8",
- "Digit9": "9",
- "Equal": "¿",
- "IntlBackslash": "<",
- "KeyA": "a",
- "KeyB": "b",
- "KeyC": "c",
- "KeyD": "d",
- "KeyE": "e",
- "KeyF": "f",
- "KeyG": "g",
- "KeyH": "h",
- "KeyI": "i",
- "KeyJ": "j",
- "KeyK": "k",
- "KeyL": "l",
- "KeyM": "m",
- "KeyN": "n",
- "KeyO": "o",
- "KeyP": "p",
- "KeyQ": "q",
- "KeyR": "r",
- "KeyS": "s",
- "KeyT": "t",
- "KeyU": "u",
- "KeyV": "v",
- "KeyW": "w",
- "KeyX": "x",
- "KeyY": "y",
- "KeyZ": "z",
- "Minus": "'",
- "Period": ".",
- "Quote": "{",
- "Semicolon": "ñ",
- "Slash": "-"
-}
\ No newline at end of file
diff --git a/fixtures/keyboard_layouts/FR.json b/fixtures/keyboard_layouts/FR.json
deleted file mode 100644
index bfde35829..000000000
--- a/fixtures/keyboard_layouts/FR.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "Backquote": "²",
- "Backslash": "*",
- "BracketLeft": "^",
- "BracketRight": "$",
- "Comma": ";",
- "Digit0": "à",
- "Digit1": "&",
- "Digit2": "é",
- "Digit3": "\"",
- "Digit4": "'",
- "Digit5": "(",
- "Digit6": "-",
- "Digit7": "è",
- "Digit8": "_",
- "Digit9": "ç",
- "Equal": "=",
- "IntlBackslash": "<",
- "KeyA": "q",
- "KeyB": "b",
- "KeyC": "c",
- "KeyD": "d",
- "KeyE": "e",
- "KeyF": "f",
- "KeyG": "g",
- "KeyH": "h",
- "KeyI": "i",
- "KeyJ": "j",
- "KeyK": "k",
- "KeyL": "l",
- "KeyM": ",",
- "KeyN": "n",
- "KeyO": "o",
- "KeyP": "p",
- "KeyQ": "a",
- "KeyR": "r",
- "KeyS": "s",
- "KeyT": "t",
- "KeyU": "u",
- "KeyV": "v",
- "KeyW": "z",
- "KeyX": "x",
- "KeyY": "y",
- "KeyZ": "w",
- "Minus": ")",
- "Period": ":",
- "Quote": "ù",
- "Semicolon": "m",
- "Slash": "!"
-}
\ No newline at end of file
diff --git a/fixtures/keyboard_layouts/GR.json b/fixtures/keyboard_layouts/GR.json
deleted file mode 100644
index fc106276f..000000000
--- a/fixtures/keyboard_layouts/GR.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "Backquote": "`",
- "Backslash": "\\",
- "BracketLeft": "[",
- "BracketRight": "]",
- "Comma": ",",
- "Digit0": "0",
- "Digit1": "1",
- "Digit2": "2",
- "Digit3": "3",
- "Digit4": "4",
- "Digit5": "5",
- "Digit6": "6",
- "Digit7": "7",
- "Digit8": "8",
- "Digit9": "9",
- "Equal": "=",
- "IntlBackslash": "«",
- "KeyA": "α",
- "KeyB": "β",
- "KeyC": "ψ",
- "KeyD": "δ",
- "KeyE": "ε",
- "KeyF": "φ",
- "KeyG": "γ",
- "KeyH": "η",
- "KeyI": "ι",
- "KeyJ": "ξ",
- "KeyK": "κ",
- "KeyL": "λ",
- "KeyM": "μ",
- "KeyN": "ν",
- "KeyO": "ο",
- "KeyP": "π",
- "KeyQ": ";",
- "KeyR": "ρ",
- "KeyS": "σ",
- "KeyT": "τ",
- "KeyU": "θ",
- "KeyV": "ω",
- "KeyW": "ς",
- "KeyX": "χ",
- "KeyY": "υ",
- "KeyZ": "ζ",
- "Minus": "-",
- "Period": ".",
- "Quote": "'",
- "Semicolon": "´",
- "Slash": "/"
-}
\ No newline at end of file
diff --git a/fixtures/keyboard_layouts/RU.json b/fixtures/keyboard_layouts/RU.json
deleted file mode 100644
index ef0fce478..000000000
--- a/fixtures/keyboard_layouts/RU.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "Backquote": "ё",
- "Backslash": "\\",
- "BracketLeft": "х",
- "BracketRight": "ъ",
- "Comma": "б",
- "Digit0": "0",
- "Digit1": "1",
- "Digit2": "2",
- "Digit3": "3",
- "Digit4": "4",
- "Digit5": "5",
- "Digit6": "6",
- "Digit7": "7",
- "Digit8": "8",
- "Digit9": "9",
- "Equal": "=",
- "IntlBackslash": "/",
- "KeyA": "ф",
- "KeyB": "и",
- "KeyC": "с",
- "KeyD": "в",
- "KeyE": "у",
- "KeyF": "а",
- "KeyG": "п",
- "KeyH": "р",
- "KeyI": "ш",
- "KeyJ": "о",
- "KeyK": "л",
- "KeyL": "д",
- "KeyM": "ь",
- "KeyN": "т",
- "KeyO": "щ",
- "KeyP": "з",
- "KeyQ": "й",
- "KeyR": "к",
- "KeyS": "ы",
- "KeyT": "е",
- "KeyU": "г",
- "KeyV": "м",
- "KeyW": "ц",
- "KeyX": "ч",
- "KeyY": "н",
- "KeyZ": "я",
- "Minus": "-",
- "Period": "ю",
- "Quote": "э",
- "Semicolon": "ж",
- "Slash": "."
-}
\ No newline at end of file
diff --git a/fixtures/keyboard_layouts/US.json b/fixtures/keyboard_layouts/US.json
deleted file mode 100644
index 9ac9d7200..000000000
--- a/fixtures/keyboard_layouts/US.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "Backquote": "`",
- "Backslash": "\\",
- "BracketLeft": "[",
- "BracketRight": "]",
- "Comma": ",",
- "Digit0": "0",
- "Digit1": "1",
- "Digit2": "2",
- "Digit3": "3",
- "Digit4": "4",
- "Digit5": "5",
- "Digit6": "6",
- "Digit7": "7",
- "Digit8": "8",
- "Digit9": "9",
- "Equal": "=",
- "IntlBackslash": "\\",
- "KeyA": "a",
- "KeyB": "b",
- "KeyC": "c",
- "KeyD": "d",
- "KeyE": "e",
- "KeyF": "f",
- "KeyG": "g",
- "KeyH": "h",
- "KeyI": "i",
- "KeyJ": "j",
- "KeyK": "k",
- "KeyL": "l",
- "KeyM": "m",
- "KeyN": "n",
- "KeyO": "o",
- "KeyP": "p",
- "KeyQ": "q",
- "KeyR": "r",
- "KeyS": "s",
- "KeyT": "t",
- "KeyU": "u",
- "KeyV": "v",
- "KeyW": "w",
- "KeyX": "x",
- "KeyY": "y",
- "KeyZ": "z",
- "Minus": "-",
- "Period": ".",
- "Quote": "'",
- "Semicolon": ";",
- "Slash": "/"
-}
\ No newline at end of file
diff --git a/src/common/input/Layout.ts b/src/common/input/Layout.ts
deleted file mode 100644
index 40e7e3f48..000000000
--- a/src/common/input/Layout.ts
+++ /dev/null
@@ -1,293 +0,0 @@
-/**
- * Copyright (c) 2026 The xterm.js authors. All rights reserved.
- * @license MIT
- *
- * Keyboard layout detection.
- */
-
-
-interface IMap {
- acc: {[index: string]: number};
- map: {[index: string]: string | string[]};
-}
-
-interface IKeyResult {
- layouts: string[];
- certain: number;
- key: string | undefined | (string | undefined)[];
-}
-
-
-/**
- * rebuild map: node bin/keyboard_layouts.mjs fixtures/keyboard_layouts/*
- */
-const MAP: IMap = {
- acc: { DE: 0, ES: 1, ES_LA: 2, FR: 3, GR: 4, RU: 5, US: 6 },
- map: {
- Backquote: '^º|²`ё`',
- Backslash: '#ç}*\\\\\\',
- BracketLeft: 'ü`´^[х[',
- BracketRight: '+++$]ъ]',
- Comma: ',,,;,б,',
- Digit0: '000à000',
- Digit1: '111&111',
- Digit2: '222é222',
- Digit3: '333"333',
- Digit4: "444'444",
- Digit5: '555(555',
- Digit6: '666-666',
- Digit7: '777è777',
- Digit8: '888_888',
- Digit9: '999ç999',
- Equal: '´¡¿====',
- IntlBackslash: '<<<<«/\\',
- KeyA: 'aaaqαфa',
- KeyB: 'bbbbβиb',
- KeyC: 'ccccψсc',
- KeyD: 'ddddδвd',
- KeyE: 'eeeeεуe',
- KeyF: 'ffffφаf',
- KeyG: 'ggggγпg',
- KeyH: 'hhhhηрh',
- KeyI: 'iiiiιшi',
- KeyJ: 'jjjjξоj',
- KeyK: 'kkkkκлk',
- KeyL: 'llllλдl',
- KeyM: 'mmm,μьm',
- KeyN: 'nnnnνтn',
- KeyO: 'ooooοщo',
- KeyP: 'ppppπзp',
- KeyQ: 'qqqa;йq',
- KeyR: 'rrrrρкr',
- KeyS: 'ssssσыs',
- KeyT: 'ttttτеt',
- KeyU: 'uuuuθгu',
- KeyV: 'vvvvωмv',
- KeyW: 'wwwzςцw',
- KeyX: 'xxxxχчx',
- KeyY: 'zyyyυнy',
- KeyZ: 'yzzwζяz',
- Minus: "ß'')---",
- Period: '...:.ю.',
- Quote: "ä´{ù'э'",
- Semicolon: 'öññm´ж;',
- Slash: '---!/./'
- }
-};
-
-
-export class LayoutDetector {
- private _keys: {[index: string]: number} = {};
- private _values: (string | string[])[] = [];
- private _rec: string[] = [];
- private _acc: string[] = Object.keys(MAP.acc);
- private _cand: {layout: string; match: number;}[];
- private _key: IKeyResult;
-
- constructor() {
- let p = 0;
- for (const key of Object.keys(MAP.map)) {
- this._keys[key] = p++;
- this._values.push(MAP.map[key]);
- this._rec.push('');
- }
- this._cand = [...this._acc].map(e => ({layout: e, match: 0 }));
- this._key = { layouts: ['US_QWERTY'], certain: 0, key: undefined };
- }
-
- /**
- * Reset detector.
- */
- public reset(): void {
- this._rec = this._rec.map(e => '');
- }
-
- /**
- * Return list of registered layouts.
- */
- public get layouts(): string[] {
- return Object.keys(MAP.acc);
- }
-
- /**
- * Return list of supported key codes.
- */
- public get codes(): string[] {
- return Object.keys(MAP.map);
- }
-
- /**
- * Get character key for key code and layout.
- * The known key codes can be requested with `.codes`,
- * the registered layouts with `.layouts`.
- */
- public getLayoutKey(code: string, layout: string): string | undefined {
- if (MAP.acc[layout] !== undefined && MAP.map[code]) {
- return MAP.map[code][MAP.acc[layout]];
- }
- }
-
- /**
- * Feed a keyboard event `ev` to the detector.
- */
- public feed(ev: KeyboardEvent): void {
- // FIXME: Should we check for OS? (not supported by Safari)
- if (ev.shiftKey || ev.ctrlKey || ev.altKey || ev.metaKey
- || ev.getModifierState('AltGraph')
- || ev.getModifierState('CapsLock')
- ) {
- return;
- }
- const pos = this._keys[ev.code];
- if (pos !== undefined) {
- if (this._rec[pos] && this._rec[pos] !== ev.key) {
- // The key value should never change for the same layout,
- // so we treat a sudden change as a layout change.
- this.reset();
- }
- this._rec[pos] = ev.key;
- }
- }
-
- /**
- * Shows all known layouts and their degree of matching mappings
- * sorted descending (likely layouts first).
- * Ideally there is only one leading layout with a match of 1.
- * If the leading match is not 1, then the user uses an
- * unknown or custom layout.
- */
- public matches(): {layout: string; match: number;}[] {
- for (let i = 0; i < this._cand.length; ++i) {
- this._cand[i].match = 0;
- }
- let c = 0;
- for (let k = 0; k < this._rec.length; ++k) {
- const v = this._rec[k];
- if (v) {
- c++;
- const values = this._values[k];
- for (let i = 0; i < this._acc.length; ++i) {
- if (v === values[i]) {
- this._cand[i].match++;
- }
- }
- }
- }
- if (!c) {
- return this._cand;
- }
- const sorted = [...this._cand].sort((a, b) => b.match - a.match);
- for (let i = 0; i < sorted.length; ++i) {
- sorted[i].match /= c;
- }
- return sorted;
- }
-
- /**
- * Tries to resolve a key code to a key character.
- * If `certain` is 1 then the result matches the listed layouts.
- * Ideally only one layout is returned, then the detector has seen enough
- * key events in `feed`.
- * If multiple layouts are returned but only one key, then the layout is
- * not yet fully determined but the key code is already known from `feed`.
- * When multiple keys are returned, then the character undetermined
- * and the layout needs further resolving with resolve.
- * A certainty lesser than 1 can have different reasons:
- * - not enough key event fed yet (multiple layouts returned)
- * - user has an unknown or custom layout
- * If `certain` is 0 the result should not be used as the dector
- * has not seen any key events at all.
- */
- public getKey(code: string): IKeyResult {
- const lm = this.matches();
- let candidates = [];
- let lastMatch = 0;
- for (let i = 0; i < lm.length; ++i) {
- if (lm[i].match === 0) {
- break;
- }
- if (lm[i].match === 1) {
- lastMatch = 1;
- candidates.push(lm[i].layout);
- } else if (lm[i].match >= lastMatch) {
- lastMatch = lm[i].match;
- candidates.push(lm[i].layout);
- }
- }
- if (candidates.length === 1) {
- this._key.layouts = candidates;
- this._key.certain = lastMatch;
- this._key.key = MAP.map[code]?.[MAP.acc[candidates[0]]];
- return this._key;
- }
- if (!candidates.length) {
- candidates = [...this._acc];
- }
- const values = [];
- for (let i = 0; i < candidates.length; ++i) {
- values.push(MAP.map[code]?.[MAP.acc[candidates[i]]]);
- }
- const valuesSet = new Set(values);
- // if all candidates yield the same char, return it
- if (valuesSet.size === 1) {
- this._key.layouts = candidates;
- this._key.certain = lastMatch;
- const [value] = values;
- this._key.key = value;
- return this._key;
- }
- // fallthrough
- this._key.layouts = candidates;
- this._key.certain = lastMatch / valuesSet.size;
- this._key.key = values;
- return this._key;
- }
-
- /**
- * Calculate distance to resolve keyboard layout.
- * Returns the candicate layouts and a list of keys resolving layout ambiguity.
- * The key list is sorted descending by candidate differences for a key code
- * (picking a high difference code needs less follow-up steps).
- * The user should be asked to press the corresponding key and the key event
- * should be fed to `feed`.
- * Repeat this process until this method returns only one layout.
- */
- public resolve(): any {
- const lm = this.matches();
- let candidates = [];
- let lastMatch = 0;
- for (let i = 0; i < lm.length; ++i) {
- if (lm[i].match === 0) {
- break;
- }
- if (lm[i].match === 1) {
- lastMatch = 1;
- candidates.push(lm[i].layout);
- } else if (lm[i].match >= lastMatch) {
- lastMatch = lm[i].match;
- candidates.push(lm[i].layout);
- }
- }
- if (candidates.length === 1) {
- return { layouts: candidates, keys: [] };
- }
- if (!candidates.length) {
- candidates = [...this._acc];
- }
- const acc = candidates.map(e => MAP.acc[e]);
- const codes = Object.keys(this._keys);
- const values = [];
- for (let i = 0; i < this._values.length; ++i) {
- const value = new Set();
- for (let k = 0; k < acc.length; ++k) {
- value.add(this._values[i][k]);
- }
- const len = (new Set(value)).size;
- if (len > 1) {
- values.push({code: codes[i], keys: [...value].sort()});
- }
- }
- values.sort((a, b) => b.keys.length - a.keys.length);
- return { layouts: candidates, keys: values };
- }
-}