From b7560be2b5c65ceb418b8540bcf8f338f119477b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 8 Nov 2021 14:03:36 +0100 Subject: [PATCH] remove named colors --- fixtures/x11-colornames/README.md | 14 - fixtures/x11-colornames/create_module.js | 447 -------------- fixtures/x11-colornames/rgb.txt | 754 ----------------------- src/common/InputHandler.test.ts | 2 +- src/common/InputHandler.ts | 4 +- src/common/data/ColorNames.ts | 91 --- 6 files changed, 2 insertions(+), 1310 deletions(-) delete mode 100644 fixtures/x11-colornames/README.md delete mode 100644 fixtures/x11-colornames/create_module.js delete mode 100644 fixtures/x11-colornames/rgb.txt delete mode 100644 src/common/data/ColorNames.ts diff --git a/fixtures/x11-colornames/README.md b/fixtures/x11-colornames/README.md deleted file mode 100644 index ee6d7b6d..00000000 --- a/fixtures/x11-colornames/README.md +++ /dev/null @@ -1,14 +0,0 @@ -### Fixture for 11 color names - -`rgb.txt` contains X11's defined color names, copied over from `/etc/X11/rgb.txt` on Ubuntu 18. - -Run `create_module.js` to create a TS module containing the color definitions. The script performs these steps: -- extract color definitions from `rgb.txt` -- remove gray definitions (re-added programmatically later) -- create a perfect hash function -- calculate crc10 for basic collision prevention -- run several collision tests -- compress table and color data -- write data with loading shim to `ColorNames.ts` - -The final file is meant to be copied over to `../../src/common/data/`. diff --git a/fixtures/x11-colornames/create_module.js b/fixtures/x11-colornames/create_module.js deleted file mode 100644 index edc1f314..00000000 --- a/fixtures/x11-colornames/create_module.js +++ /dev/null @@ -1,447 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -/** - * For decoder side: - * - reconstruct grays with f = lambda x: (x * 256 - x + 50) / 100 (needs value rounding check) - * - apply nameFilter - * - build lookup & extract functions (runtime decoding?) - * - transfer hashtable and color table - */ - -// match color entry in rgb.txt -const rexFile = /^\s*(\d+)\s*(\d+)\s*(\d+)\s*?[\t]+(.*)$/; -// match greyXX|grayXX names -const rexGrey = /^gr[ae]y\d+/; -// name match -const rexName = /^\w?[A-Za-z0-9 ]+\w/; - -function parseX11Colors(filename) { - const fileData = fs.readFileSync(filename, {encoding: 'utf8'}); - const colors = []; - for (const line of fileData.split('\n')) { - const m = rexFile.exec(line); - if (m) { - colors.push({ - color: [parseInt(m[1]), parseInt(m[2]), parseInt(m[3])], - name: m[4] - }); - } - } - return colors; -} - -// Use the FNV algorithm from http://isthe.com/chongo/tech/comp/fnv/ -function hash(d, name) { - if (!d) d = 0x01000193; - for (const c of name) { - d = ( (d * 0x01000193) ^ c.charCodeAt(0) ) & 0xffffffff; - } - return d >>> 0; -} - -// inspired from http://stevehanov.ca/blog/?id=119 -function createMinimalPerfectHash(nameList) { - const nameMap = Object.create(null); - for (const [idx, name] of nameList.entries()) { - nameMap[name] = idx; - } - const size = nameList.length; - - const buckets = []; - for (let i = 0; i < size; ++i) buckets.push([]); - const g = new Array(size).fill(0); - const v = new Array(size).fill(null); - - for (const key of nameList) { - buckets[hash(0, key) % size].push(key); - } - - buckets.sort((a, b) => b.length - a.length); - let breakIdx = 0; - for (let i = 0; i < size; ++i) { - const bucket = buckets[i]; - if (bucket.length <= 1) { - breakIdx = i; - break; - } - let d = 1; - let item = 0; - let slots = []; - - while (item < bucket.length) { - const slot = hash(d, bucket[item]) % size; - if (v[slot] !== null || slots.includes(slot)) { - d++; - item = 0; - slots = []; - } else { - slots.push(slot); - item++; - } - } - - g[hash(0, bucket[0]) % size] = d; - for (let k = 0; k < bucket.length; ++k) { - v[slots[k]] = nameMap[bucket[k]]; - } - } - - const freeList = []; - for (let i = 0; i < size; ++i) { - if (v[i] === null) freeList.push(i); - } - - for (let i = breakIdx; i < size; ++i) { - const bucket = buckets[i]; - if (!bucket.length) break; - const slot = freeList.pop(); - g[hash(0, bucket[0]) % size] = -slot - 1; - v[slot] = nameMap[bucket[0]]; - } - - return [g, v]; -} - -function lookupPerfectHash(g, v, key) { - const d = g[hash(0, key) % g.length]; - if (d < 0) return v[-d - 1]; - return v[hash(d, key) % v.length]; -} - -function checkPerfectHashTables(g, v, nameList) { - let allPassed = true; - for (const [idx, name] of nameList.entries()) { - const lookup = lookupPerfectHash(g, v, name); - if (lookup !== idx) { - console.log(`\x1b[33mmismatch: '${name}' returns ${lookup} (orig: ${idx})\x1b[m`); - allPassed = false; - } - } - return allPassed; -} - -function crc10atm(name, crc) { - if (!crc) crc = 0; - for (const c of name) { - const v = c.charCodeAt(0); - crc ^= v << 2; - for (let k = 0; k < 8; k++) { - crc = crc & 0x200 ? (crc << 1) ^ 0x233 : crc << 1; - } - } - crc &= 0x3ff; - return crc >>> 0; -} - -function checkColorList(g, v, crc, colorNames) { - let match = []; - for (const word of colorNames) { - if (!nameFilter(word)) continue; - const idx = lookupPerfectHash(g, v, word); - const crc10 = crc10atm(word); - if (crc[idx] === crc10) { - match.push({idx, word, colorName: colorNames[idx]}); - } - } - return {tested: colorNames.length, match}; -} - -function checkWordlists(g, v, crc, colorNames, filename) { - const fileData = fs.readFileSync(filename, {encoding: 'utf8'}); - const words = fileData.split('\n').filter(el => lookupPerfectHash.length !== 0); - let collisions = []; - for (const word of words) { - if (!nameFilter(word)) continue; - const idx = lookupPerfectHash(g, v, word); - const crc10 = crc10atm(word); - if (crc[idx] === crc10 && word !== colorNames[idx]) { - collisions.push({idx, word, colorName: colorNames[idx]}); - } - } - return {tested: words.length, collisions}; -} - -function nameFilter(name) { - // length 3 - 22 - if (name.length < 3 || name.length > 22) return; - // chars only in [A-Za-z0-9 ] - if (!rexName.exec(name)) return; - return name; -} - -function compressTables(g, v, crc, al) { - // g | v | crc: all in 10 bit (<1024) - // --> 30 bit - // --> fits into 5 bytes of a 64-bit char alphabet - - // g needs an offset for proper zero alignment - const gOffset = -Math.min(...g); - g = g.map(el => el + gOffset); - - // assert we are in 0..2^10 - if (Math.min(...g) < 0 || Math.min(...v) < 0 || Math.min(...crc) < 0 - || Math.max(...g) > 1023 || Math.max(...v) > 1023 || Math.max(...crc) > 1023 - ) { - console.log('\x1b[31mTables out of compressible range, manual fix needed.\x1b[m'); - process.exit(1); - } - - // assert we have same length - if (g.length !== v.length || g.length !== crc.length) { - console.log('\x1b[31mTables length mismatch, manual fix needed.\x1b[m'); - process.exit(1); - } - - // construct compressed data string - let result = ''; - const length = g.length; - for (let i = 0; i < length; ++i) { - let value = (g[i] << 20) | (v[i] << 10) | crc[i]; - let bucket = ''; - for (let k = 0; k < 5; ++k) { - bucket += al[value % al.length]; - value = Math.floor(value / al.length); - } - result += bucket.split('').reverse().join(''); - } - - return [result, length, gOffset]; -} - -function compressColors(colors, al) { - let result = ''; - for (const color of colors) { - let value = (color[0] << 16) | (color[1] << 8) | color[2]; - let bucket = ''; - for (let k = 0; k < 4; ++k) { - bucket += al[value % al.length]; - value = Math.floor(value / al.length); - } - result += bucket.split('').reverse().join(''); - } - return result; -} - -function loadData(bucket, al) { - let value = 0; - for (const c of bucket) { - value *= al.length; - value += al.indexOf(c); - } - return [value >>> 20, (value >> 10) & 0x3FF, value & 0x3FF]; -} - -function loadColor(al, data, idx) { - // color buckets are hardcoded to 4 chars - let value = 0; - for (let i = idx * 4; i < idx * 4 + 4; ++i) { - value *= al.length; - value += al.indexOf(data[i]); - } - return [value >>> 16, (value >> 8) & 0xFF, value & 0xFF]; -} - -function lookupIdx(al, data, length, gOffset, name) { - const bl = data.length / length; - let offset = (hash(0, name) % length) * bl; - let [g, v, crc] = loadData(data.slice(offset, offset + bl), al); - offset = g < gOffset - ? (-(g - gOffset) - 1) * bl - : (hash(g - gOffset, name) % length) * bl; - [_, v, _] = loadData(data.slice(offset, offset + bl), al); - offset = v * bl; - [_, _, crc] = loadData(data.slice(offset, offset + bl), al); - return crc10atm(name) === crc ? v : -1; -} - -function lookup(al, data, colorData, length, gOffset, name) { - const idx = lookupIdx(al, data, length, gOffset, name); - if (idx === -1) return; - return loadColor(al, colorData, idx); -} - -function createModule(tableData, colorData, alphabet, gOffset, length) { - const TMPL = `/** - * Copyright (c) 2021 The xterm.js authors. All rights reserved. - * @license MIT - */ - -/** - * This module enables X11 color name lookups with the help of a perfect hash function - * to not penalize the package size too much. - * saving: ~70% (from 17kB down to 5kB) - */ - -// Note: module and table data created with fixtures/x11-colornames/create_module.js -const TABLE = '${tableData}'; -const COLORS = '${colorData}'; -const ALPHABET = '${alphabet}'; -const OFFSET = ${gOffset}; -const LENGTH = ${length}; -const BUCKET_LENGTH = TABLE.length / LENGTH; - -// match greyXX|grayXX names -const rexGrey = /^gr[ae]y(\\d+)/; -// name match -const rexName = /^\\w?[A-Za-z0-9 ]+\\w/; - -function gray(n: number): [number, number, number] | undefined { - if (0 <= n && n <= 100) { - const v = Math.floor((n * 256 - n + 50) / 100); - return [v, v, v]; - } - return; -} - -function hash(d: number, name: string): number { - if (!d) d = 0x01000193; - for (const c of name) { - d = ((d * 0x01000193) ^ c.charCodeAt(0)) & 0xffffffff; - } - return d >>> 0; -} - -function crc10(name: string, crc?: number): number { - if (!crc) crc = 0; - for (const c of name) { - crc ^= c.charCodeAt(0) << 2; - for (let k = 0; k < 8; k++) { - crc = crc & 0x200 ? (crc << 1) ^ 0x233 : crc << 1; - } - } - crc &= 0x3ff; - return crc >>> 0; -} - -function loadData(idx: number): [number, number, number] { - let value = 0; - for (let i = idx * BUCKET_LENGTH; i < idx * BUCKET_LENGTH + BUCKET_LENGTH; ++i) { - value *= ALPHABET.length; - value += ALPHABET.indexOf(TABLE[i]); - } - return [value >>> 20, (value >> 10) & 0x3FF, value & 0x3FF]; -} - -function loadColor(idx: number): [number, number, number] { - // color buckets are hardcoded to 4 chars - let v = 0; - for (let i = idx * 4; i < idx * 4 + 4; ++i) { - v *= ALPHABET.length; - v += ALPHABET.indexOf(COLORS[i]); - } - return [v >>> 16, (v >> 8) & 0xFF, v & 0xFF]; -} - -function lookupIdx(name: string): number { - let b = loadData(hash(0, name) % LENGTH); - b = loadData(b[0] < OFFSET ? (-(b[0] - OFFSET) - 1) : hash(b[0] - OFFSET, name) % LENGTH); - const [ , , crc] = loadData(b[1]); - return crc10(name) === crc ? b[1] : -1; -} - -export function getColorFromName(name: string): [number, number, number] | undefined { - // basic name filtering - if (name.length < 3 || name.length > 22 || !rexName.exec(name)) return; - - // handle grays special - const m = rexGrey.exec(name); - if (m) return gray(parseInt(m[1])); - - // grab crc checked idx from PHF - const idx = lookupIdx(name); - if (idx === -1) return; - return loadColor(idx); -} -`; - return TMPL; -} - - -function main() { - // parse definitions from X11 file - const colorList = parseX11Colors(path.join(__dirname, '/rgb.txt')) - .filter(el => !rexGrey.exec(el.name)); // remove greys, as we can reconstruct them later - const nameList = colorList.map(el => el.name); - - // PHF creation and test - const [g, v] = createMinimalPerfectHash(nameList); - if (!checkPerfectHashTables(g, v, nameList)) { - console.error('\x1b[31mPHF creation failed.\x1b[m'); - process.exit(1); - } else { - console.log('\x1b[32mPHF creation successful.\x1b[m'); - } - - // calc 10-bit CRCs to rule to avoid collisions at ~1:1024 - const crc = nameList.map(el => crc10atm(el)); - - // collision check against colorNames - must all collide - console.log('Self collision test:') - const collSelf = checkColorList(g, v, crc, nameList); - console.log('self:', { - entries: collSelf.tested, - matches: collSelf.match.length, - rate: collSelf.tested / collSelf.match.length - }); - if (collSelf.match.length !== collSelf.tested) { - console.error('\x1b[31mSelf collision tested failed.\x1b[m'); - process.exit(1); - } - - // basic collision checks against dictionaries (rates should be greater than 900:1) - console.log('Dictionary collision test:') - const collEnglish = checkWordlists(g, v, crc, nameList, '/usr/share/dict/words'); - console.log('english:', { - entries: collEnglish.tested, - collisions: collEnglish.collisions.length, - rate: collEnglish.tested / collEnglish.collisions.length - }); - //console.log(collEnglish.collisions); - const collnGerman = checkWordlists(g, v, crc, nameList, '/usr/share/dict/ngerman'); - console.log('ngerman:', { - entries: collnGerman.tested, - collisions: collnGerman.collisions.length, - rate: collnGerman.tested / collnGerman.collisions.length - }); - const colloGerman = checkWordlists(g, v, crc, nameList, '/usr/share/dict/ogerman'); - console.log('ogerman:', { - entries: colloGerman.tested, - collisions: colloGerman.collisions.length, - rate: colloGerman.tested / colloGerman.collisions.length - }); - - // compression with custom alphabet - const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?'; - const [tableData, length, gOffset] = compressTables(g, v, crc, ALPHABET); - const colorData = compressColors(colorList.map(el => el.color), ALPHABET); - - // test loading of compressed table data - let failed = false; - for (const name of nameList) { - const orig = lookupPerfectHash(g, v, name); - const idx = lookupIdx(ALPHABET, tableData, length, gOffset, name); - if (idx !== orig) { - console.log('\x1b[31mcompressed loading failed for:\x1b[m', {name, idx, orig}); - failed = true; - } - } - if (failed) process.exit(1); - - // test full color decoding - for (const color of colorList) { - const loaded = lookup(ALPHABET, tableData, colorData, length, gOffset, color.name); - if (loaded[0] !== color.color[0] || loaded[1] !== color.color[1] || loaded[2] !== color.color[2]) { - console.log('\x1b[31mcolor loading failed for:\x1b[m', {color, loaded}); - failed = true; - } - } - if (failed) process.exit(1); - - // if we made it up to here, create decoding boilerplate - const moduleData = createModule(tableData, colorData, ALPHABET, gOffset, length); - fs.writeFileSync(path.join(__dirname, '/ColorNames.ts'), moduleData); - console.log(`${moduleData.length} bytes written to ${path.join(__dirname, '/ColorNames.ts')}`); -} - -main(); diff --git a/fixtures/x11-colornames/rgb.txt b/fixtures/x11-colornames/rgb.txt deleted file mode 100644 index b9e56c60..00000000 --- a/fixtures/x11-colornames/rgb.txt +++ /dev/null @@ -1,754 +0,0 @@ -! $Xorg: rgb.txt,v 1.3 2000/08/17 19:54:00 cpqbld Exp $ -255 250 250 snow -248 248 255 ghost white -248 248 255 GhostWhite -245 245 245 white smoke -245 245 245 WhiteSmoke -220 220 220 gainsboro -255 250 240 floral white -255 250 240 FloralWhite -253 245 230 old lace -253 245 230 OldLace -250 240 230 linen -250 235 215 antique white -250 235 215 AntiqueWhite -255 239 213 papaya whip -255 239 213 PapayaWhip -255 235 205 blanched almond -255 235 205 BlanchedAlmond -255 228 196 bisque -255 218 185 peach puff -255 218 185 PeachPuff -255 222 173 navajo white -255 222 173 NavajoWhite -255 228 181 moccasin -255 248 220 cornsilk -255 255 240 ivory -255 250 205 lemon chiffon -255 250 205 LemonChiffon -255 245 238 seashell -240 255 240 honeydew -245 255 250 mint cream -245 255 250 MintCream -240 255 255 azure -240 248 255 alice blue -240 248 255 AliceBlue -230 230 250 lavender -255 240 245 lavender blush -255 240 245 LavenderBlush -255 228 225 misty rose -255 228 225 MistyRose -255 255 255 white - 0 0 0 black - 47 79 79 dark slate gray - 47 79 79 DarkSlateGray - 47 79 79 dark slate grey - 47 79 79 DarkSlateGrey -105 105 105 dim gray -105 105 105 DimGray -105 105 105 dim grey -105 105 105 DimGrey -112 128 144 slate gray -112 128 144 SlateGray -112 128 144 slate grey -112 128 144 SlateGrey -119 136 153 light slate gray -119 136 153 LightSlateGray -119 136 153 light slate grey -119 136 153 LightSlateGrey -190 190 190 gray -190 190 190 grey -211 211 211 light grey -211 211 211 LightGrey -211 211 211 light gray -211 211 211 LightGray - 25 25 112 midnight blue - 25 25 112 MidnightBlue - 0 0 128 navy - 0 0 128 navy blue - 0 0 128 NavyBlue -100 149 237 cornflower blue -100 149 237 CornflowerBlue - 72 61 139 dark slate blue - 72 61 139 DarkSlateBlue -106 90 205 slate blue -106 90 205 SlateBlue -123 104 238 medium slate blue -123 104 238 MediumSlateBlue -132 112 255 light slate blue -132 112 255 LightSlateBlue - 0 0 205 medium blue - 0 0 205 MediumBlue - 65 105 225 royal blue - 65 105 225 RoyalBlue - 0 0 255 blue - 30 144 255 dodger blue - 30 144 255 DodgerBlue - 0 191 255 deep sky blue - 0 191 255 DeepSkyBlue -135 206 235 sky blue -135 206 235 SkyBlue -135 206 250 light sky blue -135 206 250 LightSkyBlue - 70 130 180 steel blue - 70 130 180 SteelBlue -176 196 222 light steel blue -176 196 222 LightSteelBlue -173 216 230 light blue -173 216 230 LightBlue -176 224 230 powder blue -176 224 230 PowderBlue -175 238 238 pale turquoise -175 238 238 PaleTurquoise - 0 206 209 dark turquoise - 0 206 209 DarkTurquoise - 72 209 204 medium turquoise - 72 209 204 MediumTurquoise - 64 224 208 turquoise - 0 255 255 cyan -224 255 255 light cyan -224 255 255 LightCyan - 95 158 160 cadet blue - 95 158 160 CadetBlue -102 205 170 medium aquamarine -102 205 170 MediumAquamarine -127 255 212 aquamarine - 0 100 0 dark green - 0 100 0 DarkGreen - 85 107 47 dark olive green - 85 107 47 DarkOliveGreen -143 188 143 dark sea green -143 188 143 DarkSeaGreen - 46 139 87 sea green - 46 139 87 SeaGreen - 60 179 113 medium sea green - 60 179 113 MediumSeaGreen - 32 178 170 light sea green - 32 178 170 LightSeaGreen -152 251 152 pale green -152 251 152 PaleGreen - 0 255 127 spring green - 0 255 127 SpringGreen -124 252 0 lawn green -124 252 0 LawnGreen - 0 255 0 green -127 255 0 chartreuse - 0 250 154 medium spring green - 0 250 154 MediumSpringGreen -173 255 47 green yellow -173 255 47 GreenYellow - 50 205 50 lime green - 50 205 50 LimeGreen -154 205 50 yellow green -154 205 50 YellowGreen - 34 139 34 forest green - 34 139 34 ForestGreen -107 142 35 olive drab -107 142 35 OliveDrab -189 183 107 dark khaki -189 183 107 DarkKhaki -240 230 140 khaki -238 232 170 pale goldenrod -238 232 170 PaleGoldenrod -250 250 210 light goldenrod yellow -250 250 210 LightGoldenrodYellow -255 255 224 light yellow -255 255 224 LightYellow -255 255 0 yellow -255 215 0 gold -238 221 130 light goldenrod -238 221 130 LightGoldenrod -218 165 32 goldenrod -184 134 11 dark goldenrod -184 134 11 DarkGoldenrod -188 143 143 rosy brown -188 143 143 RosyBrown -205 92 92 indian red -205 92 92 IndianRed -139 69 19 saddle brown -139 69 19 SaddleBrown -160 82 45 sienna -205 133 63 peru -222 184 135 burlywood -245 245 220 beige -245 222 179 wheat -244 164 96 sandy brown -244 164 96 SandyBrown -210 180 140 tan -210 105 30 chocolate -178 34 34 firebrick -165 42 42 brown -233 150 122 dark salmon -233 150 122 DarkSalmon -250 128 114 salmon -255 160 122 light salmon -255 160 122 LightSalmon -255 165 0 orange -255 140 0 dark orange -255 140 0 DarkOrange -255 127 80 coral -240 128 128 light coral -240 128 128 LightCoral -255 99 71 tomato -255 69 0 orange red -255 69 0 OrangeRed -255 0 0 red -255 105 180 hot pink -255 105 180 HotPink -255 20 147 deep pink -255 20 147 DeepPink -255 192 203 pink -255 182 193 light pink -255 182 193 LightPink -219 112 147 pale violet red -219 112 147 PaleVioletRed -176 48 96 maroon -199 21 133 medium violet red -199 21 133 MediumVioletRed -208 32 144 violet red -208 32 144 VioletRed -255 0 255 magenta -238 130 238 violet -221 160 221 plum -218 112 214 orchid -186 85 211 medium orchid -186 85 211 MediumOrchid -153 50 204 dark orchid -153 50 204 DarkOrchid -148 0 211 dark violet -148 0 211 DarkViolet -138 43 226 blue violet -138 43 226 BlueViolet -160 32 240 purple -147 112 219 medium purple -147 112 219 MediumPurple -216 191 216 thistle -255 250 250 snow1 -238 233 233 snow2 -205 201 201 snow3 -139 137 137 snow4 -255 245 238 seashell1 -238 229 222 seashell2 -205 197 191 seashell3 -139 134 130 seashell4 -255 239 219 AntiqueWhite1 -238 223 204 AntiqueWhite2 -205 192 176 AntiqueWhite3 -139 131 120 AntiqueWhite4 -255 228 196 bisque1 -238 213 183 bisque2 -205 183 158 bisque3 -139 125 107 bisque4 -255 218 185 PeachPuff1 -238 203 173 PeachPuff2 -205 175 149 PeachPuff3 -139 119 101 PeachPuff4 -255 222 173 NavajoWhite1 -238 207 161 NavajoWhite2 -205 179 139 NavajoWhite3 -139 121 94 NavajoWhite4 -255 250 205 LemonChiffon1 -238 233 191 LemonChiffon2 -205 201 165 LemonChiffon3 -139 137 112 LemonChiffon4 -255 248 220 cornsilk1 -238 232 205 cornsilk2 -205 200 177 cornsilk3 -139 136 120 cornsilk4 -255 255 240 ivory1 -238 238 224 ivory2 -205 205 193 ivory3 -139 139 131 ivory4 -240 255 240 honeydew1 -224 238 224 honeydew2 -193 205 193 honeydew3 -131 139 131 honeydew4 -255 240 245 LavenderBlush1 -238 224 229 LavenderBlush2 -205 193 197 LavenderBlush3 -139 131 134 LavenderBlush4 -255 228 225 MistyRose1 -238 213 210 MistyRose2 -205 183 181 MistyRose3 -139 125 123 MistyRose4 -240 255 255 azure1 -224 238 238 azure2 -193 205 205 azure3 -131 139 139 azure4 -131 111 255 SlateBlue1 -122 103 238 SlateBlue2 -105 89 205 SlateBlue3 - 71 60 139 SlateBlue4 - 72 118 255 RoyalBlue1 - 67 110 238 RoyalBlue2 - 58 95 205 RoyalBlue3 - 39 64 139 RoyalBlue4 - 0 0 255 blue1 - 0 0 238 blue2 - 0 0 205 blue3 - 0 0 139 blue4 - 30 144 255 DodgerBlue1 - 28 134 238 DodgerBlue2 - 24 116 205 DodgerBlue3 - 16 78 139 DodgerBlue4 - 99 184 255 SteelBlue1 - 92 172 238 SteelBlue2 - 79 148 205 SteelBlue3 - 54 100 139 SteelBlue4 - 0 191 255 DeepSkyBlue1 - 0 178 238 DeepSkyBlue2 - 0 154 205 DeepSkyBlue3 - 0 104 139 DeepSkyBlue4 -135 206 255 SkyBlue1 -126 192 238 SkyBlue2 -108 166 205 SkyBlue3 - 74 112 139 SkyBlue4 -176 226 255 LightSkyBlue1 -164 211 238 LightSkyBlue2 -141 182 205 LightSkyBlue3 - 96 123 139 LightSkyBlue4 -198 226 255 SlateGray1 -185 211 238 SlateGray2 -159 182 205 SlateGray3 -108 123 139 SlateGray4 -202 225 255 LightSteelBlue1 -188 210 238 LightSteelBlue2 -162 181 205 LightSteelBlue3 -110 123 139 LightSteelBlue4 -191 239 255 LightBlue1 -178 223 238 LightBlue2 -154 192 205 LightBlue3 -104 131 139 LightBlue4 -224 255 255 LightCyan1 -209 238 238 LightCyan2 -180 205 205 LightCyan3 -122 139 139 LightCyan4 -187 255 255 PaleTurquoise1 -174 238 238 PaleTurquoise2 -150 205 205 PaleTurquoise3 -102 139 139 PaleTurquoise4 -152 245 255 CadetBlue1 -142 229 238 CadetBlue2 -122 197 205 CadetBlue3 - 83 134 139 CadetBlue4 - 0 245 255 turquoise1 - 0 229 238 turquoise2 - 0 197 205 turquoise3 - 0 134 139 turquoise4 - 0 255 255 cyan1 - 0 238 238 cyan2 - 0 205 205 cyan3 - 0 139 139 cyan4 -151 255 255 DarkSlateGray1 -141 238 238 DarkSlateGray2 -121 205 205 DarkSlateGray3 - 82 139 139 DarkSlateGray4 -127 255 212 aquamarine1 -118 238 198 aquamarine2 -102 205 170 aquamarine3 - 69 139 116 aquamarine4 -193 255 193 DarkSeaGreen1 -180 238 180 DarkSeaGreen2 -155 205 155 DarkSeaGreen3 -105 139 105 DarkSeaGreen4 - 84 255 159 SeaGreen1 - 78 238 148 SeaGreen2 - 67 205 128 SeaGreen3 - 46 139 87 SeaGreen4 -154 255 154 PaleGreen1 -144 238 144 PaleGreen2 -124 205 124 PaleGreen3 - 84 139 84 PaleGreen4 - 0 255 127 SpringGreen1 - 0 238 118 SpringGreen2 - 0 205 102 SpringGreen3 - 0 139 69 SpringGreen4 - 0 255 0 green1 - 0 238 0 green2 - 0 205 0 green3 - 0 139 0 green4 -127 255 0 chartreuse1 -118 238 0 chartreuse2 -102 205 0 chartreuse3 - 69 139 0 chartreuse4 -192 255 62 OliveDrab1 -179 238 58 OliveDrab2 -154 205 50 OliveDrab3 -105 139 34 OliveDrab4 -202 255 112 DarkOliveGreen1 -188 238 104 DarkOliveGreen2 -162 205 90 DarkOliveGreen3 -110 139 61 DarkOliveGreen4 -255 246 143 khaki1 -238 230 133 khaki2 -205 198 115 khaki3 -139 134 78 khaki4 -255 236 139 LightGoldenrod1 -238 220 130 LightGoldenrod2 -205 190 112 LightGoldenrod3 -139 129 76 LightGoldenrod4 -255 255 224 LightYellow1 -238 238 209 LightYellow2 -205 205 180 LightYellow3 -139 139 122 LightYellow4 -255 255 0 yellow1 -238 238 0 yellow2 -205 205 0 yellow3 -139 139 0 yellow4 -255 215 0 gold1 -238 201 0 gold2 -205 173 0 gold3 -139 117 0 gold4 -255 193 37 goldenrod1 -238 180 34 goldenrod2 -205 155 29 goldenrod3 -139 105 20 goldenrod4 -255 185 15 DarkGoldenrod1 -238 173 14 DarkGoldenrod2 -205 149 12 DarkGoldenrod3 -139 101 8 DarkGoldenrod4 -255 193 193 RosyBrown1 -238 180 180 RosyBrown2 -205 155 155 RosyBrown3 -139 105 105 RosyBrown4 -255 106 106 IndianRed1 -238 99 99 IndianRed2 -205 85 85 IndianRed3 -139 58 58 IndianRed4 -255 130 71 sienna1 -238 121 66 sienna2 -205 104 57 sienna3 -139 71 38 sienna4 -255 211 155 burlywood1 -238 197 145 burlywood2 -205 170 125 burlywood3 -139 115 85 burlywood4 -255 231 186 wheat1 -238 216 174 wheat2 -205 186 150 wheat3 -139 126 102 wheat4 -255 165 79 tan1 -238 154 73 tan2 -205 133 63 tan3 -139 90 43 tan4 -255 127 36 chocolate1 -238 118 33 chocolate2 -205 102 29 chocolate3 -139 69 19 chocolate4 -255 48 48 firebrick1 -238 44 44 firebrick2 -205 38 38 firebrick3 -139 26 26 firebrick4 -255 64 64 brown1 -238 59 59 brown2 -205 51 51 brown3 -139 35 35 brown4 -255 140 105 salmon1 -238 130 98 salmon2 -205 112 84 salmon3 -139 76 57 salmon4 -255 160 122 LightSalmon1 -238 149 114 LightSalmon2 -205 129 98 LightSalmon3 -139 87 66 LightSalmon4 -255 165 0 orange1 -238 154 0 orange2 -205 133 0 orange3 -139 90 0 orange4 -255 127 0 DarkOrange1 -238 118 0 DarkOrange2 -205 102 0 DarkOrange3 -139 69 0 DarkOrange4 -255 114 86 coral1 -238 106 80 coral2 -205 91 69 coral3 -139 62 47 coral4 -255 99 71 tomato1 -238 92 66 tomato2 -205 79 57 tomato3 -139 54 38 tomato4 -255 69 0 OrangeRed1 -238 64 0 OrangeRed2 -205 55 0 OrangeRed3 -139 37 0 OrangeRed4 -255 0 0 red1 -238 0 0 red2 -205 0 0 red3 -139 0 0 red4 -215 7 81 DebianRed -255 20 147 DeepPink1 -238 18 137 DeepPink2 -205 16 118 DeepPink3 -139 10 80 DeepPink4 -255 110 180 HotPink1 -238 106 167 HotPink2 -205 96 144 HotPink3 -139 58 98 HotPink4 -255 181 197 pink1 -238 169 184 pink2 -205 145 158 pink3 -139 99 108 pink4 -255 174 185 LightPink1 -238 162 173 LightPink2 -205 140 149 LightPink3 -139 95 101 LightPink4 -255 130 171 PaleVioletRed1 -238 121 159 PaleVioletRed2 -205 104 137 PaleVioletRed3 -139 71 93 PaleVioletRed4 -255 52 179 maroon1 -238 48 167 maroon2 -205 41 144 maroon3 -139 28 98 maroon4 -255 62 150 VioletRed1 -238 58 140 VioletRed2 -205 50 120 VioletRed3 -139 34 82 VioletRed4 -255 0 255 magenta1 -238 0 238 magenta2 -205 0 205 magenta3 -139 0 139 magenta4 -255 131 250 orchid1 -238 122 233 orchid2 -205 105 201 orchid3 -139 71 137 orchid4 -255 187 255 plum1 -238 174 238 plum2 -205 150 205 plum3 -139 102 139 plum4 -224 102 255 MediumOrchid1 -209 95 238 MediumOrchid2 -180 82 205 MediumOrchid3 -122 55 139 MediumOrchid4 -191 62 255 DarkOrchid1 -178 58 238 DarkOrchid2 -154 50 205 DarkOrchid3 -104 34 139 DarkOrchid4 -155 48 255 purple1 -145 44 238 purple2 -125 38 205 purple3 - 85 26 139 purple4 -171 130 255 MediumPurple1 -159 121 238 MediumPurple2 -137 104 205 MediumPurple3 - 93 71 139 MediumPurple4 -255 225 255 thistle1 -238 210 238 thistle2 -205 181 205 thistle3 -139 123 139 thistle4 - 0 0 0 gray0 - 0 0 0 grey0 - 3 3 3 gray1 - 3 3 3 grey1 - 5 5 5 gray2 - 5 5 5 grey2 - 8 8 8 gray3 - 8 8 8 grey3 - 10 10 10 gray4 - 10 10 10 grey4 - 13 13 13 gray5 - 13 13 13 grey5 - 15 15 15 gray6 - 15 15 15 grey6 - 18 18 18 gray7 - 18 18 18 grey7 - 20 20 20 gray8 - 20 20 20 grey8 - 23 23 23 gray9 - 23 23 23 grey9 - 26 26 26 gray10 - 26 26 26 grey10 - 28 28 28 gray11 - 28 28 28 grey11 - 31 31 31 gray12 - 31 31 31 grey12 - 33 33 33 gray13 - 33 33 33 grey13 - 36 36 36 gray14 - 36 36 36 grey14 - 38 38 38 gray15 - 38 38 38 grey15 - 41 41 41 gray16 - 41 41 41 grey16 - 43 43 43 gray17 - 43 43 43 grey17 - 46 46 46 gray18 - 46 46 46 grey18 - 48 48 48 gray19 - 48 48 48 grey19 - 51 51 51 gray20 - 51 51 51 grey20 - 54 54 54 gray21 - 54 54 54 grey21 - 56 56 56 gray22 - 56 56 56 grey22 - 59 59 59 gray23 - 59 59 59 grey23 - 61 61 61 gray24 - 61 61 61 grey24 - 64 64 64 gray25 - 64 64 64 grey25 - 66 66 66 gray26 - 66 66 66 grey26 - 69 69 69 gray27 - 69 69 69 grey27 - 71 71 71 gray28 - 71 71 71 grey28 - 74 74 74 gray29 - 74 74 74 grey29 - 77 77 77 gray30 - 77 77 77 grey30 - 79 79 79 gray31 - 79 79 79 grey31 - 82 82 82 gray32 - 82 82 82 grey32 - 84 84 84 gray33 - 84 84 84 grey33 - 87 87 87 gray34 - 87 87 87 grey34 - 89 89 89 gray35 - 89 89 89 grey35 - 92 92 92 gray36 - 92 92 92 grey36 - 94 94 94 gray37 - 94 94 94 grey37 - 97 97 97 gray38 - 97 97 97 grey38 - 99 99 99 gray39 - 99 99 99 grey39 -102 102 102 gray40 -102 102 102 grey40 -105 105 105 gray41 -105 105 105 grey41 -107 107 107 gray42 -107 107 107 grey42 -110 110 110 gray43 -110 110 110 grey43 -112 112 112 gray44 -112 112 112 grey44 -115 115 115 gray45 -115 115 115 grey45 -117 117 117 gray46 -117 117 117 grey46 -120 120 120 gray47 -120 120 120 grey47 -122 122 122 gray48 -122 122 122 grey48 -125 125 125 gray49 -125 125 125 grey49 -127 127 127 gray50 -127 127 127 grey50 -130 130 130 gray51 -130 130 130 grey51 -133 133 133 gray52 -133 133 133 grey52 -135 135 135 gray53 -135 135 135 grey53 -138 138 138 gray54 -138 138 138 grey54 -140 140 140 gray55 -140 140 140 grey55 -143 143 143 gray56 -143 143 143 grey56 -145 145 145 gray57 -145 145 145 grey57 -148 148 148 gray58 -148 148 148 grey58 -150 150 150 gray59 -150 150 150 grey59 -153 153 153 gray60 -153 153 153 grey60 -156 156 156 gray61 -156 156 156 grey61 -158 158 158 gray62 -158 158 158 grey62 -161 161 161 gray63 -161 161 161 grey63 -163 163 163 gray64 -163 163 163 grey64 -166 166 166 gray65 -166 166 166 grey65 -168 168 168 gray66 -168 168 168 grey66 -171 171 171 gray67 -171 171 171 grey67 -173 173 173 gray68 -173 173 173 grey68 -176 176 176 gray69 -176 176 176 grey69 -179 179 179 gray70 -179 179 179 grey70 -181 181 181 gray71 -181 181 181 grey71 -184 184 184 gray72 -184 184 184 grey72 -186 186 186 gray73 -186 186 186 grey73 -189 189 189 gray74 -189 189 189 grey74 -191 191 191 gray75 -191 191 191 grey75 -194 194 194 gray76 -194 194 194 grey76 -196 196 196 gray77 -196 196 196 grey77 -199 199 199 gray78 -199 199 199 grey78 -201 201 201 gray79 -201 201 201 grey79 -204 204 204 gray80 -204 204 204 grey80 -207 207 207 gray81 -207 207 207 grey81 -209 209 209 gray82 -209 209 209 grey82 -212 212 212 gray83 -212 212 212 grey83 -214 214 214 gray84 -214 214 214 grey84 -217 217 217 gray85 -217 217 217 grey85 -219 219 219 gray86 -219 219 219 grey86 -222 222 222 gray87 -222 222 222 grey87 -224 224 224 gray88 -224 224 224 grey88 -227 227 227 gray89 -227 227 227 grey89 -229 229 229 gray90 -229 229 229 grey90 -232 232 232 gray91 -232 232 232 grey91 -235 235 235 gray92 -235 235 235 grey92 -237 237 237 gray93 -237 237 237 grey93 -240 240 240 gray94 -240 240 240 grey94 -242 242 242 gray95 -242 242 242 grey95 -245 245 245 gray96 -245 245 245 grey96 -247 247 247 gray97 -247 247 247 grey97 -250 250 250 gray98 -250 250 250 grey98 -252 252 252 gray99 -252 252 252 grey99 -255 255 255 gray100 -255 255 255 grey100 -169 169 169 dark grey -169 169 169 DarkGrey -169 169 169 dark gray -169 169 169 DarkGray -0 0 139 dark blue -0 0 139 DarkBlue -0 139 139 dark cyan -0 139 139 DarkCyan -139 0 139 dark magenta -139 0 139 DarkMagenta -139 0 0 dark red -139 0 0 DarkRed -144 238 144 light green -144 238 144 LightGreen diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index ff1879bc..e8c4c8bf 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -55,7 +55,7 @@ class TestInputHandler extends InputHandler { } } - public parseColorSpec(data: string): void | [number, number, number] { + public parseColorSpec(data: string): undefined | [number, number, number] { return this._parseColorSpec(data); } } diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 9a56de6f..5384bf8d 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -21,7 +21,6 @@ import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowSe import { OscHandler } from 'common/parser/OscParser'; import { DcsHandler } from 'common/parser/DcsParser'; import { IBuffer } from 'common/buffer/Types'; -import { getColorFromName } from 'common/data/ColorNames'; /** * Map collect to glevel. Used in `selectCharset`. @@ -2877,7 +2876,7 @@ export class InputHandler extends Disposable implements IInputHandler { * All other formats like rgbi: or device-independent string specifications * with float numbering are not supported. */ - protected _parseColorSpec(data: string): [number, number, number] | void { + protected _parseColorSpec(data: string): [number, number, number] | undefined { if (!data) return; // also handle uppercases let low = data.toLowerCase(); @@ -2908,7 +2907,6 @@ export class InputHandler extends Disposable implements IInputHandler { return result; } } - return getColorFromName(data); } /** diff --git a/src/common/data/ColorNames.ts b/src/common/data/ColorNames.ts deleted file mode 100644 index 68dd06b6..00000000 --- a/src/common/data/ColorNames.ts +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (c) 2021 The xterm.js authors. All rights reserved. - * @license MIT - */ - -/** - * This module enables X11 color name lookups with the help of a perfect hash function - * to not penalize the package size too much. - * saving: ~70% (from 17kB down to 5kB) - */ - -// Note: module and table data created with fixtures/x11-colornames/create_module.js -const TABLE = 'AB!!!id!jsih!ZYigHp3AkceNiiImVihW3Uih?DFihrenihDEQiwgziieGJvAoMnsidOM3idOtQiciazAsFrtieFZyidKSgAx8odip818ieFiXieF97ic34eihOxpA4UPNidz51A8znjBAX?uBU9ynitOZdigRMNBYgIEBcaXPBk9LVB0xlOB9mcFihmlWCRq0yidmG7idqsHid7RmCV7pCClqRAimG5kCpsb4ipt78CtqLeig17aigJb7ioC4rihzLdigmoNigEDTihzZKCwIz1C4j5sih4QQihlg2igwsHDBFTuDESshDJFzIig1cbihZ3wipZphigiKcihZUxihZLODRm7RilG1Cid3tmDVGffDYJsPDc1JrixgxGidDn3Dli9uDsOl0imDQPiyDhbimDyZihU00icbZSEJs6VieEzpicF2YEqB?PicemNiduxiihEL9ieBjnEuI53icdLPiqBYWiduYFExunsFB3JqFEXPuihnyvFQkNAFVVjlic8SLicIeOFYvurFwrh5icQ4RicHUgidVbJidVA3idN3LGECqgGJiKSGRl8UidT9qipssVGZHNyidy3widTu8idgHsidgcgGdggRGkODXihH!8ilyhpihWj0ihWcailWHjGwO?OilD4BG888ZHJzmGHZtoyicqlkiwWfkicEbdHg3uEHtMkRH0TgkH5MBRIQE9VIUh5VIYeSyieFFgIlC6Qidvc5idv65icprGicNfhItjoJI4N3mJRFpIicLVGJgMY7J2GebKAPoGKyITuidFGWic2olicYLfLFuJDidnoticCc!icx2bieAcuLIv3UicoYuic594LRQ86LZc3NidcphicnOVic09yisjDiitRyFLc7NTicTaFicFbvic6jPLk3JtigqSiL1QJUjJQZpidQvJicUVVidYVsidNOjidNQfidNnLicyCAicHGeidY17icL3cL8DSKMcPzVMgc8dicEg6ig61OMwImmM06KXM6Hl!M96LNicQEbicUjBNAt2Aid4Hwix3w0Ndba5Nt5pqNwuVljBbJaicYjeigAxGN1b!LOEvTnisIIoORf1cOVV!TiczJbiddd5iddgpiclyxidfd8idfuEieACwid?zWih2rlOp2waid?r2OtUKQOxMyjihUpcigKWQO4y32PNAPFidAU6PZAhBPhjAni0PYUiceDridjwXPqEBxPsZ5Cicoi9icBWoieHXOP0B?9QF50CigWlyQJBkUQMs8nici3YQQ?MXidedxicjVCidhu9icqIFidhZjidhBQid0avicmIYQZLp!QdLBNQwFKyipSwfikPB5Q1SZKipSC1idL08Q44Vaic4tpikVWWQ9x5KikK4sig4Afit?bgihvhKRA?wsidxIfidGjgikw?ORRruoRYQWbRh2dkRk!EPRo!Vpig!taR92Glicf4gicxZGSCIB1jED6KSF0tyid0MUieEUnidLfYSRRoKSUk5sSczRfih06gSkpOgikVvGio5X1icp8Kio5NFik0sjix9EQSp8Pvide28icanaidyPpidekWSx71CTANkkicssXTE1nojEbGQTJp32ic?fFTcYU6icuDuicNCIT1B67T4DhEice8dihBd7ismVIUIRe3UVJeiUZBPEVNXn3idXcIj0jici5yT6VgGbJVlXA2idcRxicfAXicT4kicRjbVpnXZieEm?V4feMigLlzV95OGip4?git4nTWF3csicyWQWJGH2ikH?FWMo06ieCn5WSC2fieDOsWUm1Tidor2WZoaQidoCjicz5cWlxroicTKOW4dS9ido5CidnBwic0AWXJX4lXNdDaicS!nXkWPBXotnyYAgsNicrXhicnmHidHe0idHlLicaNvicG8Jida06YMOfFidTV!icY0YidDcrYRiXUYZivaigDO8ig8GPigGNwi88iCikuzkiharXicoAoihJPbihae9ihJmOihJ9xigV9UiwsMyidaEBichf!ic9ZEYk9oiigCARY9kLuidkWPidknpidk?aihh0likBkKZEJFsidjdfieJmgZIU5dieH47isgQIZNxb3ZQn7hidI6HZVIi0il9ZLix9nYih92!ihCeNZZClyZhISFi1IDjid6bQicwQvZl66Eid6riZoGjRicpYuieBC5ic5jfZwlrsicKATimA?cZ8ZO6icxGJieAt2iculVaA40zidYsAacin?aglNzalwMVi9d0mictfZascgqicbxMbABJ?ignSAjYM8?bIhNZigd1qig7eVieJNPbQq8pikKkaigVPligW!fjgR?5bWCHKidCM1bcrI5idppfidpRsi5P6TbkXgIbo2xucEAZdihvCiidPJXidPYxicAACcIXb9isr67cMtDzcgfiVctsKmc8khZigZjTilrC1ihpKGjQhh5dJr30igymSjKJehihMVeig3VrigwENipRc!idKnBdRRFodhKEOdxEc9idEnCidE8zic!9VidK1md18eZit!FHieGkhicJ8SieCXticlSNidbjridA7YeIdgneNtbMeVlKqeZlSZicbpmixtEVesAlzfU2dAfdwW?fsSYbf5w59gB1xOicMKxgN1q8icZbagZPjpidSoWid1Y0ic2JSid1Bhgo7qeidcLjilYKFiw6S2isa5Jgxwl9g00UbicSMohA73XhELGKhUQqNi8cGshgsaridfCIhkkePhtUeth0vCqileCnit5YaiE?plieHKPiJTPmiN7Kt'; -const COLORS = '??r6!Pj?!Pj?9fX19fX13Nzc??rw??rw?fXm?fXm!vDm!uvX!uvX?!?V?!?V?!vN?!vN?!TE?9q5?9q5?96t?96t?!S1??jc???w??rN??rN??Xu8P?w9f?69f?68P??8Pj?8Pj?5ub6??D1??D1?!Th?!Th????AAAAL09PL09PL09PL09PaWlpaWlpaWlpaWlpcICQcICQcICQcICQd4iZd4iZd4iZd4iZvr6!vr6!09PT09PT09PT09PTGRlwGRlwAACAAACAAACAZJXtZJXtSD2LSD2LalrNalrNe2jue2juhHD?hHD?AADNAADNQWnhQWnhAAD?HpD?HpD?AL??AL??h87rh87rh876h876RoK0RoK0sMTesMTerdjmrdjmsODmsODmr!7ur!7uAM7RAM7RSNHMSNHMQODQAP??4P??4P??X56gX56gZs2qZs2qf??UAGQAAGQAVWsvVWsvj7yPj7yPLotXLotXPLNxPLNxILKqILKqmPuYmPuYAP9?AP9?fPwAfPwAAP8Af?8AAPqaAPqarf8vrf8vMs0yMs0yms0yms0yIosiIosia44ja44jvbdrvbdr8OaM7uiq7uiq!vrS!vrS???g???g??8A?9cA7t2C7t2C2qUguIYLuIYLvI!PvI!PzVxczVxci0UTi0UToFItzYU?3riH9fXc9d6z9KRg9KRg0rSM0mkesiIipSoq6ZZ66ZZ6!oBy?6B6?6B6?6UA?4wA?4wA?39Q8ICA8ICA?2NH?0UA?0UA?wAA?2m0?2m0?xST?xST?8DL?7bB?7bB23CT23CTsDBgxxWFxxWF0CCQ0CCQ?wD?7oLu3aDd2nDWulXTulXTmTLMmTLMlADTlADTiiviiivioCDwk3Dbk3Db2L?Y??r67unpzcnJi4mJ??Xu7uXezcW?i4aC?!?b7t?MzcCwi4N4?!TE7tW3zbeei31r?9q57sutza!Vi3dl?96t7s!hzbOLi3le??rN7um?zcmli4lw??jc7ujNzcixi4h4???w7u7gzc3Bi4uD8P?w4O7gwc3Bg4uD??D17uDlzcHFi4OG?!Th7tXSzbe1i3178P??4O7uwc3Ng4uLg2??emfuaVnNRzyLSHb?Q27uOl?NJ0CLAAD?AADuAADNAACLHpD?HIbuGHTNEE6LY7j?XKzuT5TNNmSLAL??ALLuAJrNAGiLh87?fsDubKbNSnCLsOL?pNPujbbNYHuLxuL?udPun7bNbHuLyuH?vNLuorXNbnuLv!??st?umsDNaIOL4P??0e7utM3NeouLu???ru7uls3NZouLmPX?juXuesXNU4aLAPX?AOXuAMXNAIaLAP??AO7uAM3NAIuLl???je7uec3NUouLf??Udu7GZs2qRYt0wf?BtO60m82baYtpVP!fTu6UQ82ALotXmv!akO6QfM18VItUAP9?AO52AM1mAItFAP8AAO4AAM0AAIsAf?8Adu4AZs0ARYsAwP8!s!46ms0yaYsiyv9wvO5oos1abos9??aP7uaFzcZzi4ZO?!yL7tyCzb5wi4FM???g7u7Rzc20i4t6??8A7u4Azc0Ai4sA?9cA7skAza0Ai3UA?8El7rQizZsdi2kU?7kP7q0OzZUMi2UI?8HB7rS0zZubi2lp?2pq7mNjzVVVizo6?4JH7nlCzWg5i0cm?9Ob7sWRzap9i3NV?!e67tiuzbqWi35m?6VP7ppJzYU?i1or?38k7nYhzWYdi0UT?zAw7iwszSYmixoa?0BA7js7zTMziyMj?4xp7oJizXBUi0w5?6B67pVyzYFii1dC?6UA7poAzYUAi1oA?38A7nYAzWYAi0UA?3JW7mpQzVtFiz4v?2NH7lxCzU85izYm?0UA7kAAzTcAiyUA?wAA7gAAzQAAiwAA1wdR?xST7hKJzRB2iwpQ?2607mqnzWCQizpi?7XF7qm4zZGei2Ns?6657qKtzYyVi19l?4Kr7nmfzWiJi0dd?zSz7jCnzSmQixxi?z6W7jqMzTJ4iyJS?wD?7gDuzQDNiwCL?4P67nrpzWnJi0eJ?7v?7q7uzZbNi2aL4Gb?0V?utFLNejeLvz7?sjrumjLNaCKLmzD?kSzufSbNVRqLq4L?n3nuiWjNXUeL?!H?7tLuzbXNi3uLqampqampqampqampAACLAACLAIuLAIuLiwCLiwCLiwAAiwAAkO6QkO6Q'; -const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?'; -const OFFSET = 551; -const LENGTH = 551; -const BUCKET_LENGTH = TABLE.length / LENGTH; - -// match greyXX|grayXX names -const rexGrey = /^gr[ae]y(\d+)/; -// name match -const rexName = /^\w?[A-Za-z0-9 ]+\w/; - -function gray(n: number): [number, number, number] | undefined { - if (0 <= n && n <= 100) { - const v = Math.floor((n * 256 - n + 50) / 100); - return [v, v, v]; - } - return; -} - -function hash(d: number, name: string): number { - if (!d) d = 0x01000193; - for (const c of name) { - d = ((d * 0x01000193) ^ c.charCodeAt(0)) & 0xffffffff; - } - return d >>> 0; -} - -function crc10(name: string, crc?: number): number { - if (!crc) crc = 0; - for (const c of name) { - crc ^= c.charCodeAt(0) << 2; - for (let k = 0; k < 8; k++) { - crc = crc & 0x200 ? (crc << 1) ^ 0x233 : crc << 1; - } - } - crc &= 0x3ff; - return crc >>> 0; -} - -function loadData(idx: number): [number, number, number] { - let value = 0; - for (let i = idx * BUCKET_LENGTH; i < idx * BUCKET_LENGTH + BUCKET_LENGTH; ++i) { - value *= ALPHABET.length; - value += ALPHABET.indexOf(TABLE[i]); - } - return [value >>> 20, (value >> 10) & 0x3FF, value & 0x3FF]; -} - -function loadColor(idx: number): [number, number, number] { - // color buckets are hardcoded to 4 chars - let v = 0; - for (let i = idx * 4; i < idx * 4 + 4; ++i) { - v *= ALPHABET.length; - v += ALPHABET.indexOf(COLORS[i]); - } - return [v >>> 16, (v >> 8) & 0xFF, v & 0xFF]; -} - -function lookupIdx(name: string): number { - let b = loadData(hash(0, name) % LENGTH); - b = loadData(b[0] < OFFSET ? (-(b[0] - OFFSET) - 1) : hash(b[0] - OFFSET, name) % LENGTH); - const [ , , crc] = loadData(b[1]); - return crc10(name) === crc ? b[1] : -1; -} - -export function getColorFromName(name: string): [number, number, number] | undefined { - // basic name filtering - if (name.length < 3 || name.length > 22 || !rexName.exec(name)) return; - - // handle grays special - const m = rexGrey.exec(name); - if (m) return gray(parseInt(m[1])); - - // grab crc checked idx from PHF - const idx = lookupIdx(name); - if (idx === -1) return; - return loadColor(idx); -}