├── .editorconfig ├── .gitignore ├── LICENSE.md ├── README.md ├── fixtures ├── hyper │ ├── atom.js │ ├── empty.js │ ├── external.js │ ├── faulty-color.js │ ├── faulty.js │ ├── legacy.js │ ├── missing-color.js │ ├── missing.js │ └── seti.js ├── iterm2 │ ├── Atom.itermcolors │ ├── Seti.itermcolors │ ├── empty.itermcolors │ ├── incomplete.itermcolors │ ├── malformed-keys.itermcolors │ ├── malformed-range.itermcolors │ ├── malformed-values.itermcolors │ └── serialized.itermcolors ├── konsole │ ├── Atom.colorscheme │ ├── Seti.colorscheme │ ├── empty.colorscheme │ ├── incomplete.colorscheme │ ├── malformed-keys.colorscheme │ ├── malformed-range.colorscheme │ └── malformed-values.colorscheme ├── remmina │ ├── Atom.colors │ ├── Seti.colors │ ├── empty.colors │ ├── incomplete.colors │ └── malformed-values.colors ├── terminal │ ├── Atom.terminal │ ├── Seti.terminal │ ├── colorspaces.terminal │ ├── empty.terminal │ ├── incomplete.terminal │ ├── malformed-keys.terminal │ ├── malformed-values.terminal │ └── malformed.terminal ├── terminator │ ├── Atom.config │ ├── Seti.config │ ├── empty.config │ ├── incomplete-palette.config │ ├── incomplete.config │ ├── malformed-palette-item.config │ ├── malformed-palette.config │ └── malformed-values.config ├── termite │ ├── Atom │ ├── Seti │ ├── empty │ ├── incomplete │ └── malformed-values ├── tilda │ ├── Atom.config_0 │ ├── Seti.config_0 │ ├── empty.config_0 │ ├── incomplete-palette.config_0 │ ├── incomplete.config_0 │ ├── malformed-palette-item.config_0 │ ├── malformed-palette.config_0 │ └── malformed-values.config_0 ├── xfce │ ├── Atom.theme │ ├── Seti.theme │ ├── empty.theme │ ├── incomplete-palette.theme │ ├── incomplete.theme │ ├── malformed-palette.theme │ └── malformed-values.theme ├── xresources │ ├── Atom │ ├── Seti │ ├── empty │ ├── incomplete │ └── malformed-values └── xterm │ ├── Atom.xrdb │ ├── Seti.xrdb │ ├── empty.xrdb │ ├── incomplete.xrdb │ └── malformed-values.xrdb ├── package.json ├── src ├── helpers.ts ├── index.test.js ├── index.ts ├── matchers.ts └── parsers │ ├── hyper.test.js │ ├── hyper.ts │ ├── iterm2.test.js │ ├── iterm2.ts │ ├── konsole.test.js │ ├── konsole.ts │ ├── remmina.test.js │ ├── remmina.ts │ ├── term-scheme.ts │ ├── terminal.test.js │ ├── terminal.ts │ ├── terminator.test.js │ ├── terminator.ts │ ├── termite.test.js │ ├── termite.ts │ ├── tilda.test.js │ ├── tilda.ts │ ├── xfce.test.js │ ├── xfce.ts │ ├── xresources.test.js │ ├── xresources.ts │ ├── xterm.test.js │ └── xterm.ts ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib 2 | node_modules 3 | *.log 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright Mario Nebl 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > Parse and normalize common terminal emulator color schemes 2 | 3 | # term-schemes 4 | 5 | * Supports **10** formats 6 | * Normalizes to common structure 7 | * Works well with svg-term 8 | * TypeScript support 9 | 10 | ## Example 11 | 12 | ```js 13 | const termSchemes = require('term-schemes'); 14 | const fs = require('fs'); 15 | const util = require('util'); 16 | const readFile = util.promisify(fs.readFile); 17 | 18 | async function main() { 19 | const raw = String(await readFile('./Seti.itermcolors')); 20 | const scheme = termSchemes.iterm2(raw); // => {0: [50, 50, 50], .., background: [17, 18, 19]} 21 | } 22 | 23 | ``` 24 | 25 | ## API 26 | 27 | ```ts 28 | // Available methods 29 | export iterm2: Parser; 30 | export konsole: Parser; 31 | export remmina: Parser; 32 | export terminal: Parser; 33 | export terminator: Parser; 34 | export termite: Parser; 35 | export tilda: Parser; 36 | export xfce: Parser; 37 | export xresources: Parser; 38 | export xterm: Parser; 39 | 40 | type Parser = (input: any) => TermScheme; 41 | 42 | /** RGB Color: [R, G, B], each item number between 0 and 255 */ 43 | type TermSchemeColor = [number, number, number]; 44 | 45 | interface TermScheme { 46 | /** Black */ 47 | 0: TermSchemeColor; 48 | /** Red */ 49 | 1: TermSchemeColor; 50 | /** Green */ 51 | 2: TermSchemeColor; 52 | /** Yellow */ 53 | 3: TermSchemeColor; 54 | /** Blue */ 55 | 4: TermSchemeColor; 56 | /** Magenta */ 57 | 5: TermSchemeColor; 58 | /** Cyan */ 59 | 6: TermSchemeColor; 60 | /** White */ 61 | 7: TermSchemeColor; 62 | /** Bright Black */ 63 | 8: TermSchemeColor; 64 | /** Bright Red */ 65 | 9: TermSchemeColor; 66 | /** Bright Green */ 67 | 10: TermSchemeColor; 68 | /** Bright Yellow */ 69 | 11: TermSchemeColor; 70 | /** Bright Blue */ 71 | 12: TermSchemeColor; 72 | /** Bright Magenta */ 73 | 13: TermSchemeColor; 74 | /** Bright Cyan */ 75 | 14: TermSchemeColor; 76 | /** Bright White */ 77 | 15: TermSchemeColor; 78 | /** Background color */ 79 | background: TermSchemeColor; 80 | /** Bold text color */ 81 | bold: TermSchemeColor; 82 | /** Cursor background color */ 83 | cursor: TermSchemeColor; 84 | /** Text color */ 85 | text: TermSchemeColor; 86 | } 87 | ``` 88 | 89 | ## Supported formats 90 | 91 | * [x] Hyper `.js` 92 | * [x] iTerm2 `.itermcolors` 93 | * [x] Konsole `.colorscheme` 94 | * [x] Remmina `.colors` 95 | * [x] Terminal `.terminal` 96 | * [x] Terminator `.config` 97 | * [x] Termite ` ` 98 | * [x] Tilda `.config_0` 99 | * [x] Xfce `.theme` 100 | * [x] XTerm `.xrdb`, `Xresources` 101 | 102 | ## License 103 | 104 | Copyright Mario Nebl. term-schemes is released under the MIT license. 105 | 106 | ## Related 107 | 108 | * Test fixtures sourced from [mbadolato/iTerm2-Color-Schemes](https://github.com/mbadolato/iTerm2-Color-Schemes) 109 | 110 | ## Development 111 | 112 | ``` 113 | npx yarn install 114 | npx yarn start 115 | ``` 116 | -------------------------------------------------------------------------------- /fixtures/hyper/atom.js: -------------------------------------------------------------------------------- 1 | // Future versions of Hyper may add additional config options, 2 | // which will not automatically be merged into this file. 3 | // See https://hyper.is#cfg for all currently supported options. 4 | 5 | module.exports = { 6 | config: { 7 | cursorColor: '#d0d0d0', 8 | 9 | // color of the text 10 | foregroundColor: '#c5c8c6', 11 | 12 | // terminal background color 13 | backgroundColor: '#161719', 14 | 15 | // the full list. if you're going to provide the full color palette, 16 | // including the 6 x 6 color cubes and the grayscale map, just provide 17 | // an array here instead of a color map object 18 | colors: { 19 | black: '#000000', 20 | red: '#fd5ff1', 21 | green: '#87c38a', 22 | yellow: '#ffd7b1', 23 | blue: '#85befd', 24 | magenta: '#b9b6fc', 25 | cyan: '#85befd', 26 | white: '#e0e0e0', 27 | lightBlack: '#000000', 28 | lightRed: '#fd5ff1', 29 | lightGreen: '#94fa36', 30 | lightYellow: '#f5ffa8', 31 | lightBlue: '#96cbfe', 32 | lightMagenta: '#b9b6fc', 33 | lightCyan: '#85befd', 34 | lightWhite: '#e0e0e0' 35 | } 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /fixtures/hyper/empty.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | -------------------------------------------------------------------------------- /fixtures/hyper/external.js: -------------------------------------------------------------------------------- 1 | const atom = require('./atom'); 2 | 3 | module.exports = atom; 4 | -------------------------------------------------------------------------------- /fixtures/hyper/faulty-color.js: -------------------------------------------------------------------------------- 1 | // Future versions of Hyper may add additional config options, 2 | // which will not automatically be merged into this file. 3 | // See https://hyper.is#cfg for all currently supported options. 4 | 5 | module.exports = { 6 | config: { 7 | cursorColor: '#035fd2', 8 | 9 | // color of the text 10 | foregroundColor: '#fff', 11 | 12 | // terminal background color 13 | backgroundColor: '#000', 14 | 15 | // the full list. if you're going to provide the full color palette, 16 | // including the 6 x 6 color cubes and the grayscale map, just provide 17 | // an array here instead of a color map object 18 | colors: { 19 | black: 'foo', 20 | red: '#ff0000', 21 | green: '#33ff00', 22 | yellow: '#ffff00', 23 | blue: '#0066ff', 24 | magenta: '#cc00ff', 25 | cyan: '#00ffff', 26 | white: '#d0d0d0', 27 | lightBlack: '#808080', 28 | lightRed: '#ff0000', 29 | lightGreen: '#33ff00', 30 | lightYellow: '#ffff00', 31 | lightBlue: '#0066ff', 32 | lightMagenta: '#cc00ff', 33 | lightCyan: '#00ffff', 34 | lightWhite: '#ffffff' 35 | } 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /fixtures/hyper/faulty.js: -------------------------------------------------------------------------------- 1 | // Future versions of Hyper may add additional config options, 2 | // which will not automatically be merged into this file. 3 | // See https://hyper.is#cfg for all currently supported options. 4 | 5 | module.exports = { 6 | config: { 7 | cursorColor: 'foo', 8 | foregroundColor: '#fff', 9 | backgroundColor: '#000', 10 | colors: {} 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /fixtures/hyper/legacy.js: -------------------------------------------------------------------------------- 1 | // Future versions of Hyper may add additional config options, 2 | // which will not automatically be merged into this file. 3 | // See https://hyper.is#cfg for all currently supported options. 4 | 5 | module.exports = { 6 | config: { 7 | cursorColor: '#e3bf21', 8 | 9 | // color of the text 10 | foregroundColor: '#cacecd', 11 | 12 | // terminal background color 13 | backgroundColor: '#111213', 14 | 15 | // the full list. if you're going to provide the full color palette, 16 | // including the 6 x 6 color cubes and the grayscale map, just provide 17 | // an array here instead of a color map object 18 | colors: [ 19 | '#323232', 20 | '#c22832', 21 | '#8ec43d', 22 | '#e0c64f', 23 | '#43a5d5', 24 | '#8b57b5', 25 | '#8ec43d', 26 | '#eeeeee', 27 | '#323232', 28 | '#c22832', 29 | '#8ec43d', 30 | '#e0c64f', 31 | '#43a5d5', 32 | '#8b57b5', 33 | '#8ec43d', 34 | '#ffffff' 35 | ] 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /fixtures/hyper/missing-color.js: -------------------------------------------------------------------------------- 1 | // Future versions of Hyper may add additional config options, 2 | // which will not automatically be merged into this file. 3 | // See https://hyper.is#cfg for all currently supported options. 4 | 5 | module.exports = { 6 | config: { 7 | cursorColor: '#035fd2', 8 | 9 | // color of the text 10 | foregroundColor: '#fff', 11 | 12 | // terminal background color 13 | backgroundColor: '#000', 14 | 15 | // the full list. if you're going to provide the full color palette, 16 | // including the 6 x 6 color cubes and the grayscale map, just provide 17 | // an array here instead of a color map object 18 | colors: { 19 | red: '#ff0000', 20 | green: '#33ff00', 21 | yellow: '#ffff00', 22 | blue: '#0066ff', 23 | magenta: '#cc00ff', 24 | cyan: '#00ffff', 25 | white: '#d0d0d0', 26 | lightBlack: '#808080', 27 | lightRed: '#ff0000', 28 | lightGreen: '#33ff00', 29 | lightYellow: '#ffff00', 30 | lightBlue: '#0066ff', 31 | lightMagenta: '#cc00ff', 32 | lightCyan: '#00ffff', 33 | lightWhite: '#ffffff' 34 | } 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /fixtures/hyper/missing.js: -------------------------------------------------------------------------------- 1 | // Future versions of Hyper may add additional config options, 2 | // which will not automatically be merged into this file. 3 | // See https://hyper.is#cfg for all currently supported options. 4 | 5 | module.exports = { 6 | config: { 7 | // color of the text 8 | foregroundColor: '#fff', 9 | 10 | // terminal background color 11 | backgroundColor: '#000', 12 | 13 | colors: {} 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /fixtures/hyper/seti.js: -------------------------------------------------------------------------------- 1 | // Future versions of Hyper may add additional config options, 2 | // which will not automatically be merged into this file. 3 | // See https://hyper.is#cfg for all currently supported options. 4 | 5 | module.exports = { 6 | config: { 7 | cursorColor: '#e3bf21', 8 | 9 | // color of the text 10 | foregroundColor: '#cacecd', 11 | 12 | // terminal background color 13 | backgroundColor: '#111213', 14 | 15 | // the full list. if you're going to provide the full color palette, 16 | // including the 6 x 6 color cubes and the grayscale map, just provide 17 | // an array here instead of a color map object 18 | colors: { 19 | black: '#323232', 20 | red: '#c22832', 21 | green: '#8ec43d', 22 | yellow: '#e0c64f', 23 | blue: '#43a5d5', 24 | magenta: '#8b57b5', 25 | cyan: '#8ec43d', 26 | white: '#eeeeee', 27 | lightBlack: '#323232', 28 | lightRed: '#c22832', 29 | lightGreen: '#8ec43d', 30 | lightYellow: '#e0c64f', 31 | lightBlue: '#43a5d5', 32 | lightMagenta: '#8b57b5', 33 | lightCyan: '#8ec43d', 34 | lightWhite: '#ffffff' 35 | } 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /fixtures/iterm2/Atom.itermcolors: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ansi 0 Color 6 | 7 | Blue Component 8 | 0.0 9 | Green Component 10 | 0.0 11 | Red Component 12 | 0.0 13 | 14 | Ansi 1 Color 15 | 16 | Blue Component 17 | 0.94509803920000002 18 | Green Component 19 | 0.37254901959999998 20 | Red Component 21 | 0.99215686270000003 22 | 23 | Ansi 10 Color 24 | 25 | Blue Component 26 | 0.21213282644748688 27 | Green Component 28 | 0.97885209321975708 29 | Red Component 30 | 0.58183550834655762 31 | 32 | Ansi 11 Color 33 | 34 | Blue Component 35 | 0.6569250226020813 36 | Green Component 37 | 1 38 | Red Component 39 | 0.96221715211868286 40 | 41 | Ansi 12 Color 42 | 43 | Blue Component 44 | 0.99607843137254903 45 | Green Component 46 | 0.79607843137254897 47 | Red Component 48 | 0.58823529411764708 49 | 50 | Ansi 13 Color 51 | 52 | Blue Component 53 | 0.98932766914367676 54 | Green Component 55 | 0.71280097961425781 56 | Red Component 57 | 0.72722584009170532 58 | 59 | Ansi 14 Color 60 | 61 | Blue Component 62 | 0.99405109882354736 63 | Green Component 64 | 0.74560397863388062 65 | Red Component 66 | 0.5230981707572937 67 | 68 | Ansi 15 Color 69 | 70 | Blue Component 71 | 0.87804841995239258 72 | Green Component 73 | 0.87803351879119873 74 | Red Component 75 | 0.87805980443954468 76 | 77 | Ansi 2 Color 78 | 79 | Blue Component 80 | 0.54117647058823526 81 | Green Component 82 | 0.76470588235294112 83 | Red Component 84 | 0.52941176470588236 85 | 86 | Ansi 3 Color 87 | 88 | Blue Component 89 | 0.69411764705882351 90 | Green Component 91 | 0.84313725490196079 92 | Red Component 93 | 1 94 | 95 | Ansi 4 Color 96 | 97 | Blue Component 98 | 0.99405109882354736 99 | Green Component 100 | 0.74560397863388062 101 | Red Component 102 | 0.5230981707572937 103 | 104 | Ansi 5 Color 105 | 106 | Blue Component 107 | 0.98932766914367676 108 | Green Component 109 | 0.71280097961425781 110 | Red Component 111 | 0.72722584009170532 112 | 113 | Ansi 6 Color 114 | 115 | Blue Component 116 | 0.99405109882354736 117 | Green Component 118 | 0.74560397863388062 119 | Red Component 120 | 0.5230981707572937 121 | 122 | Ansi 7 Color 123 | 124 | Blue Component 125 | 0.87804847955703735 126 | Green Component 127 | 0.87803357839584351 128 | Red Component 129 | 0.87805986404418945 130 | 131 | Ansi 8 Color 132 | 133 | Blue Component 134 | 0.0 135 | Green Component 136 | 0.0 137 | Red Component 138 | 0.0 139 | 140 | Ansi 9 Color 141 | 142 | Blue Component 143 | 0.94509803920000002 144 | Green Component 145 | 0.37254901959999998 146 | Red Component 147 | 0.99215686270000003 148 | 149 | Background Color 150 | 151 | Blue Component 152 | 0.097707755863666534 153 | Green Component 154 | 0.092142701148986816 155 | Red Component 156 | 0.086937598884105682 157 | 158 | Bold Color 159 | 160 | Blue Component 161 | 0.77647058823529413 162 | Green Component 163 | 0.78431372549019607 164 | Red Component 165 | 0.77254901960784317 166 | 167 | Cursor Color 168 | 169 | Blue Component 170 | 0.81568628549575806 171 | Green Component 172 | 0.81568628549575806 173 | Red Component 174 | 0.81568628549575806 175 | 176 | Cursor Text Color 177 | 178 | Blue Component 179 | 0.08235294371843338 180 | Green Component 181 | 0.08235294371843338 182 | Red Component 183 | 0.08235294371843338 184 | 185 | Foreground Color 186 | 187 | Blue Component 188 | 0.77647058823529413 189 | Green Component 190 | 0.78431372549019607 191 | Red Component 192 | 0.77254901960784317 193 | 194 | Selected Text Color 195 | 196 | Blue Component 197 | 0.77647058823529413 198 | Green Component 199 | 0.78431372549019607 200 | Red Component 201 | 0.77254901960784317 202 | 203 | Selection Color 204 | 205 | Blue Component 206 | 0.26666666666666666 207 | Green Component 208 | 0.26666666666666666 209 | Red Component 210 | 0.26666666666666666 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /fixtures/iterm2/Seti.itermcolors: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ansi 0 Color 6 | 7 | Blue Component 8 | 0.19607843137254902 9 | Green Component 10 | 0.19607843137254902 11 | Red Component 12 | 0.19607843137254902 13 | 14 | Ansi 1 Color 15 | 16 | Blue Component 17 | 0.19607843458652496 18 | Green Component 19 | 0.15686275064945221 20 | Red Component 21 | 0.7607843279838562 22 | 23 | Ansi 10 Color 24 | 25 | Blue Component 26 | 0.23921568691730499 27 | Green Component 28 | 0.76862746477127075 29 | Red Component 30 | 0.55686277151107788 31 | 32 | Ansi 11 Color 33 | 34 | Blue Component 35 | 0.30980393290519714 36 | Green Component 37 | 0.7764706015586853 38 | Red Component 39 | 0.87843137979507446 40 | 41 | Ansi 12 Color 42 | 43 | Blue Component 44 | 0.83529412746429443 45 | Green Component 46 | 0.64705884456634521 47 | Red Component 48 | 0.26274511218070984 49 | 50 | Ansi 13 Color 51 | 52 | Blue Component 53 | 0.70980393886566162 54 | Green Component 55 | 0.34117648005485535 56 | Red Component 57 | 0.54509806632995605 58 | 59 | Ansi 14 Color 60 | 61 | Blue Component 62 | 0.23921568691730499 63 | Green Component 64 | 0.76862746477127075 65 | Red Component 66 | 0.55686277151107788 67 | 68 | Ansi 15 Color 69 | 70 | Blue Component 71 | 1 72 | Green Component 73 | 1 74 | Red Component 75 | 1 76 | 77 | Ansi 2 Color 78 | 79 | Blue Component 80 | 0.23921568691730499 81 | Green Component 82 | 0.76862746477127075 83 | Red Component 84 | 0.55686277151107788 85 | 86 | Ansi 3 Color 87 | 88 | Blue Component 89 | 0.30980393290519714 90 | Green Component 91 | 0.7764706015586853 92 | Red Component 93 | 0.87843137979507446 94 | 95 | Ansi 4 Color 96 | 97 | Blue Component 98 | 0.83529412746429443 99 | Green Component 100 | 0.64705884456634521 101 | Red Component 102 | 0.26274511218070984 103 | 104 | Ansi 5 Color 105 | 106 | Blue Component 107 | 0.70980393886566162 108 | Green Component 109 | 0.34117648005485535 110 | Red Component 111 | 0.54509806632995605 112 | 113 | Ansi 6 Color 114 | 115 | Blue Component 116 | 0.23921568691730499 117 | Green Component 118 | 0.76862746477127075 119 | Red Component 120 | 0.55686277151107788 121 | 122 | Ansi 7 Color 123 | 124 | Blue Component 125 | 0.93353170156478882 126 | Green Component 127 | 0.93353170156478882 128 | Red Component 129 | 0.93353170156478882 130 | 131 | Ansi 8 Color 132 | 133 | Blue Component 134 | 0.19607843137254902 135 | Green Component 136 | 0.19607843137254902 137 | Red Component 138 | 0.19607843137254902 139 | 140 | Ansi 9 Color 141 | 142 | Blue Component 143 | 0.19607843458652496 144 | Green Component 145 | 0.15686275064945221 146 | Red Component 147 | 0.7607843279838562 148 | 149 | Background Color 150 | 151 | Blue Component 152 | 0.074509806931018829 153 | Green Component 154 | 0.070588238537311554 155 | Red Component 156 | 0.066666670143604279 157 | 158 | Bold Color 159 | 160 | Blue Component 161 | 0.80392158031463623 162 | Green Component 163 | 0.80784314870834351 164 | Red Component 165 | 0.7921568751335144 166 | 167 | Cursor Color 168 | 169 | Blue Component 170 | 0.12981389462947845 171 | Green Component 172 | 0.74717473983764648 173 | Red Component 174 | 0.8895719051361084 175 | 176 | Cursor Text Color 177 | 178 | Blue Component 179 | 0.18040022253990173 180 | Green Component 181 | 0.74690163135528564 182 | Red Component 183 | 0.88014161586761475 184 | 185 | Foreground Color 186 | 187 | Blue Component 188 | 0.80392158031463623 189 | Green Component 190 | 0.80784314870834351 191 | Red Component 192 | 0.7921568751335144 193 | 194 | Selected Text Color 195 | 196 | Blue Component 197 | 0.80392158031463623 198 | Green Component 199 | 0.80784314870834351 200 | Red Component 201 | 0.7921568751335144 202 | 203 | Selection Color 204 | 205 | Blue Component 206 | 0.20000000298023224 207 | Green Component 208 | 0.19607843458652496 209 | Red Component 210 | 0.18823529779911041 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /fixtures/iterm2/empty.itermcolors: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fixtures/iterm2/incomplete.itermcolors: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Selection Color 6 | 7 | Blue Component 8 | 0.20000000298023224 9 | Green Component 10 | 0.19607843458652496 11 | Red Component 12 | 0.18823529779911041 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /fixtures/iterm2/malformed-keys.itermcolors: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ansi 0 Color 6 | 7 | Blue 8 | 0.19607843137254902 9 | Green Component 10 | 0.19607843137254902 11 | Red Component 12 | 0.19607843137254902 13 | 14 | Ansi 1 Color 15 | 16 | Blue Component 17 | 0.19607843458652496 18 | Green Component 19 | 0.15686275064945221 20 | Red Component 21 | 0.7607843279838562 22 | 23 | Ansi 10 Color 24 | 25 | Blue Component 26 | 0.23921568691730499 27 | Green Component 28 | 0.76862746477127075 29 | Red Component 30 | 0.55686277151107788 31 | 32 | Ansi 11 Color 33 | 34 | Blue Component 35 | 0.30980393290519714 36 | Green Component 37 | 0.7764706015586853 38 | Red Component 39 | 0.87843137979507446 40 | 41 | Ansi 12 Color 42 | 43 | Blue Component 44 | 0.83529412746429443 45 | Green Component 46 | 0.64705884456634521 47 | Red Component 48 | 0.26274511218070984 49 | 50 | Ansi 13 Color 51 | 52 | Blue Component 53 | 0.70980393886566162 54 | Green Component 55 | 0.34117648005485535 56 | Red Component 57 | 0.54509806632995605 58 | 59 | Ansi 14 Color 60 | 61 | Blue Component 62 | 0.23921568691730499 63 | Green Component 64 | 0.76862746477127075 65 | Red Component 66 | 0.55686277151107788 67 | 68 | Ansi 15 Color 69 | 70 | Blue Component 71 | 1 72 | Green Component 73 | 1 74 | Red Component 75 | 1 76 | 77 | Ansi 2 Color 78 | 79 | Blue Component 80 | 0.23921568691730499 81 | Green Component 82 | 0.76862746477127075 83 | Red Component 84 | 0.55686277151107788 85 | 86 | Ansi 3 Color 87 | 88 | Blue Component 89 | 0.30980393290519714 90 | Green Component 91 | 0.7764706015586853 92 | Red Component 93 | 0.87843137979507446 94 | 95 | Ansi 4 Color 96 | 97 | Blue Component 98 | 0.83529412746429443 99 | Green Component 100 | 0.64705884456634521 101 | Red Component 102 | 0.26274511218070984 103 | 104 | Ansi 5 Color 105 | 106 | Blue Component 107 | 0.70980393886566162 108 | Green Component 109 | 0.34117648005485535 110 | Red Component 111 | 0.54509806632995605 112 | 113 | Ansi 6 Color 114 | 115 | Blue Component 116 | 0.23921568691730499 117 | Green Component 118 | 0.76862746477127075 119 | Red Component 120 | 0.55686277151107788 121 | 122 | Ansi 7 Color 123 | 124 | Blue Component 125 | 0.93353170156478882 126 | Green Component 127 | 0.93353170156478882 128 | Red Component 129 | 0.93353170156478882 130 | 131 | Ansi 8 Color 132 | 133 | Blue Component 134 | 0.19607843137254902 135 | Green Component 136 | 0.19607843137254902 137 | Red Component 138 | 0.19607843137254902 139 | 140 | Ansi 9 Color 141 | 142 | Blue Component 143 | 0.19607843458652496 144 | Green Component 145 | 0.15686275064945221 146 | Red Component 147 | 0.7607843279838562 148 | 149 | Background Color 150 | 151 | Blue Component 152 | 0.074509806931018829 153 | Green Component 154 | 0.070588238537311554 155 | Red Component 156 | 0.066666670143604279 157 | 158 | Bold Color 159 | 160 | Blue Component 161 | 0.80392158031463623 162 | Green Component 163 | 0.80784314870834351 164 | Red Component 165 | 0.7921568751335144 166 | 167 | Cursor Color 168 | 169 | Blue Component 170 | 0.12981389462947845 171 | Green Component 172 | 0.74717473983764648 173 | Red Component 174 | 0.8895719051361084 175 | 176 | Cursor Text Color 177 | 178 | Blue Component 179 | 0.18040022253990173 180 | Green Component 181 | 0.74690163135528564 182 | Red Component 183 | 0.88014161586761475 184 | 185 | Foreground Color 186 | 187 | Blue Component 188 | 0.80392158031463623 189 | Green Component 190 | 0.80784314870834351 191 | Red Component 192 | 0.7921568751335144 193 | 194 | Selected Text Color 195 | 196 | Blue Component 197 | 0.80392158031463623 198 | Green Component 199 | 0.80784314870834351 200 | Red Component 201 | 0.7921568751335144 202 | 203 | Selection Color 204 | 205 | Blue Component 206 | 0.20000000298023224 207 | Green Component 208 | 0.19607843458652496 209 | Red Component 210 | 0.18823529779911041 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /fixtures/iterm2/malformed-range.itermcolors: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ansi 0 Color 6 | 7 | Blue Component 8 | 2 9 | Green Component 10 | 0.19607843137254902 11 | Red Component 12 | 0.19607843137254902 13 | 14 | Ansi 1 Color 15 | 16 | Blue Component 17 | 0.19607843458652496 18 | Green Component 19 | 0.15686275064945221 20 | Red Component 21 | 0.7607843279838562 22 | 23 | Ansi 10 Color 24 | 25 | Blue Component 26 | 0.23921568691730499 27 | Green Component 28 | 0.76862746477127075 29 | Red Component 30 | 0.55686277151107788 31 | 32 | Ansi 11 Color 33 | 34 | Blue Component 35 | 0.30980393290519714 36 | Green Component 37 | 0.7764706015586853 38 | Red Component 39 | 0.87843137979507446 40 | 41 | Ansi 12 Color 42 | 43 | Blue Component 44 | 0.83529412746429443 45 | Green Component 46 | 0.64705884456634521 47 | Red Component 48 | 0.26274511218070984 49 | 50 | Ansi 13 Color 51 | 52 | Blue Component 53 | 0.70980393886566162 54 | Green Component 55 | 0.34117648005485535 56 | Red Component 57 | 0.54509806632995605 58 | 59 | Ansi 14 Color 60 | 61 | Blue Component 62 | 0.23921568691730499 63 | Green Component 64 | 0.76862746477127075 65 | Red Component 66 | 0.55686277151107788 67 | 68 | Ansi 15 Color 69 | 70 | Blue Component 71 | 1 72 | Green Component 73 | 1 74 | Red Component 75 | 1 76 | 77 | Ansi 2 Color 78 | 79 | Blue Component 80 | 0.23921568691730499 81 | Green Component 82 | 0.76862746477127075 83 | Red Component 84 | 0.55686277151107788 85 | 86 | Ansi 3 Color 87 | 88 | Blue Component 89 | 0.30980393290519714 90 | Green Component 91 | 0.7764706015586853 92 | Red Component 93 | 0.87843137979507446 94 | 95 | Ansi 4 Color 96 | 97 | Blue Component 98 | 0.83529412746429443 99 | Green Component 100 | 0.64705884456634521 101 | Red Component 102 | 0.26274511218070984 103 | 104 | Ansi 5 Color 105 | 106 | Blue Component 107 | 0.70980393886566162 108 | Green Component 109 | 0.34117648005485535 110 | Red Component 111 | 0.54509806632995605 112 | 113 | Ansi 6 Color 114 | 115 | Blue Component 116 | 0.23921568691730499 117 | Green Component 118 | 0.76862746477127075 119 | Red Component 120 | 0.55686277151107788 121 | 122 | Ansi 7 Color 123 | 124 | Blue Component 125 | 0.93353170156478882 126 | Green Component 127 | 0.93353170156478882 128 | Red Component 129 | 0.93353170156478882 130 | 131 | Ansi 8 Color 132 | 133 | Blue Component 134 | 0.19607843137254902 135 | Green Component 136 | 0.19607843137254902 137 | Red Component 138 | 0.19607843137254902 139 | 140 | Ansi 9 Color 141 | 142 | Blue Component 143 | 0.19607843458652496 144 | Green Component 145 | 0.15686275064945221 146 | Red Component 147 | 0.7607843279838562 148 | 149 | Background Color 150 | 151 | Blue Component 152 | 0.074509806931018829 153 | Green Component 154 | 0.070588238537311554 155 | Red Component 156 | 0.066666670143604279 157 | 158 | Bold Color 159 | 160 | Blue Component 161 | 0.80392158031463623 162 | Green Component 163 | 0.80784314870834351 164 | Red Component 165 | 0.7921568751335144 166 | 167 | Cursor Color 168 | 169 | Blue Component 170 | 0.12981389462947845 171 | Green Component 172 | 0.74717473983764648 173 | Red Component 174 | 0.8895719051361084 175 | 176 | Cursor Text Color 177 | 178 | Blue Component 179 | 0.18040022253990173 180 | Green Component 181 | 0.74690163135528564 182 | Red Component 183 | 0.88014161586761475 184 | 185 | Foreground Color 186 | 187 | Blue Component 188 | 0.80392158031463623 189 | Green Component 190 | 0.80784314870834351 191 | Red Component 192 | 0.7921568751335144 193 | 194 | Selected Text Color 195 | 196 | Blue Component 197 | 0.80392158031463623 198 | Green Component 199 | 0.80784314870834351 200 | Red Component 201 | 0.7921568751335144 202 | 203 | Selection Color 204 | 205 | Blue Component 206 | 0.20000000298023224 207 | Green Component 208 | 0.19607843458652496 209 | Red Component 210 | 0.18823529779911041 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /fixtures/iterm2/malformed-values.itermcolors: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ansi 0 Color 6 | 7 | Blue Component 8 | This should not be here 9 | Green Component 10 | 0.19607843137254902 11 | Red Component 12 | 0.19607843137254902 13 | 14 | Ansi 1 Color 15 | 16 | Blue Component 17 | 0.19607843458652496 18 | Green Component 19 | 0.15686275064945221 20 | Red Component 21 | 0.7607843279838562 22 | 23 | Ansi 10 Color 24 | 25 | Blue Component 26 | 0.23921568691730499 27 | Green Component 28 | 0.76862746477127075 29 | Red Component 30 | 0.55686277151107788 31 | 32 | Ansi 11 Color 33 | 34 | Blue Component 35 | 0.30980393290519714 36 | Green Component 37 | 0.7764706015586853 38 | Red Component 39 | 0.87843137979507446 40 | 41 | Ansi 12 Color 42 | 43 | Blue Component 44 | 0.83529412746429443 45 | Green Component 46 | 0.64705884456634521 47 | Red Component 48 | 0.26274511218070984 49 | 50 | Ansi 13 Color 51 | 52 | Blue Component 53 | 0.70980393886566162 54 | Green Component 55 | 0.34117648005485535 56 | Red Component 57 | 0.54509806632995605 58 | 59 | Ansi 14 Color 60 | 61 | Blue Component 62 | 0.23921568691730499 63 | Green Component 64 | 0.76862746477127075 65 | Red Component 66 | 0.55686277151107788 67 | 68 | Ansi 15 Color 69 | 70 | Blue Component 71 | 1 72 | Green Component 73 | 1 74 | Red Component 75 | 1 76 | 77 | Ansi 2 Color 78 | 79 | Blue Component 80 | 0.23921568691730499 81 | Green Component 82 | 0.76862746477127075 83 | Red Component 84 | 0.55686277151107788 85 | 86 | Ansi 3 Color 87 | 88 | Blue Component 89 | 0.30980393290519714 90 | Green Component 91 | 0.7764706015586853 92 | Red Component 93 | 0.87843137979507446 94 | 95 | Ansi 4 Color 96 | 97 | Blue Component 98 | 0.83529412746429443 99 | Green Component 100 | 0.64705884456634521 101 | Red Component 102 | 0.26274511218070984 103 | 104 | Ansi 5 Color 105 | 106 | Blue Component 107 | 0.70980393886566162 108 | Green Component 109 | 0.34117648005485535 110 | Red Component 111 | 0.54509806632995605 112 | 113 | Ansi 6 Color 114 | 115 | Blue Component 116 | 0.23921568691730499 117 | Green Component 118 | 0.76862746477127075 119 | Red Component 120 | 0.55686277151107788 121 | 122 | Ansi 7 Color 123 | 124 | Blue Component 125 | 0.93353170156478882 126 | Green Component 127 | 0.93353170156478882 128 | Red Component 129 | 0.93353170156478882 130 | 131 | Ansi 8 Color 132 | 133 | Blue Component 134 | 0.19607843137254902 135 | Green Component 136 | 0.19607843137254902 137 | Red Component 138 | 0.19607843137254902 139 | 140 | Ansi 9 Color 141 | 142 | Blue Component 143 | 0.19607843458652496 144 | Green Component 145 | 0.15686275064945221 146 | Red Component 147 | 0.7607843279838562 148 | 149 | Background Color 150 | 151 | Blue Component 152 | 0.074509806931018829 153 | Green Component 154 | 0.070588238537311554 155 | Red Component 156 | 0.066666670143604279 157 | 158 | Bold Color 159 | 160 | Blue Component 161 | 0.80392158031463623 162 | Green Component 163 | 0.80784314870834351 164 | Red Component 165 | 0.7921568751335144 166 | 167 | Cursor Color 168 | 169 | Blue Component 170 | 0.12981389462947845 171 | Green Component 172 | 0.74717473983764648 173 | Red Component 174 | 0.8895719051361084 175 | 176 | Cursor Text Color 177 | 178 | Blue Component 179 | 0.18040022253990173 180 | Green Component 181 | 0.74690163135528564 182 | Red Component 183 | 0.88014161586761475 184 | 185 | Foreground Color 186 | 187 | Blue Component 188 | 0.80392158031463623 189 | Green Component 190 | 0.80784314870834351 191 | Red Component 192 | 0.7921568751335144 193 | 194 | Selected Text Color 195 | 196 | Blue Component 197 | 0.80392158031463623 198 | Green Component 199 | 0.80784314870834351 200 | Red Component 201 | 0.7921568751335144 202 | 203 | Selection Color 204 | 205 | Blue Component 206 | 0.20000000298023224 207 | Green Component 208 | 0.19607843458652496 209 | Red Component 210 | 0.18823529779911041 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /fixtures/konsole/Atom.colorscheme: -------------------------------------------------------------------------------- 1 | [General] 2 | Description=Atom 3 | Opacity=1 4 | Wallpaper= 5 | 6 | [Background] 7 | Color=22,23,25 8 | 9 | [BackgroundIntense] 10 | Color=22,23,25 11 | 12 | [Foreground] 13 | Color=197,200,198 14 | 15 | [ForegroundIntense] 16 | Color=197,200,198 17 | 18 | [Color0] 19 | Color=0,0,0 20 | 21 | [Color1] 22 | Color=253,95,241 23 | 24 | [Color2Intense] 25 | Color=148,250,54 26 | 27 | [Color3Intense] 28 | Color=245,255,168 29 | 30 | [Color4Intense] 31 | Color=150,203,254 32 | 33 | [Color5Intense] 34 | Color=185,182,252 35 | 36 | [Color6Intense] 37 | Color=133,190,253 38 | 39 | [Color7Intense] 40 | Color=224,224,224 41 | 42 | [Color2] 43 | Color=135,195,138 44 | 45 | [Color3] 46 | Color=255,215,177 47 | 48 | [Color4] 49 | Color=133,190,253 50 | 51 | [Color5] 52 | Color=185,182,252 53 | 54 | [Color6] 55 | Color=133,190,253 56 | 57 | [Color7] 58 | Color=224,224,224 59 | 60 | [Color0Intense] 61 | Color=0,0,0 62 | 63 | [Color1Intense] 64 | Color=253,95,241 65 | -------------------------------------------------------------------------------- /fixtures/konsole/Seti.colorscheme: -------------------------------------------------------------------------------- 1 | [General] 2 | Description=Seti 3 | Opacity=1 4 | Wallpaper= 5 | 6 | [Background] 7 | Color=17,18,19 8 | 9 | [BackgroundIntense] 10 | Color=17,18,19 11 | 12 | [Foreground] 13 | Color=202,206,205 14 | 15 | [ForegroundIntense] 16 | Color=202,206,205 17 | 18 | [Color0] 19 | Color=50,50,50 20 | 21 | [Color1] 22 | Color=194,40,50 23 | 24 | [Color2Intense] 25 | Color=142,196,61 26 | 27 | [Color3Intense] 28 | Color=224,198,79 29 | 30 | [Color4Intense] 31 | Color=67,165,213 32 | 33 | [Color5Intense] 34 | Color=139,87,181 35 | 36 | [Color6Intense] 37 | Color=142,196,61 38 | 39 | [Color7Intense] 40 | Color=255,255,255 41 | 42 | [Color2] 43 | Color=142,196,61 44 | 45 | [Color3] 46 | Color=224,198,79 47 | 48 | [Color4] 49 | Color=67,165,213 50 | 51 | [Color5] 52 | Color=139,87,181 53 | 54 | [Color6] 55 | Color=142,196,61 56 | 57 | [Color7] 58 | Color=238,238,238 59 | 60 | [Color0Intense] 61 | Color=50,50,50 62 | 63 | [Color1Intense] 64 | Color=194,40,50 65 | -------------------------------------------------------------------------------- /fixtures/konsole/empty.colorscheme: -------------------------------------------------------------------------------- 1 | ;[General] 2 | ;Description=Seti 3 | ;Opacity=1 4 | ;Wallpaper= 5 | 6 | -------------------------------------------------------------------------------- /fixtures/konsole/incomplete.colorscheme: -------------------------------------------------------------------------------- 1 | [General] 2 | Description=Seti 3 | Opacity=1 4 | Wallpaper= 5 | 6 | [Background] 7 | Color=17,18,19 8 | 9 | [BackgroundIntense] 10 | Color=17,18,19 11 | 12 | [Foreground] 13 | Color=202,206,205 14 | 15 | [ForegroundIntense] 16 | Color=202,206,205 17 | 18 | [Color1] 19 | Color=194,40,50 20 | 21 | [Color2Intense] 22 | Color=142,196,61 23 | 24 | [Color3Intense] 25 | Color=224,198,79 26 | 27 | [Color4Intense] 28 | Color=67,165,213 29 | 30 | [Color5Intense] 31 | Color=139,87,181 32 | 33 | [Color6Intense] 34 | Color=142,196,61 35 | 36 | [Color7Intense] 37 | Color=255,255,255 38 | 39 | [Color2] 40 | Color=142,196,61 41 | 42 | [Color3] 43 | Color=224,198,79 44 | 45 | [Color4] 46 | Color=67,165,213 47 | 48 | [Color5] 49 | Color=139,87,181 50 | 51 | [Color6] 52 | Color=142,196,61 53 | 54 | [Color7] 55 | Color=238,238,238 56 | 57 | [Color0Intense] 58 | Color=50,50,50 59 | 60 | [Color1Intense] 61 | Color=194,40,50 62 | -------------------------------------------------------------------------------- /fixtures/konsole/malformed-keys.colorscheme: -------------------------------------------------------------------------------- 1 | [General] 2 | Description=Seti 3 | Opacity=1 4 | Wallpaper= 5 | 6 | [Background] 7 | InvalidColor=17,18,19 8 | 9 | [BackgroundIntense] 10 | Color=17,18,19 11 | 12 | [Foreground] 13 | Color=202,206,205 14 | 15 | [ForegroundIntense] 16 | Color=202,206,205 17 | 18 | [Color0] 19 | Color=50,50,50 20 | 21 | [Color1] 22 | Color=194,40,50 23 | 24 | [Color2Intense] 25 | Color=142,196,61 26 | 27 | [Color3Intense] 28 | Color=224,198,79 29 | 30 | [Color4Intense] 31 | Color=67,165,213 32 | 33 | [Color5Intense] 34 | Color=139,87,181 35 | 36 | [Color6Intense] 37 | Color=142,196,61 38 | 39 | [Color7Intense] 40 | Color=255,255,255 41 | 42 | [Color2] 43 | Color=142,196,61 44 | 45 | [Color3] 46 | Color=224,198,79 47 | 48 | [Color4] 49 | Color=67,165,213 50 | 51 | [Color5] 52 | Color=139,87,181 53 | 54 | [Color6] 55 | Color=142,196,61 56 | 57 | [Color7] 58 | Color=238,238,238 59 | 60 | [Color0Intense] 61 | Color=50,50,50 62 | 63 | [Color1Intense] 64 | Color=194,40,50 65 | -------------------------------------------------------------------------------- /fixtures/konsole/malformed-range.colorscheme: -------------------------------------------------------------------------------- 1 | [General] 2 | Description=Seti 3 | Opacity=1 4 | Wallpaper= 5 | 6 | [Background] 7 | Color=256,18,19 8 | 9 | [BackgroundIntense] 10 | Color=17,18,19 11 | 12 | [Foreground] 13 | Color=202,206,205 14 | 15 | [ForegroundIntense] 16 | Color=202,206,205 17 | 18 | [Color0] 19 | Color=50,50,50 20 | 21 | [Color1] 22 | Color=194,40,50 23 | 24 | [Color2Intense] 25 | Color=142,196,61 26 | 27 | [Color3Intense] 28 | Color=224,198,79 29 | 30 | [Color4Intense] 31 | Color=67,165,213 32 | 33 | [Color5Intense] 34 | Color=139,87,181 35 | 36 | [Color6Intense] 37 | Color=142,196,61 38 | 39 | [Color7Intense] 40 | Color=255,255,255 41 | 42 | [Color2] 43 | Color=142,196,61 44 | 45 | [Color3] 46 | Color=224,198,79 47 | 48 | [Color4] 49 | Color=67,165,213 50 | 51 | [Color5] 52 | Color=139,87,181 53 | 54 | [Color6] 55 | Color=142,196,61 56 | 57 | [Color7] 58 | Color=238,238,238 59 | 60 | [Color0Intense] 61 | Color=50,50,50 62 | 63 | [Color1Intense] 64 | Color=194,40,50 65 | -------------------------------------------------------------------------------- /fixtures/konsole/malformed-values.colorscheme: -------------------------------------------------------------------------------- 1 | [General] 2 | Description=Seti 3 | Opacity=1 4 | Wallpaper= 5 | 6 | [Background] 7 | Color=InvalidValue 8 | 9 | [BackgroundIntense] 10 | Color=17,18,19 11 | 12 | [Foreground] 13 | Color=202,206,205 14 | 15 | [ForegroundIntense] 16 | Color=202,206,205 17 | 18 | [Color0] 19 | Color=50,50,50 20 | 21 | [Color1] 22 | Color=194,40,50 23 | 24 | [Color2Intense] 25 | Color=142,196,61 26 | 27 | [Color3Intense] 28 | Color=224,198,79 29 | 30 | [Color4Intense] 31 | Color=67,165,213 32 | 33 | [Color5Intense] 34 | Color=139,87,181 35 | 36 | [Color6Intense] 37 | Color=142,196,61 38 | 39 | [Color7Intense] 40 | Color=255,255,255 41 | 42 | [Color2] 43 | Color=142,196,61 44 | 45 | [Color3] 46 | Color=224,198,79 47 | 48 | [Color4] 49 | Color=67,165,213 50 | 51 | [Color5] 52 | Color=139,87,181 53 | 54 | [Color6] 55 | Color=142,196,61 56 | 57 | [Color7] 58 | Color=238,238,238 59 | 60 | [Color0Intense] 61 | Color=50,50,50 62 | 63 | [Color1Intense] 64 | Color=194,40,50 65 | -------------------------------------------------------------------------------- /fixtures/remmina/Atom.colors: -------------------------------------------------------------------------------- 1 | [ssh_colors] 2 | background = #161719 3 | cursor = #d0d0d0 4 | foreground = #c5c8c6 5 | color0 = #000000 6 | color1 = #fd5ff1 7 | color2 = #87c38a 8 | color3 = #ffd7b1 9 | color4 = #85befd 10 | color5 = #b9b6fc 11 | color6 = #85befd 12 | color7 = #e0e0e0 13 | color8 = #000000 14 | color9 = #fd5ff1 15 | color10 = #94fa36 16 | color11 = #f5ffa8 17 | color12 = #96cbfe 18 | color13 = #b9b6fc 19 | color14 = #85befd 20 | color15 = #e0e0e0 21 | colorBD = #c5c8c6 22 | colorIT = 23 | colorUL = 24 | -------------------------------------------------------------------------------- /fixtures/remmina/Seti.colors: -------------------------------------------------------------------------------- 1 | [ssh_colors] 2 | background = #111213 3 | cursor = #e3bf21 4 | foreground = #cacecd 5 | color0 = #323232 6 | color1 = #c22832 7 | color2 = #8ec43d 8 | color3 = #e0c64f 9 | color4 = #43a5d5 10 | color5 = #8b57b5 11 | color6 = #8ec43d 12 | color7 = #eeeeee 13 | color8 = #323232 14 | color9 = #c22832 15 | color10 = #8ec43d 16 | color11 = #e0c64f 17 | color12 = #43a5d5 18 | color13 = #8b57b5 19 | color14 = #8ec43d 20 | color15 = #ffffff 21 | colorBD = #cacecd 22 | colorIT = 23 | colorUL = 24 | -------------------------------------------------------------------------------- /fixtures/remmina/empty.colors: -------------------------------------------------------------------------------- 1 | [ssh_colors] 2 | -------------------------------------------------------------------------------- /fixtures/remmina/incomplete.colors: -------------------------------------------------------------------------------- 1 | [ssh_colors] 2 | cursor = #e3bf21 3 | foreground = #cacecd 4 | color0 = #323232 5 | color1 = #c22832 6 | color2 = #8ec43d 7 | color3 = #e0c64f 8 | color4 = #43a5d5 9 | color5 = #8b57b5 10 | color6 = #8ec43d 11 | color7 = #eeeeee 12 | color8 = #323232 13 | color9 = #c22832 14 | color10 = #8ec43d 15 | color11 = #e0c64f 16 | color12 = #43a5d5 17 | color13 = #8b57b5 18 | color14 = #8ec43d 19 | color15 = #ffffff 20 | colorBD = #cacecd 21 | colorIT = 22 | colorUL = 23 | -------------------------------------------------------------------------------- /fixtures/remmina/malformed-values.colors: -------------------------------------------------------------------------------- 1 | [ssh_colors] 2 | background = malformed-value 3 | cursor = #e3bf21 4 | foreground = #cacecd 5 | color0 = #323232 6 | color1 = #c22832 7 | color2 = #8ec43d 8 | color3 = #e0c64f 9 | color4 = #43a5d5 10 | color5 = #8b57b5 11 | color6 = #8ec43d 12 | color7 = #eeeeee 13 | color8 = #323232 14 | color9 = #c22832 15 | color10 = #8ec43d 16 | color11 = #e0c64f 17 | color12 = #43a5d5 18 | color13 = #8b57b5 19 | color14 = #8ec43d 20 | color15 = #ffffff 21 | colorBD = #cacecd 22 | colorIT = 23 | colorUL = 24 | -------------------------------------------------------------------------------- /fixtures/terminal/Atom.terminal: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ANSIBlackColor 6 | 7 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 8 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NGMCAw 9 | IDAAEAKAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVj 10 | dF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FITltiaWttcn2GjpGa 11 | rK+0AAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAALY= 12 | 13 | ANSIBlueColor 14 | 15 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 16 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 17 | LjUyMzA5ODE3MDggMC43NDU2MDM5Nzg2IDAuOTk0MDUxMDk4OAAQAoAC0hAREhNaJGNs 18 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 19 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 20 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 21 | 22 | ANSIBrightBlackColor 23 | 24 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 25 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NGMCAw 26 | IDAAEAKAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVj 27 | dF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FITltiaWttcn2GjpGa 28 | rK+0AAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAALY= 29 | 30 | ANSIBrightBlueColor 31 | 32 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 33 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 34 | LjU4ODIzNTI5NDEgMC43OTYwNzg0MzE0IDAuOTk2MDc4NDMxNAAQAoAC0hAREhNaJGNs 35 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 36 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 37 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 38 | 39 | ANSIBrightCyanColor 40 | 41 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 42 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 43 | LjUyMzA5ODE3MDggMC43NDU2MDM5Nzg2IDAuOTk0MDUxMDk4OAAQAoAC0hAREhNaJGNs 44 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 45 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 46 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 47 | 48 | ANSIBrightGreenColor 49 | 50 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 51 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 52 | LjU4MTgzNTUwODMgMC45Nzg4NTIwOTMyIDAuMjEyMTMyODI2NAAQAoAC0hAREhNaJGNs 53 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 54 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 55 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 56 | 57 | ANSIBrightMagentaColor 58 | 59 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 60 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 61 | LjcyNzIyNTg0MDEgMC43MTI4MDA5Nzk2IDAuOTg5MzI3NjY5MQAQAoAC0hAREhNaJGNs 62 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 63 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 64 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 65 | 66 | ANSIBrightRedColor 67 | 68 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 69 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 70 | Ljk5MjE1Njg2MjcgMC4zNzI1NDkwMTk2IDAuOTQ1MDk4MDM5MgAQAoAC0hAREhNaJGNs 71 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 72 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 73 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 74 | 75 | ANSIBrightWhiteColor 76 | 77 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 78 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECUw 79 | Ljg3ODA1OTgwNDQgMC44NzgwMzM1MTg4IDAuODc4MDQ4NDIAEAKAAtIQERITWiRjbGFz 80 | c25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZl 81 | ctEXGFRyb290gAEIERojLTI3O0FITltiioyOk56nr7K7zdDVAAAAAAAAAQEAAAAAAAAA 82 | GQAAAAAAAAAAAAAAAAAAANc= 83 | 84 | ANSIBrightYellowColor 85 | 86 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 87 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPEBww 88 | Ljk2MjIxNzE1MjEgMSAwLjY1NjkyNTAyMjYAEAKAAtIQERITWiRjbGFzc25hbWVYJGNs 89 | YXNzZXNXTlNDb2xvcqISFFhOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290 90 | gAEIERojLTI3O0FITltigYOFipWepqmyxMfMAAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAA 91 | AAAAAAAAAM4= 92 | 93 | ANSICyanColor 94 | 95 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 96 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 97 | LjUyMzA5ODE3MDggMC43NDU2MDM5Nzg2IDAuOTk0MDUxMDk4OAAQAoAC0hAREhNaJGNs 98 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 99 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 100 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 101 | 102 | ANSIGreenColor 103 | 104 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 105 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 106 | LjUyOTQxMTc2NDcgMC43NjQ3MDU4ODI0IDAuNTQxMTc2NDcwNgAQAoAC0hAREhNaJGNs 107 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 108 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 109 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 110 | 111 | ANSIMagentaColor 112 | 113 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 114 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 115 | LjcyNzIyNTg0MDEgMC43MTI4MDA5Nzk2IDAuOTg5MzI3NjY5MQAQAoAC0hAREhNaJGNs 116 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 117 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 118 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 119 | 120 | ANSIRedColor 121 | 122 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 123 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 124 | Ljk5MjE1Njg2MjcgMC4zNzI1NDkwMTk2IDAuOTQ1MDk4MDM5MgAQAoAC0hAREhNaJGNs 125 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 126 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 127 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 128 | 129 | ANSIWhiteColor 130 | 131 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 132 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 133 | Ljg3ODA1OTg2NCAwLjg3ODAzMzU3ODQgMC44NzgwNDg0Nzk2ABACgALSEBESE1okY2xh 134 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 135 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 136 | ABkAAAAAAAAAAAAAAAAAAADY 137 | 138 | ANSIYellowColor 139 | 140 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 141 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPEBwx 142 | IDAuODQzMTM3MjU0OSAwLjY5NDExNzY0NzEAEAKAAtIQERITWiRjbGFzc25hbWVYJGNs 143 | YXNzZXNXTlNDb2xvcqISFFhOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290 144 | gAEIERojLTI3O0FITltigYOFipWepqmyxMfMAAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAA 145 | AAAAAAAAAM4= 146 | 147 | BackgroundColor 148 | 149 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 150 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECow 151 | LjA4NjkzNzU5ODg4IDAuMDkyMTQyNzAxMTUgMC4wOTc3MDc3NTU4NgAQAoAC0hAREhNa 152 | JGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFy 153 | Y2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KPkZOYo6y0t8DS1doAAAAAAAABAQAA 154 | AAAAAAAZAAAAAAAAAAAAAAAAAAAA3A== 155 | 156 | CursorColor 157 | 158 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 159 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 160 | LjgxNTY4NjI4NTUgMC44MTU2ODYyODU1IDAuODE1Njg2Mjg1NQAQAoAC0hAREhNaJGNs 161 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 162 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 163 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 164 | 165 | ProfileCurrentVersion 166 | 2.04 167 | SelectionColor 168 | 169 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 170 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 171 | LjI2NjY2NjY2NjcgMC4yNjY2NjY2NjY3IDAuMjY2NjY2NjY2NwAQAoAC0hAREhNaJGNs 172 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 173 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 174 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 175 | 176 | TextBoldColor 177 | 178 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 179 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 180 | Ljc3MjU0OTAxOTYgMC43ODQzMTM3MjU1IDAuNzc2NDcwNTg4MgAQAoAC0hAREhNaJGNs 181 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 182 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 183 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 184 | 185 | TextColor 186 | 187 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 188 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 189 | Ljc3MjU0OTAxOTYgMC43ODQzMTM3MjU1IDAuNzc2NDcwNTg4MgAQAoAC0hAREhNaJGNs 190 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 191 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 192 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 193 | 194 | columnCount 195 | 90 196 | name 197 | Atom 198 | rowCount 199 | 50 200 | type 201 | Window Settings 202 | 203 | 204 | -------------------------------------------------------------------------------- /fixtures/terminal/colorspaces.terminal: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BackgroundColor 6 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OV05TV2hpdGVcTlNDb2xvclNwYWNlViRjbGFzc00wIDAuODk5OTk5OTgAEAOAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FIUF1kcnR2e4aPl5qjtbi9AAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAAL8= 7 | CursorType 8 | 0 9 | FontAntialias 10 | 11 | SelectionColor 12 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPEB4wLjAzNDU3ODM5NSAwIDAuOTEzMjY1MzEgMC42NQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KDhYeMl6Coq7TGyc4AAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA0A== 13 | Font 14 | YnBsaXN0MDDUAQIDBAUGGBlYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKQHCBESVSRudWxs1AkKCwwNDg8QVk5TU2l6ZVhOU2ZGbGFnc1ZOU05hbWVWJGNsYXNzI0AoAAAAAAAAEBCAAoADWkFuZGFsZU1vbm/SExQVFlokY2xhc3NuYW1lWCRjbGFzc2VzVk5TRm9udKIVF1hOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZlctEaG1Ryb290gAEIERojLTI3PEJLUltiaXJ0dniDiJOco6avwcTJAAAAAAAAAQEAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAMs= 15 | type 16 | Window Settings 17 | TextBoldColor 18 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NGMCAxIDAAEAGAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FITltiaWttcn2GjpGarK+0AAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAALY= 19 | CursorBlink 20 | 21 | TextColor 22 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECIwLjE1Njg2Mjc1IDAuOTk2MDc4NDkgMC4wNzg0MzEzNzUAEAKAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FITltih4mLkJukrK+4ys3SAAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAANQ= 23 | CursorColor 24 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECEwLjIxOTYwNzg2IDAuOTk2MDc4NDkgMC4xNTI5NDExOAAQAoAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KGiIqPmqOrrrfJzNEAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA0w== 25 | ProfileCurrentVersion 26 | 2.05 27 | name 28 | Homebrew 29 | 30 | 31 | -------------------------------------------------------------------------------- /fixtures/terminal/empty.terminal: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fixtures/terminal/incomplete.terminal: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BackgroundColor 6 | 7 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 8 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECow 9 | LjA2NjY2NjY3MDE0IDAuMDcwNTg4MjM4NTQgMC4wNzQ1MDk4MDY5MwAQAoAC0hAREhNa 10 | JGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFy 11 | Y2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KPkZOYo6y0t8DS1doAAAAAAAABAQAA 12 | AAAAAAAZAAAAAAAAAAAAAAAAAAAA3A== 13 | 14 | CursorColor 15 | 16 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 17 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 18 | Ljg4OTU3MTkwNTEgMC43NDcxNzQ3Mzk4IDAuMTI5ODEzODk0NgAQAoAC0hAREhNaJGNs 19 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 20 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 21 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 22 | 23 | ProfileCurrentVersion 24 | 2.04 25 | SelectionColor 26 | 27 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 28 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 29 | LjE4ODIzNTI5NzggMC4xOTYwNzg0MzQ2IDAuMjAwMDAwMDAzABACgALSEBESE1okY2xh 30 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 31 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 32 | ABkAAAAAAAAAAAAAAAAAAADY 33 | 34 | TextBoldColor 35 | 36 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 37 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 38 | Ljc5MjE1Njg3NTEgMC44MDc4NDMxNDg3IDAuODAzOTIxNTgwMwAQAoAC0hAREhNaJGNs 39 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 40 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 41 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 42 | 43 | TextColor 44 | 45 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 46 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 47 | Ljc5MjE1Njg3NTEgMC44MDc4NDMxNDg3IDAuODAzOTIxNTgwMwAQAoAC0hAREhNaJGNs 48 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 49 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 50 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 51 | 52 | columnCount 53 | 90 54 | name 55 | Seti 56 | rowCount 57 | 50 58 | type 59 | Window Settings 60 | 61 | 62 | -------------------------------------------------------------------------------- /fixtures/terminal/malformed-keys.terminal: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ANSIBlackColor 6 | 7 | this is malformed 8 | 9 | ANSIBlueColor 10 | Seti 11 | ANSIBrightBlackColor 12 | 13 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 14 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 15 | LjE5NjA3ODQzMTQgMC4xOTYwNzg0MzE0IDAuMTk2MDc4NDMxNAAQAoAC0hAREhNaJGNs 16 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 17 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 18 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 19 | 20 | ANSIBrightBlueColor 21 | 22 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 23 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 24 | LjI2Mjc0NTExMjIgMC42NDcwNTg4NDQ2IDAuODM1Mjk0MTI3NQAQAoAC0hAREhNaJGNs 25 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 26 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 27 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 28 | 29 | ANSIBrightCyanColor 30 | 31 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 32 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 33 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 34 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 35 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 36 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 37 | 38 | ANSIBrightGreenColor 39 | 40 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 41 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 42 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 43 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 44 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 45 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 46 | 47 | ANSIBrightMagentaColor 48 | 49 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 50 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 51 | LjU0NTA5ODA2NjMgMC4zNDExNzY0ODAxIDAuNzA5ODAzOTM4OQAQAoAC0hAREhNaJGNs 52 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 53 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 54 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 55 | 56 | ANSIBrightRedColor 57 | 58 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 59 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 60 | Ljc2MDc4NDMyOCAwLjE1Njg2Mjc1MDYgMC4xOTYwNzg0MzQ2ABACgALSEBESE1okY2xh 61 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 62 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 63 | ABkAAAAAAAAAAAAAAAAAAADY 64 | 65 | ANSIBrightWhiteColor 66 | 67 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 68 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NGMSAx 69 | IDEAEAKAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVj 70 | dF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FITltiaWttcn2GjpGa 71 | rK+0AAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAALY= 72 | 73 | ANSIBrightYellowColor 74 | 75 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 76 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 77 | Ljg3ODQzMTM3OTggMC43NzY0NzA2MDE2IDAuMzA5ODAzOTMyOQAQAoAC0hAREhNaJGNs 78 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 79 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 80 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 81 | 82 | ANSICyanColor 83 | 84 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 85 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 86 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 87 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 88 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 89 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 90 | 91 | ANSIGreenColor 92 | 93 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 94 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 95 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 96 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 97 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 98 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 99 | 100 | ANSIMagentaColor 101 | 102 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 103 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 104 | LjU0NTA5ODA2NjMgMC4zNDExNzY0ODAxIDAuNzA5ODAzOTM4OQAQAoAC0hAREhNaJGNs 105 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 106 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 107 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 108 | 109 | ANSIRedColor 110 | 111 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 112 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 113 | Ljc2MDc4NDMyOCAwLjE1Njg2Mjc1MDYgMC4xOTYwNzg0MzQ2ABACgALSEBESE1okY2xh 114 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 115 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 116 | ABkAAAAAAAAAAAAAAAAAAADY 117 | 118 | ANSIWhiteColor 119 | 120 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 121 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 122 | LjkzMzUzMTcwMTYgMC45MzM1MzE3MDE2IDAuOTMzNTMxNzAxNgAQAoAC0hAREhNaJGNs 123 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 124 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 125 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 126 | 127 | ANSIYellowColor 128 | 129 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 130 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 131 | Ljg3ODQzMTM3OTggMC43NzY0NzA2MDE2IDAuMzA5ODAzOTMyOQAQAoAC0hAREhNaJGNs 132 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 133 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 134 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 135 | 136 | BackgroundColor 137 | 138 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 139 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECow 140 | LjA2NjY2NjY3MDE0IDAuMDcwNTg4MjM4NTQgMC4wNzQ1MDk4MDY5MwAQAoAC0hAREhNa 141 | JGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFy 142 | Y2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KPkZOYo6y0t8DS1doAAAAAAAABAQAA 143 | AAAAAAAZAAAAAAAAAAAAAAAAAAAA3A== 144 | 145 | CursorColor 146 | 147 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 148 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 149 | Ljg4OTU3MTkwNTEgMC43NDcxNzQ3Mzk4IDAuMTI5ODEzODk0NgAQAoAC0hAREhNaJGNs 150 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 151 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 152 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 153 | 154 | ProfileCurrentVersion 155 | 2.04 156 | SelectionColor 157 | 158 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 159 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 160 | LjE4ODIzNTI5NzggMC4xOTYwNzg0MzQ2IDAuMjAwMDAwMDAzABACgALSEBESE1okY2xh 161 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 162 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 163 | ABkAAAAAAAAAAAAAAAAAAADY 164 | 165 | TextBoldColor 166 | 167 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 168 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 169 | Ljc5MjE1Njg3NTEgMC44MDc4NDMxNDg3IDAuODAzOTIxNTgwMwAQAoAC0hAREhNaJGNs 170 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 171 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 172 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 173 | 174 | TextColor 175 | 176 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 177 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 178 | Ljc5MjE1Njg3NTEgMC44MDc4NDMxNDg3IDAuODAzOTIxNTgwMwAQAoAC0hAREhNaJGNs 179 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 180 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 181 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 182 | 183 | columnCount 184 | 90 185 | name 186 | Seti 187 | rowCount 188 | 50 189 | type 190 | Window Settings 191 | 192 | 193 | -------------------------------------------------------------------------------- /fixtures/terminal/malformed-values.terminal: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ANSIBlackColor 6 | 7 | YnBsaXN0MDDUAQIDBAUGGBlYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 8 | AAGGoKQHCBESVSRudWxs1AkKCwwNDg8QVk5TU2l6ZVhOU2ZGbGFnc1ZOU05hbWVWJGNs 9 | YXNzI0AmAAAAAAAAEBCAAoADXU1lbmxvLVJlZ3VsYXLSExQVFlokY2xhc3NuYW1lWCRj 10 | bGFzc2VzVk5TRm9udKIVF1hOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZlctEaG1Ryb290 11 | gAEIERojLTI3PEJLUltiaXJ0dniGi5afpqmyxMfMAAAAAAAAAQEAAAAAAAAAHAAAAAAA 12 | AAAAAAAAAAAAAM4= 13 | 14 | ANSIBlueColor 15 | Seti 16 | ANSIBrightBlackColor 17 | 18 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 19 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 20 | LjE5NjA3ODQzMTQgMC4xOTYwNzg0MzE0IDAuMTk2MDc4NDMxNAAQAoAC0hAREhNaJGNs 21 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 22 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 23 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 24 | 25 | ANSIBrightBlueColor 26 | 27 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 28 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 29 | LjI2Mjc0NTExMjIgMC42NDcwNTg4NDQ2IDAuODM1Mjk0MTI3NQAQAoAC0hAREhNaJGNs 30 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 31 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 32 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 33 | 34 | ANSIBrightCyanColor 35 | 36 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 37 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 38 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 39 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 40 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 41 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 42 | 43 | ANSIBrightGreenColor 44 | 45 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 46 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 47 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 48 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 49 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 50 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 51 | 52 | ANSIBrightMagentaColor 53 | 54 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 55 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 56 | LjU0NTA5ODA2NjMgMC4zNDExNzY0ODAxIDAuNzA5ODAzOTM4OQAQAoAC0hAREhNaJGNs 57 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 58 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 59 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 60 | 61 | ANSIBrightRedColor 62 | 63 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 64 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 65 | Ljc2MDc4NDMyOCAwLjE1Njg2Mjc1MDYgMC4xOTYwNzg0MzQ2ABACgALSEBESE1okY2xh 66 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 67 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 68 | ABkAAAAAAAAAAAAAAAAAAADY 69 | 70 | ANSIBrightWhiteColor 71 | 72 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 73 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NGMSAx 74 | IDEAEAKAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVj 75 | dF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FITltiaWttcn2GjpGa 76 | rK+0AAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAALY= 77 | 78 | ANSIBrightYellowColor 79 | 80 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 81 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 82 | Ljg3ODQzMTM3OTggMC43NzY0NzA2MDE2IDAuMzA5ODAzOTMyOQAQAoAC0hAREhNaJGNs 83 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 84 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 85 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 86 | 87 | ANSICyanColor 88 | 89 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 90 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 91 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 92 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 93 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 94 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 95 | 96 | ANSIGreenColor 97 | 98 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 99 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 100 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 101 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 102 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 103 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 104 | 105 | ANSIMagentaColor 106 | 107 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 108 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 109 | LjU0NTA5ODA2NjMgMC4zNDExNzY0ODAxIDAuNzA5ODAzOTM4OQAQAoAC0hAREhNaJGNs 110 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 111 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 112 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 113 | 114 | ANSIRedColor 115 | 116 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 117 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 118 | Ljc2MDc4NDMyOCAwLjE1Njg2Mjc1MDYgMC4xOTYwNzg0MzQ2ABACgALSEBESE1okY2xh 119 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 120 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 121 | ABkAAAAAAAAAAAAAAAAAAADY 122 | 123 | ANSIWhiteColor 124 | 125 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 126 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 127 | LjkzMzUzMTcwMTYgMC45MzM1MzE3MDE2IDAuOTMzNTMxNzAxNgAQAoAC0hAREhNaJGNs 128 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 129 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 130 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 131 | 132 | ANSIYellowColor 133 | 134 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 135 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 136 | Ljg3ODQzMTM3OTggMC43NzY0NzA2MDE2IDAuMzA5ODAzOTMyOQAQAoAC0hAREhNaJGNs 137 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 138 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 139 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 140 | 141 | BackgroundColor 142 | 143 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 144 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECow 145 | LjA2NjY2NjY3MDE0IDAuMDcwNTg4MjM4NTQgMC4wNzQ1MDk4MDY5MwAQAoAC0hAREhNa 146 | JGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFy 147 | Y2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KPkZOYo6y0t8DS1doAAAAAAAABAQAA 148 | AAAAAAAZAAAAAAAAAAAAAAAAAAAA3A== 149 | 150 | CursorColor 151 | 152 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 153 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 154 | Ljg4OTU3MTkwNTEgMC43NDcxNzQ3Mzk4IDAuMTI5ODEzODk0NgAQAoAC0hAREhNaJGNs 155 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 156 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 157 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 158 | 159 | ProfileCurrentVersion 160 | 2.04 161 | SelectionColor 162 | 163 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 164 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 165 | LjE4ODIzNTI5NzggMC4xOTYwNzg0MzQ2IDAuMjAwMDAwMDAzABACgALSEBESE1okY2xh 166 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 167 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 168 | ABkAAAAAAAAAAAAAAAAAAADY 169 | 170 | TextBoldColor 171 | 172 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 173 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 174 | Ljc5MjE1Njg3NTEgMC44MDc4NDMxNDg3IDAuODAzOTIxNTgwMwAQAoAC0hAREhNaJGNs 175 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 176 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 177 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 178 | 179 | TextColor 180 | 181 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 182 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 183 | Ljc5MjE1Njg3NTEgMC44MDc4NDMxNDg3IDAuODAzOTIxNTgwMwAQAoAC0hAREhNaJGNs 184 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 185 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 186 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 187 | 188 | columnCount 189 | 90 190 | name 191 | Seti 192 | rowCount 193 | 50 194 | type 195 | Window Settings 196 | 197 | 198 | -------------------------------------------------------------------------------- /fixtures/terminal/malformed.terminal: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ANSIBlackColor 6 | 7 | this is malformed 8 | 9 | ANSIBlueColor 10 | 11 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 12 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 13 | LjI2Mjc0NTExMjIgMC42NDcwNTg4NDQ2IDAuODM1Mjk0MTI3NQAQAoAC0hAREhNaJGNs 14 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 15 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 16 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 17 | 18 | ANSIBrightBlackColor 19 | 20 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 21 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 22 | LjE5NjA3ODQzMTQgMC4xOTYwNzg0MzE0IDAuMTk2MDc4NDMxNAAQAoAC0hAREhNaJGNs 23 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 24 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 25 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 26 | 27 | ANSIBrightBlueColor 28 | 29 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 30 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 31 | LjI2Mjc0NTExMjIgMC42NDcwNTg4NDQ2IDAuODM1Mjk0MTI3NQAQAoAC0hAREhNaJGNs 32 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 33 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 34 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 35 | 36 | ANSIBrightCyanColor 37 | 38 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 39 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 40 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 41 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 42 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 43 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 44 | 45 | ANSIBrightGreenColor 46 | 47 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 48 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 49 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 50 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 51 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 52 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 53 | 54 | ANSIBrightMagentaColor 55 | 56 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 57 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 58 | LjU0NTA5ODA2NjMgMC4zNDExNzY0ODAxIDAuNzA5ODAzOTM4OQAQAoAC0hAREhNaJGNs 59 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 60 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 61 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 62 | 63 | ANSIBrightRedColor 64 | 65 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 66 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 67 | Ljc2MDc4NDMyOCAwLjE1Njg2Mjc1MDYgMC4xOTYwNzg0MzQ2ABACgALSEBESE1okY2xh 68 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 69 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 70 | ABkAAAAAAAAAAAAAAAAAAADY 71 | 72 | ANSIBrightWhiteColor 73 | 74 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 75 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NGMSAx 76 | IDEAEAKAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVj 77 | dF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FITltiaWttcn2GjpGa 78 | rK+0AAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAALY= 79 | 80 | ANSIBrightYellowColor 81 | 82 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 83 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 84 | Ljg3ODQzMTM3OTggMC43NzY0NzA2MDE2IDAuMzA5ODAzOTMyOQAQAoAC0hAREhNaJGNs 85 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 86 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 87 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 88 | 89 | ANSICyanColor 90 | 91 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 92 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 93 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 94 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 95 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 96 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 97 | 98 | ANSIGreenColor 99 | 100 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 101 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 102 | LjU1Njg2Mjc3MTUgMC43Njg2Mjc0NjQ4IDAuMjM5MjE1Njg2OQAQAoAC0hAREhNaJGNs 103 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 104 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 105 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 106 | 107 | ANSIMagentaColor 108 | 109 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 110 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 111 | LjU0NTA5ODA2NjMgMC4zNDExNzY0ODAxIDAuNzA5ODAzOTM4OQAQAoAC0hAREhNaJGNs 112 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 113 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 114 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 115 | 116 | ANSIRedColor 117 | 118 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 119 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 120 | Ljc2MDc4NDMyOCAwLjE1Njg2Mjc1MDYgMC4xOTYwNzg0MzQ2ABACgALSEBESE1okY2xh 121 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 122 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 123 | ABkAAAAAAAAAAAAAAAAAAADY 124 | 125 | ANSIWhiteColor 126 | 127 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 128 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 129 | LjkzMzUzMTcwMTYgMC45MzM1MzE3MDE2IDAuOTMzNTMxNzAxNgAQAoAC0hAREhNaJGNs 130 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 131 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 132 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 133 | 134 | ANSIYellowColor 135 | 136 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 137 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 138 | Ljg3ODQzMTM3OTggMC43NzY0NzA2MDE2IDAuMzA5ODAzOTMyOQAQAoAC0hAREhNaJGNs 139 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 140 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 141 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 142 | 143 | BackgroundColor 144 | 145 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 146 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECow 147 | LjA2NjY2NjY3MDE0IDAuMDcwNTg4MjM4NTQgMC4wNzQ1MDk4MDY5MwAQAoAC0hAREhNa 148 | JGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFy 149 | Y2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KPkZOYo6y0t8DS1doAAAAAAAABAQAA 150 | AAAAAAAZAAAAAAAAAAAAAAAAAAAA3A== 151 | 152 | CursorColor 153 | 154 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 155 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 156 | Ljg4OTU3MTkwNTEgMC43NDcxNzQ3Mzk4IDAuMTI5ODEzODk0NgAQAoAC0hAREhNaJGNs 157 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 158 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 159 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 160 | 161 | ProfileCurrentVersion 162 | 2.04 163 | SelectionColor 164 | 165 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 166 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECYw 167 | LjE4ODIzNTI5NzggMC4xOTYwNzg0MzQ2IDAuMjAwMDAwMDAzABACgALSEBESE1okY2xh 168 | c3NuYW1lWCRjbGFzc2VzV05TQ29sb3KiEhRYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2 169 | ZXLRFxhUcm9vdIABCBEaIy0yNztBSE5bYouNj5SfqLCzvM7R1gAAAAAAAAEBAAAAAAAA 170 | ABkAAAAAAAAAAAAAAAAAAADY 171 | 172 | TextBoldColor 173 | 174 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 175 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 176 | Ljc5MjE1Njg3NTEgMC44MDc4NDMxNDg3IDAuODAzOTIxNTgwMwAQAoAC0hAREhNaJGNs 177 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 178 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 179 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 180 | 181 | TextColor 182 | 183 | YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS 184 | AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcw 185 | Ljc5MjE1Njg3NTEgMC44MDc4NDMxNDg3IDAuODAzOTIxNTgwMwAQAoAC0hAREhNaJGNs 186 | YXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hp 187 | dmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAA 188 | AAAZAAAAAAAAAAAAAAAAAAAA2Q== 189 | 190 | columnCount 191 | 90 192 | name 193 | Seti 194 | rowCount 195 | 50 196 | type 197 | Window Settings 198 | 199 | 200 | -------------------------------------------------------------------------------- /fixtures/terminator/Atom.config: -------------------------------------------------------------------------------- 1 | 2 | [[Atom]] 3 | palette = "#000000:#fd5ff1:#87c38a:#ffd7b1:#85befd:#b9b6fc:#85befd:#e0e0e0:#000000:#fd5ff1:#94fa36:#f5ffa8:#96cbfe:#b9b6fc:#85befd:#e0e0e0" 4 | background_color = "#161719" 5 | cursor_color = "#d0d0d0" 6 | foreground_color = "#c5c8c6" 7 | background_image = None 8 | -------------------------------------------------------------------------------- /fixtures/terminator/Seti.config: -------------------------------------------------------------------------------- 1 | 2 | [[Seti]] 3 | palette = "#323232:#c22832:#8ec43d:#e0c64f:#43a5d5:#8b57b5:#8ec43d:#eeeeee:#323232:#c22832:#8ec43d:#e0c64f:#43a5d5:#8b57b5:#8ec43d:#ffffff" 4 | background_color = "#111213" 5 | cursor_color = "#e3bf21" 6 | foreground_color = "#cacecd" 7 | background_image = None 8 | -------------------------------------------------------------------------------- /fixtures/terminator/empty.config: -------------------------------------------------------------------------------- 1 | [[Atom]] 2 | -------------------------------------------------------------------------------- /fixtures/terminator/incomplete-palette.config: -------------------------------------------------------------------------------- 1 | 2 | [[Seti]] 3 | palette = "#323232:#c22832:#8ec43d:#e0c64f:#43a5d5:#8b57b5:#8ec43d:#eeeeee:#323232:#c22832:#8ec43d:#e0c64f:#43a5d5:#8b57b5:#8ec43d" 4 | background_color = "#111213" 5 | cursor_color = "#e3bf21" 6 | foreground_color = "#cacecd" 7 | background_image = None 8 | -------------------------------------------------------------------------------- /fixtures/terminator/incomplete.config: -------------------------------------------------------------------------------- 1 | [[Seti]] 2 | background_color = "#111213" 3 | cursor_color = "#e3bf21" 4 | foreground_color = "#cacecd" 5 | background_image = None 6 | -------------------------------------------------------------------------------- /fixtures/terminator/malformed-palette-item.config: -------------------------------------------------------------------------------- 1 | 2 | [[Seti]] 3 | palette = "#malformed:#c22832:#8ec43d:#e0c64f:#43a5d5:#8b57b5:#8ec43d:#eeeeee:#323232:#c22832:#8ec43d:#e0c64f:#43a5d5:#8b57b5:#8ec43d:#ffffff" 4 | background_color = "#111213" 5 | cursor_color = "#e3bf21" 6 | foreground_color = "#cacecd" 7 | background_image = None 8 | -------------------------------------------------------------------------------- /fixtures/terminator/malformed-palette.config: -------------------------------------------------------------------------------- 1 | [[Seti]] 2 | palette = "malformed-palette" 3 | background_color = "#111213" 4 | cursor_color = "#e3bf21" 5 | foreground_color = "#cacecd" 6 | background_image = None 7 | -------------------------------------------------------------------------------- /fixtures/terminator/malformed-values.config: -------------------------------------------------------------------------------- 1 | 2 | [[Seti]] 3 | palette = "#323232:#c22832:#8ec43d:#e0c64f:#43a5d5:#8b57b5:#8ec43d:#eeeeee:#323232:#c22832:#8ec43d:#e0c64f:#43a5d5:#8b57b5:#8ec43d:#ffffff" 4 | background_color = "#invalid-value" 5 | cursor_color = "#e3bf21" 6 | foreground_color = "#cacecd" 7 | background_image = None 8 | -------------------------------------------------------------------------------- /fixtures/termite/Atom: -------------------------------------------------------------------------------- 1 | [colors] 2 | background = "#161719" 3 | cursor = "#d0d0d0" 4 | foreground = "#c5c8c6" 5 | color0 = #000000 6 | color1 = #fd5ff1 7 | color2 = #87c38a 8 | color3 = #ffd7b1 9 | color4 = #85befd 10 | color5 = #b9b6fc 11 | color6 = #85befd 12 | color7 = #e0e0e0 13 | color8 = #000000 14 | color9 = #fd5ff1 15 | color10 = #94fa36 16 | color11 = #f5ffa8 17 | color12 = #96cbfe 18 | color13 = #b9b6fc 19 | color14 = #85befd 20 | color15 = #e0e0e0 21 | colorBD = #c5c8c6 22 | colorIT = 23 | colorUL = 24 | -------------------------------------------------------------------------------- /fixtures/termite/Seti: -------------------------------------------------------------------------------- 1 | [colors] 2 | background = "#111213" 3 | cursor = "#e3bf21" 4 | foreground = "#cacecd" 5 | color0 = #323232 6 | color1 = #c22832 7 | color2 = #8ec43d 8 | color3 = #e0c64f 9 | color4 = #43a5d5 10 | color5 = #8b57b5 11 | color6 = #8ec43d 12 | color7 = #eeeeee 13 | color8 = #323232 14 | color9 = #c22832 15 | color10 = #8ec43d 16 | color11 = #e0c64f 17 | color12 = #43a5d5 18 | color13 = #8b57b5 19 | color14 = #8ec43d 20 | color15 = #ffffff 21 | colorBD = #cacecd 22 | colorIT = 23 | colorUL = 24 | -------------------------------------------------------------------------------- /fixtures/termite/empty: -------------------------------------------------------------------------------- 1 | [colors] 2 | 3 | -------------------------------------------------------------------------------- /fixtures/termite/incomplete: -------------------------------------------------------------------------------- 1 | [colors] 2 | cursor = "#e3bf21" 3 | foreground = "#cacecd" 4 | color0 = #323232 5 | color1 = #c22832 6 | color2 = #8ec43d 7 | color3 = #e0c64f 8 | color4 = #43a5d5 9 | color5 = #8b57b5 10 | color6 = #8ec43d 11 | color7 = #eeeeee 12 | color8 = #323232 13 | color9 = #c22832 14 | color10 = #8ec43d 15 | color11 = #e0c64f 16 | color12 = #43a5d5 17 | color13 = #8b57b5 18 | color14 = #8ec43d 19 | color15 = #ffffff 20 | colorBD = #cacecd 21 | colorIT = 22 | colorUL = 23 | -------------------------------------------------------------------------------- /fixtures/termite/malformed-values: -------------------------------------------------------------------------------- 1 | [colors] 2 | background = "malformed-value" 3 | cursor = "#e3bf21" 4 | foreground = "#cacecd" 5 | color0 = #323232 6 | color1 = #c22832 7 | color2 = #8ec43d 8 | color3 = #e0c64f 9 | color4 = #43a5d5 10 | color5 = #8b57b5 11 | color6 = #8ec43d 12 | color7 = #eeeeee 13 | color8 = #323232 14 | color9 = #c22832 15 | color10 = #8ec43d 16 | color11 = #e0c64f 17 | color12 = #43a5d5 18 | color13 = #8b57b5 19 | color14 = #8ec43d 20 | color15 = #ffffff 21 | colorBD = #cacecd 22 | colorIT = 23 | colorUL = 24 | -------------------------------------------------------------------------------- /fixtures/tilda/Atom.config_0: -------------------------------------------------------------------------------- 1 | back_blue = 4883 2 | back_green = 4626 3 | back_red = 4369 4 | cursor_blue = 8481 5 | cursor_green = 49087 6 | cursor_red = 58339 7 | palette = {12850, 12850, 12850, 49858, 10280, 12850, 36494, 50372, 15677, 57568, 50886, 20303, 17219, 42405, 54741, 35723, 22359, 46517, 36494, 50372, 15677, 61166, 61166, 61166, 12850, 12850, 12850, 49858, 10280, 12850, 36494, 50372, 15677, 57568, 50886, 20303, 17219, 42405, 54741, 35723, 22359, 46517, 36494, 50372, 15677, 65792, 65792, 65792} 8 | text_blue = 52685 9 | text_green = 52942 10 | text_red = 51914 11 | -------------------------------------------------------------------------------- /fixtures/tilda/Seti.config_0: -------------------------------------------------------------------------------- 1 | back_blue = 6425 2 | back_green = 5911 3 | back_red = 5654 4 | cursor_blue = 53456 5 | cursor_green = 53456 6 | cursor_red = 53456 7 | palette = {0, 0, 0, 65021, 24415, 61937, 34695, 50115, 35466, 65792, 55255, 45489, 34181, 48830, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568, 0, 0, 0, 65021, 24415, 61937, 38036, 64250, 13878, 63222, 65792, 43176, 38550, 52171, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568} 8 | text_blue = 50886 9 | text_green = 51400 10 | text_red = 50629 11 | -------------------------------------------------------------------------------- /fixtures/tilda/empty.config_0: -------------------------------------------------------------------------------- 1 | ;some comment 2 | -------------------------------------------------------------------------------- /fixtures/tilda/incomplete-palette.config_0: -------------------------------------------------------------------------------- 1 | back_blue = 6425 2 | back_green = 5911 3 | back_red = 5654 4 | cursor_blue = 53456 5 | cursor_green = 53456 6 | cursor_red = 53456 7 | palette = {0, 0, 65021, 24415, 61937, 34695, 50115, 35466, 65792, 55255, 45489, 34181, 48830, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568, 0, 0, 0, 65021, 24415, 61937, 38036, 64250, 13878, 63222, 65792, 43176, 38550, 52171, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568} 8 | text_blue = 50886 9 | text_green = 51400 10 | text_red = 50629 11 | -------------------------------------------------------------------------------- /fixtures/tilda/incomplete.config_0: -------------------------------------------------------------------------------- 1 | back_blue = 6425 2 | back_red = 5654 3 | cursor_blue = 53456 4 | cursor_green = 53456 5 | cursor_red = 53456 6 | palette = {0, 0, 0, 65021, 24415, 61937, 34695, 50115, 35466, 65792, 55255, 45489, 34181, 48830, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568, 0, 0, 0, 65021, 24415, 61937, 38036, 64250, 13878, 63222, 65792, 43176, 38550, 52171, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568} 7 | text_blue = 50886 8 | text_green = 51400 9 | text_red = 50629 10 | -------------------------------------------------------------------------------- /fixtures/tilda/malformed-palette-item.config_0: -------------------------------------------------------------------------------- 1 | back_blue = 6425 2 | back_green = 5911 3 | back_red = 5654 4 | cursor_blue = 53456 5 | cursor_green = 53456 6 | cursor_red = 53456 7 | palette = {malformed, 0, 0, 65021, 24415, 61937, 34695, 50115, 35466, 65792, 55255, 45489, 34181, 48830, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568, 0, 0, 0, 65021, 24415, 61937, 38036, 64250, 13878, 63222, 65792, 43176, 38550, 52171, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568} 8 | text_blue = 50886 9 | text_green = 51400 10 | text_red = 50629 11 | -------------------------------------------------------------------------------- /fixtures/tilda/malformed-palette.config_0: -------------------------------------------------------------------------------- 1 | back_blue = 6425 2 | back_green = 5911 3 | back_red = 5654 4 | cursor_blue = 53456 5 | cursor_green = 53456 6 | cursor_red = 53456 7 | palette = 0, 0, 0, 65021, 24415, 61937, 34695, 50115, 35466, 65792, 55255, 45489, 34181, 48830, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568, 0, 0, 0, 65021, 24415, 61937, 38036, 64250, 13878, 63222, 65792, 43176, 38550, 52171, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568} 8 | text_blue = 50886 9 | text_green = 51400 10 | text_red = 50629 11 | -------------------------------------------------------------------------------- /fixtures/tilda/malformed-values.config_0: -------------------------------------------------------------------------------- 1 | back_blue = malformed 2 | back_green = 5911 3 | back_red = 5654 4 | cursor_blue = 53456 5 | cursor_green = 53456 6 | cursor_red = 53456 7 | palette = {0, 0, 0, 65021, 24415, 61937, 34695, 50115, 35466, 65792, 55255, 45489, 34181, 48830, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568, 0, 0, 0, 65021, 24415, 61937, 38036, 64250, 13878, 63222, 65792, 43176, 38550, 52171, 65278, 47802, 46774, 65021, 34181, 48830, 65278, 57568, 57568, 57568} 8 | text_blue = 50886 9 | text_green = 51400 10 | text_red = 50629 11 | -------------------------------------------------------------------------------- /fixtures/xfce/Atom.theme: -------------------------------------------------------------------------------- 1 | 2 | [Scheme] 3 | Name=Atom 4 | ColorForeground=#c5c8c6 5 | ColorBackground=#161719 6 | ColorCursor=#d0d0d0 7 | ColorPalette=#000000;#fd5ff1;#87c38a;#ffd7b1;#85befd;#b9b6fc;#85befd;#e0e0e0;#000000;#fd5ff1;#94fa36;#f5ffa8;#96cbfe;#b9b6fc;#85befd;#e0e0e0 8 | -------------------------------------------------------------------------------- /fixtures/xfce/Seti.theme: -------------------------------------------------------------------------------- 1 | 2 | [Scheme] 3 | Name=Seti 4 | ColorForeground=#cacecd 5 | ColorBackground=#111213 6 | ColorCursor=#e3bf21 7 | ColorPalette=#323232;#c22832;#8ec43d;#e0c64f;#43a5d5;#8b57b5;#8ec43d;#eeeeee;#323232;#c22832;#8ec43d;#e0c64f;#43a5d5;#8b57b5;#8ec43d;#ffffff 8 | -------------------------------------------------------------------------------- /fixtures/xfce/empty.theme: -------------------------------------------------------------------------------- 1 | [Scheme] 2 | -------------------------------------------------------------------------------- /fixtures/xfce/incomplete-palette.theme: -------------------------------------------------------------------------------- 1 | 2 | [Scheme] 3 | Name=Seti 4 | ColorForeground=#cacecd 5 | ColorBackground=#111213 6 | ColorCursor=#e3bf21 7 | ColorPalette=#c22832;#8ec43d;#e0c64f;#43a5d5;#8b57b5;#8ec43d;#eeeeee;#323232;#c22832;#8ec43d;#e0c64f;#43a5d5;#8b57b5;#8ec43d;#ffffff 8 | -------------------------------------------------------------------------------- /fixtures/xfce/incomplete.theme: -------------------------------------------------------------------------------- 1 | 2 | [Scheme] 3 | Name=Seti 4 | ColorForeground=#cacecd 5 | ColorCursor=#e3bf21 6 | ColorPalette=#323232;#c22832;#8ec43d;#e0c64f;#43a5d5;#8b57b5;#8ec43d;#eeeeee;#323232;#c22832;#8ec43d;#e0c64f;#43a5d5;#8b57b5;#8ec43d;#ffffff 7 | -------------------------------------------------------------------------------- /fixtures/xfce/malformed-palette.theme: -------------------------------------------------------------------------------- 1 | 2 | [Scheme] 3 | Name=Seti 4 | ColorForeground=#cacecd 5 | ColorBackground=#111213 6 | ColorCursor=#e3bf21 7 | ColorPalette=#323232:#323232;#c22832;#8ec43d;#e0c64f;#43a5d5;#8b57b5;#8ec43d;#eeeeee;#323232;#c22832;#8ec43d;#e0c64f;#43a5d5;#8b57b5;#8ec43d;#ffffff 8 | -------------------------------------------------------------------------------- /fixtures/xfce/malformed-values.theme: -------------------------------------------------------------------------------- 1 | 2 | [Scheme] 3 | Name=Seti 4 | ColorForeground=malformed 5 | ColorBackground=#111213 6 | ColorCursor=#e3bf21 7 | ColorPalette=#323232;#c22832;#8ec43d;#e0c64f;#43a5d5;#8b57b5;#8ec43d;#eeeeee;#323232;#c22832;#8ec43d;#e0c64f;#43a5d5;#8b57b5;#8ec43d;#ffffff 8 | -------------------------------------------------------------------------------- /fixtures/xresources/Atom: -------------------------------------------------------------------------------- 1 | ! 2 | ! Generated with : 3 | ! XRDB2Xreources.py 4 | ! 5 | *.foreground: #c5c8c6 6 | *.background: #161719 7 | *.cursorColor: #d0d0d0 8 | ! 9 | ! Black 10 | *.color0: #000000 11 | *.color8: #000000 12 | ! 13 | ! Red 14 | *.color1: #fd5ff1 15 | *.color9: #fd5ff1 16 | ! 17 | ! Green 18 | *.color2: #87c38a 19 | *.color10: #94fa36 20 | ! 21 | ! Yellow 22 | *.color3: #ffd7b1 23 | *.color11: #f5ffa8 24 | ! 25 | ! Blue 26 | *.color4: #85befd 27 | *.color12: #96cbfe 28 | ! 29 | ! Magenta 30 | *.color5: #b9b6fc 31 | *.color13: #b9b6fc 32 | ! 33 | ! Cyan 34 | *.color6: #85befd 35 | *.color14: #85befd 36 | ! 37 | ! White 38 | *.color7: #e0e0e0 39 | *.color15: #e0e0e0 40 | ! 41 | ! Bold, Italic, Underline 42 | *.colorBD: #c5c8c6 43 | !*.colorIT: 44 | !*.colorUL: 45 | -------------------------------------------------------------------------------- /fixtures/xresources/Seti: -------------------------------------------------------------------------------- 1 | ! 2 | ! Generated with : 3 | ! XRDB2Xreources.py 4 | ! 5 | *.foreground: #cacecd 6 | *.background: #111213 7 | *.cursorColor: #e3bf21 8 | ! 9 | ! Black 10 | *.color0: #323232 11 | *.color8: #323232 12 | ! 13 | ! Red 14 | *.color1: #c22832 15 | *.color9: #c22832 16 | ! 17 | ! Green 18 | *.color2: #8ec43d 19 | *.color10: #8ec43d 20 | ! 21 | ! Yellow 22 | *.color3: #e0c64f 23 | *.color11: #e0c64f 24 | ! 25 | ! Blue 26 | *.color4: #43a5d5 27 | *.color12: #43a5d5 28 | ! 29 | ! Magenta 30 | *.color5: #8b57b5 31 | *.color13: #8b57b5 32 | ! 33 | ! Cyan 34 | *.color6: #8ec43d 35 | *.color14: #8ec43d 36 | ! 37 | ! White 38 | *.color7: #eeeeee 39 | *.color15: #ffffff 40 | ! 41 | ! Bold, Italic, Underline 42 | *.colorBD: #cacecd 43 | !*.colorIT: 44 | !*.colorUL: 45 | -------------------------------------------------------------------------------- /fixtures/xresources/empty: -------------------------------------------------------------------------------- 1 | ! 2 | ! Generated with : 3 | ! XRDB2Xreources.py 4 | ! 5 | -------------------------------------------------------------------------------- /fixtures/xresources/incomplete: -------------------------------------------------------------------------------- 1 | ! 2 | ! Generated with : 3 | ! XRDB2Xreources.py 4 | ! 5 | *.background: #111213 6 | *.cursorColor: #e3bf21 7 | ! 8 | ! Black 9 | *.color0: #323232 10 | *.color8: #323232 11 | ! 12 | ! Red 13 | *.color1: #c22832 14 | *.color9: #c22832 15 | ! 16 | ! Green 17 | *.color2: #8ec43d 18 | *.color10: #8ec43d 19 | ! 20 | ! Yellow 21 | *.color3: #e0c64f 22 | *.color11: #e0c64f 23 | ! 24 | ! Blue 25 | *.color4: #43a5d5 26 | *.color12: #43a5d5 27 | ! 28 | ! Magenta 29 | *.color5: #8b57b5 30 | *.color13: #8b57b5 31 | ! 32 | ! Cyan 33 | *.color6: #8ec43d 34 | *.color14: #8ec43d 35 | ! 36 | ! White 37 | *.color7: #eeeeee 38 | *.color15: #ffffff 39 | ! 40 | ! Bold, Italic, Underline 41 | *.colorBD: #cacecd 42 | !*.colorIT: 43 | !*.colorUL: 44 | -------------------------------------------------------------------------------- /fixtures/xresources/malformed-values: -------------------------------------------------------------------------------- 1 | ! 2 | ! Generated with : 3 | ! XRDB2Xreources.py 4 | ! 5 | *.foreground: malformed_value 6 | *.background: #111213 7 | *.cursorColor: #e3bf21 8 | ! 9 | ! Black 10 | *.color0: #323232 11 | *.color8: #323232 12 | ! 13 | ! Red 14 | *.color1: #c22832 15 | *.color9: #c22832 16 | ! 17 | ! Green 18 | *.color2: #8ec43d 19 | *.color10: #8ec43d 20 | ! 21 | ! Yellow 22 | *.color3: #e0c64f 23 | *.color11: #e0c64f 24 | ! 25 | ! Blue 26 | *.color4: #43a5d5 27 | *.color12: #43a5d5 28 | ! 29 | ! Magenta 30 | *.color5: #8b57b5 31 | *.color13: #8b57b5 32 | ! 33 | ! Cyan 34 | *.color6: #8ec43d 35 | *.color14: #8ec43d 36 | ! 37 | ! White 38 | *.color7: #eeeeee 39 | *.color15: #ffffff 40 | ! 41 | ! Bold, Italic, Underline 42 | *.colorBD: #cacecd 43 | !*.colorIT: 44 | !*.colorUL: 45 | -------------------------------------------------------------------------------- /fixtures/xterm/Atom.xrdb: -------------------------------------------------------------------------------- 1 | #define Ansi_0_Color #000000 2 | #define Ansi_1_Color #fd5ff1 3 | #define Ansi_10_Color #94fa36 4 | #define Ansi_11_Color #f5ffa8 5 | #define Ansi_12_Color #96cbfe 6 | #define Ansi_13_Color #b9b6fc 7 | #define Ansi_14_Color #85befd 8 | #define Ansi_15_Color #e0e0e0 9 | #define Ansi_2_Color #87c38a 10 | #define Ansi_3_Color #ffd7b1 11 | #define Ansi_4_Color #85befd 12 | #define Ansi_5_Color #b9b6fc 13 | #define Ansi_6_Color #85befd 14 | #define Ansi_7_Color #e0e0e0 15 | #define Ansi_8_Color #000000 16 | #define Ansi_9_Color #fd5ff1 17 | #define Background_Color #161719 18 | #define Bold_Color #c5c8c6 19 | #define Cursor_Color #d0d0d0 20 | #define Cursor_Text_Color #151515 21 | #define Foreground_Color #c5c8c6 22 | #define Selected_Text_Color #c5c8c6 23 | #define Selection_Color #444444 24 | -------------------------------------------------------------------------------- /fixtures/xterm/Seti.xrdb: -------------------------------------------------------------------------------- 1 | #define Ansi_0_Color #323232 2 | #define Ansi_1_Color #c22832 3 | #define Ansi_10_Color #8ec43d 4 | #define Ansi_11_Color #e0c64f 5 | #define Ansi_12_Color #43a5d5 6 | #define Ansi_13_Color #8b57b5 7 | #define Ansi_14_Color #8ec43d 8 | #define Ansi_15_Color #ffffff 9 | #define Ansi_2_Color #8ec43d 10 | #define Ansi_3_Color #e0c64f 11 | #define Ansi_4_Color #43a5d5 12 | #define Ansi_5_Color #8b57b5 13 | #define Ansi_6_Color #8ec43d 14 | #define Ansi_7_Color #eeeeee 15 | #define Ansi_8_Color #323232 16 | #define Ansi_9_Color #c22832 17 | #define Background_Color #111213 18 | #define Bold_Color #cacecd 19 | #define Cursor_Color #e3bf21 20 | #define Cursor_Text_Color #e0be2e 21 | #define Foreground_Color #cacecd 22 | #define Selected_Text_Color #cacecd 23 | #define Selection_Color #303233 24 | -------------------------------------------------------------------------------- /fixtures/xterm/empty.xrdb: -------------------------------------------------------------------------------- 1 | !this is empty 2 | -------------------------------------------------------------------------------- /fixtures/xterm/incomplete.xrdb: -------------------------------------------------------------------------------- 1 | #define Ansi_1_Color #fd5ff1 2 | #define Ansi_10_Color #94fa36 3 | #define Ansi_11_Color #f5ffa8 4 | #define Ansi_12_Color #96cbfe 5 | #define Ansi_13_Color #b9b6fc 6 | #define Ansi_14_Color #85befd 7 | #define Ansi_15_Color #e0e0e0 8 | #define Ansi_2_Color #87c38a 9 | #define Ansi_3_Color #ffd7b1 10 | #define Ansi_4_Color #85befd 11 | #define Ansi_5_Color #b9b6fc 12 | #define Ansi_6_Color #85befd 13 | #define Ansi_7_Color #e0e0e0 14 | #define Ansi_8_Color #000000 15 | #define Ansi_9_Color #fd5ff1 16 | #define Background_Color #161719 17 | #define Bold_Color #c5c8c6 18 | #define Cursor_Color #d0d0d0 19 | #define Cursor_Text_Color #151515 20 | #define Foreground_Color #c5c8c6 21 | #define Selected_Text_Color #c5c8c6 22 | #define Selection_Color #444444 23 | -------------------------------------------------------------------------------- /fixtures/xterm/malformed-values.xrdb: -------------------------------------------------------------------------------- 1 | #define Ansi_0_Color this_is_malformed 2 | #define Ansi_1_Color #fd5ff1 3 | #define Ansi_10_Color #94fa36 4 | #define Ansi_11_Color #f5ffa8 5 | #define Ansi_12_Color #96cbfe 6 | #define Ansi_13_Color #b9b6fc 7 | #define Ansi_14_Color #85befd 8 | #define Ansi_15_Color #e0e0e0 9 | #define Ansi_2_Color #87c38a 10 | #define Ansi_3_Color #ffd7b1 11 | #define Ansi_4_Color #85befd 12 | #define Ansi_5_Color #b9b6fc 13 | #define Ansi_6_Color #85befd 14 | #define Ansi_7_Color #e0e0e0 15 | #define Ansi_8_Color #000000 16 | #define Ansi_9_Color #fd5ff1 17 | #define Background_Color #161719 18 | #define Bold_Color #c5c8c6 19 | #define Cursor_Color #d0d0d0 20 | #define Cursor_Text_Color #151515 21 | #define Foreground_Color #c5c8c6 22 | #define Selected_Text_Color #c5c8c6 23 | #define Selection_Color #444444 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "term-schemes", 3 | "version": "1.2.1", 4 | "description": "Parse and normalize common terminal emulator color schemes", 5 | "main": "lib/index.js", 6 | "types": "lib/index.d.ts", 7 | "files": [ 8 | "lib" 9 | ], 10 | "scripts": { 11 | "start": "npx jest --watch", 12 | "build": "npx tsc", 13 | "test": "npx jest" 14 | }, 15 | "jest": { 16 | "globals": { 17 | "ts-jest": { 18 | "skipBabel": true 19 | } 20 | }, 21 | "moduleFileExtensions": [ 22 | "ts", 23 | "tsx", 24 | "js", 25 | "jsx", 26 | "json" 27 | ], 28 | "testRegex": "src/(.*)\\.test\\.(ts|js)$", 29 | "transform": { 30 | "^.+\\.ts$": "/node_modules/ts-jest/preprocessor.js" 31 | } 32 | }, 33 | "author": "Mario Nebl ", 34 | "repository": { 35 | "type": "git", 36 | "url": "https://github.com/marionebl/term-schemes.git" 37 | }, 38 | "bugs": { 39 | "url": "https://github.com/marionebl/term-schemes/issues" 40 | }, 41 | "license": "MIT", 42 | "devDependencies": { 43 | "@types/color": "^2.0.0", 44 | "@types/require-from-string": "^1.2.0", 45 | "globby": "^6.1.0", 46 | "jest": "^21.2.1", 47 | "jest-cli": "^21.2.1", 48 | "pkg-dir": "^2.0.0", 49 | "prettier": "^1.8.2", 50 | "ts-jest": "^21.2.1", 51 | "tslint": "^5.8.0", 52 | "tslint-config-prettier": "^1.6.0", 53 | "typescript": "^2.6.1" 54 | }, 55 | "dependencies": { 56 | "@marionebl/is": "^0.5.1-0", 57 | "@types/globby": "^6.1.0", 58 | "@types/ini": "^1.3.29", 59 | "@types/jest": "^21.1.5", 60 | "@types/lodash": "^4.14.84", 61 | "@types/node": "^8.0.50", 62 | "aggregate-error": "^1.0.0", 63 | "bplist-parser": "^0.1.1", 64 | "color": "^2.0.1", 65 | "hex-rgb": "^1.0.0", 66 | "ini": "^1.3.4", 67 | "lodash": "^4.17.4", 68 | "plist": "^2.1.0", 69 | "require-from-string": "^2.0.1", 70 | "resolve-from": "^4.0.0", 71 | "terminal-default-colors": "^1.0.2" 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/helpers.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as globby from 'globby'; 3 | import * as path from 'path'; 4 | import {promisify} from 'util'; 5 | 6 | const pkgDir = require('pkg-dir'); 7 | const readFile = promisify(fs.readFile); 8 | 9 | export async function fixture(id: string): Promise { 10 | const fixtures = path.join(await pkgDir(__dirname), 'fixtures'); 11 | const fixturePath = await resolveFixture(id); 12 | 13 | if (!fs.existsSync(fixturePath)) { 14 | const rel = path.relative(process.cwd(), fixturePath); 15 | const available = await globby([`**/*`], {cwd: fixtures, nodir: true}); 16 | 17 | throw new RangeError(`Could not find fixture ${id} at ${rel}. Available fixtures: ${available}`); 18 | } 19 | 20 | return String(await readFile(fixturePath)); 21 | } 22 | 23 | export async function resolveFixture(id: string): Promise { 24 | return path.join(path.join(await pkgDir(__dirname), 'fixtures'), id); 25 | } 26 | 27 | export const seti = { 28 | 0: [50, 50, 50], 29 | 1: [194, 40, 50], 30 | 2: [142, 196, 61], 31 | 3: [224, 198, 79], 32 | 4: [67, 165, 213], 33 | 5: [139, 87, 181], 34 | 6: [142, 196, 61], 35 | 7: [238, 238, 238], 36 | 8: [50, 50, 50], 37 | 9: [194, 40, 50], 38 | 10: [142, 196, 61], 39 | 11: [224, 198, 79], 40 | 12: [67, 165, 213], 41 | 13: [139, 87, 181], 42 | 14: [142, 196, 61], 43 | 15: [255, 255, 255], 44 | background: [17, 18, 19], 45 | bold: [202, 206, 205], 46 | cursor: [227, 191, 33], 47 | text: [202, 206, 205] 48 | }; 49 | 50 | export const atom = { 51 | 0: [0, 0, 0], 52 | 1: [253, 95, 241], 53 | 2: [135, 195, 138], 54 | 3: [255, 215, 177], 55 | 4: [133, 190, 253], 56 | 5: [185, 182, 252], 57 | 6: [133, 190, 253], 58 | 7: [224, 224, 224], 59 | 8: [0, 0, 0], 60 | 9: [253, 95, 241], 61 | 10: [148, 250, 54], 62 | 11: [245, 255, 168], 63 | 12: [150, 203, 254], 64 | 13: [185, 182, 252], 65 | 14: [133, 190, 253], 66 | 15: [224, 224, 224], 67 | background: [22, 23, 25], 68 | bold: [197, 200, 198], 69 | cursor: [208, 208, 208], 70 | text: [197, 200, 198] 71 | }; 72 | -------------------------------------------------------------------------------- /src/index.test.js: -------------------------------------------------------------------------------- 1 | const matchers = require('./matchers'); 2 | const termSchemes = require('.'); 3 | 4 | expect.extend(matchers); 5 | 6 | test('exports hyper method', () => { 7 | expect(termSchemes).toHaveProperty('hyper'); 8 | expect(termSchemes.hyper).isFunction(); 9 | }); 10 | 11 | test('exports iterm2 method', () => { 12 | expect(termSchemes).toHaveProperty('iterm2'); 13 | expect(termSchemes.iterm2).isFunction(); 14 | }); 15 | 16 | test('exports konsole method', () => { 17 | expect(termSchemes).toHaveProperty('konsole'); 18 | expect(termSchemes.konsole).isFunction(); 19 | }); 20 | 21 | test('exports remmina method', () => { 22 | expect(termSchemes).toHaveProperty('remmina'); 23 | expect(termSchemes.remmina).isFunction(); 24 | }); 25 | 26 | test('exports terminal method', () => { 27 | expect(termSchemes).toHaveProperty('terminal'); 28 | expect(termSchemes.terminal).isFunction(); 29 | }); 30 | 31 | test('exports terminator method', () => { 32 | expect(termSchemes).toHaveProperty('terminator'); 33 | expect(termSchemes.terminator).isFunction(); 34 | }); 35 | 36 | test('exports termite method', () => { 37 | expect(termSchemes).toHaveProperty('termite'); 38 | expect(termSchemes.termite).isFunction(); 39 | }); 40 | 41 | test('exports tilda method', () => { 42 | expect(termSchemes).toHaveProperty('tilda'); 43 | expect(termSchemes.tilda).isFunction(); 44 | }); 45 | 46 | test('exports xfce method', () => { 47 | expect(termSchemes).toHaveProperty('xfce'); 48 | expect(termSchemes.xfce).isFunction(); 49 | }); 50 | 51 | test('exports xresources method', () => { 52 | expect(termSchemes).toHaveProperty('xresources'); 53 | expect(termSchemes.xresources).isFunction(); 54 | }); 55 | 56 | test('exports xterm method', () => { 57 | expect(termSchemes).toHaveProperty('xterm'); 58 | expect(termSchemes.xterm).isFunction(); 59 | }); 60 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export enum TermSchemes { 2 | hyper = "hyper", 3 | iterm2 = "iterm2", 4 | konsole = "konsole", 5 | remmina = "remmina", 6 | terminal = "terminal", 7 | terminator = "terminator", 8 | termite = "termite", 9 | tilda = "tilda", 10 | xcfe = "xcfe", 11 | xresources = "xresources", 12 | xterm = "xterm" 13 | }; 14 | 15 | export { hyper } from "./parsers/hyper"; 16 | export { iterm2 } from "./parsers/iterm2"; 17 | export { konsole } from "./parsers/konsole"; 18 | export { remmina } from "./parsers/remmina"; 19 | export { terminal } from "./parsers/terminal"; 20 | export { terminator } from "./parsers/terminator"; 21 | export { termite } from "./parsers/termite"; 22 | export { TermScheme } from './parsers/term-scheme'; 23 | export { tilda } from "./parsers/tilda"; 24 | export { xfce } from "./parsers/xfce"; 25 | export { xresources } from "./parsers/xresources"; 26 | export { xterm } from "./parsers/xterm"; 27 | -------------------------------------------------------------------------------- /src/matchers.ts: -------------------------------------------------------------------------------- 1 | import isType, {TypeName} from '@marionebl/is'; 2 | import {inspect} from 'util'; 3 | 4 | export interface IMessageContext { 5 | actual: TypeName; 6 | expected: string; 7 | pass: boolean; 8 | received: any; 9 | } 10 | 11 | export interface IMatcherResult { 12 | pass: boolean; 13 | message(): string; 14 | } 15 | 16 | export type IIsMatcher = (received: any, expected: string) => IMatcherResult; 17 | 18 | export type ICheck = (value: any) => boolean; 19 | 20 | export interface IIsExtend extends jest.Expect { 21 | is: IIsMatcher; 22 | } 23 | 24 | export function is(received: any, expected: string) { 25 | const actual = isType(received); 26 | const pass = actual === expected; 27 | return { 28 | message: message({actual, expected, pass, received}), 29 | pass 30 | }; 31 | } 32 | 33 | export const isUndefined = strictCheck('undefined', isType.undefined); 34 | export const isNull = strictCheck('null', isType.null_); 35 | export const isString = strictCheck('string', isType.string); 36 | export const isNumber = strictCheck('number', isType.number); 37 | export const isBoolean = strictCheck('boolean', isType.boolean); 38 | export const isSymbol = strictCheck('symbol', isType.symbol); 39 | export const isArray = strictCheck('Array', isType.array); 40 | export const isFunction = strictCheck('Function', isType.function_); 41 | export const isBuffer = strictCheck('Buffer', isType.buffer); 42 | export const isObject = strictCheck('Object', isType.object); 43 | export const isRegExp = strictCheck('RegExp', isType.regExp); 44 | export const isDate = strictCheck('Date', isType.date); 45 | export const isError = strictCheck('Error', isType.error); 46 | export const isNativePromise = strictCheck('Promise', isType.nativePromise); 47 | export const isMap = strictCheck('Map', isType.map); 48 | export const isSet = strictCheck('Set', isType.set); 49 | export const isWeakMap = strictCheck('WeakMap', isType.weakMap); 50 | export const isWeakSet = strictCheck('WeakSet', isType.weakSet); 51 | export const isInt8Array = strictCheck('Int8Array', isType.int8Array); 52 | export const isUint8Array = strictCheck('Uint8Array', isType.uint8Array); 53 | export const isUint8ClampedArray = strictCheck('Uint8ClampedArray', isType.uint8ClampedArray); 54 | export const isInt16Array = strictCheck('Int16Array', isType.int16Array); 55 | export const isUint16Array = strictCheck('Uint16Array', isType.uint16Array); 56 | export const isInt32Array = strictCheck('Int32Array', isType.int32Array); 57 | export const isUint32Array = strictCheck('Uint32Array', isType.uint32Array); 58 | export const isfloat32Array = strictCheck('Float32Array', isType.float32Array); 59 | export const isfloat64Array = strictCheck('Float64Array', isType.float64Array); 60 | export const isArrayBuffer = strictCheck('ArrayBuffer', isType.arrayBuffer); 61 | export const isSharedArrayBuffer = strictCheck('SharedArrayBuffer', isType.sharedArrayBuffer); 62 | 63 | export const isPromise = surfaceCheck('promise-like', isType.promise); 64 | export const isGenerator = surfaceCheck('a generator', isType.generator); 65 | export const isAsyncFunction = surfaceCheck('an async function', isType.asyncFunction); 66 | export const isTruthy = surfaceCheck('truthy', isType.truthy); 67 | export const isFalsy = surfaceCheck('falsy', isType.falsy); 68 | export const isNaN = surfaceCheck('NaN', isType.nan); 69 | export const isNullOrUndefined = surfaceCheck('either null or undefined', isType.nullOrUndefined); 70 | export const isPrimitive = surfaceCheck('a primitive value', isType.primitive); 71 | export const isInteger = surfaceCheck('an integer', isType.integer); 72 | export const isSafeInteger = surfaceCheck('a safe integer', isType.safeInteger); 73 | export const isPlainObject = surfaceCheck('a plain object', isType.plainObject); 74 | export const isIterable = surfaceCheck('an iterable', isType.iterable); 75 | export const isClass = surfaceCheck('a class', isType.class_); 76 | export const isTypedArray = surfaceCheck('a typed array', isType.typedArray); 77 | export const isArrayLike = surfaceCheck('array-like', isType.arrayLike); 78 | 79 | export const isDomElement = surfaceCheck('DOM Element', isType.domElement); 80 | export const isInfinite = surfaceCheck('infinite', isType.infinite); 81 | export const isEven = surfaceCheck('even', isType.even); 82 | export const isOdd = surfaceCheck('odd', isType.odd); 83 | export const isEmpty = surfaceCheck('empty', isType.empty); 84 | export const isEmptyOrWhitespace = surfaceCheck('empty or whitespace', isType.emptyOrWhitespace); 85 | 86 | // export const isInRange = surfaceCheck('in range', ) 87 | // export const isAny 88 | // export const isAll 89 | 90 | function surfaceCheck(description: string, check: ICheck): IIsMatcher { 91 | return (received: any) => { 92 | const actual = isType(received); 93 | const pass = check(received); 94 | return { 95 | message() { 96 | const expectation = `expected value ${inspect(received)} to be ${description}`; 97 | return pass ? expectation : `${expectation}, was of type ${actual}`; 98 | }, 99 | pass 100 | }; 101 | }; 102 | } 103 | 104 | function strictCheck(expected: string, check: ICheck): IIsMatcher { 105 | return (received: any) => { 106 | const actual = isType(received); 107 | const pass = check(received); 108 | return { 109 | message: message({actual, expected, pass, received}), 110 | pass 111 | }; 112 | }; 113 | }; 114 | 115 | function message(c: IMessageContext): () => string { 116 | const expectation = `expected value ${inspect(c.received)} to be of type ${c.expected}`; 117 | return () => c.pass ? expectation : `${expectation}, was of type ${c.actual}`; 118 | } 119 | -------------------------------------------------------------------------------- /src/parsers/hyper.test.js: -------------------------------------------------------------------------------- 1 | const { hyper } = require("./hyper"); 2 | const matchers = require("../matchers"); 3 | const { atom, fixture, resolveFixture, seti } = require("../helpers"); 4 | 5 | expect.extend(matchers); 6 | 7 | test("exports a function", () => { 8 | expect(hyper).isFunction(); 9 | }); 10 | 11 | test("throws for empty input", () => { 12 | expect(() => hyper(undefined, {filename: 'placeholder'})).toThrow(/hyper: input must be non-empty string/); 13 | }); 14 | 15 | test("throws for empty string", () => { 16 | expect(() => hyper("", {filename: 'placeholder'})).toThrow(/hyper: input must be non-empty string/); 17 | }); 18 | 19 | test("throws for whitespace only input", () => { 20 | expect(() => hyper(" ", {filename: 'placeholder'})).toThrow(/hyper: input must be non-empty string/); 21 | }); 22 | 23 | test("throws for empty config", async () => { 24 | const empty = await fixture("hyper/empty.js"); 25 | expect(() => hyper(empty, {filename: 'placeholder'})).toThrow(/expected non-empty object, received {}/); 26 | }); 27 | 28 | test("defaults missing top level keys", async () => { 29 | const missing = await fixture("hyper/missing.js"); 30 | const actual = hyper(missing, {filename: 'placeholder'}); 31 | expect(actual.cursor).toEqual([217, 0, 189]); 32 | }); 33 | 34 | test("throws for faulty extra color", async () => { 35 | const empty = await fixture("hyper/faulty.js"); 36 | expect(() => hyper(empty, {filename: 'placeholder'})).toThrow(/"config.cursorColor" must be valid color, received "foo"/); 37 | }); 38 | 39 | test("defaults for missing color", async () => { 40 | const missingColor = await fixture("hyper/missing-color.js"); 41 | const actual = hyper(missingColor, {filename: 'placeholder'}); 42 | expect(actual[0]).toEqual([0, 0, 0]); 43 | }); 44 | 45 | test("throws for faulty color", async () => { 46 | const empty = await fixture("hyper/faulty-color.js"); 47 | expect(() => hyper(empty, {filename: 'placeholder'})).toThrow(/"config.colors.black" must be valid color/); 48 | }); 49 | 50 | test("works for valid input", async () => { 51 | const seti = await fixture("hyper/seti.js"); 52 | expect(() => hyper(seti, {filename: 'placeholder'})).not.toThrow(); 53 | }); 54 | 55 | test("returns expected result for Atom", async () => { 56 | const data = await fixture("hyper/atom.js"); 57 | expect(hyper(data, {filename: 'placeholder'})).toEqual(atom); 58 | }); 59 | 60 | test("returns expected result for Seti", async () => { 61 | const data = await fixture("hyper/seti.js"); 62 | expect(hyper(data, {filename: 'placeholder'})).toEqual(seti); 63 | }); 64 | 65 | test("returns expected result for Seti", async () => { 66 | const data = await fixture("hyper/legacy.js"); 67 | expect(hyper(data, {filename: 'placeholder'})).toEqual(seti); 68 | }); 69 | 70 | test("works with require", async () => { 71 | const data = await fixture("hyper/external.js"); 72 | const filename = await resolveFixture("hyper/external.js"); 73 | expect(hyper(data, {filename})).toEqual(atom); 74 | }); 75 | -------------------------------------------------------------------------------- /src/parsers/hyper.ts: -------------------------------------------------------------------------------- 1 | import * as fs from "fs"; 2 | import * as os from "os"; 3 | import * as path from "path"; 4 | import { inspect, error } from "util"; 5 | import * as Color from "color"; 6 | import is from "@marionebl/is"; 7 | import * as requireFromString from "require-from-string"; 8 | import { TermScheme, TermSchemeColor } from "./term-scheme"; 9 | 10 | const AggregateError = require("aggregate-error"); 11 | const resolveFrom = require("resolve-from"); 12 | 13 | type LegacyHyperColors = string[]; 14 | 15 | interface HyperColors { 16 | black: string; 17 | red: string; 18 | green: string; 19 | yellow: string; 20 | blue: string; 21 | magenta: string; 22 | cyan: string; 23 | white: string; 24 | lightBlack: string; 25 | lightRed: string; 26 | lightGreen: string; 27 | lightYellow: string; 28 | lightBlue: string; 29 | lightMagenta: string; 30 | lightCyan: string; 31 | lightWhite: string; 32 | } 33 | 34 | interface HyperConfig { 35 | config: { 36 | cursorColor: string; 37 | foregroundColor: string; 38 | backgroundColor: string; 39 | colors: HyperColors | LegacyHyperColors; 40 | } 41 | } 42 | 43 | interface NormalizedHyperConfig { 44 | cursorColor: string; 45 | foregroundColor: string; 46 | backgroundColor: string; 47 | colors: HyperColors; 48 | } 49 | 50 | export interface HyperParserConfig { 51 | filename: string; 52 | } 53 | 54 | const REQUIRED_KEYS = ['cursorColor', 'foregroundColor', 'backgroundColor', 'colors']; 55 | const EXTRA_COLORS = ['cursorColor', 'foregroundColor', 'backgroundColor']; 56 | const REQUIRED_COLORS = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'lightBlack', 'lightRed', 'lightGreen', 'lightYellow', 'lightBlue', 'lightMagenta', 'lightCyan', 'lightWhite']; 57 | 58 | const DEFAULTS: {[name: string]: string} = { 59 | cursorColor: 'rgb(217, 0, 189)', 60 | foregroundColor: 'rgb(255, 255, 255)', 61 | backgroundColor: 'rgb(0, 0, 0)', 62 | black: 'rgb(0, 0, 0)', 63 | red: 'rgb(255, 0, 0)', 64 | green: 'rgb(0, 255, 0)', 65 | yellow: 'rgb(253, 255, 0)', 66 | blue: 'rgb(0, 97, 255)', 67 | magenta: 'rgb(224, 0, 255)', 68 | cyan: 'rgb(0, 255, 255)', 69 | white: 'rgb(208, 208, 208)', 70 | lightBlack: 'rgb(128, 128, 128)', 71 | lightRed: 'rgb(255, 0, 0)', 72 | lightGreen: 'rgb(0, 255, 255)', 73 | lightYellow: 'rgb(253, 255, 0)', 74 | lightBlue: 'rgb(0, 97, 255)', 75 | lightMagenta: 'rgb(224, 0, 255)', 76 | lightCyan: 'rgb(0, 255, 255)', 77 | lightWhite: 'rgb(255, 255, 255)', 78 | }; 79 | 80 | export function hyper(input: string, parserConfig: HyperParserConfig): TermScheme { 81 | if (!is.string(input) || is.emptyOrWhitespace(input)) { 82 | throw new TypeError(`hyper: input must be non-empty string`); 83 | } 84 | 85 | if (!is.plainObject(parserConfig)) { 86 | throw new TypeError(`hyper: parserConfig must be object`); 87 | } 88 | 89 | if (typeof parserConfig.filename !== 'string') { 90 | throw new TypeError(`hyper: parserConfig.filename must be string`); 91 | } 92 | 93 | const data = resolveHyperConfig(input, {filename: parserConfig.filename}); 94 | const errs = getHyperConfigErrors(data); 95 | 96 | if (errs.length > 0) { 97 | throw new TypeError( 98 | `hyper: input is invalid: ${new AggregateError(errs)}` 99 | ); 100 | } 101 | 102 | const {backgroundColor, colors, cursorColor, foregroundColor} = normalizeHyperConfig(data); 103 | 104 | return { 105 | 0: get(colors.black), 106 | 1: get(colors.red), 107 | 2: get(colors.green), 108 | 3: get(colors.yellow), 109 | 4: get(colors.blue), 110 | 5: get(colors.magenta), 111 | 6: get(colors.cyan), 112 | 7: get(colors.white), 113 | 8: get(colors.lightBlack), 114 | 9: get(colors.lightRed), 115 | 10: get(colors.lightGreen), 116 | 11: get(colors.lightYellow), 117 | 12: get(colors.lightBlue), 118 | 13: get(colors.lightMagenta), 119 | 14: get(colors.lightCyan), 120 | 15: get(colors.lightWhite), 121 | background: get(backgroundColor), 122 | bold: get(colors.lightBlack), 123 | cursor: get(cursorColor), 124 | text: get(foregroundColor) 125 | }; 126 | } 127 | 128 | function get(value: string): TermSchemeColor { 129 | const {r, g, b} = Color(value).object(); 130 | return [r, g, b]; 131 | } 132 | 133 | function isHyperColor(color: string) { 134 | if (!color) { 135 | return false; 136 | } 137 | 138 | if (typeof color !== 'string') { 139 | return false; 140 | } 141 | 142 | try { 143 | const parsed = Color(color); 144 | return true; 145 | } catch (err) { 146 | return false; 147 | } 148 | } 149 | 150 | function getHyperConfigErrors(data: any): TypeError[] { 151 | if (is.empty(data)) { 152 | return [new TypeError(`expected non-empty object, received ${inspect(data)}`)]; 153 | } 154 | 155 | if (!('config' in data) || typeof data.config !== 'object') { 156 | return [new TypeError(`expected .config, received ${inspect(data)}`)]; 157 | } 158 | 159 | const {config = {}} = data; 160 | const {colors = {}} = config; 161 | const errors: TypeError[] = []; 162 | 163 | EXTRA_COLORS 164 | .filter(key => (key in config)) 165 | .filter(key => !isHyperColor(config[key])) 166 | .forEach((key) => { 167 | errors.push(new TypeError(`"config.${key}" must be valid color, received "${config[key]}"`)); 168 | }); 169 | 170 | REQUIRED_COLORS 171 | .filter(key => (key in colors)) 172 | .filter(key => !isHyperColor(colors[key])) 173 | .forEach((key) => { 174 | errors.push(new TypeError(`"config.colors.${key}" must be valid color, received "${colors[key]}"`)); 175 | }); 176 | 177 | return errors; 178 | } 179 | 180 | function normalizeHyperConfig(data: HyperConfig): NormalizedHyperConfig { 181 | const {config} = data; 182 | 183 | const colors = Array.isArray(config.colors) ? 184 | config.colors.reduce((acc: any, color, index) => { 185 | const name = REQUIRED_COLORS[index]; 186 | acc[name] = color; 187 | return acc as NormalizedHyperConfig; 188 | }, {}) : 189 | config.colors || {}; 190 | 191 | REQUIRED_COLORS.forEach(required => { 192 | if (!(required in colors)) { 193 | colors[required] = DEFAULTS[required]; 194 | } 195 | }); 196 | 197 | return { 198 | backgroundColor: config.backgroundColor || DEFAULTS.backgroundColor, 199 | cursorColor: config.cursorColor || DEFAULTS.cursorColor, 200 | colors, 201 | foregroundColor: config.foregroundColor || DEFAULTS.foregroundColor 202 | }; 203 | } 204 | 205 | function resolveHyperConfig(source: string, config: {filename: string}): any { 206 | const PRELUDE = ` 207 | var _require = require; 208 | require = function(id) { 209 | switch (id) { 210 | case 'electron': 211 | return {}; 212 | default: 213 | return _require(id); 214 | } 215 | }; 216 | `; 217 | 218 | let base = requireFromString(source, config.filename); 219 | 220 | if (Array.isArray(base.plugins)) { 221 | base.plugins.forEach((p: string) => { 222 | const hyperPrefix = path.join(os.homedir(), ".hyper_plugins"); 223 | const pluginPath = resolveFrom(hyperPrefix, p); 224 | const pluginSource = fs.readFileSync(pluginPath); 225 | 226 | const plugin = requireFromString([PRELUDE, pluginSource].join('\n'), pluginPath); 227 | 228 | if (plugin.decorateConfig) { 229 | base.config = plugin.decorateConfig(base.config); 230 | } 231 | }); 232 | } 233 | 234 | return base; 235 | } 236 | -------------------------------------------------------------------------------- /src/parsers/iterm2.test.js: -------------------------------------------------------------------------------- 1 | const { iterm2 } = require("./iterm2"); 2 | const matchers = require("../matchers"); 3 | const { atom, fixture, seti } = require("../helpers"); 4 | 5 | expect.extend(matchers); 6 | 7 | test("exports a function", () => { 8 | expect(iterm2).isFunction(); 9 | }); 10 | 11 | test("throws for empty input", () => { 12 | expect(() => iterm2()).toThrow(/iterm2: input must be non-empty string/); 13 | }); 14 | 15 | test("throws for empty string", () => { 16 | expect(() => iterm2("")).toThrow(/iterm2: input must be non-empty string/); 17 | }); 18 | 19 | test("throws for whitespace only input", () => { 20 | expect(() => iterm2(" ")).toThrow(/iterm2: input must be non-empty string/); 21 | }); 22 | 23 | test("throws for empty plist", async () => { 24 | const empty = await fixture("iterm2/empty.itermcolors"); 25 | expect(() => iterm2(empty)).toThrow(/iterm2: input must be non-empty plist, received \[\]/); 26 | }); 27 | 28 | test("throws for incomplete input", async () => { 29 | const empty = await fixture("iterm2/incomplete.itermcolors"); 30 | expect(() => iterm2(empty)).toThrow(/Missing Ansi 0 Color/); 31 | }); 32 | 33 | test("throws for input with malformed keys", async () => { 34 | const malformed = await fixture("iterm2/malformed-keys.itermcolors"); 35 | expect(() => iterm2(malformed)).toThrow( 36 | /Missing "Blue Component" in "Ansi 0 Color"/ 37 | ); 38 | }); 39 | 40 | test("throws for input with malformed values", async () => { 41 | const malformed = await fixture("iterm2/malformed-values.itermcolors"); 42 | expect(() => iterm2(malformed)).toThrow( 43 | /"Blue Component" in "Ansi 0 Color" must be number, received string/ 44 | ); 45 | }); 46 | 47 | test("throws for input with out of range values", async () => { 48 | const malformed = await fixture("iterm2/malformed-range.itermcolors"); 49 | expect(() => iterm2(malformed)).toThrow( 50 | /"Blue Component" in "Ansi 0 Color" must range between 0 and 1 in Blue Component in Blue Component, was 2/ 51 | ); 52 | }); 53 | 54 | test("works for valid input", async () => { 55 | const seti = await fixture("iterm2/Seti.itermcolors"); 56 | expect(() => iterm2(seti)).not.toThrow(); 57 | }); 58 | 59 | test("returns expected result for Seti", async () => { 60 | const data = await fixture("iterm2/Seti.itermcolors"); 61 | expect(iterm2(data)).toEqual(seti); 62 | }); 63 | 64 | test("returns expected result for Atom", async () => { 65 | const data = await fixture("iterm2/Atom.itermcolors"); 66 | expect(iterm2(data)).toEqual(atom); 67 | }); 68 | 69 | test("returns expected result for serialized Seti", async () => { 70 | const data = await fixture("iterm2/serialized.itermcolors"); 71 | expect(iterm2(data)).toEqual({ 72 | 0: [65, 65, 65], 73 | 1: [207, 61, 65], 74 | 2: [158, 203, 77], 75 | 3: [231, 206, 97], 76 | 4: [81, 180, 221], 77 | 5: [158, 112, 194], 78 | 6: [158, 203, 77], 79 | 7: [241, 241, 241], 80 | 8: [65, 65, 65], 81 | 9: [207, 61, 65], 82 | 10: [158, 203, 77], 83 | 11: [231, 206, 97], 84 | 12: [81, 180, 221], 85 | 13: [158, 112, 194], 86 | 14: [158, 203, 77], 87 | 15: [255, 255, 255], 88 | background: [21, 23, 24], 89 | bold: [212, 215, 214], 90 | cursor: [233, 200, 42], 91 | text: [212, 215, 214] 92 | }); 93 | }); 94 | -------------------------------------------------------------------------------- /src/parsers/iterm2.ts: -------------------------------------------------------------------------------- 1 | import is from "@marionebl/is"; 2 | import { entries, includes, values } from "lodash"; 3 | import { inspect, error } from "util"; 4 | import { TermScheme, TermSchemeColor } from "./term-scheme"; 5 | 6 | const AggregateError = require("aggregate-error"); 7 | const { parse } = require("plist"); 8 | 9 | enum Iterm2ColorName { 10 | Black = "Ansi 0 Color", 11 | Red = "Ansi 1 Color", 12 | Green = "Ansi 2 Color", 13 | Yellow = "Ansi 3 Color", 14 | Blue = "Ansi 4 Color", 15 | Magenta = "Ansi 5 Color", 16 | Cyan = "Ansi 6 Color", 17 | White = "Ansi 7 Color", 18 | LightBlack = "Ansi 8 Color", 19 | LightRed = "Ansi 9 Color", 20 | LightGreen = "Ansi 10 Color", 21 | LightYellow = "Ansi 11 Color", 22 | LightBlue = "Ansi 12 Color", 23 | LightMagenta = "Ansi 13 Color", 24 | LightCyan = "Ansi 14 Color", 25 | LightWhite = "Ansi 15 Color", 26 | Background = "Background Color", 27 | Bold = "Bold Color", 28 | Cursor = "Cursor Color", 29 | CursorText = "Cursor Text Color", 30 | Foreground = "Foreground Color" 31 | } 32 | 33 | interface Iterm2Color { 34 | "Blue Component": number; 35 | "Green Component": number; 36 | "Red Component": number; 37 | } 38 | 39 | interface Iterm2Data { 40 | "Ansi 0 Color": Iterm2Color; 41 | "Ansi 1 Color": Iterm2Color; 42 | "Ansi 2 Color": Iterm2Color; 43 | "Ansi 3 Color": Iterm2Color; 44 | "Ansi 4 Color": Iterm2Color; 45 | "Ansi 5 Color": Iterm2Color; 46 | "Ansi 6 Color": Iterm2Color; 47 | "Ansi 7 Color": Iterm2Color; 48 | "Ansi 8 Color": Iterm2Color; 49 | "Ansi 9 Color": Iterm2Color; 50 | "Ansi 10 Color": Iterm2Color; 51 | "Ansi 11 Color": Iterm2Color; 52 | "Ansi 12 Color": Iterm2Color; 53 | "Ansi 13 Color": Iterm2Color; 54 | "Ansi 14 Color": Iterm2Color; 55 | "Ansi 15 Color": Iterm2Color; 56 | "Background Color": Iterm2Color; 57 | "Bold Color": Iterm2Color; 58 | "Cursor Color": Iterm2Color; 59 | "Cursor Text Color": Iterm2Color; 60 | "Foreground Color": Iterm2Color; 61 | } 62 | 63 | const COLOR_KEYS = ["Red Component", "Green Component", "Blue Component"]; 64 | const COLOR_NAMES = values(Iterm2ColorName); 65 | 66 | /* Convert a string to TermScheme */ 67 | export function iterm2(input: string): TermScheme { 68 | if (!is.string(input) || is.emptyOrWhitespace(input)) { 69 | throw new TypeError(`iterm2: input must be non-empty string`); 70 | } 71 | 72 | const data = parse(input); 73 | 74 | if (!isIterm2Data(data)) { 75 | const errs = getIterm2DataErrrors(data); 76 | throw new TypeError( 77 | `iterm2: input ${inspect(data)} is invalid: ${new AggregateError(errs)}` 78 | ); 79 | } 80 | 81 | const get = getColor(data); 82 | 83 | return { 84 | 0: get(Iterm2ColorName.Black), 85 | 1: get(Iterm2ColorName.Red), 86 | 2: get(Iterm2ColorName.Green), 87 | 3: get(Iterm2ColorName.Yellow), 88 | 4: get(Iterm2ColorName.Blue), 89 | 5: get(Iterm2ColorName.Magenta), 90 | 6: get(Iterm2ColorName.Cyan), 91 | 7: get(Iterm2ColorName.White), 92 | 8: get(Iterm2ColorName.LightBlack), 93 | 9: get(Iterm2ColorName.LightRed), 94 | 10: get(Iterm2ColorName.LightGreen), 95 | 11: get(Iterm2ColorName.LightYellow), 96 | 12: get(Iterm2ColorName.LightBlue), 97 | 13: get(Iterm2ColorName.LightMagenta), 98 | 14: get(Iterm2ColorName.LightCyan), 99 | 15: get(Iterm2ColorName.LightWhite), 100 | background: get(Iterm2ColorName.Background), 101 | bold: get(Iterm2ColorName.Bold), 102 | cursor: get(Iterm2ColorName.Cursor), 103 | text: get(Iterm2ColorName.Foreground) 104 | }; 105 | } 106 | 107 | /** Check if data is valid and complete iTerm2 colors profile */ 108 | function isIterm2Data(data: any): data is Iterm2Data { 109 | if (!is.plainObject(data)) { 110 | return false; 111 | } 112 | 113 | const present = Object.keys(data); 114 | 115 | const missing = COLOR_NAMES.filter( 116 | (name: any) => typeof name === "string" 117 | ).some((name: string) => !includes(present, name)); 118 | 119 | if (missing) { 120 | return false; 121 | } 122 | 123 | const malformed = values(data).some((color: any) => !isIterm2Color(color)); 124 | 125 | if (malformed) { 126 | return false; 127 | } 128 | 129 | return true; 130 | } 131 | 132 | /** Check if data is valid iTerm2Color */ 133 | function isIterm2Color(data: any): data is Iterm2Color { 134 | if (!is.plainObject(data)) { 135 | return false; 136 | } 137 | 138 | const missing = COLOR_KEYS.some((key: string) => !(key in data)); 139 | 140 | if (missing) { 141 | return false; 142 | } 143 | 144 | const malformed = entries(data) 145 | .filter(([name]) => includes(COLOR_KEYS, name)) 146 | .some(([, color]) => !is.inRange(color as number, 1)); 147 | 148 | if (malformed) { 149 | return false; 150 | } 151 | 152 | return true; 153 | } 154 | 155 | function getColor(data: Iterm2Data) { 156 | return function get(name: Iterm2ColorName): TermSchemeColor { 157 | const color = data[name]; 158 | return [ 159 | toColor(color["Red Component"]), 160 | toColor(color["Green Component"]), 161 | toColor(color["Blue Component"]) 162 | ]; 163 | }; 164 | } 165 | 166 | function toColor(input: number): number { 167 | return Math.round(input * 255); 168 | } 169 | 170 | function getIterm2DataErrrors(data: any): TypeError[] { 171 | if (!is.plainObject(data)) { 172 | if (is.array(data) && data.length === 0) { 173 | return [new TypeError(`iterm2: input must be non-empty plist, received []`)]; 174 | } 175 | 176 | return [new TypeError(`expected type object, received ${is(data)}`)]; 177 | } 178 | 179 | const errors: TypeError[] = []; 180 | 181 | const present = Object.keys(data); 182 | 183 | COLOR_NAMES.filter((name: string) => !includes(present, name)).forEach( 184 | (name: string) => errors.push(new TypeError(`Missing ${name}`)) 185 | ); 186 | 187 | const colorErrors = Object.keys(data) 188 | .filter((name: any) => typeof name === "string") 189 | .filter((name: string) => includes(COLOR_NAMES, name)) 190 | .reduce((acc: TypeError[], colorName: string) => { 191 | const color = data[colorName]; 192 | const errs = getIterm2ColorErrors(color, colorName); 193 | return [...acc, ...errs]; 194 | }, []); 195 | 196 | return [...errors, ...colorErrors]; 197 | } 198 | 199 | function getIterm2ColorErrors(data: any, id: string): TypeError[] { 200 | if (!is.plainObject(data)) { 201 | return [ 202 | new TypeError(`expected type object, received ${is(data)} for ${id}`) 203 | ]; 204 | } 205 | 206 | const errors: TypeError[] = []; 207 | 208 | const present = Object.keys(data); 209 | 210 | COLOR_KEYS.filter((name: string) => !includes(present, name)).forEach( 211 | (key: string) => errors.push(new TypeError(`Missing "${key}" in "${id}"`)) 212 | ); 213 | 214 | entries(data) 215 | .filter(([name]) => includes(COLOR_KEYS, name)) 216 | .forEach(([name, color]) => { 217 | if (!is.number(color)) { 218 | errors.push( 219 | new TypeError( 220 | `"${name}" in "${id}" must be number, received ${is(color)}` 221 | ) 222 | ); 223 | } 224 | 225 | if (!is.inRange(color as number, 1)) { 226 | errors.push( 227 | new TypeError( 228 | `"${name}" in "${id}" must range between 0 and 1 in ${name} in ${ 229 | name 230 | }, was ${color}` 231 | ) 232 | ); 233 | } 234 | }); 235 | 236 | return errors; 237 | } 238 | -------------------------------------------------------------------------------- /src/parsers/konsole.test.js: -------------------------------------------------------------------------------- 1 | const { konsole } = require("./konsole"); 2 | const matchers = require("../matchers"); 3 | const { atom, fixture, seti } = require("../helpers"); 4 | 5 | expect.extend(matchers); 6 | 7 | test("exports a function", () => { 8 | expect(konsole).isFunction(); 9 | }); 10 | 11 | test("throws for empty input", () => { 12 | expect(() => konsole()).toThrow(/konsole: input must be non-empty string/); 13 | }); 14 | 15 | test("throws for empty string", () => { 16 | expect(() => konsole("")).toThrow(/konsole: input must be non-empty string/); 17 | }); 18 | 19 | test("throws for whitespace only input", () => { 20 | expect(() => konsole(" ")).toThrow(/konsole: input must be non-empty string/); 21 | }); 22 | 23 | test("throws for empty input", async () => { 24 | const empty = await fixture("konsole/empty.colorscheme"); 25 | expect(() => konsole(empty)).toThrow(/konsole: input must be non-empty colorscheme/); 26 | }); 27 | 28 | test("throws for incomplete input", async () => { 29 | const incomplete = await fixture("konsole/incomplete.colorscheme"); 30 | expect(() => konsole(incomplete)).toThrow(/konsole: missing "Color0"/); 31 | }); 32 | 33 | test("throws for malformed keys", async () => { 34 | const incomplete = await fixture("konsole/malformed-keys.colorscheme"); 35 | expect(() => konsole(incomplete)).toThrow(/konsole: missing "Color" in "Background"/); 36 | }); 37 | 38 | test("throws for malformed values", async () => { 39 | const incomplete = await fixture("konsole/malformed-values.colorscheme"); 40 | expect(() => konsole(incomplete)).toThrow(/konsole: expected "Background" to be comma-separated rgb, received "InvalidValue"/); 41 | }); 42 | 43 | test("throws for malformed range", async () => { 44 | const incomplete = await fixture("konsole/malformed-range.colorscheme"); 45 | expect(() => konsole(incomplete)).toThrow(/konsole: expected "Background" to be comma-separated rgb, received "256,18,19"/); 46 | }); 47 | 48 | test("returns expected result for Seti", async () => { 49 | const data = await fixture("konsole/Seti.colorscheme"); 50 | expect(konsole(data)).toEqual({ 51 | 0: [50, 50, 50], 52 | 1: [194, 40, 50], 53 | 2: [142, 196, 61], 54 | 3: [224, 198, 79], 55 | 4: [67, 165, 213], 56 | 5: [139, 87, 181], 57 | 6: [142, 196, 61], 58 | 7: [238, 238, 238], 59 | 8: [50, 50, 50], 60 | 9: [194, 40, 50], 61 | 10: [142, 196, 61], 62 | 11: [224, 198, 79], 63 | 12: [67, 165, 213], 64 | 13: [139, 87, 181], 65 | 14: [142, 196, 61], 66 | 15: [255, 255, 255], 67 | background: [17, 18, 19], 68 | bold: [202, 206, 205], 69 | cursor: [202, 206, 205], 70 | text: [202, 206, 205] 71 | }); 72 | }); 73 | 74 | test("returns expected result for Atom", async () => { 75 | const data = await fixture("konsole/Atom.colorscheme"); 76 | expect(konsole(data)).toEqual({ 77 | 0: [0, 0, 0], 78 | 1: [253, 95, 241], 79 | 2: [135, 195, 138], 80 | 3: [255, 215, 177], 81 | 4: [133, 190, 253], 82 | 5: [185, 182, 252], 83 | 6: [133, 190, 253], 84 | 7: [224, 224, 224], 85 | 8: [0, 0, 0], 86 | 9: [253, 95, 241], 87 | 10: [148, 250, 54], 88 | 11: [245, 255, 168], 89 | 12: [150, 203, 254], 90 | 13: [185, 182, 252], 91 | 14: [133, 190, 253], 92 | 15: [224, 224, 224], 93 | background: [22, 23, 25], 94 | bold: [197, 200, 198], 95 | cursor: [197, 200, 198], 96 | text: [197, 200, 198] 97 | }); 98 | }); 99 | -------------------------------------------------------------------------------- /src/parsers/konsole.ts: -------------------------------------------------------------------------------- 1 | import { inspect } from "util"; 2 | import is from "@marionebl/is"; 3 | import { decode } from "ini"; 4 | import { TermScheme, TermSchemeColor } from "./term-scheme"; 5 | 6 | const AggregateError = require("aggregate-error"); 7 | 8 | interface KonsoleScheme { 9 | Color0: TermSchemeColor; 10 | Color0Intense: TermSchemeColor; 11 | Color1: TermSchemeColor; 12 | Color1Intense: TermSchemeColor; 13 | Color2: TermSchemeColor; 14 | Color2Intense: TermSchemeColor; 15 | Color3: TermSchemeColor; 16 | Color3Intense: TermSchemeColor; 17 | Color4: TermSchemeColor; 18 | Color4Intense: TermSchemeColor; 19 | Color5: TermSchemeColor; 20 | Color5Intense: TermSchemeColor; 21 | Color6: TermSchemeColor; 22 | Color6Intense: TermSchemeColor; 23 | Color7: TermSchemeColor; 24 | Color7Intense: TermSchemeColor; 25 | Background: TermSchemeColor; 26 | Foreground: TermSchemeColor; 27 | } 28 | 29 | const KONSOLE_KEYS = [ 30 | 'Color0', 31 | 'Color0Intense', 32 | 'Color1', 33 | 'Color1Intense', 34 | 'Color2', 35 | 'Color3Intense', 36 | 'Color4', 37 | 'Color4Intense', 38 | 'Color5', 39 | 'Color5Intense', 40 | 'Color6', 41 | 'Color6Intense', 42 | 'Color7', 43 | 'Color7Intense', 44 | 'Background', 45 | 'Foreground' 46 | ]; 47 | 48 | export function konsole(input: any): TermScheme { 49 | if (!is.string(input) || is.emptyOrWhitespace(input)) { 50 | throw new TypeError(`konsole: input must be non-empty string`); 51 | } 52 | 53 | const data = decode(input); 54 | const [err, n] = normalize(data); 55 | 56 | if (err) { 57 | throw err; 58 | } 59 | 60 | return { 61 | 1: n.Color1, 62 | 0: n.Color0, 63 | 2: n.Color2, 64 | 3: n.Color3, 65 | 4: n.Color4, 66 | 5: n.Color5, 67 | 6: n.Color6, 68 | 7: n.Color7, 69 | 8: n.Color0Intense, 70 | 9: n.Color1Intense, 71 | 10: n.Color2Intense, 72 | 11: n.Color3Intense, 73 | 12: n.Color4Intense, 74 | 13: n.Color5Intense, 75 | 14: n.Color6Intense, 76 | 15: n.Color7Intense, 77 | bold: n.Foreground, 78 | cursor: n.Foreground, 79 | text: n.Foreground, 80 | background: n.Background 81 | }; 82 | } 83 | 84 | function normalize(data: any): [Error, null] | [null, KonsoleScheme] { 85 | if (is.empty(data)) { 86 | throw new TypeError(`konsole: input must be non-empty colorscheme`); 87 | } 88 | 89 | const errors: Error[] = []; 90 | 91 | KONSOLE_KEYS 92 | .filter((key) => { 93 | if (!(key in data)) { 94 | errors.push(new TypeError(`konsole: missing "${key}"`)); 95 | return false; 96 | } 97 | return true; 98 | }) 99 | .filter((key) => { 100 | const val = data[key]; 101 | 102 | if (!is.plainObject(val)) { 103 | errors.push(new TypeError(`konsole: expected "${key}" to be object, received "${typeof val}"`)); 104 | return false; 105 | } 106 | 107 | if (!('Color' in val)) { 108 | errors.push(new TypeError(`konsole: missing "Color" in "${key}", received "${inspect(val)}"`)); 109 | return false; 110 | } 111 | 112 | return true; 113 | }) 114 | .filter((key) => { 115 | const val = data[key].Color; 116 | const fragments = val.split(','); 117 | 118 | if (fragments.length !== 3) { 119 | errors.push(new TypeError(`konsole: expected "${key}" to be comma-separated rgb, received "${val}"`)); 120 | return false; 121 | } 122 | 123 | const nums = fragments.map((f: string) => Number(f)); 124 | 125 | if (nums.length !== 3) { 126 | errors.push(new TypeError(`konsole: expected "${key}" to be comma-separated rgb, received "${val}"`)); 127 | return false; 128 | } 129 | 130 | const invalid = nums.filter((n: number) => !is.inRange(n, 255)); 131 | 132 | if (invalid.length > 0) { 133 | errors.push(new TypeError(`konsole: expected "${key}" to be comma-separated rgb, received "${val}"`)); 134 | return false; 135 | } 136 | }); 137 | 138 | if (errors.length > 0) { 139 | return [new AggregateError(errors), null]; 140 | } 141 | 142 | return [null, { 143 | Color0: toRgb(data.Color0.Color), 144 | Color0Intense: toRgb(data.Color0Intense.Color), 145 | Color1: toRgb(data.Color1.Color), 146 | Color1Intense: toRgb(data.Color1Intense.Color), 147 | Color2: toRgb(data.Color2.Color), 148 | Color2Intense: toRgb(data.Color2Intense.Color), 149 | Color3: toRgb(data.Color3.Color), 150 | Color3Intense: toRgb(data.Color3Intense.Color), 151 | Color4: toRgb(data.Color4.Color), 152 | Color4Intense: toRgb(data.Color4Intense.Color), 153 | Color5: toRgb(data.Color5.Color), 154 | Color5Intense: toRgb(data.Color5Intense.Color), 155 | Color6: toRgb(data.Color6.Color), 156 | Color6Intense: toRgb(data.Color6Intense.Color), 157 | Color7: toRgb(data.Color7.Color), 158 | Color7Intense: toRgb(data.Color7Intense.Color), 159 | Background: toRgb(data.Background.Color), 160 | Foreground: toRgb(data.Foreground.Color) 161 | }]; 162 | } 163 | 164 | function toRgb(input: string): TermSchemeColor { 165 | const f = input.split(',').map((i: string) => Number(i)); 166 | return [f[0], f[1], f[2]]; 167 | } 168 | -------------------------------------------------------------------------------- /src/parsers/remmina.test.js: -------------------------------------------------------------------------------- 1 | const { remmina } = require("./remmina"); 2 | const matchers = require("../matchers"); 3 | const { atom, fixture, seti } = require("../helpers"); 4 | 5 | expect.extend(matchers); 6 | 7 | test("exports a function", () => { 8 | expect(remmina).isFunction(); 9 | }); 10 | 11 | test("throws for empty input", () => { 12 | expect(() => remmina()).toThrow(/remmina: input must be non-empty string/); 13 | }); 14 | 15 | test("throws for empty string", () => { 16 | expect(() => remmina("")).toThrow(/remmina: input must be non-empty string/); 17 | }); 18 | 19 | test("throws for whitespace only input", () => { 20 | expect(() => remmina(" ")).toThrow(/remmina: input must be non-empty string/); 21 | }); 22 | 23 | test("throws for empty input", async () => { 24 | const empty = await fixture("remmina/empty.colors"); 25 | expect(() => remmina(empty)).toThrow(/remmina: input must be non-empty colors/); 26 | }); 27 | 28 | test("throws for incomplete input", async () => { 29 | const incomplete = await fixture("remmina/incomplete.colors"); 30 | expect(() => remmina(incomplete)).toThrow(/remmina: missing "background"/); 31 | }); 32 | 33 | test("throws for malformed values", async () => { 34 | const incomplete = await fixture("remmina/malformed-values.colors"); 35 | expect(() => remmina(incomplete)).toThrow(/remmina: expected "background" to be hex color, received "malformed-value"/); 36 | }); 37 | 38 | test("returns expected result for Seti", async () => { 39 | const data = await fixture("remmina/Seti.colors"); 40 | expect(remmina(data)).toEqual(seti); 41 | }); 42 | 43 | test("returns expected result for Atom", async () => { 44 | const data = await fixture("remmina/Atom.colors"); 45 | expect(remmina(data)).toEqual(atom); 46 | }); 47 | -------------------------------------------------------------------------------- /src/parsers/remmina.ts: -------------------------------------------------------------------------------- 1 | import { inspect } from "util"; 2 | import is from "@marionebl/is"; 3 | import { decode } from "ini"; 4 | import { TermScheme, TermSchemeColor } from "./term-scheme"; 5 | 6 | const AggregateError = require("aggregate-error"); 7 | const hexRgb = require("hex-rgb"); 8 | 9 | export type Parser = (raw: any) => TermScheme; 10 | export type Normalizer = (raw: string) => [Error, null] | [null, RemminaScheme]; 11 | 12 | export interface ParserOptions { 13 | group: string | null; 14 | wrap: boolean; 15 | } 16 | 17 | export interface NormalizerOptions { 18 | group: string; 19 | } 20 | 21 | export interface RemminaScheme { 22 | color0: TermSchemeColor; 23 | color1: TermSchemeColor; 24 | color2: TermSchemeColor; 25 | color3: TermSchemeColor; 26 | color4: TermSchemeColor; 27 | color5: TermSchemeColor; 28 | color6: TermSchemeColor; 29 | color7: TermSchemeColor; 30 | color8: TermSchemeColor; 31 | color9: TermSchemeColor; 32 | color10: TermSchemeColor; 33 | color11: TermSchemeColor; 34 | color12: TermSchemeColor; 35 | color13: TermSchemeColor; 36 | color14: TermSchemeColor; 37 | color15: TermSchemeColor; 38 | background: TermSchemeColor; 39 | bold: TermSchemeColor; 40 | cursor: TermSchemeColor; 41 | foreground: TermSchemeColor; 42 | } 43 | 44 | const REMINNA_KEYS = [ 45 | 'background', 46 | 'colorBD', 47 | 'cursor', 48 | 'foreground', 49 | 'color0', 50 | 'color1', 51 | 'color2', 52 | 'color3', 53 | 'color4', 54 | 'color5', 55 | 'color6', 56 | 'color7', 57 | 'color8', 58 | 'color9', 59 | 'color10', 60 | 'color11', 61 | 'color12', 62 | 'color14', 63 | 'color15' 64 | ]; 65 | 66 | const EXACT_HEX_MATCH = /^#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/; 67 | const HEX_MATCH = /= (#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{6})/g; 68 | 69 | export const remmina = createParser('remmina', { 70 | group: 'ssh_colors', 71 | wrap: true 72 | }); 73 | 74 | export function createParser(name: string, opts: ParserOptions): Parser { 75 | const normalize = createNormalizer(name, {group: opts.group}); 76 | 77 | return (raw: any): TermScheme => { 78 | if (!is.string(raw) || is.emptyOrWhitespace(raw)) { 79 | throw new TypeError(`${name}: input must be non-empty string`); 80 | } 81 | 82 | // Wrap hex colors in quotes 83 | const input = opts.wrap ? raw.replace(HEX_MATCH, '= "$1"') : raw; 84 | const data = decode(input); 85 | 86 | const [err, n] = normalize(data); 87 | 88 | if (err) { 89 | throw err; 90 | } 91 | 92 | return { 93 | 0: n.color0, 94 | 1: n.color1, 95 | 2: n.color2, 96 | 3: n.color3, 97 | 4: n.color4, 98 | 5: n.color5, 99 | 6: n.color6, 100 | 7: n.color7, 101 | 8: n.color8, 102 | 9: n.color9, 103 | 10: n.color10, 104 | 11: n.color11, 105 | 12: n.color12, 106 | 13: n.color13, 107 | 14: n.color14, 108 | 15: n.color15, 109 | bold: n.bold, 110 | cursor: n.cursor, 111 | text: n.foreground, 112 | background: n.background 113 | }; 114 | }; 115 | } 116 | 117 | function createNormalizer(name: string, opts: NormalizerOptions): Normalizer { 118 | return function normalize(raw: any): [Error, null] | [null, RemminaScheme] { 119 | if (is.empty(raw)) { 120 | throw new TypeError(`${name}: input must be non-empty colors`); 121 | } 122 | 123 | if (!(opts.group in raw)) { 124 | throw new TypeError(`${name}: expected ${opts.group} group in colorscheme`); 125 | } 126 | 127 | const data = raw[opts.group]; 128 | 129 | if (is.empty(data)) { 130 | throw new TypeError(`${name}: input must be non-empty colors, ${opts.group} was empty`); 131 | } 132 | 133 | const errors: Error[] = []; 134 | 135 | REMINNA_KEYS 136 | .filter((key) => { 137 | if (!(key in data)) { 138 | errors.push(new TypeError(`${name}: missing "${key}"`)); 139 | return false; 140 | } 141 | return true; 142 | }) 143 | .filter((key) => { 144 | const val = data[key]; 145 | 146 | if (!is.string(val)) { 147 | errors.push(new TypeError(`${name}: expected "${key}" to be string, received "${typeof val}"`)); 148 | return false; 149 | } 150 | 151 | return true; 152 | }) 153 | .filter((key) => { 154 | const val = data[key]; 155 | 156 | if (!val.match(EXACT_HEX_MATCH)) { 157 | errors.push(new TypeError(`${name}: expected "${key}" to be hex color, received "${val}"`)); 158 | return false; 159 | } 160 | 161 | return true; 162 | }); 163 | 164 | if (errors.length > 0) { 165 | return [new AggregateError(errors), null]; 166 | } 167 | 168 | return [null, { 169 | color0: toRgb(data.color0), 170 | color1: toRgb(data.color1), 171 | color2: toRgb(data.color2), 172 | color3: toRgb(data.color3), 173 | color4: toRgb(data.color4), 174 | color5: toRgb(data.color5), 175 | color6: toRgb(data.color6), 176 | color7: toRgb(data.color7), 177 | color8: toRgb(data.color8), 178 | color9: toRgb(data.color9), 179 | color10: toRgb(data.color10), 180 | color11: toRgb(data.color11), 181 | color12: toRgb(data.color12), 182 | color13: toRgb(data.color13), 183 | color14: toRgb(data.color14), 184 | color15: toRgb(data.color15), 185 | background: toRgb(data.background), 186 | bold: toRgb(data.colorBD), 187 | cursor: toRgb(data.cursor), 188 | foreground: toRgb(data.foreground) 189 | }]; 190 | } 191 | } 192 | 193 | function toRgb(input: string): TermSchemeColor { 194 | return hexRgb(input); 195 | } 196 | -------------------------------------------------------------------------------- /src/parsers/term-scheme.ts: -------------------------------------------------------------------------------- 1 | export type TermSchemeColor = [number, number, number]; 2 | 3 | export interface TermScheme { 4 | /** Black */ 5 | 0: TermSchemeColor; 6 | /** Red */ 7 | 1: TermSchemeColor; 8 | /** Green */ 9 | 2: TermSchemeColor; 10 | /** Yellow */ 11 | 3: TermSchemeColor; 12 | /** Blue */ 13 | 4: TermSchemeColor; 14 | /** Magenta */ 15 | 5: TermSchemeColor; 16 | /** Cyan */ 17 | 6: TermSchemeColor; 18 | /** White */ 19 | 7: TermSchemeColor; 20 | /** Bright Black */ 21 | 8: TermSchemeColor; 22 | /** Bright Red */ 23 | 9: TermSchemeColor; 24 | /** Bright Green */ 25 | 10: TermSchemeColor; 26 | /** Bright Yellow */ 27 | 11: TermSchemeColor; 28 | /** Bright Blue */ 29 | 12: TermSchemeColor; 30 | /** Bright Magenta */ 31 | 13: TermSchemeColor; 32 | /** Bright Cyan */ 33 | 14: TermSchemeColor; 34 | /** Bright White */ 35 | 15: TermSchemeColor; 36 | /** Background color */ 37 | background: TermSchemeColor; 38 | /** Bold text color */ 39 | bold: TermSchemeColor; 40 | /** Cursor background color */ 41 | cursor: TermSchemeColor; 42 | /** Text color */ 43 | text: TermSchemeColor; 44 | } 45 | -------------------------------------------------------------------------------- /src/parsers/terminal.test.js: -------------------------------------------------------------------------------- 1 | const { terminal } = require("./terminal"); 2 | const matchers = require("../matchers"); 3 | const { atom, fixture, seti } = require("../helpers"); 4 | const { terminal: {colors} } = require("terminal-default-colors"); 5 | 6 | expect.extend(matchers); 7 | 8 | test("exports a function", () => { 9 | expect(terminal).isFunction(); 10 | }); 11 | 12 | test("throws for empty input", () => { 13 | expect(() => terminal()).toThrow(/terminal: input must be non-empty string/); 14 | }); 15 | 16 | test("throws for empty string", () => { 17 | expect(() => terminal("")).toThrow(/terminal: input must be non-empty string/); 18 | }); 19 | 20 | test("throws for whitespace only input", () => { 21 | expect(() => terminal(" ")).toThrow(/terminal: input must be non-empty string/); 22 | }); 23 | 24 | test("throws for empty plist", async () => { 25 | const empty = await fixture("terminal/empty.terminal"); 26 | expect(() => terminal(empty)).toThrow(/terminal: input must be non-empty p-list/); 27 | }); 28 | 29 | test("works for valid input", async () => { 30 | const oneDark = await fixture("terminal/Seti.terminal"); 31 | expect(() => terminal(oneDark)).not.toThrow(); 32 | }); 33 | 34 | test("works for all known colorspaces", async () => { 35 | const colorspaces = await fixture("terminal/colorspaces.terminal"); 36 | expect(() => terminal(colorspaces)).not.toThrow(); 37 | }); 38 | 39 | test("throws for malformed input", async () => { 40 | const malformed = await fixture("terminal/malformed.terminal"); 41 | expect(() => terminal(malformed)).toThrow( 42 | /Parsing black failed/ 43 | ); 44 | }); 45 | 46 | test("throws for input with malformed keys", async () => { 47 | const malformed = await fixture("terminal/malformed-keys.terminal"); 48 | expect(() => terminal(malformed)).toThrow( 49 | /Parsing black failed/ 50 | ); 51 | }); 52 | 53 | test("throws for input with malformed values", async () => { 54 | const malformed = await fixture("terminal/malformed-values.terminal"); 55 | expect(() => terminal(malformed)).toThrow( 56 | /Unknown NSColorSpace undefined in color black/ 57 | ); 58 | }); 59 | 60 | test("returns expected result for Seti", async () => { 61 | const data = await fixture("terminal/Seti.terminal"); 62 | expect(terminal(data)).toEqual(seti); 63 | }); 64 | 65 | test("returns expected result for Atom", async () => { 66 | const data = await fixture("terminal/Atom.terminal"); 67 | expect(terminal(data)).toEqual(atom); 68 | }); 69 | 70 | test("returns expected result for incomplete input", async () => { 71 | const incomplete = await fixture("terminal/incomplete.terminal"); 72 | const actual = terminal(incomplete); 73 | 74 | expect(actual[0]).toEqual(colors[0].rgb); 75 | expect(actual[1]).toEqual(colors[1].rgb); 76 | expect(actual[2]).toEqual(colors[2].rgb); 77 | expect(actual[3]).toEqual(colors[3].rgb); 78 | expect(actual[4]).toEqual(colors[4].rgb); 79 | expect(actual[5]).toEqual(colors[5].rgb); 80 | expect(actual[6]).toEqual(colors[6].rgb); 81 | expect(actual[7]).toEqual(colors[7].rgb); 82 | expect(actual[8]).toEqual(colors[8].rgb); 83 | expect(actual[9]).toEqual(colors[9].rgb); 84 | expect(actual[10]).toEqual(colors[10].rgb); 85 | }); 86 | -------------------------------------------------------------------------------- /src/parsers/terminal.ts: -------------------------------------------------------------------------------- 1 | import * as util from "util"; 2 | import is from "@marionebl/is"; 3 | import { TermScheme, TermSchemeColor } from "./term-scheme"; 4 | 5 | const AggregateError = require("aggregate-error"); 6 | const { parse } = require("plist"); 7 | const { parseBuffer } = require("bplist-parser"); 8 | const {terminal: terminalDefaults} = require("terminal-default-colors"); 9 | 10 | interface DefaultMap { 11 | [name: string]: {rgb: TermSchemeColor}; 12 | } 13 | 14 | const ADDITIONAL_DEFAULTS: DefaultMap = { 15 | BackgroundColor: {rgb: [255, 255, 255]}, 16 | TextBoldColor: {rgb: [0, 0, 0]}, 17 | CursorColor: {rgb: [146, 146, 146]}, 18 | CursorTextColor: {rgb: [0, 0, 0]}, 19 | TextColor: {rgb: [0, 0, 0]} 20 | }; 21 | 22 | interface TerminalData { 23 | ANSIBlackColor: Buffer; 24 | ANSIRedColor: Buffer; 25 | ANSIGreenColor: Buffer; 26 | ANSIYellowColor: Buffer; 27 | ANSIBlueColor: Buffer; 28 | ANSIMagentaColor: Buffer; 29 | ANSICyanColor: Buffer; 30 | ANSIWhiteColor: Buffer; 31 | ANSIBrightBlackColor: Buffer; 32 | ANSIBrightBlueColor: Buffer; 33 | ANSIBrightCyanColor: Buffer; 34 | ANSIBrightGreenColor: Buffer; 35 | ANSIBrightMagentaColor: Buffer; 36 | ANSIBrightRedColor: Buffer; 37 | ANSIBrightWhiteColor: Buffer; 38 | ANSIBrightYellowColor: Buffer; 39 | BackgroundColor: Buffer; 40 | TextBoldColor: Buffer; 41 | CursorColor: Buffer; 42 | CursorTextColor: Buffer; 43 | TextColor: Buffer; 44 | } 45 | 46 | export function terminal(input: any): TermScheme { 47 | if (!is.string(input) || is.emptyOrWhitespace(input)) { 48 | throw new TypeError(`terminal: input must be non-empty string`); 49 | } 50 | 51 | const raw = parse(input); 52 | 53 | if (!is.plainObject(raw)) { 54 | if (is.array(raw) && raw.length === 0) { 55 | throw new TypeError(`terminal: input must be non-empty p-list, received []`); 56 | } 57 | 58 | throw new TypeError(`expected type object, received ${is(raw)}`); 59 | } 60 | 61 | return { 62 | 0: toRGB(raw.ANSIBlackColor, "black"), 63 | 1: toRGB(raw.ANSIRedColor, "red"), 64 | 2: toRGB(raw.ANSIGreenColor, "green"), 65 | 3: toRGB(raw.ANSIYellowColor, "yellow"), 66 | 4: toRGB(raw.ANSIBlueColor, "blue"), 67 | 5: toRGB(raw.ANSIMagentaColor, "magenta"), 68 | 6: toRGB(raw.ANSICyanColor, "cyan"), 69 | 7: toRGB(raw.ANSIWhiteColor, "white"), 70 | 8: toRGB(raw.ANSIBrightBlackColor, "brightBlack"), 71 | 9: toRGB(raw.ANSIBrightRedColor, "brightRed"), 72 | 10: toRGB(raw.ANSIBrightGreenColor, "brightGreen"), 73 | 11: toRGB(raw.ANSIBrightYellowColor, "brightYellow"), 74 | 12: toRGB(raw.ANSIBrightBlueColor, "brightBlue"), 75 | 13: toRGB(raw.ANSIBrightMagentaColor, "brightMagenta"), 76 | 14: toRGB(raw.ANSIBrightCyanColor, "brightCyan"), 77 | 15: toRGB(raw.ANSIBrightWhiteColor, "brightWhite"), 78 | background: toRGB(raw.BackgroundColor, "BackgroundColor"), 79 | bold: toRGB(raw.TextBoldColor, "TextBoldColor"), 80 | cursor: toRGB(raw.CursorColor, "CursorColor"), 81 | text: toRGB(raw.TextColor, "TextColor") 82 | }; 83 | } 84 | 85 | /** Convert a NSArchiver base64-encoded Buffer containing NSColor to TermSchemeColor */ 86 | function toRGB(archive: any, name: string): TermSchemeColor { 87 | if (is.undefined(archive)) { 88 | const defaultColor = terminalDefaults.colors.find((c: any) => c.name === name) || ADDITIONAL_DEFAULTS[name] as any; 89 | if (!defaultColor) { 90 | throw new TypeError( 91 | `Missing ${name}` 92 | ); 93 | } 94 | return defaultColor.rgb; 95 | } 96 | 97 | if (!is.buffer(archive)) { 98 | throw new TypeError( 99 | `NSArchiver archive must be buffer, was ${is(archive)}` 100 | ); 101 | } 102 | 103 | const [err, result] = parseBplist(archive); 104 | 105 | if (err) { 106 | throw new AggregateError([ 107 | new TypeError(`Parsing ${name} failed`), 108 | err 109 | ]); 110 | } 111 | 112 | if (!Array.isArray(result)) { 113 | throw new TypeError(`Unexpected archive type in ${name}: ${is(result)}`); 114 | } 115 | 116 | if (result.length === 0) { 117 | throw new TypeError(`Unexpected zero length archive in ${name}`); 118 | } 119 | 120 | const [value] = result; 121 | 122 | if (!("$objects" in value)) { 123 | throw new TypeError(`Missing $objects key in ${name}`); 124 | } 125 | 126 | const objects = value["$objects"]; 127 | 128 | if (!Array.isArray(objects)) { 129 | throw new TypeError(`Unexpected $objects type of ${name}: ${is(result)}`); 130 | } 131 | 132 | if (objects.length < 1) { 133 | throw new TypeError( 134 | `Unexpected $objects length ${result.length} of ${name}` 135 | ); 136 | } 137 | 138 | const color = objects[1]; 139 | return parseNSColor(color, name); 140 | } 141 | 142 | function parseBplist(input: Buffer): [Error | null, any] { 143 | try { 144 | return [null, parseBuffer(input)]; 145 | } catch (err) { 146 | return [err, null]; 147 | } 148 | } 149 | 150 | function parseNSColor(color: any, name: string): TermSchemeColor { 151 | switch(color.NSColorSpace) { 152 | case 1: 153 | case 2: { 154 | return color.NSRGB.toString() 155 | .replace("\u0000", "") 156 | .split(" ") 157 | .map((item: string) => parseFloat(item)) 158 | .map((num: number) => Math.round(num * 255)); 159 | } 160 | case 3: { 161 | const val = parseFloat(String(color.NSWhite)); 162 | const result = Math.round(val * 255); 163 | return [result, result, result]; 164 | } 165 | default: 166 | throw new TypeError(`Unknown NSColorSpace ${color.NSColorSpace} in color ${name}: ${util.inspect(color)}`); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/parsers/terminator.test.js: -------------------------------------------------------------------------------- 1 | const { terminator } = require("./terminator"); 2 | const matchers = require("../matchers"); 3 | const { atom, fixture, seti } = require("../helpers"); 4 | 5 | expect.extend(matchers); 6 | 7 | test("exports a function", () => { 8 | expect(terminator).isFunction(); 9 | }); 10 | 11 | test("throws for empty input", () => { 12 | expect(() => terminator()).toThrow(/terminator: input must be non-empty string/); 13 | }); 14 | 15 | test("throws for empty string", () => { 16 | expect(() => terminator("")).toThrow(/terminator: input must be non-empty string/); 17 | }); 18 | 19 | test("throws for whitespace only input", () => { 20 | expect(() => terminator(" ")).toThrow(/terminator: input must be non-empty string/); 21 | }); 22 | 23 | test("throws for empty input", async () => { 24 | const empty = await fixture("terminator/empty.config"); 25 | expect(() => terminator(empty)).toThrow(/terminator: config must be non-empty/); 26 | }); 27 | 28 | test("throws for incomplete input", async () => { 29 | const empty = await fixture("terminator/incomplete.config"); 30 | expect(() => terminator(empty)).toThrow(/terminator: "palette" missing from config/); 31 | }); 32 | 33 | test("throws for input with malformed values", async () => { 34 | const empty = await fixture("terminator/malformed-values.config"); 35 | expect(() => terminator(empty)).toThrow(/terminator: "background_color" must be hex color, received "#invalid-value"/); 36 | }); 37 | 38 | test("throws for input with malformed palette", async () => { 39 | const empty = await fixture("terminator/malformed-palette.config"); 40 | expect(() => terminator(empty)).toThrow(/terminator: "palette" must be list of 15 hex colors delimited by ":", received "malformed-palette"/); 41 | }); 42 | 43 | test("throws for input with incomplete palette", async () => { 44 | const empty = await fixture("terminator/incomplete-palette.config"); 45 | expect(() => terminator(empty)).toThrow(/terminator: "palette" must be list of 15 hex colors delimited by ":"/); 46 | }); 47 | 48 | test("throws for input with malformed palette item", async () => { 49 | const empty = await fixture("terminator/malformed-palette-item.config"); 50 | expect(() => terminator(empty)).toThrow(/terminator: "palette" must be list of 15 hex colors delimited by ":"/); 51 | }); 52 | 53 | test("returns expected result for Seti", async () => { 54 | const data = await fixture("terminator/Seti.config"); 55 | expect(terminator(data)).toEqual(seti); 56 | }); 57 | 58 | test("returns expected result for Atom", async () => { 59 | const data = await fixture("terminator/Atom.config"); 60 | expect(terminator(data)).toEqual(atom); 61 | }); 62 | -------------------------------------------------------------------------------- /src/parsers/terminator.ts: -------------------------------------------------------------------------------- 1 | import is from "@marionebl/is"; 2 | import { decode } from "ini"; 3 | import { normalize } from "path"; 4 | import { TermScheme, TermSchemeColor } from "./term-scheme"; 5 | import { error } from "util"; 6 | 7 | const AggregateError = require("aggregate-error"); 8 | const hexRgb = require('hex-rgb'); 9 | 10 | interface TerminatorScheme { 11 | palette: string; 12 | background_color: string; 13 | cursor_color: string; 14 | foreground_color: string; 15 | [colorName: string]: string; 16 | } 17 | 18 | interface NormalizedTerminatorScheme { 19 | palette: TermSchemeColor[]; 20 | background: TermSchemeColor; 21 | cursor: TermSchemeColor; 22 | text: TermSchemeColor; 23 | } 24 | 25 | const TERMINATOR_KEYS = ['background_color', 'cursor_color', 'foreground_color']; 26 | const HEADER_MATCH = /\[\[(.*)\]\]/; 27 | const HEX_MATCH = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{6})/; 28 | const PALETTE_EXPECTATION = "\"palette\" must be list of 15 hex colors delimited by \":\""; 29 | 30 | export function terminator(input: any): TermScheme { 31 | if (!is.string(input) || is.emptyOrWhitespace(input)) { 32 | throw new TypeError(`terminator: input must be non-empty string`); 33 | } 34 | 35 | const data = decode(input); 36 | const [err, normalized] = normalizeData(data); 37 | 38 | if (err) { 39 | throw err; 40 | } 41 | 42 | return { 43 | 0: normalized.palette[0], 44 | 1: normalized.palette[1], 45 | 2: normalized.palette[2], 46 | 3: normalized.palette[3], 47 | 4: normalized.palette[4], 48 | 5: normalized.palette[5], 49 | 6: normalized.palette[6], 50 | 7: normalized.palette[7], 51 | 8: normalized.palette[8], 52 | 9: normalized.palette[9], 53 | 10: normalized.palette[10], 54 | 11: normalized.palette[11], 55 | 12: normalized.palette[12], 56 | 13: normalized.palette[13], 57 | 14: normalized.palette[14], 58 | 15: normalized.palette[15], 59 | bold: normalized.text, 60 | background: normalized.background, 61 | cursor: normalized.cursor, 62 | text: normalized.text 63 | }; 64 | } 65 | 66 | function normalizeData(data: TerminatorScheme): [Error, null] | [null, NormalizedTerminatorScheme] { 67 | if (isEmpty(data)) { 68 | return [new TypeError('terminator: config must be non-empty'), null]; 69 | } 70 | 71 | const errors: Error[] = []; 72 | 73 | const faultyColors = TERMINATOR_KEYS 74 | .map((key: string) => { 75 | if (!(key in data)) { 76 | return new TypeError(`terminator: "${key}" missing from config`); 77 | } 78 | 79 | const val = data[key]; 80 | 81 | if (!is.string(val)) { 82 | return new TypeError(`terminator: "${key}" must be string, received ${typeof val}`); 83 | } 84 | 85 | if (!val.match(HEX_MATCH)) { 86 | return new TypeError(`terminator: "${key}" must be hex color, received "${val}"`); 87 | } 88 | }) 89 | .filter(Boolean); 90 | 91 | errors.push(...faultyColors); 92 | 93 | if (!('palette' in data)) { 94 | errors.push(new TypeError(`terminator: "palette" missing from config`)); 95 | } 96 | 97 | if (!is.string(data.palette)) { 98 | errors.push(new TypeError(`terminator: "palette" must be string, received "${typeof data.palette}"`)); 99 | } 100 | 101 | const fragments = (data.palette || '').split(':'); 102 | 103 | if (fragments.length !== 16) { 104 | errors.push(new TypeError(`terminator: ${PALETTE_EXPECTATION}, received "${data.palette}"`)); 105 | } 106 | 107 | const paletteErrors = fragments 108 | .map((color: string, index: number) => { 109 | if (!color.match(HEX_MATCH)) { 110 | return new TypeError(`terminator: invalid palette item at index ${index}, expected hex color, received ${color}"`); 111 | } 112 | }) 113 | .filter(Boolean); 114 | 115 | if (paletteErrors.length > 0) { 116 | errors.push(new TypeError(`terminator: ${PALETTE_EXPECTATION}, received "${data.palette}"`)); 117 | errors.push(...paletteErrors); 118 | } 119 | 120 | if (errors.length > 0) { 121 | const err: Error = new AggregateError(errors); 122 | return [err, null]; 123 | } 124 | 125 | const palette = fragments.map(color => hexRgb(color)); 126 | 127 | return [null, { 128 | palette, 129 | background: hexRgb(data.background_color), 130 | cursor: hexRgb(data.cursor_color), 131 | text: hexRgb(data.foreground_color) 132 | }] 133 | } 134 | 135 | function isEmpty(data: any): boolean { 136 | return Object.keys(data || {}).every((key) => Boolean(key.match(HEADER_MATCH))); 137 | } 138 | -------------------------------------------------------------------------------- /src/parsers/termite.test.js: -------------------------------------------------------------------------------- 1 | const { termite } = require("./termite"); 2 | const matchers = require("../matchers"); 3 | const { atom, fixture, seti } = require("../helpers"); 4 | 5 | expect.extend(matchers); 6 | 7 | test("exports a function", () => { 8 | expect(termite).isFunction(); 9 | }); 10 | 11 | test("throws for empty input", () => { 12 | expect(() => termite()).toThrow(/termite: input must be non-empty string/); 13 | }); 14 | 15 | test("throws for empty string", () => { 16 | expect(() => termite("")).toThrow(/termite: input must be non-empty string/); 17 | }); 18 | 19 | test("throws for whitespace only input", () => { 20 | expect(() => termite(" ")).toThrow(/termite: input must be non-empty string/); 21 | }); 22 | 23 | test("throws for empty input", async () => { 24 | const empty = await fixture("termite/empty"); 25 | expect(() => termite(empty)).toThrow(/termite: input must be non-empty colors/); 26 | }); 27 | 28 | test("throws for incomplete input", async () => { 29 | const incomplete = await fixture("termite/incomplete"); 30 | expect(() => termite(incomplete)).toThrow(/termite: missing "background"/); 31 | }); 32 | 33 | test("throws for malformed values", async () => { 34 | const incomplete = await fixture("termite/malformed-values"); 35 | expect(() => termite(incomplete)).toThrow(/termite: expected "background" to be hex color, received "malformed-value"/); 36 | }); 37 | 38 | test("returns expected result for Seti", async () => { 39 | const data = await fixture("termite/Seti"); 40 | expect(termite(data)).toEqual(seti); 41 | }); 42 | 43 | test("returns expected result for Atom", async () => { 44 | const data = await fixture("termite/Atom"); 45 | expect(termite(data)).toEqual(atom); 46 | }); 47 | -------------------------------------------------------------------------------- /src/parsers/termite.ts: -------------------------------------------------------------------------------- 1 | import { createParser, Parser } from "./remmina"; 2 | 3 | export const termite: Parser = createParser("termite", { 4 | group: 'colors', 5 | wrap: true 6 | }); 7 | -------------------------------------------------------------------------------- /src/parsers/tilda.test.js: -------------------------------------------------------------------------------- 1 | const { tilda } = require("./tilda"); 2 | const matchers = require("../matchers"); 3 | const { fixture } = require("../helpers"); 4 | 5 | expect.extend(matchers); 6 | 7 | test("exports a function", () => { 8 | expect(tilda).isFunction(); 9 | }); 10 | 11 | test("throws for empty input", () => { 12 | expect(() => tilda()).toThrow(/tilda: input must be non-empty string/); 13 | }); 14 | 15 | test("throws for empty string", () => { 16 | expect(() => tilda("")).toThrow(/tilda: input must be non-empty string/); 17 | }); 18 | 19 | test("throws for whitespace only input", () => { 20 | expect(() => tilda(" ")).toThrow(/tilda: input must be non-empty string/); 21 | }); 22 | 23 | test("throws for empty input", async () => { 24 | const empty = await fixture("tilda/empty.config_0"); 25 | expect(() => tilda(empty)).toThrow(/tilda: input must be non-empty config/); 26 | }); 27 | 28 | test("throws for incomplete input", async () => { 29 | const empty = await fixture("tilda/incomplete.config_0"); 30 | expect(() => tilda(empty)).toThrow(/tilda: missing back_green/); 31 | }); 32 | 33 | test("throws for malformed value", async () => { 34 | const empty = await fixture("tilda/malformed-values.config_0"); 35 | expect(() => tilda(empty)).toThrow(/"back_blue" must be castable to number, received "malformed"/); 36 | }); 37 | 38 | test("throws for malformed palette", async () => { 39 | const empty = await fixture("tilda/malformed-palette.config_0"); 40 | expect(() => tilda(empty)).toThrow(/Expected first char in palette to be {, received 0/); 41 | }); 42 | 43 | test("throws for incomplete palette", async () => { 44 | const empty = await fixture("tilda/incomplete-palette.config_0"); 45 | expect(() => tilda(empty)).toThrow(/Expected palette to be comma separated list of 48 numbers, received 47/); 46 | }); 47 | 48 | test("throws for malformed palette", async () => { 49 | const empty = await fixture("tilda/malformed-palette-item.config_0"); 50 | expect(() => tilda(empty)).toThrow(/tilda: palette item "0" must be castable to number, received "malformed"/); 51 | }); 52 | 53 | test("returns expected result for Seti", async () => { 54 | const data = await fixture("tilda/Seti.config_0"); 55 | expect(tilda(data)).toEqual({ 56 | '0': [ 0, 0, 0 ], 57 | '1': [ 253, 95, 241 ], 58 | '2': [ 135, 195, 138 ], 59 | '3': [ 256, 215, 177 ], 60 | '4': [ 133, 190, 254 ], 61 | '5': [ 186, 182, 253 ], 62 | '6': [ 133, 190, 254 ], 63 | '7': [ 224, 224, 224 ], 64 | '8': [ 0, 0, 0 ], 65 | '9': [ 253, 95, 241 ], 66 | '10': [ 148, 250, 54 ], 67 | '11': [ 246, 256, 168 ], 68 | '12': [ 150, 203, 254 ], 69 | '13': [ 186, 182, 253 ], 70 | '14': [ 133, 190, 254 ], 71 | '15': [ 224, 224, 224 ], 72 | background: [ 22, 23, 25 ], 73 | bold: [ 197, 200, 198 ], 74 | cursor: [ 208, 208, 208 ], 75 | text: [ 197, 200, 198 ] 76 | }); 77 | }); 78 | 79 | test("returns expected result for Atom", async () => { 80 | const data = await fixture("tilda/Atom.config_0"); 81 | expect(tilda(data)).toEqual({ '0': [ 50, 50, 50 ], 82 | '1': [ 194, 40, 50 ], 83 | '2': [ 142, 196, 61 ], 84 | '3': [ 224, 198, 79 ], 85 | '4': [ 67, 165, 213 ], 86 | '5': [ 139, 87, 181 ], 87 | '6': [ 142, 196, 61 ], 88 | '7': [ 238, 238, 238 ], 89 | '8': [ 50, 50, 50 ], 90 | '9': [ 194, 40, 50 ], 91 | '10': [ 142, 196, 61 ], 92 | '11': [ 224, 198, 79 ], 93 | '12': [ 67, 165, 213 ], 94 | '13': [ 139, 87, 181 ], 95 | '14': [ 142, 196, 61 ], 96 | '15': [ 256, 256, 256 ], 97 | background: [ 17, 18, 19 ], 98 | bold: [ 202, 206, 205 ], 99 | cursor: [ 227, 191, 33 ], 100 | text: [ 202, 206, 205 ] 101 | }); 102 | }); 103 | -------------------------------------------------------------------------------- /src/parsers/tilda.ts: -------------------------------------------------------------------------------- 1 | import is from "@marionebl/is"; 2 | import { decode } from "ini"; 3 | import { TermScheme, TermSchemeColor } from "./term-scheme"; 4 | 5 | const AggregateError = require("aggregate-error"); 6 | 7 | interface TildaScheme { 8 | back: TermSchemeColor; 9 | text: TermSchemeColor; 10 | cursor: TermSchemeColor; 11 | 0: TermSchemeColor; 12 | 1: TermSchemeColor; 13 | 2: TermSchemeColor; 14 | 3: TermSchemeColor; 15 | 4: TermSchemeColor; 16 | 5: TermSchemeColor; 17 | 6: TermSchemeColor; 18 | 7: TermSchemeColor; 19 | 8: TermSchemeColor; 20 | 9: TermSchemeColor; 21 | 10: TermSchemeColor; 22 | 11: TermSchemeColor; 23 | 12: TermSchemeColor; 24 | 13: TermSchemeColor; 25 | 14: TermSchemeColor; 26 | 15: TermSchemeColor; 27 | } 28 | 29 | const TILDA_KEYS = [ 30 | 'back_red', 31 | 'back_green', 32 | 'back_blue', 33 | 'cursor_red', 34 | 'cursor_green', 35 | 'cursor_blue', 36 | 'text_red', 37 | 'text_green', 38 | 'text_blue' 39 | ]; 40 | 41 | export function tilda(raw: any): TermScheme { 42 | if (!is.string(raw) || is.emptyOrWhitespace(raw)) { 43 | throw new TypeError(`tilda: input must be non-empty string`); 44 | } 45 | 46 | const data = decode(raw); 47 | 48 | const [error, n] = normalize(data); 49 | 50 | if (error) { 51 | throw error; 52 | } 53 | 54 | return { 55 | background: n.back, 56 | bold: n.text, 57 | cursor: n.cursor, 58 | text: n.text, 59 | 0: n[0], 60 | 1: n[1], 61 | 2: n[2], 62 | 3: n[3], 63 | 4: n[4], 64 | 5: n[5], 65 | 6: n[6], 66 | 7: n[7], 67 | 8: n[8], 68 | 9: n[9], 69 | 10: n[10], 70 | 11: n[11], 71 | 12: n[12], 72 | 13: n[13], 73 | 14: n[14], 74 | 15: n[15] 75 | }; 76 | } 77 | 78 | function normalize(data: any): [Error, null] | [null, TildaScheme] { 79 | if (is.empty(data)) { 80 | return [new TypeError(`tilda: input must be non-empty config`), null]; 81 | } 82 | 83 | const errors: Error[] = []; 84 | 85 | const faulty = TILDA_KEYS 86 | .map(key => { 87 | if (!(key in data)) { 88 | return new TypeError(`tilda: missing ${key}`); 89 | } 90 | 91 | const val = data[key]; 92 | 93 | if (!is.string(val)) { 94 | return new TypeError(`tilda: "${key}" must be string, received "${typeof val}"`); 95 | } 96 | 97 | const num = Number(val); 98 | 99 | if (is.nan(num)) { 100 | return new TypeError(`tilda: "${key}" must be castable to number, received "${val}"`); 101 | } 102 | }) 103 | .filter(Boolean); 104 | 105 | if (!('palette' in data)) { 106 | errors.push(new TypeError(`tilda: missing palette`)); 107 | } 108 | 109 | errors.push(...faulty); 110 | 111 | const {palette: rp} = data; 112 | const leading = rp.charAt(0) === '{'; 113 | const trailing = rp.charAt(rp.length - 1) === '}'; 114 | const valid = leading && trailing; 115 | 116 | if (!leading) { 117 | errors.push(new TypeError(`Expected first char in palette to be {, received ${rp.charAt(0)}`)); 118 | } 119 | 120 | if (!trailing) { 121 | errors.push(new TypeError(`Expected first char in palette to be }, received ${rp.charAt(rp.length - 1)}`)); 122 | } 123 | 124 | const palette = data.palette 125 | .replace(/^{/, '') 126 | .replace(/}$/, '') 127 | .split(',') 128 | .map((item: string) => item.trim()); 129 | 130 | if (palette.length !== 48) { 131 | errors.push(new TypeError(`Expected palette to be comma separated list of 48 numbers, received ${palette.length}`)); 132 | } 133 | 134 | const paletteErrors = palette 135 | .map((c: number, i: number) => { 136 | const num = Number(c); 137 | 138 | if (is.nan(num)) { 139 | return new TypeError(`tilda: palette item "${i}" must be castable to number, received "${c}"`); 140 | } 141 | }) 142 | .filter(Boolean); 143 | 144 | const colors = palette.reduce((acc: TermSchemeColor[], component: string, i: number) => { 145 | const j = Math.floor(i / 3); 146 | const k = Math.floor(i % 3); 147 | const ready = Array.isArray(acc[j]); 148 | 149 | const color: any = ready ? acc[j] : []; 150 | color[k] = comp(component); 151 | 152 | if (!ready) { 153 | acc.push(color); 154 | } 155 | 156 | return acc; 157 | }, []); 158 | 159 | errors.push(...paletteErrors); 160 | 161 | if (errors.length > 0) { 162 | return [new AggregateError(errors), null]; 163 | } 164 | 165 | const back: TermSchemeColor = [comp(data.back_red), comp(data.back_green), comp(data.back_blue)]; 166 | const text: TermSchemeColor = [comp(data.text_red), comp(data.text_green), comp(data.text_blue)]; 167 | const cursor: TermSchemeColor = [comp(data.cursor_red), comp(data.cursor_green), comp(data.cursor_blue)]; 168 | 169 | return [ 170 | null, 171 | { 172 | back: back, 173 | cursor: cursor, 174 | text: text, 175 | 0: colors[0], 176 | 1: colors[1], 177 | 2: colors[2], 178 | 3: colors[3], 179 | 4: colors[4], 180 | 5: colors[5], 181 | 6: colors[6], 182 | 7: colors[7], 183 | 8: colors[8], 184 | 9: colors[9], 185 | 10: colors[10], 186 | 11: colors[11], 187 | 12: colors[12], 188 | 13: colors[13], 189 | 14: colors[14], 190 | 15: colors[15] 191 | } 192 | ]; 193 | } 194 | 195 | function comp(input: string): number { 196 | return Math.round((Number(input) / 0xFFFF) * 255); 197 | } 198 | -------------------------------------------------------------------------------- /src/parsers/xfce.test.js: -------------------------------------------------------------------------------- 1 | const { xfce } = require("./xfce"); 2 | const matchers = require("../matchers"); 3 | const { atom, fixture, seti } = require("../helpers"); 4 | 5 | expect.extend(matchers); 6 | 7 | test("exports a function", () => { 8 | expect(xfce).isFunction(); 9 | }); 10 | 11 | test("throws for empty input", () => { 12 | expect(() => xfce()).toThrow(/xfce: input must be non-empty string/); 13 | }); 14 | 15 | test("throws for empty string", () => { 16 | expect(() => xfce("")).toThrow(/xfce: input must be non-empty string/); 17 | }); 18 | 19 | test("throws for whitespace only input", () => { 20 | expect(() => xfce(" ")).toThrow(/xfce: input must be non-empty string/); 21 | }); 22 | 23 | test("throws for empty input", async () => { 24 | const empty = await fixture("xfce/empty.theme"); 25 | expect(() => xfce(empty)).toThrow(/xfce: input must be non-empty config/); 26 | }); 27 | 28 | test("throws for incomplete input", async () => { 29 | const incomplete = await fixture("xfce/incomplete.theme"); 30 | expect(() => xfce(incomplete)).toThrow(/xfce: missing ColorBackground/); 31 | }); 32 | 33 | test("throws for malformed input values", async () => { 34 | const m = await fixture("xfce/malformed-values.theme"); 35 | expect(() => xfce(m)).toThrow(/xfce: expected "ColorForeground" to be hex color, received "malformed"/); 36 | }); 37 | 38 | test("throws for incomplete palette", async () => { 39 | const m = await fixture("xfce/incomplete-palette.theme"); 40 | expect(() => xfce(m)).toThrow(/xcfe: expected "ColorPalette" to be list of 16 hex colors separated by ";", received 15/); 41 | }); 42 | 43 | test("throws for malformed palette", async () => { 44 | const m = await fixture("xfce/malformed-palette.theme"); 45 | expect(() => xfce(m)).toThrow(/xcfe: "ColorPalette" item "0" must be hex color, received "#323232:#323232"/); 46 | }); 47 | 48 | test("returns expected result for Seti", async () => { 49 | const data = await fixture("xfce/Seti.theme"); 50 | expect(xfce(data)).toEqual(seti); 51 | }); 52 | 53 | test("returns expected result for Atom", async () => { 54 | const data = await fixture("xfce/Atom.theme"); 55 | expect(xfce(data)).toEqual(atom); 56 | }); 57 | -------------------------------------------------------------------------------- /src/parsers/xfce.ts: -------------------------------------------------------------------------------- 1 | import is from "@marionebl/is"; 2 | import { decode } from "ini"; 3 | import { partition } from "lodash"; 4 | import { TermScheme, TermSchemeColor } from "./term-scheme"; 5 | 6 | const AggregateError = require("aggregate-error"); 7 | const hexRgb = require("hex-rgb"); 8 | 9 | interface XfceScheme { 10 | 0: TermSchemeColor; 11 | 1: TermSchemeColor; 12 | 2: TermSchemeColor; 13 | 3: TermSchemeColor; 14 | 4: TermSchemeColor; 15 | 5: TermSchemeColor; 16 | 6: TermSchemeColor; 17 | 7: TermSchemeColor; 18 | 8: TermSchemeColor; 19 | 9: TermSchemeColor; 20 | 10: TermSchemeColor; 21 | 11: TermSchemeColor; 22 | 12: TermSchemeColor; 23 | 13: TermSchemeColor; 24 | 14: TermSchemeColor; 25 | 15: TermSchemeColor; 26 | ColorBackground: TermSchemeColor; 27 | ColorForeground: TermSchemeColor; 28 | ColorCursor: TermSchemeColor; 29 | } 30 | 31 | const XCFE_KEYS = [ 32 | 'ColorForeground', 33 | 'ColorBackground', 34 | 'ColorCursor' 35 | ]; 36 | 37 | const EXACT_HEX_MATCH = /^#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/; 38 | const HEX_MATCH = /=(?: ?)(#(:?.*))/g; 39 | 40 | export function xfce(raw: any): TermScheme { 41 | if (!is.string(raw) || is.emptyOrWhitespace(raw)) { 42 | throw new TypeError(`xfce: input must be non-empty string`); 43 | } 44 | 45 | const input = raw.replace(HEX_MATCH, '="$1"'); 46 | const data = decode(input); 47 | 48 | const [error, n] = normalize(data); 49 | 50 | if (error) { 51 | throw error; 52 | } 53 | 54 | return { 55 | background: n.ColorBackground, 56 | bold: n.ColorForeground, 57 | cursor: n.ColorCursor, 58 | text: n.ColorForeground, 59 | 0: n[0], 60 | 1: n[1], 61 | 2: n[2], 62 | 3: n[3], 63 | 4: n[4], 64 | 5: n[5], 65 | 6: n[6], 66 | 7: n[7], 67 | 8: n[8], 68 | 9: n[9], 69 | 10: n[10], 70 | 11: n[11], 71 | 12: n[12], 72 | 13: n[13], 73 | 14: n[14], 74 | 15: n[15] 75 | }; 76 | } 77 | 78 | function normalize(raw: any): [Error, null] | [null, XfceScheme] { 79 | const data = raw.Scheme; 80 | 81 | if (is.empty(data)) { 82 | return [new TypeError(`xfce: input must be non-empty config`), null]; 83 | } 84 | 85 | const errors = XCFE_KEYS 86 | .map(key => { 87 | if (!(key in data)) { 88 | return new TypeError(`xfce: missing ${key}`); 89 | } 90 | 91 | const val = data[key]; 92 | 93 | if (!is.string(val)) { 94 | return new TypeError(`xfce: "${key}" must be string, received "${typeof val}"`); 95 | } 96 | 97 | if (!val.match(EXACT_HEX_MATCH)) { 98 | return new TypeError(`xfce: expected "${key}" to be hex color, received "${val}"`); 99 | } 100 | }) 101 | .filter(Boolean); 102 | 103 | if (!('ColorPalette' in data)) { 104 | errors.push(new TypeError(`xfce: missing "ColorPalette"`)); 105 | } 106 | 107 | const palette = (data.ColorPalette || '').split(';'); 108 | 109 | if (palette.length !== 16) { 110 | errors.push(new TypeError(`xcfe: expected "ColorPalette" to be list of 16 hex colors separated by ";", received ${palette.length}`)); 111 | } 112 | 113 | const items = palette 114 | .map((item: string, i: number) => { 115 | if (!item.match(EXACT_HEX_MATCH)) { 116 | return new TypeError(`xcfe: "ColorPalette" item "${i}" must be hex color, received "${item}"`); 117 | } 118 | return hexRgb(item); 119 | }) 120 | 121 | const [err, colors] = partition(items, (i: any) => is.error(i)); 122 | 123 | errors.push(...err); 124 | 125 | if (errors.length > 0) { 126 | return [new AggregateError(errors), null]; 127 | } 128 | 129 | return [ 130 | null, 131 | { 132 | 0: colors[0], 133 | 1: colors[1], 134 | 2: colors[2], 135 | 3: colors[3], 136 | 4: colors[4], 137 | 5: colors[5], 138 | 6: colors[6], 139 | 7: colors[7], 140 | 8: colors[8], 141 | 9: colors[9], 142 | 10: colors[10], 143 | 11: colors[11], 144 | 12: colors[12], 145 | 13: colors[13], 146 | 14: colors[14], 147 | 15: colors[15], 148 | ColorForeground: hexRgb(data.ColorForeground), 149 | ColorBackground: hexRgb(data.ColorBackground), 150 | ColorCursor: hexRgb(data.ColorCursor) 151 | } 152 | ]; 153 | } 154 | -------------------------------------------------------------------------------- /src/parsers/xresources.test.js: -------------------------------------------------------------------------------- 1 | const { xresources } = require("./xresources"); 2 | const matchers = require("../matchers"); 3 | const { atom, fixture, seti } = require("../helpers"); 4 | 5 | expect.extend(matchers); 6 | 7 | test("exports a function", () => { 8 | expect(xresources).isFunction(); 9 | }); 10 | 11 | test("throws for empty input", () => { 12 | expect(() => xresources()).toThrow(/xresources: input must be non-empty string/); 13 | }); 14 | 15 | test("throws for empty string", () => { 16 | expect(() => xresources("")).toThrow(/xresources: input must be non-empty string/); 17 | }); 18 | 19 | test("throws for whitespace only input", () => { 20 | expect(() => xresources(" ")).toThrow(/xresources: input must be non-empty string/); 21 | }); 22 | 23 | test("throws for empty input", async () => { 24 | const empty = await fixture("xresources/empty"); 25 | expect(() => xresources(empty)).toThrow(/xresources: input must be non-empty config/); 26 | }); 27 | 28 | test("throws for incomplete input", async () => { 29 | const incomplete = await fixture("xresources/incomplete"); 30 | expect(() => xresources(incomplete)).toThrow(/xresources: missing "foreground"/); 31 | }); 32 | 33 | test.only("throws for malformed values", async () => { 34 | const incomplete = await fixture("xresources/malformed-values"); 35 | expect(() => xresources(incomplete)).toThrow(/xresources: expected "foreground" to be hex color, received "malformed_value"/); 36 | }); 37 | 38 | test("returns expected result for Seti", async () => { 39 | const data = await fixture("xresources/Seti"); 40 | expect(xresources(data)).toEqual(seti); 41 | }); 42 | 43 | test("returns expected result for Atom", async () => { 44 | const data = await fixture("xresources/Atom"); 45 | expect(xresources(data)).toEqual(atom); 46 | }); 47 | -------------------------------------------------------------------------------- /src/parsers/xresources.ts: -------------------------------------------------------------------------------- 1 | import is from "@marionebl/is"; 2 | import { decode } from "ini"; 3 | import { partition } from "lodash"; 4 | import { TermScheme, TermSchemeColor } from "./term-scheme"; 5 | 6 | const AggregateError = require("aggregate-error"); 7 | const hexRgb = require("hex-rgb"); 8 | 9 | interface XResourcesScheme { 10 | background: TermSchemeColor; 11 | colorBD: TermSchemeColor; 12 | cursorColor: TermSchemeColor; 13 | foreground: TermSchemeColor; 14 | color0: TermSchemeColor; 15 | color1: TermSchemeColor; 16 | color2: TermSchemeColor; 17 | color3: TermSchemeColor; 18 | color4: TermSchemeColor; 19 | color5: TermSchemeColor; 20 | color6: TermSchemeColor; 21 | color7: TermSchemeColor; 22 | color8: TermSchemeColor; 23 | color9: TermSchemeColor; 24 | color10: TermSchemeColor; 25 | color11: TermSchemeColor; 26 | color12: TermSchemeColor; 27 | color13: TermSchemeColor; 28 | color14: TermSchemeColor; 29 | color15: TermSchemeColor; 30 | } 31 | 32 | const XRESOURCES_KEY = [ 33 | "background", 34 | "colorBD", 35 | "cursorColor", 36 | "foreground", 37 | "color0", 38 | "color1", 39 | "color2", 40 | "color3", 41 | "color4", 42 | "color5", 43 | "color6", 44 | "color7", 45 | "color8", 46 | "color9", 47 | "color10", 48 | "color11", 49 | "color12", 50 | "color13", 51 | "color14", 52 | "color15", 53 | ]; 54 | 55 | const EXACT_HEX_MATCH = /^#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/; 56 | const LINE_MATCH = /(?:\r\n|\r|\n)/g; 57 | 58 | export function xresources(raw: any): TermScheme { 59 | if (!is.string(raw) || is.emptyOrWhitespace(raw)) { 60 | throw new TypeError(`xresources: input must be non-empty string`); 61 | } 62 | 63 | const data = parse(raw); 64 | const [error, n] = normalize(data); 65 | 66 | if (error) { 67 | throw error; 68 | } 69 | 70 | return { 71 | 0: n.color0, 72 | 1: n.color1, 73 | 2: n.color2, 74 | 3: n.color3, 75 | 4: n.color4, 76 | 5: n.color5, 77 | 6: n.color6, 78 | 7: n.color7, 79 | 8: n.color8, 80 | 9: n.color9, 81 | 10: n.color10, 82 | 11: n.color11, 83 | 12: n.color12, 84 | 13: n.color13, 85 | 14: n.color14, 86 | 15: n.color15, 87 | background: n.background, 88 | bold: n.colorBD, 89 | cursor: n.cursorColor, 90 | text: n.foreground, 91 | }; 92 | } 93 | 94 | function parse(raw: any): {[key: string]: string} { 95 | if (!is.string(raw)) { 96 | return {}; 97 | } 98 | 99 | const lines = raw 100 | .split(LINE_MATCH) 101 | .filter(Boolean) 102 | .filter((line: string) => line.charAt(0) !== '!'); 103 | 104 | return lines.reduce((acc: {[key: string]: string}, line: string) => { 105 | const segments = line 106 | .split(':') 107 | .filter(Boolean) 108 | .map((s: string) => s.trim()); 109 | 110 | if (segments.length !== 2) { 111 | return acc; 112 | } 113 | 114 | const [rawKey, value] = segments; 115 | const keySegments = rawKey.split('.'); 116 | const key = keySegments[keySegments.length - 1]; 117 | 118 | acc[key] = value; 119 | return acc; 120 | }, {}); 121 | } 122 | 123 | function normalize(data: any): [Error, null] | [null, XResourcesScheme] { 124 | if (is.empty(data)) { 125 | return [new TypeError(`xresources: input must be non-empty config`), null]; 126 | } 127 | 128 | const errors = XRESOURCES_KEY 129 | .map(key => { 130 | if (!(key in data)) { 131 | return new TypeError(`xresources: missing "${key}"`); 132 | } 133 | 134 | const val = data[key]; 135 | 136 | if (!is.string(val)) { 137 | return new TypeError(`xresources: "${key}" must be string, received "${typeof val}"`); 138 | } 139 | 140 | if (!val.match(EXACT_HEX_MATCH)) { 141 | return new TypeError(`xresources: expected "${key}" to be hex color, received "${val}"`); 142 | } 143 | }) 144 | .filter(Boolean); 145 | 146 | if (errors.length > 0) { 147 | return [new AggregateError(errors), null]; 148 | } 149 | 150 | return [ 151 | null, 152 | { 153 | background: hexRgb(data.background), 154 | colorBD: hexRgb(data.colorBD), 155 | cursorColor: hexRgb(data.cursorColor), 156 | foreground: hexRgb(data.foreground), 157 | color0: hexRgb(data.color0), 158 | color1: hexRgb(data.color1), 159 | color2: hexRgb(data.color2), 160 | color3: hexRgb(data.color3), 161 | color4: hexRgb(data.color4), 162 | color5: hexRgb(data.color5), 163 | color6: hexRgb(data.color6), 164 | color7: hexRgb(data.color7), 165 | color8: hexRgb(data.color8), 166 | color9: hexRgb(data.color9), 167 | color10: hexRgb(data.color10), 168 | color11: hexRgb(data.color11), 169 | color12: hexRgb(data.color12), 170 | color13: hexRgb(data.color13), 171 | color14: hexRgb(data.color14), 172 | color15: hexRgb(data.color15), 173 | }, 174 | ]; 175 | } 176 | -------------------------------------------------------------------------------- /src/parsers/xterm.test.js: -------------------------------------------------------------------------------- 1 | const { xterm } = require("./xterm"); 2 | const matchers = require("../matchers"); 3 | const { atom, fixture, seti } = require("../helpers"); 4 | 5 | expect.extend(matchers); 6 | 7 | test("exports a function", () => { 8 | expect(xterm).isFunction(); 9 | }); 10 | 11 | test("throws for empty input", () => { 12 | expect(() => xterm()).toThrow(/xterm: input must be non-empty string/); 13 | }); 14 | 15 | test("throws for empty string", () => { 16 | expect(() => xterm("")).toThrow(/xterm: input must be non-empty string/); 17 | }); 18 | 19 | test("throws for whitespace only input", () => { 20 | expect(() => xterm(" ")).toThrow(/xterm: input must be non-empty string/); 21 | }); 22 | 23 | test("throws for empty input", async () => { 24 | const empty = await fixture("xterm/empty.xrdb"); 25 | expect(() => xterm(empty)).toThrow(/xterm: input must be non-empty config/); 26 | }); 27 | 28 | test("throws for incomplete input", async () => { 29 | const incomplete = await fixture("xterm/incomplete.xrdb"); 30 | expect(() => xterm(incomplete)).toThrow(/xterm: missing "Ansi_0_Color"/); 31 | }); 32 | 33 | test("throws for malformed values", async () => { 34 | const incomplete = await fixture("xterm/malformed-values.xrdb"); 35 | expect(() => xterm(incomplete)).toThrow(/xterm: expected "Ansi_0_Color" to be hex color, received "this_is_malformed"/); 36 | }); 37 | 38 | test("returns expected result for Seti", async () => { 39 | const data = await fixture("xterm/Seti.xrdb"); 40 | expect(xterm(data)).toEqual(seti); 41 | }); 42 | 43 | test("returns expected result for Atom", async () => { 44 | const data = await fixture("xterm/Atom.xrdb"); 45 | expect(xterm(data)).toEqual(atom); 46 | }); 47 | -------------------------------------------------------------------------------- /src/parsers/xterm.ts: -------------------------------------------------------------------------------- 1 | import is from "@marionebl/is"; 2 | import { decode } from "ini"; 3 | import { partition } from "lodash"; 4 | import { TermScheme, TermSchemeColor } from "./term-scheme"; 5 | 6 | const AggregateError = require("aggregate-error"); 7 | const hexRgb = require("hex-rgb"); 8 | 9 | interface XTermScheme { 10 | Ansi_0_Color: TermSchemeColor; 11 | Ansi_1_Color: TermSchemeColor; 12 | Ansi_2_Color: TermSchemeColor; 13 | Ansi_3_Color: TermSchemeColor; 14 | Ansi_4_Color: TermSchemeColor; 15 | Ansi_5_Color: TermSchemeColor; 16 | Ansi_6_Color: TermSchemeColor; 17 | Ansi_7_Color: TermSchemeColor; 18 | Ansi_8_Color: TermSchemeColor; 19 | Ansi_9_Color: TermSchemeColor; 20 | Ansi_10_Color: TermSchemeColor; 21 | Ansi_11_Color: TermSchemeColor; 22 | Ansi_12_Color: TermSchemeColor; 23 | Ansi_13_Color: TermSchemeColor; 24 | Ansi_14_Color: TermSchemeColor; 25 | Ansi_15_Color: TermSchemeColor; 26 | Background_Color: TermSchemeColor; 27 | Bold_Color: TermSchemeColor; 28 | Cursor_Color: TermSchemeColor; 29 | Foreground_Color: TermSchemeColor; 30 | } 31 | 32 | const XTERM_KEYS = [ 33 | "Ansi_0_Color", 34 | "Ansi_1_Color", 35 | "Ansi_2_Color", 36 | "Ansi_3_Color", 37 | "Ansi_4_Color", 38 | "Ansi_5_Color", 39 | "Ansi_6_Color", 40 | "Ansi_7_Color", 41 | "Ansi_8_Color", 42 | "Ansi_9_Color", 43 | "Ansi_10_Color", 44 | "Ansi_11_Color", 45 | "Ansi_12_Color", 46 | "Ansi_13_Color", 47 | "Ansi_14_Color", 48 | "Ansi_15_Color", 49 | "Background_Color", 50 | "Bold_Color", 51 | "Cursor_Color", 52 | "Foreground_Color", 53 | ]; 54 | 55 | const EXACT_HEX_MATCH = /^#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/; 56 | const LINE_MATCH = /(?:\r\n|\r|\n)/g; 57 | 58 | export function xterm(raw: any): TermScheme { 59 | if (!is.string(raw) || is.emptyOrWhitespace(raw)) { 60 | throw new TypeError(`xterm: input must be non-empty string`); 61 | } 62 | 63 | const data = parse(raw); 64 | const [error, n] = normalize(data); 65 | 66 | if (error) { 67 | throw error; 68 | } 69 | 70 | return { 71 | 0: n.Ansi_0_Color, 72 | 1: n.Ansi_1_Color, 73 | 2: n.Ansi_2_Color, 74 | 3: n.Ansi_3_Color, 75 | 4: n.Ansi_4_Color, 76 | 5: n.Ansi_5_Color, 77 | 6: n.Ansi_6_Color, 78 | 7: n.Ansi_7_Color, 79 | 8: n.Ansi_8_Color, 80 | 9: n.Ansi_9_Color, 81 | 10: n.Ansi_10_Color, 82 | 11: n.Ansi_11_Color, 83 | 12: n.Ansi_12_Color, 84 | 13: n.Ansi_13_Color, 85 | 14: n.Ansi_14_Color, 86 | 15: n.Ansi_15_Color, 87 | background: n.Background_Color, 88 | bold: n.Bold_Color, 89 | cursor: n.Cursor_Color, 90 | text: n.Foreground_Color 91 | }; 92 | } 93 | 94 | function parse(raw: any): {[key: string]: string} { 95 | if (!is.string(raw)) { 96 | return {}; 97 | } 98 | 99 | const lines = raw 100 | .split(LINE_MATCH) 101 | .filter(Boolean) 102 | .filter((line: string) => line.charAt(0) !== '!'); 103 | 104 | return lines.reduce((acc: {[key: string]: string}, line: string) => { 105 | const segments = line.split(' ').filter(Boolean); 106 | 107 | if (segments.length !== 3) { 108 | return acc; 109 | } 110 | 111 | const [stanza, key, value] = segments; 112 | 113 | if (stanza !== '#define') { 114 | return acc; 115 | } 116 | 117 | acc[key] = value; 118 | return acc; 119 | }, {}); 120 | } 121 | 122 | function normalize(data: any): [Error, null] | [null, XTermScheme] { 123 | if (is.empty(data)) { 124 | return [new TypeError(`xterm: input must be non-empty config`), null]; 125 | } 126 | 127 | const errors = XTERM_KEYS 128 | .map(key => { 129 | if (!(key in data)) { 130 | return new TypeError(`xterm: missing "${key}"`); 131 | } 132 | 133 | const val = data[key]; 134 | 135 | if (!is.string(val)) { 136 | return new TypeError(`xterm: "${key}" must be string, received "${typeof val}"`); 137 | } 138 | 139 | if (!val.match(EXACT_HEX_MATCH)) { 140 | return new TypeError(`xterm: expected "${key}" to be hex color, received "${val}"`); 141 | } 142 | }) 143 | .filter(Boolean); 144 | 145 | if (errors.length > 0) { 146 | return [new AggregateError(errors), null]; 147 | } 148 | 149 | return [ 150 | null, 151 | { 152 | Ansi_0_Color: hexRgb(data.Ansi_0_Color), 153 | Ansi_1_Color: hexRgb(data.Ansi_1_Color), 154 | Ansi_2_Color: hexRgb(data.Ansi_2_Color), 155 | Ansi_3_Color: hexRgb(data.Ansi_3_Color), 156 | Ansi_4_Color: hexRgb(data.Ansi_4_Color), 157 | Ansi_5_Color: hexRgb(data.Ansi_5_Color), 158 | Ansi_6_Color: hexRgb(data.Ansi_6_Color), 159 | Ansi_7_Color: hexRgb(data.Ansi_7_Color), 160 | Ansi_8_Color: hexRgb(data.Ansi_8_Color), 161 | Ansi_9_Color: hexRgb(data.Ansi_9_Color), 162 | Ansi_10_Color: hexRgb(data.Ansi_10_Color), 163 | Ansi_11_Color: hexRgb(data.Ansi_11_Color), 164 | Ansi_12_Color: hexRgb(data.Ansi_12_Color), 165 | Ansi_13_Color: hexRgb(data.Ansi_13_Color), 166 | Ansi_14_Color: hexRgb(data.Ansi_14_Color), 167 | Ansi_15_Color: hexRgb(data.Ansi_15_Color), 168 | Background_Color: hexRgb(data.Background_Color), 169 | Bold_Color: hexRgb(data.Bold_Color), 170 | Cursor_Color: hexRgb(data.Cursor_Color), 171 | Foreground_Color: hexRgb(data.Foreground_Color) 172 | }, 173 | ]; 174 | } 175 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "module": "commonjs", 5 | "noImplicitAny": true, 6 | "pretty": true, 7 | "target": "es2015", 8 | "outDir": "lib/", 9 | "lib": ["es2015"] 10 | } 11 | } 12 | --------------------------------------------------------------------------------