diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-22 17:35:49 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-22 17:35:49 -0600 |
| commit | 20ef0d92694465ac86b550df139e8366a0a2b4fa (patch) | |
| tree | 3f14589e1ce6eb9306a3af31c3a1f9e1af5ed637 /vendor/github.com/gookit | |
| parent | 44e0d272c040cdc53a98b9f1dc58ae7da67752e6 (diff) | |
feat: connect to spicedb
Diffstat (limited to 'vendor/github.com/gookit')
20 files changed, 5647 insertions, 0 deletions
diff --git a/vendor/github.com/gookit/color/.gitignore b/vendor/github.com/gookit/color/.gitignore new file mode 100644 index 0000000..5efa5e3 --- /dev/null +++ b/vendor/github.com/gookit/color/.gitignore @@ -0,0 +1,20 @@ +*.log +*.swp +.idea +*.patch +### Go template +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out +.DS_Store +app +demo diff --git a/vendor/github.com/gookit/color/.nojekyll b/vendor/github.com/gookit/color/.nojekyll new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vendor/github.com/gookit/color/.nojekyll diff --git a/vendor/github.com/gookit/color/LICENSE b/vendor/github.com/gookit/color/LICENSE new file mode 100644 index 0000000..d839cdc --- /dev/null +++ b/vendor/github.com/gookit/color/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2016 inhere + +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: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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.
\ No newline at end of file diff --git a/vendor/github.com/gookit/color/README.md b/vendor/github.com/gookit/color/README.md new file mode 100644 index 0000000..77d50ca --- /dev/null +++ b/vendor/github.com/gookit/color/README.md @@ -0,0 +1,580 @@ +# CLI Color + + +[](https://github.com/gookit/color/actions) +[](https://www.codacy.com/gh/gookit/color/dashboard?utm_source=github.com&utm_medium=referral&utm_content=gookit/color&utm_campaign=Badge_Grade) +[](https://pkg.go.dev/github.com/gookit/color?tab=overview) +[](https://github.com/gookit/color) +[](https://travis-ci.org/gookit/color) +[](https://coveralls.io/github/gookit/color?branch=master) +[](https://goreportcard.com/report/github.com/gookit/color) + +A command-line color library with 16/256/True color support, universal API methods and Windows support. + +> **[中文说明](README.zh-CN.md)** + +Basic color preview: + + + +Now, 256 colors and RGB colors have also been supported to work in Windows CMD and PowerShell: + + + +## Features + + - Simple to use, zero dependencies + - Supports rich color output: 16-color (4-bit), 256-color (8-bit), true color (24-bit, RGB) + - 16-color output is the most commonly used and most widely supported, working on any Windows version + - Since `v1.2.4` **the 256-color (8-bit), true color (24-bit) support windows CMD and PowerShell** + - See [this gist](https://gist.github.com/XVilka/8346728) for information on true color support + - Support converts `HEX` `HSL` value to RGB color + - Generic API methods: `Print`, `Printf`, `Println`, `Sprint`, `Sprintf` + - Supports HTML tag-style color rendering, such as `<green>message</> <fg=red;bg=blue>text</>`. + - In addition to using built-in tags, it also supports custom color attributes + - Custom color attributes support the use of 16 color names, 256 color values, rgb color values and hex color values + - Support working on Windows `cmd` and `powerShell` terminal + - Basic colors: `Bold`, `Black`, `White`, `Gray`, `Red`, `Green`, `Yellow`, `Blue`, `Magenta`, `Cyan` + - Additional styles: `Info`, `Note`, `Light`, `Error`, `Danger`, `Notice`, `Success`, `Comment`, `Primary`, `Warning`, `Question`, `Secondary` + - Support by set `NO_COLOR` for disable color or use `FORCE_COLOR` for force open color render. + - Support Rgb, 256, 16 color conversion + +## GoDoc + + - [godoc for gopkg](https://pkg.go.dev/gopkg.in/gookit/color.v1) + - [godoc for github](https://pkg.go.dev/github.com/gookit/color) + +## Install + +```bash +go get github.com/gookit/color +``` + +## Quick start + +```go +package main + +import ( + "fmt" + + "github.com/gookit/color" +) + +func main() { + // quick use package func + color.Redp("Simple to use color") + color.Redln("Simple to use color") + color.Greenp("Simple to use color\n") + color.Cyanln("Simple to use color") + color.Yellowln("Simple to use color") + + // quick use like fmt.Print* + color.Red.Println("Simple to use color") + color.Green.Print("Simple to use color\n") + color.Cyan.Printf("Simple to use %s\n", "color") + color.Yellow.Printf("Simple to use %s\n", "color") + + // use like func + red := color.FgRed.Render + green := color.FgGreen.Render + fmt.Printf("%s line %s library\n", red("Command"), green("color")) + + // custom color + color.New(color.FgWhite, color.BgBlack).Println("custom color style") + + // can also: + color.Style{color.FgCyan, color.OpBold}.Println("custom color style") + + // internal theme/style: + color.Info.Tips("message") + color.Info.Prompt("message") + color.Info.Println("message") + color.Warn.Println("message") + color.Error.Println("message") + + // use style tag + color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>\n") + // Custom label attr: Supports the use of 16 color names, 256 color values, rgb color values and hex color values + color.Println("<fg=11aa23>he</><bg=120,35,156>llo</>, <fg=167;bg=232>wel</><fg=red>come</>") + + // apply a style tag + color.Tag("info").Println("info style text") + + // prompt message + color.Info.Prompt("prompt style message") + color.Warn.Prompt("prompt style message") + + // tips message + color.Info.Tips("tips style message") + color.Warn.Tips("tips style message") +} +``` + +Run demo: `go run ./_examples/demo.go` + + + +## Basic/16 color + +Supported on any Windows version. Provide generic API methods: `Print`, `Printf`, `Println`, `Sprint`, `Sprintf` + +```go +color.Bold.Println("bold message") +color.Cyan.Println("yellow message") +color.Yellow.Println("yellow message") +color.Magenta.Println("yellow message") + +// Only use foreground color +color.FgCyan.Printf("Simple to use %s\n", "color") +// Only use background color +color.BgRed.Printf("Simple to use %s\n", "color") +``` + +Run demo: `go run ./_examples/color_16.go` + + + +### Custom build color + +```go +// Full custom: foreground, background, option +myStyle := color.New(color.FgWhite, color.BgBlack, color.OpBold) +myStyle.Println("custom color style") + +// can also: +color.Style{color.FgCyan, color.OpBold}.Println("custom color style") +``` + +custom set console settings: + +```go +// set console color +color.Set(color.FgCyan) + +// print message +fmt.Print("message") + +// reset console settings +color.Reset() +``` + +### Additional styles + +provide generic API methods: `Print`, `Printf`, `Println`, `Sprint`, `Sprintf` + +print message use defined style: + +```go +color.Info.Println("Info message") +color.Notice.Println("Notice message") +color.Error.Println("Error message") +// ... +``` + +Run demo: `go run ./_examples/theme_basic.go` + + + +**Tips style** + +```go +color.Info.Tips("Info tips message") +color.Notice.Tips("Notice tips message") +color.Error.Tips("Error tips message") +color.Secondary.Tips("Secondary tips message") +``` + +Run demo: `go run ./_examples/theme_tips.go` + + + +**Prompt Style** + +```go +color.Info.Prompt("Info prompt message") +color.Notice.Prompt("Notice prompt message") +color.Error.Prompt("Error prompt message") +// ... +``` + +Run demo: `go run ./_examples/theme_prompt.go` + + + +**Block Style** + +```go +color.Danger.Block("Danger block message") +color.Warn.Block("Warn block message") +// ... +``` + +Run demo: `go run ./_examples/theme_block.go` + + + +## 256-color usage + +> 256 colors support Windows CMD, PowerShell environment after `v1.2.4` + +### Set the foreground or background color + +- `color.C256(val uint8, isBg ...bool) Color256` + +```go +c := color.C256(132) // fg color +c.Println("message") +c.Printf("format %s", "message") + +c := color.C256(132, true) // bg color +c.Println("message") +c.Printf("format %s", "message") +``` + +### 256-color style + +Can be used to set foreground and background colors at the same time. + +- `S256(fgAndBg ...uint8) *Style256` + +```go +s := color.S256(32, 203) +s.Println("message") +s.Printf("format %s", "message") +``` + +with options: + +```go +s := color.S256(32, 203) +s.SetOpts(color.Opts{color.OpBold}) + +s.Println("style with options") +s.Printf("style with %s\n", "options") +``` + +Run demo: `go run ./_examples/color_256.go` + + + +## RGB/True color + +> RGB colors support Windows `CMD`, `PowerShell` environment after `v1.2.4` + +**Preview:** + +> Run demo: `Run demo: go run ./_examples/color_rgb.go` + + + +example: + +```go +color.RGB(30, 144, 255).Println("message. use RGB number") + +color.HEX("#1976D2").Println("blue-darken") +color.HEX("#D50000", true).Println("red-accent. use HEX style") + +color.RGBStyleFromString("213,0,0").Println("red-accent. use RGB number") +color.HEXStyle("eee", "D50000").Println("deep-purple color") +``` + +### Set the foreground or background color + +- `color.RGB(r, g, b uint8, isBg ...bool) RGBColor` + +```go +c := color.RGB(30,144,255) // fg color +c.Println("message") +c.Printf("format %s", "message") + +c := color.RGB(30,144,255, true) // bg color +c.Println("message") +c.Printf("format %s", "message") +``` + +Create a style from an hexadecimal color string: + +- `color.HEX(hex string, isBg ...bool) RGBColor` + +```go +c := color.HEX("ccc") // can also: "cccccc" "#cccccc" +c.Println("message") +c.Printf("format %s", "message") + +c = color.HEX("aabbcc", true) // as bg color +c.Println("message") +c.Printf("format %s", "message") +``` + +### RGB color style + +Can be used to set the foreground and background colors at the same time. + +- `color.NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle` + +```go +s := color.NewRGBStyle(RGB(20, 144, 234), RGB(234, 78, 23)) +s.Println("message") +s.Printf("format %s", "message") +``` + +Create a style from an hexadecimal color string: + +- `color.HEXStyle(fg string, bg ...string) *RGBStyle` + +```go +s := color.HEXStyle("11aa23", "eee") +s.Println("message") +s.Printf("format %s", "message") +``` + +with options: + +```go +s := color.HEXStyle("11aa23", "eee") +s.SetOpts(color.Opts{color.OpBold}) + +s.Println("style with options") +s.Printf("style with %s\n", "options") +``` + +## HTML-like tag usage + +`Print,Printf,Println` functions support auto parse and render color tags. + +```go + text := ` + <mga1>gookit/color:</> + A <green>command-line</> + <cyan>color library</> with <fg=167;bg=232>256-color</> + and <fg=11aa23;op=bold>True-color</> support, + <fg=mga;op=i>universal API</> methods + and <cyan>Windows</> support. +` + color.Print(text) +``` + +Preview, code please see [_examples/demo_tag.go](_examples/demo_tag.go): + + + +**Tag formats:** + +- Use built in tags: `<TAG_NAME>CONTENT</>` e.g: `<info>message</>` +- Custom tag attributes: `<fg=VALUE;bg=VALUE;op=VALUES>CONTENT</>` e.g: `<fg=167;bg=232>wel</>` + +> **Supported** on Windows `cmd.exe` `PowerShell`. + +Examples: + +```go +// use style tag +color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>") +color.Println("<suc>hello</>") +color.Println("<error>hello</>") +color.Println("<warning>hello</>") + +// custom color attributes +color.Print("<fg=yellow;bg=black;op=underscore;>hello, welcome</>\n") + +// Custom label attr: Supports the use of 16 color names, 256 color values, rgb color values and hex color values +color.Println("<fg=11aa23>he</><bg=120,35,156>llo</>, <fg=167;bg=232>wel</><fg=red>come</>") +``` + +### Tag attributes + +tag attributes format: + +```text +attr format: + // VALUE please see var: FgColors, BgColors, AllOptions + "fg=VALUE;bg=VALUE;op=VALUE" + +16 color: + "fg=yellow" + "bg=red" + "op=bold,underscore" // option is allow multi value + "fg=white;bg=blue;op=bold" + "fg=white;op=bold,underscore" + +256 color: + "fg=167" + "fg=167;bg=23" + "fg=167;bg=23;op=bold" + +True color: + // hex + "fg=fc1cac" + "fg=fc1cac;bg=c2c3c4" + // r,g,b + "fg=23,45,214" + "fg=23,45,214;bg=109,99,88" +``` + +> tag attributes parse please see `func ParseCodeFromAttr()` + +### Built-in tags + +Built-in tags please see var `colorTags` in [color_tag.go](color_tag.go) + +```go +// use style tag +color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>") +color.Println("<suc>hello</>") +color.Println("<error>hello</>") +``` + +Run demo: `go run ./_examples/color_tag.go` + + + +**Use `color.Tag` build message**: + +```go +// set a style tag +color.Tag("info").Print("info style text") +color.Tag("info").Printf("%s style text", "info") +color.Tag("info").Println("info style text") +``` + +## Color convert + +Supports conversion between Rgb, 256, 16 colors, `Rgb <=> 256 <=> 16` + +```go +basic := color.Red +basic.Println("basic color") + +c256 := color.Red.C256() +c256.Println("256 color") +c256.C16().Println("basic color") + +rgb := color.Red.RGB() +rgb.Println("rgb color") +rgb.C256().Println("256 color") +``` + +### Convert utils + +`color` has many built-in color conversion utility functions. + +```go +func Basic2hex(val uint8) string + +func Bg2Fg(val uint8) uint8 +func Fg2Bg(val uint8) uint8 + +func C256ToRgb(val uint8) (rgb []uint8) +func C256ToRgbV1(val uint8) (rgb []uint8) + +func Hex2basic(hex string, asBg ...bool) uint8 +func Hex2rgb(hex string) []int +func HexToRGB(hex string) []int +func HexToRgb(hex string) (rgb []int) + +func HslIntToRgb(h, s, l int) (rgb []uint8) +func HslToRgb(h, s, l float64) (rgb []uint8) +func HsvToRgb(h, s, v int) (rgb []uint8) + +func Rgb2ansi(r, g, b uint8, isBg bool) uint8 +func Rgb2basic(r, g, b uint8, isBg bool) uint8 +func Rgb2hex(rgb []int) string +func Rgb2short(r, g, b uint8) uint8 +func RgbTo256(r, g, b uint8) uint8 +func RgbTo256Table() map[string]uint8 +func RgbToAnsi(r, g, b uint8, isBg bool) uint8 +func RgbToHex(rgb []int) string +func RgbToHsl(r, g, b uint8) []float64 +func RgbToHslInt(r, g, b uint8) []int +``` + +**Convert to `RGBColor`**: + +- `func RGBFromSlice(rgb []uint8, isBg ...bool) RGBColor` +- `func RGBFromString(rgb string, isBg ...bool) RGBColor` +- `func HEX(hex string, isBg ...bool) RGBColor` +- `func HSL(h, s, l float64, isBg ...bool) RGBColor` +- `func HSLInt(h, s, l int, isBg ...bool) RGBColor` + +## Util functions + +There are some useful functions reference + +- `Disable()` disable color render +- `SetOutput(io.Writer)` custom set the colored text output writer +- `ForceOpenColor()` force open color render +- `Colors2code(colors ...Color) string` Convert colors to code. return like "32;45;3" +- `ClearCode(str string) string` Use for clear color codes +- `ClearTag(s string) string` clear all color html-tag for a string +- `IsConsole(w io.Writer)` Determine whether w is one of stderr, stdout, stdin + +> More useful func please see https://pkg.go.dev/github.com/gookit/color + +### Detect color level + +`color` automatically checks the color levels supported by the current environment. + +```go +// Level is the color level supported by a terminal. +type Level = terminfo.ColorLevel + +// terminal color available level alias of the terminfo.ColorLevel* +const ( + LevelNo = terminfo.ColorLevelNone // not support color. + Level16 = terminfo.ColorLevelBasic // basic - 3/4 bit color supported + Level256 = terminfo.ColorLevelHundreds // hundreds - 8-bit color supported + LevelRgb = terminfo.ColorLevelMillions // millions - (24 bit)true color supported +) +``` + +- `func SupportColor() bool` Whether the current environment supports color output +- `func Support256Color() bool` Whether the current environment supports 256-color output +- `func SupportTrueColor() bool` Whether the current environment supports (RGB)True-color output +- `func TermColorLevel() Level` Get the currently supported color level + + +## Projects using color + +Check out these projects, which use https://github.com/gookit/color : + +- https://github.com/Delta456/box-cli-maker Make Highly Customized Boxes for your CLI +- https://github.com/flipped-aurora/gin-vue-admin 基于gin+vue搭建的(中)后台系统框架 +- https://github.com/JanDeDobbeleer/oh-my-posh A prompt theme engine for any shell. +- https://github.com/jesseduffield/lazygit Simple terminal UI for git commands +- https://github.com/olivia-ai/olivia 💁♀️Your new best friend powered by an artificial neural network +- https://github.com/pterm/pterm PTerm is a modern Go module to beautify console output. Featuring charts, progressbars, tables, trees, etc. +- https://github.com/securego/gosec Golang security checker +- https://github.com/TNK-Studio/lazykube ⎈ The lazier way to manage kubernetes. +- [+ See More](https://pkg.go.dev/github.com/gookit/color?tab=importedby) + +## Gookit packages + + - [gookit/ini](https://github.com/gookit/ini) Go config management, use INI files + - [gookit/rux](https://github.com/gookit/rux) Simple and fast request router for golang HTTP + - [gookit/gcli](https://github.com/gookit/gcli) build CLI application, tool library, running CLI commands + - [gookit/slog](https://github.com/gookit/slog) Concise and extensible go log library + - [gookit/event](https://github.com/gookit/event) Lightweight event manager and dispatcher implements by Go + - [gookit/cache](https://github.com/gookit/cache) Generic cache use and cache manager for golang. support File, Memory, Redis, Memcached. + - [gookit/config](https://github.com/gookit/config) Go config management. support JSON, YAML, TOML, INI, HCL, ENV and Flags + - [gookit/color](https://github.com/gookit/color) A command-line color library with true color support, universal API methods and Windows support + - [gookit/filter](https://github.com/gookit/filter) Provide filtering, sanitizing, and conversion of golang data + - [gookit/validate](https://github.com/gookit/validate) Use for data validation and filtering. support Map, Struct, Form data + - [gookit/goutil](https://github.com/gookit/goutil) Some utils for the Go: string, array/slice, map, format, cli, env, filesystem, test and more + - More, please see https://github.com/gookit + +## See also + + - [inhere/console](https://github.com/inhere/php-console) + - [xo/terminfo](https://github.com/xo/terminfo) + - [beego/bee](https://github.com/beego/bee) + - [issue9/term](https://github.com/issue9/term) + - [muesli/termenv](https://github.com/muesli/termenv) + - [ANSI escape code](https://en.wikipedia.org/wiki/ANSI_escape_code) + - [Standard ANSI color map](https://conemu.github.io/en/AnsiEscapeCodes.html#Standard_ANSI_color_map) + - [Terminal Colors](https://gist.github.com/XVilka/8346728) + +## License + +[MIT](/LICENSE) diff --git a/vendor/github.com/gookit/color/README.zh-CN.md b/vendor/github.com/gookit/color/README.zh-CN.md new file mode 100644 index 0000000..192a89c --- /dev/null +++ b/vendor/github.com/gookit/color/README.zh-CN.md @@ -0,0 +1,591 @@ +# CLI Color + + +[](https://github.com/gookit/color/actions) +[](https://www.codacy.com/gh/gookit/color/dashboard?utm_source=github.com&utm_medium=referral&utm_content=gookit/color&utm_campaign=Badge_Grade) +[](https://pkg.go.dev/github.com/gookit/color?tab=overview) +[](https://github.com/gookit/color) +[](https://travis-ci.org/gookit/color) +[](https://coveralls.io/github/gookit/color?branch=master) +[](https://goreportcard.com/report/github.com/gookit/color) + +Golang下的命令行色彩使用库, 拥有丰富的色彩(16/256/True)渲染输出,通用的API方法,兼容Windows系统 + +> **[EN README](README.md)** + +基本颜色预览: + + + +现在,256色和RGB色彩也已经支持windows CMD和PowerShell中工作: + + + +## 功能特色 + + - 使用简单方便 + - 支持丰富的颜色输出, 16色(4bit),256色(8bit),RGB色彩(24bit, RGB) + - 16色(4bit)是最常用和支持最广的,支持Windows `cmd.exe` + - 自 `v1.2.4` 起 **256色(8bit),RGB色彩(24bit)均支持Windows CMD和PowerShell终端** + - 请查看 [this gist](https://gist.github.com/XVilka/8346728) 了解支持RGB色彩的终端 + - 支持转换 `HEX` `HSL` 等为RGB色彩 + - 提供通用的API方法:`Print` `Printf` `Println` `Sprint` `Sprintf` + - 同时支持html标签式的颜色渲染,除了使用内置标签,同时支持自定义颜色属性 + - 例如: `this an <green>message</> <fg=red;bg=blue>text</>` 标签内部文本将会渲染对应色彩 + - 自定义颜色属性: 支持使用16色彩名称,256色彩值,rgb色彩值以及hex色彩值 + - 基础色彩: `Bold` `Black` `White` `Gray` `Red` `Green` `Yellow` `Blue` `Magenta` `Cyan` + - 扩展风格: `Info` `Note` `Light` `Error` `Danger` `Notice` `Success` `Comment` `Primary` `Warning` `Question` `Secondary` + - 支持通过设置环境变量 `NO_COLOR` 来禁用色彩,或者使用 `FORCE_COLOR` 来强制使用色彩渲染. + - 支持 Rgb, 256, 16 色彩之间的互相转换 + - 支持Linux、Mac,同时兼容Windows系统环境 + +## GoDoc + + - [godoc for gopkg](https://pkg.go.dev/gopkg.in/gookit/color.v1) + - [godoc for github](https://pkg.go.dev/github.com/gookit/color) + +## 安装 + +```bash +go get github.com/gookit/color +``` + +## 快速开始 + +如下,引入当前包就可以快速的使用 + +```go +package main + +import ( + "fmt" + + "github.com/gookit/color" +) + +func main() { + // 简单快速的使用,跟 fmt.Print* 类似 + color.Redp("Simple to use color") + color.Redln("Simple to use color") + color.Greenp("Simple to use color\n") + color.Cyanln("Simple to use color") + color.Yellowln("Simple to use color") + + // 简单快速的使用,跟 fmt.Print* 类似 + color.Red.Println("Simple to use color") + color.Green.Print("Simple to use color\n") + color.Cyan.Printf("Simple to use %s\n", "color") + color.Yellow.Printf("Simple to use %s\n", "color") + + // use like func + red := color.FgRed.Render + green := color.FgGreen.Render + fmt.Printf("%s line %s library\n", red("Command"), green("color")) + + // 自定义颜色 + color.New(color.FgWhite, color.BgBlack).Println("custom color style") + + // 也可以: + color.Style{color.FgCyan, color.OpBold}.Println("custom color style") + + // internal style: + color.Info.Println("message") + color.Warn.Println("message") + color.Error.Println("message") + + // 使用内置颜色标签 + color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>\n") + // 自定义标签: 支持使用16色彩名称,256色彩值,rgb色彩值以及hex色彩值 + color.Println("<fg=11aa23>he</><bg=120,35,156>llo</>, <fg=167;bg=232>wel</><fg=red>come</>") + + // apply a style tag + color.Tag("info").Println("info style text") + + // prompt message + color.Info.Prompt("prompt style message") + color.Warn.Prompt("prompt style message") + + // tips message + color.Info.Tips("tips style message") + color.Warn.Tips("tips style message") +} +``` + +> 运行 demo: `go run ./_examples/demo.go` + + + +## 基础颜色(16-color) + +提供通用的API方法:`Print` `Printf` `Println` `Sprint` `Sprintf` + +> 支持在windows `cmd.exe` `powerShell` 等终端使用 + +```go +color.Bold.Println("bold message") +color.Black.Println("bold message") +color.White.Println("bold message") +// ... + +// Only use foreground color +color.FgCyan.Printf("Simple to use %s\n", "color") +// Only use background color +color.BgRed.Printf("Simple to use %s\n", "color") +``` + +> 运行demo: `go run ./_examples/color_16.go` + + + +### 构建风格 + +```go +// 仅设置前景色 +color.FgCyan.Printf("Simple to use %s\n", "color") +// 仅设置背景色 +color.BgRed.Printf("Simple to use %s\n", "color") + +// 完全自定义: 前景色 背景色 选项 +style := color.New(color.FgWhite, color.BgBlack, color.OpBold) +style.Println("custom color style") + +// 也可以: +color.Style{color.FgCyan, color.OpBold}.Println("custom color style") +``` + +直接设置控制台属性: + +```go +// 设置console颜色 +color.Set(color.FgCyan) + +// 输出信息 +fmt.Print("message") + +// 重置console颜色 +color.Reset() +``` + +> 当然,color已经内置丰富的色彩风格支持 + +### 扩展风格方法 + +提供通用的API方法:`Print` `Printf` `Println` `Sprint` `Sprintf` + +> 支持在windows `cmd.exe` `powerShell` 等终端使用 + +基础使用: + +```go +// print message +color.Info.Println("Info message") +color.Note.Println("Note message") +color.Notice.Println("Notice message") +// ... +``` + +Run demo: `go run ./_examples/theme_basic.go` + + + +**简约提示风格** + +```go +color.Info.Tips("Info tips message") +color.Notice.Tips("Notice tips message") +color.Error.Tips("Error tips message") +// ... +``` + +Run demo: `go run ./_examples/theme_tips.go` + + + +**着重提示风格** + +```go +color.Info.Prompt("Info prompt message") +color.Error.Prompt("Error prompt message") +color.Danger.Prompt("Danger prompt message") +``` + +Run demo: `go run ./_examples/theme_prompt.go` + + + +**强调提示风格** + +```go +color.Warn.Block("Warn block message") +color.Debug.Block("Debug block message") +color.Question.Block("Question block message") +``` + +Run demo: `go run ./_examples/theme_block.go` + + + +## 256 色彩使用 + +> 256色彩在 `v1.2.4` 后支持Windows CMD,PowerShell 环境 + +### 使用前景或后景色 + +- `color.C256(val uint8, isBg ...bool) Color256` + +```go +c := color.C256(132) // fg color +c.Println("message") +c.Printf("format %s", "message") + +c := color.C256(132, true) // bg color +c.Println("message") +c.Printf("format %s", "message") +``` + +### 使用256 色彩风格 + +> 可同时设置前景和背景色 + +- `color.S256(fgAndBg ...uint8) *Style256` + +```go +s := color.S256(32, 203) +s.Println("message") +s.Printf("format %s", "message") +``` + +可以同时添加选项设置: + +```go +s := color.S256(32, 203) +s.SetOpts(color.Opts{color.OpBold}) + +s.Println("style with options") +s.Printf("style with %s\n", "options") +``` + +> 运行 demo: `go run ./_examples/color_256.go` + + + +## RGB/True色彩使用 + +> RGB色彩在 `v1.2.4` 后支持 Windows `CMD`, `PowerShell` 环境 + +**效果预览:** + +> 运行 demo: `Run demo: go run ./_examples/color_rgb.go` + + + +代码示例: + +```go +color.RGB(30, 144, 255).Println("message. use RGB number") + +color.HEX("#1976D2").Println("blue-darken") +color.HEX("#D50000", true).Println("red-accent. use HEX style") + +color.RGBStyleFromString("213,0,0").Println("red-accent. use RGB number") +color.HEXStyle("eee", "D50000").Println("deep-purple color") +``` + +### 使用前景或后景色 + +- `color.RGB(r, g, b uint8, isBg ...bool) RGBColor` + +```go +c := color.RGB(30,144,255) // fg color +c.Println("message") +c.Printf("format %s", "message") + +c := color.RGB(30,144,255, true) // bg color +c.Println("message") +c.Printf("format %s", "message") +``` + +- `color.HEX(hex string, isBg ...bool) RGBColor` 从16进制颜色创建 + +```go +c := color.HEX("ccc") // 也可以写为: "cccccc" "#cccccc" +c.Println("message") +c.Printf("format %s", "message") + +c = color.HEX("aabbcc", true) // as bg color +c.Println("message") +c.Printf("format %s", "message") +``` + +### 使用RGB风格 + +> TIP: 可同时设置前景和背景色 + +- `color.NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle` + +```go +s := color.NewRGBStyle(RGB(20, 144, 234), RGB(234, 78, 23)) +s.Println("message") +s.Printf("format %s", "message") +``` + +- `color.HEXStyle(fg string, bg ...string) *RGBStyle` 从16进制颜色创建 + +```go +s := color.HEXStyle("11aa23", "eee") +s.Println("message") +s.Printf("format %s", "message") +``` + +- 可以同时添加选项设置: + +```go +s := color.HEXStyle("11aa23", "eee") +s.SetOpts(color.Opts{color.OpBold}) + +s.Println("style with options") +s.Printf("style with %s\n", "options") +``` + +## 使用颜色标签 + +`Print,Printf,Println` 等方法支持自动解析并渲染 HTML 风格的颜色标签 + +> **支持** 在windows `cmd.exe` `PowerShell` 使用 + +简单示例: + +```go + text := ` + <mga1>gookit/color:</> + A <green>command-line</> + <cyan>color library</> with <fg=167;bg=232>256-color</> + and <fg=11aa23;op=bold>True-color</> support, + <fg=mga;op=i>universal API</> methods + and <cyan>Windows</> support. +` + color.Print(text) +``` + +输出效果, 示例代码请看 [_examples/demo_tag.go](_examples/demo_tag.go): + + + +**颜色标签格式:** + +- 直接使用内置风格标签: `<TAG_NAME>CONTENT</>` e.g: `<info>message</>` +- 自定义标签属性: `<fg=VALUE;bg=VALUE;op=VALUES>CONTENT</>` e.g: `<fg=167;bg=232>wel</>` + +使用内置的颜色标签,可以非常方便简单的构建自己需要的任何格式 + +> 同时支持自定义颜色属性: 支持使用16色彩名称,256色彩值,rgb色彩值以及hex色彩值 + +```go +// 使用内置的 color tag +color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>") +color.Println("<suc>hello</>") +color.Println("<error>hello</>") +color.Println("<warning>hello</>") + +// 自定义颜色属性 +color.Print("<fg=yellow;bg=black;op=underscore;>hello, welcome</>\n") + +// 自定义颜色属性: 支持使用16色彩名称,256色彩值,rgb色彩值以及hex色彩值 +color.Println("<fg=11aa23>he</><bg=120,35,156>llo</>, <fg=167;bg=232>wel</><fg=red>come</>") +``` + +### 自定义标签属性 + +标签属性格式: + +```text +attr format: + // VALUE please see var: FgColors, BgColors, AllOptions + "fg=VALUE;bg=VALUE;op=VALUE" + +16 color: + "fg=yellow" + "bg=red" + "op=bold,underscore" // option is allow multi value + "fg=white;bg=blue;op=bold" + "fg=white;op=bold,underscore" + +256 color: + "fg=167" + "fg=167;bg=23" + "fg=167;bg=23;op=bold" + +True color: + // hex + "fg=fc1cac" + "fg=fc1cac;bg=c2c3c4" + // r,g,b + "fg=23,45,214" + "fg=23,45,214;bg=109,99,88" +``` + +> tag attributes parse please see `func ParseCodeFromAttr()` + +### 内置标签 + +内置标签请参见变量 `colorTags` 定义, 源文件 [color_tag.go](color_tag.go) + +```go +// use style tag +color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>") +color.Println("<suc>hello</>") +color.Println("<error>hello</>") +``` + +> 运行 demo: `go run ./_examples/color_tag.go` + + + +**使用 `color.Tag` 包装标签**: + +可以使用通用的输出API方法,给后面输出的文本信息加上给定的颜色风格标签 + +```go +// set a style tag +color.Tag("info").Print("info style text") +color.Tag("info").Printf("%s style text", "info") +color.Tag("info").Println("info style text") +``` + +## 颜色转换 + +支持 Rgb, 256, 16 色彩之间的互相转换 `Rgb <=> 256 <=> 16` + +```go +basic := color.Red +basic.Println("basic color") + +c256 := color.Red.C256() +c256.Println("256 color") +c256.C16().Println("basic color") + +rgb := color.Red.RGB() +rgb.Println("rgb color") +rgb.C256().Println("256 color") +``` + +### 颜色转换方法 + +`color` 内置了许多颜色转换工具方法 + +```go +func Basic2hex(val uint8) string + +func Bg2Fg(val uint8) uint8 +func Fg2Bg(val uint8) uint8 + +func C256ToRgb(val uint8) (rgb []uint8) +func C256ToRgbV1(val uint8) (rgb []uint8) + +func Hex2basic(hex string, asBg ...bool) uint8 +func Hex2rgb(hex string) []int +func HexToRGB(hex string) []int +func HexToRgb(hex string) (rgb []int) + +func HslIntToRgb(h, s, l int) (rgb []uint8) +func HslToRgb(h, s, l float64) (rgb []uint8) +func HsvToRgb(h, s, v int) (rgb []uint8) + +func Rgb2ansi(r, g, b uint8, isBg bool) uint8 +func Rgb2basic(r, g, b uint8, isBg bool) uint8 +func Rgb2hex(rgb []int) string +func Rgb2short(r, g, b uint8) uint8 +func RgbTo256(r, g, b uint8) uint8 +func RgbTo256Table() map[string]uint8 +func RgbToAnsi(r, g, b uint8, isBg bool) uint8 +func RgbToHex(rgb []int) string +func RgbToHsl(r, g, b uint8) []float64 +func RgbToHslInt(r, g, b uint8) []int +``` + +**转换为 `RGBColor`**: + +- `func RGBFromSlice(rgb []uint8, isBg ...bool) RGBColor` +- `func RGBFromString(rgb string, isBg ...bool) RGBColor` +- `func HEX(hex string, isBg ...bool) RGBColor` +- `func HSL(h, s, l float64, isBg ...bool) RGBColor` +- `func HSLInt(h, s, l int, isBg ...bool) RGBColor` + +## 工具方法参考 + +一些有用的工具方法参考 + +- `Disable()` 禁用颜色渲染输出 +- `SetOutput(io.Writer)` 自定义设置渲染后的彩色文本输出位置 +- `ForceOpenColor()` 强制开启颜色渲染 +- `ClearCode(str string) string` Use for clear color codes +- `Colors2code(colors ...Color) string` Convert colors to code. return like "32;45;3" +- `ClearTag(s string) string` clear all color html-tag for a string +- `IsConsole(w io.Writer)` Determine whether w is one of stderr, stdout, stdin +- 更多请查看文档 https://pkg.go.dev/github.com/gookit/color + +### 检测支持的颜色级别 + +`color` 会自动检查当前环境支持的颜色级别 + +```go +// Level is the color level supported by a terminal. +type Level = terminfo.ColorLevel + +// terminal color available level alias of the terminfo.ColorLevel* +const ( + LevelNo = terminfo.ColorLevelNone // not support color. + Level16 = terminfo.ColorLevelBasic // basic - 3/4 bit color supported + Level256 = terminfo.ColorLevelHundreds // hundreds - 8-bit color supported + LevelRgb = terminfo.ColorLevelMillions // millions - (24 bit)true color supported +) +``` + +- `func SupportColor() bool` 当前环境是否支持色彩输出 +- `func Support256Color() bool` 当前环境是否支持256色彩输出 +- `func SupportTrueColor() bool` 当前环境是否支持(RGB)True色彩输出 +- `func TermColorLevel() Level` 获取当前支持的颜色级别 + +## 使用Color的项目 + +看看这些使用了 https://github.com/gookit/color 的项目: + +- https://github.com/Delta456/box-cli-maker Make Highly Customized Boxes for your CLI +- https://github.com/flipped-aurora/gin-vue-admin 基于gin+vue搭建的(中)后台系统框架 +- https://github.com/JanDeDobbeleer/oh-my-posh A prompt theme engine for any shell. +- https://github.com/jesseduffield/lazygit Simple terminal UI for git commands +- https://github.com/olivia-ai/olivia 💁♀️Your new best friend powered by an artificial neural network +- https://github.com/pterm/pterm PTerm is a modern Go module to beautify console output. Featuring charts, progressbars, tables, trees, etc. +- https://github.com/securego/gosec Golang security checker +- https://github.com/TNK-Studio/lazykube ⎈ The lazier way to manage kubernetes. +- [+ See More](https://pkg.go.dev/github.com/gookit/color?tab=importedby) + +## Gookit 工具包 + + - [gookit/ini](https://github.com/gookit/ini) INI配置读取管理,支持多文件加载,数据覆盖合并, 解析ENV变量, 解析变量引用 + - [gookit/rux](https://github.com/gookit/rux) Simple and fast request router for golang HTTP + - [gookit/gcli](https://github.com/gookit/gcli) Go的命令行应用,工具库,运行CLI命令,支持命令行色彩,用户交互,进度显示,数据格式化显示 + - [gookit/slog](https://github.com/gookit/slog) 简洁易扩展的go日志库 + - [gookit/event](https://github.com/gookit/event) Go实现的轻量级的事件管理、调度程序库, 支持设置监听器的优先级, 支持对一组事件进行监听 + - [gookit/cache](https://github.com/gookit/cache) 通用的缓存使用包装库,通过包装各种常用的驱动,来提供统一的使用API + - [gookit/config](https://github.com/gookit/config) Go应用配置管理,支持多种格式(JSON, YAML, TOML, INI, HCL, ENV, Flags),多文件加载,远程文件加载,数据合并 + - [gookit/color](https://github.com/gookit/color) CLI 控制台颜色渲染工具库, 拥有简洁的使用API,支持16色,256色,RGB色彩渲染输出 + - [gookit/filter](https://github.com/gookit/filter) 提供对Golang数据的过滤,净化,转换 + - [gookit/validate](https://github.com/gookit/validate) Go通用的数据验证与过滤库,使用简单,内置大部分常用验证、过滤器 + - [gookit/goutil](https://github.com/gookit/goutil) Go 的一些工具函数,格式化,特殊处理,常用信息获取等 + - 更多请查看 https://github.com/gookit + +## 参考项目 + + - [inhere/console](https://github.com/inhere/php-console) + - [muesli/termenv](https://github.com/muesli/termenv) + - [xo/terminfo](https://github.com/xo/terminfo) + - [beego/bee](https://github.com/beego/bee) + - [issue9/term](https://github.com/issue9/term) + - [ANSI转义序列](https://zh.wikipedia.org/wiki/ANSI转义序列) + - [Standard ANSI color map](https://conemu.github.io/en/AnsiEscapeCodes.html#Standard_ANSI_color_map) + - [Terminal Colors](https://gist.github.com/XVilka/8346728) + +## License + +MIT diff --git a/vendor/github.com/gookit/color/any.go b/vendor/github.com/gookit/color/any.go new file mode 100644 index 0000000..8bf31c1 --- /dev/null +++ b/vendor/github.com/gookit/color/any.go @@ -0,0 +1,6 @@ +//go:build !go1.18 +// +build !go1.18 + +package color + +type any = interface{} diff --git a/vendor/github.com/gookit/color/color.go b/vendor/github.com/gookit/color/color.go new file mode 100644 index 0000000..22de1b0 --- /dev/null +++ b/vendor/github.com/gookit/color/color.go @@ -0,0 +1,251 @@ +/* +Package color is command line color library. +Support rich color rendering output, universal API method, compatible with Windows system + +Source code and other details for the project are available at GitHub: + + https://github.com/gookit/color + +More usage please see README and tests. +*/ +package color + +import ( + "fmt" + "io" + "os" + "regexp" + "strings" + + "github.com/xo/terminfo" +) + +// color render templates +// +// ESC 操作的表示: +// +// "\033"(Octal 8进制) = "\x1b"(Hexadecimal 16进制) = 27 (10进制) +const ( + // StartSet chars + StartSet = "\x1b[" + // ResetSet close all properties. + ResetSet = "\x1b[0m" + // SettingTpl string. + SettingTpl = "\x1b[%sm" + // FullColorTpl for build color code + FullColorTpl = "\x1b[%sm%s\x1b[0m" + // CodeSuffix string for color code. + CodeSuffix = "[0m" +) + +// CodeExpr regex to clear color codes eg "\033[1;36mText\x1b[0m" +const CodeExpr = `\033\[[\d;?]+m` + +var ( + // Enable switch color render and display + // + // NOTICE: + // if ENV: NO_COLOR is not empty, will disable color render. + Enable = os.Getenv("NO_COLOR") == "" + // RenderTag render HTML tag on call color.Xprint, color.PrintX + RenderTag = true + // debug mode for development. + // + // set env: + // COLOR_DEBUG_MODE=on + // or: + // COLOR_DEBUG_MODE=on go run ./_examples/envcheck.go + debugMode = os.Getenv("COLOR_DEBUG_MODE") == "on" + // inner errors record on detect color level + innerErrs []error + // output the default io.Writer message print + output io.Writer = os.Stdout + // mark current env, It's like in `cmd.exe` + // if not in windows, it's always False. + isLikeInCmd bool + // the color support level for current terminal + // needVTP - need enable VTP, only for Windows OS + colorLevel, needVTP = detectTermColorLevel() + // match color codes + codeRegex = regexp.MustCompile(CodeExpr) + // mark current env is support color. + // Always: isLikeInCmd != supportColor + // supportColor = IsSupportColor() +) + +// TermColorLevel Get the currently supported color level +func TermColorLevel() Level { + return colorLevel +} + +// SupportColor Whether the current environment supports color output +func SupportColor() bool { + return colorLevel > terminfo.ColorLevelNone +} + +// Support16Color on the current ENV +// func Support16Color() bool { +// return colorLevel > terminfo.ColorLevelNone +// } + +// Support256Color Whether the current environment supports 256-color output +func Support256Color() bool { + return colorLevel > terminfo.ColorLevelBasic +} + +// SupportTrueColor Whether the current environment supports (RGB)True-color output +func SupportTrueColor() bool { + return colorLevel > terminfo.ColorLevelHundreds +} + +/************************************************************* + * global settings + *************************************************************/ + +// Set console color attributes +func Set(colors ...Color) (int, error) { + code := Colors2code(colors...) + err := SetTerminal(code) + return 0, err +} + +// Reset reset console color attributes +func Reset() (int, error) { + err := ResetTerminal() + return 0, err +} + +// Disable disable color output +func Disable() bool { + oldVal := Enable + Enable = false + return oldVal +} + +// NotRenderTag on call color.Xprint, color.PrintX +func NotRenderTag() { + RenderTag = false +} + +// SetOutput set default colored text output +func SetOutput(w io.Writer) { + output = w +} + +// ResetOutput reset output +func ResetOutput() { + output = os.Stdout +} + +// ResetOptions reset all package option setting +func ResetOptions() { + RenderTag = true + Enable = true + output = os.Stdout +} + +// ForceSetColorLevel force open color render +func ForceSetColorLevel(level terminfo.ColorLevel) terminfo.ColorLevel { + oldLevelVal := colorLevel + colorLevel = level + return oldLevelVal +} + +// ForceColor force open color render +func ForceColor() terminfo.ColorLevel { + return ForceOpenColor() +} + +// ForceOpenColor force open color render +func ForceOpenColor() terminfo.ColorLevel { + // TODO should set level to ? + return ForceSetColorLevel(terminfo.ColorLevelMillions) +} + +// IsLikeInCmd check result +// +// Deprecated: please don't use +func IsLikeInCmd() bool { + return isLikeInCmd +} + +// InnerErrs info +func InnerErrs() []error { + return innerErrs +} + +/************************************************************* + * render color code + *************************************************************/ + +// RenderCode render message by color code. +// +// Usage: +// +// msg := RenderCode("3;32;45", "some", "message") +func RenderCode(code string, args ...any) string { + var message string + if ln := len(args); ln == 0 { + return "" + } + + message = fmt.Sprint(args...) + if len(code) == 0 { + return message + } + + // disabled OR not support color + if !Enable || !SupportColor() { + return ClearCode(message) + } + + // return fmt.Sprintf(FullColorTpl, code, message) + return StartSet + code + "m" + message + ResetSet +} + +// RenderWithSpaces Render code with spaces. +// If the number of args is > 1, a space will be added between the args +func RenderWithSpaces(code string, args ...any) string { + msg := formatArgsForPrintln(args) + if len(code) == 0 { + return msg + } + + // disabled OR not support color + if !Enable || !SupportColor() { + return ClearCode(msg) + } + + return StartSet + code + "m" + msg + ResetSet +} + +// RenderString render a string with color code. +// +// Usage: +// +// msg := RenderString("3;32;45", "a message") +func RenderString(code string, str string) string { + if len(code) == 0 || str == "" { + return str + } + + // disabled OR not support color + if !Enable || !SupportColor() { + return ClearCode(str) + } + + // return fmt.Sprintf(FullColorTpl, code, str) + return StartSet + code + "m" + str + ResetSet +} + +// ClearCode clear color codes. +// +// eg: +// +// "\033[36;1mText\x1b[0m" -> "Text" +func ClearCode(str string) string { + if !strings.Contains(str, CodeSuffix) { + return str + } + return codeRegex.ReplaceAllString(str, "") +} diff --git a/vendor/github.com/gookit/color/color_16.go b/vendor/github.com/gookit/color/color_16.go new file mode 100644 index 0000000..eda226a --- /dev/null +++ b/vendor/github.com/gookit/color/color_16.go @@ -0,0 +1,511 @@ +package color + +import ( + "fmt" + "strconv" +) + +// Color Color16, 16 color value type +// 3(2^3=8) OR 4(2^4=16) bite color. +type Color uint8 +type Basic = Color // alias of Color + +// Opts basic color options. code: 0 - 9 +type Opts []Color + +// Add option value +func (o *Opts) Add(ops ...Color) { + for _, op := range ops { + if uint8(op) < 10 { + *o = append(*o, op) + } + } +} + +// IsValid options +func (o Opts) IsValid() bool { + return len(o) > 0 +} + +// IsEmpty options +func (o Opts) IsEmpty() bool { + return len(o) == 0 +} + +// String options to string. eg: "1;3" +func (o Opts) String() string { + return Colors2code(o...) +} + +/************************************************************* + * Basic 16 color definition + *************************************************************/ + +const ( + // OptMax max option value. range: 0 - 9 + OptMax = 10 + // DiffFgBg diff foreground and background color + DiffFgBg = 10 +) + +// Boundary value for foreground/background color 16 +// +// - base: fg 30~37, bg 40~47 +// - light: fg 90~97, bg 100~107 +const ( + FgBase uint8 = 30 + FgMax uint8 = 37 + BgBase uint8 = 40 + BgMax uint8 = 47 + + HiFgBase uint8 = 90 + HiFgMax uint8 = 97 + HiBgBase uint8 = 100 + HiBgMax uint8 = 107 +) + +// Foreground colors. basic foreground colors 30 - 37 +const ( + FgBlack Color = iota + 30 + FgRed + FgGreen + FgYellow + FgBlue + FgMagenta // 品红 + FgCyan // 青色 + FgWhite + // FgDefault revert default FG + FgDefault Color = 39 +) + +// Extra foreground color 90 - 97(非标准) +const ( + FgDarkGray Color = iota + 90 // 亮黑(灰) + FgLightRed + FgLightGreen + FgLightYellow + FgLightBlue + FgLightMagenta + FgLightCyan + FgLightWhite + // FgGray is alias of FgDarkGray + FgGray Color = 90 // 亮黑(灰) +) + +// Background colors. basic background colors 40 - 47 +const ( + BgBlack Color = iota + 40 + BgRed + BgGreen + BgYellow // BgBrown like yellow + BgBlue + BgMagenta + BgCyan + BgWhite + // BgDefault revert default BG + BgDefault Color = 49 +) + +// Extra background color 100 - 107 (non-standard) +const ( + BgDarkGray Color = iota + 100 + BgLightRed + BgLightGreen + BgLightYellow + BgLightBlue + BgLightMagenta + BgLightCyan + BgLightWhite + // BgGray is alias of BgDarkGray + BgGray Color = 100 +) + +// Option settings. range: 0 - 9 +const ( + OpReset Color = iota // 0 重置所有设置 + OpBold // 1 加粗 + OpFuzzy // 2 模糊(不是所有的终端仿真器都支持) + OpItalic // 3 斜体(不是所有的终端仿真器都支持) + OpUnderscore // 4 下划线 + OpBlink // 5 闪烁 + OpFastBlink // 6 快速闪烁(未广泛支持) + OpReverse // 7 颠倒的 交换背景色与前景色 + OpConcealed // 8 隐匿的 + OpStrikethrough // 9 删除的,删除线(未广泛支持) +) + +// There are basic and light foreground color aliases +const ( + Red = FgRed + Cyan = FgCyan + Gray = FgDarkGray // is light Black + Blue = FgBlue + Black = FgBlack + Green = FgGreen + White = FgWhite + Yellow = FgYellow + Magenta = FgMagenta + + // special + + Bold = OpBold + Normal = FgDefault + + // extra light + + LightRed = FgLightRed + LightCyan = FgLightCyan + LightBlue = FgLightBlue + LightGreen = FgLightGreen + LightWhite = FgLightWhite + LightYellow = FgLightYellow + LightMagenta = FgLightMagenta + + HiRed = FgLightRed + HiCyan = FgLightCyan + HiBlue = FgLightBlue + HiGreen = FgLightGreen + HiWhite = FgLightWhite + HiYellow = FgLightYellow + HiMagenta = FgLightMagenta + + BgHiRed = BgLightRed + BgHiCyan = BgLightCyan + BgHiBlue = BgLightBlue + BgHiGreen = BgLightGreen + BgHiWhite = BgLightWhite + BgHiYellow = BgLightYellow + BgHiMagenta = BgLightMagenta +) + +// Bit4 a method for create Color +func Bit4(code uint8) Color { return Color(code) } + +/************************************************************* + * Color render methods + *************************************************************/ + +// Name get color code name. +func (c Color) Name() string { + name, ok := basic2nameMap[uint8(c)] + if ok { + return name + } + return "unknown" +} + +// Text render a text message +func (c Color) Text(message string) string { return RenderString(c.String(), message) } + +// Render messages by color setting +// +// Usage: +// +// green := color.FgGreen.Render +// fmt.Println(green("message")) +func (c Color) Render(a ...any) string { return RenderCode(c.String(), a...) } + +// Renderln messages by color setting. +// like Println, will add spaces for each argument +// +// Usage: +// +// green := color.FgGreen.Renderln +// fmt.Println(green("message")) +func (c Color) Renderln(a ...any) string { return RenderWithSpaces(c.String(), a...) } + +// Sprint render messages by color setting. is alias of the Render() +func (c Color) Sprint(a ...any) string { return RenderCode(c.String(), a...) } + +// Sprintf format and render message. +// +// Usage: +// +// green := color.Green.Sprintf +// colored := green("message") +func (c Color) Sprintf(format string, args ...any) string { + return RenderString(c.String(), fmt.Sprintf(format, args...)) +} + +// Print messages. +// +// Usage: +// +// color.Green.Print("message") +// +// OR: +// +// green := color.FgGreen.Print +// green("message") +func (c Color) Print(args ...any) { + doPrintV2(c.Code(), fmt.Sprint(args...)) +} + +// Printf format and print messages. +// +// Usage: +// +// color.Cyan.Printf("string %s", "arg0") +func (c Color) Printf(format string, a ...any) { + doPrintV2(c.Code(), fmt.Sprintf(format, a...)) +} + +// Println messages with new line +func (c Color) Println(a ...any) { doPrintlnV2(c.String(), a) } + +// Light current color. eg: 36(FgCyan) -> 96(FgLightCyan). +// +// Usage: +// +// lightCyan := Cyan.Light() +// lightCyan.Print("message") +func (c Color) Light() Color { + val := uint8(c) + if val >= 30 && val <= 47 { + return Color(val + 60) + } + + // don't change + return c +} + +// Darken current color. eg. 96(FgLightCyan) -> 36(FgCyan) +// +// Usage: +// +// cyan := LightCyan.Darken() +// cyan.Print("message") +func (c Color) Darken() Color { + val := uint8(c) + if val >= 90 && val <= 107 { + return Color(val - 60) + } + + // don't change + return c +} + +// C256 convert 16 color to 256-color code. +func (c Color) C256() Color256 { + val := uint8(c) + if val < 10 { // is option code + return emptyC256 // empty + } + + var isBg uint8 + if val >= BgBase && val <= 47 { // is bg + isBg = AsBg + val = val - 10 // to fg code + } else if val >= HiBgBase && val <= 107 { // is hi bg + isBg = AsBg + val = val - 10 // to fg code + } + + if c256, ok := basicTo256Map[val]; ok { + return Color256{c256, isBg} + } + + // use raw value direct convert + return Color256{val} +} + +// ToFg always convert fg +func (c Color) ToFg() Color { + val := uint8(c) + // option code, don't change + if val < 10 { + return c + } + return Color(Bg2Fg(val)) +} + +// ToBg always convert bg +func (c Color) ToBg() Color { + val := uint8(c) + // option code, don't change + if val < 10 { + return c + } + return Color(Fg2Bg(val)) +} + +// RGB convert 16 color to 256-color code. +func (c Color) RGB() RGBColor { + val := uint8(c) + if val < 10 { // is option code + return emptyRGBColor + } + + return HEX(Basic2hex(val), c.IsBg()) +} + +// Code convert to code string. eg "35" +func (c Color) Code() string { + return strconv.FormatInt(int64(c), 10) +} + +// String convert to code string. eg "35" +func (c Color) String() string { + return strconv.FormatInt(int64(c), 10) +} + +// IsBg check is background color +func (c Color) IsBg() bool { + val := uint8(c) + return val >= BgBase && val <= BgMax || val >= HiBgBase && val <= HiBgMax +} + +// IsFg check is foreground color +func (c Color) IsFg() bool { + val := uint8(c) + return val >= FgBase && val <= FgMax || val >= HiFgBase && val <= HiFgMax +} + +// IsOption check is option code: 0-9 +func (c Color) IsOption() bool { return uint8(c) < OptMax } + +// IsValid color value +func (c Color) IsValid() bool { return uint8(c) < HiBgMax } + +/************************************************************* + * basic color maps + *************************************************************/ + +// FgColors foreground colors map +var FgColors = map[string]Color{ + "black": FgBlack, + "red": FgRed, + "green": FgGreen, + "yellow": FgYellow, + "blue": FgBlue, + "magenta": FgMagenta, + "cyan": FgCyan, + "white": FgWhite, + "default": FgDefault, +} + +// BgColors background colors map +var BgColors = map[string]Color{ + "black": BgBlack, + "red": BgRed, + "green": BgGreen, + "yellow": BgYellow, + "blue": BgBlue, + "magenta": BgMagenta, + "cyan": BgCyan, + "white": BgWhite, + "default": BgDefault, +} + +// ExFgColors extra foreground colors map +var ExFgColors = map[string]Color{ + "darkGray": FgDarkGray, + "lightRed": FgLightRed, + "lightGreen": FgLightGreen, + "lightYellow": FgLightYellow, + "lightBlue": FgLightBlue, + "lightMagenta": FgLightMagenta, + "lightCyan": FgLightCyan, + "lightWhite": FgLightWhite, +} + +// ExBgColors extra background colors map +var ExBgColors = map[string]Color{ + "darkGray": BgDarkGray, + "lightRed": BgLightRed, + "lightGreen": BgLightGreen, + "lightYellow": BgLightYellow, + "lightBlue": BgLightBlue, + "lightMagenta": BgLightMagenta, + "lightCyan": BgLightCyan, + "lightWhite": BgLightWhite, +} + +// Options color options map +// +// Deprecated: please use AllOptions instead. +var Options = AllOptions + +// AllOptions color options map +var AllOptions = map[string]Color{ + "reset": OpReset, + "bold": OpBold, + "fuzzy": OpFuzzy, + "italic": OpItalic, + "underscore": OpUnderscore, + "blink": OpBlink, + "reverse": OpReverse, + "concealed": OpConcealed, +} + +var ( + // TODO basic name alias + // basicNameAlias = map[string]string{} + // optionWithAlias = buildOpWithAlias() + // basic color name to code + // name2basicMap = initName2basicMap() + + // basic2nameMap basic color code to name + basic2nameMap = map[uint8]string{ + 30: "black", + 31: "red", + 32: "green", + 33: "yellow", + 34: "blue", + 35: "magenta", + 36: "cyan", + 37: "white", + // hi color code + 90: "lightBlack", + 91: "lightRed", + 92: "lightGreen", + 93: "lightYellow", + 94: "lightBlue", + 95: "lightMagenta", + 96: "lightCyan", + 97: "lightWhite", + // options + 0: "reset", + 1: "bold", + 2: "fuzzy", + 3: "italic", + 4: "underscore", + 5: "blink", + 7: "reverse", + 8: "concealed", + } +) + +// Bg2Fg bg color value to fg value +func Bg2Fg(val uint8) uint8 { + if val >= BgBase && val <= 47 { // is bg + val = val - 10 + } else if val >= HiBgBase && val <= 107 { // is hi bg + val = val - 10 + } + return val +} + +// Fg2Bg fg color value to bg value +func Fg2Bg(val uint8) uint8 { + if val >= FgBase && val <= 37 { // is fg + val = val + 10 + } else if val >= HiFgBase && val <= 97 { // is hi fg + val = val + 10 + } + return val +} + +// Basic2nameMap data +func Basic2nameMap() map[uint8]string { return basic2nameMap } + +// func initName2basicMap() map[string]uint8 { +// n2b := make(map[string]uint8, len(basic2nameMap)) +// for u, s := range basic2nameMap { +// n2b[s] = u +// } +// return n2b +// } + +// func buildOpWithAlias() map[string]uint8 { +// } diff --git a/vendor/github.com/gookit/color/color_256.go b/vendor/github.com/gookit/color/color_256.go new file mode 100644 index 0000000..79ae5f8 --- /dev/null +++ b/vendor/github.com/gookit/color/color_256.go @@ -0,0 +1,303 @@ +package color + +import ( + "fmt" + "strconv" + "strings" +) + +/* +from wikipedia, 256 color: + ESC[ … 38;5;<n> … m选择前景色 + ESC[ … 48;5;<n> … m选择背景色 + 0- 7:标准颜色(同 ESC[30–37m) + 8- 15:高强度颜色(同 ESC[90–97m) + 16-231:6 × 6 × 6 立方(216色): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5) + 232-255:从黑到白的24阶灰度色 +*/ + +// tpl for 8 bit 256 color(`2^8`) +// +// format: +// +// ESC[ … 38;5;<n> … m // 选择前景色 +// ESC[ … 48;5;<n> … m // 选择背景色 +// +// example: +// +// fg "\x1b[38;5;242m" +// bg "\x1b[48;5;208m" +// both "\x1b[38;5;242;48;5;208m" +// +// links: +// +// https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#8位 +const ( + TplFg256 = "38;5;%d" + TplBg256 = "48;5;%d" + Fg256Pfx = "38;5;" + Bg256Pfx = "48;5;" +) + +/************************************************************* + * 8bit(256) Color: Bit8Color Color256 + *************************************************************/ + +// Color256 256 color (8 bit), uint8 range at 0 - 255. +// Support 256 color on windows CMD, PowerShell +// +// 颜色值使用10进制和16进制都可 0x98 = 152 +// +// The color consists of two uint8: +// +// 0: color value +// 1: color type; Fg=0, Bg=1, >1: unset value +// +// example: +// +// fg color: [152, 0] +// bg color: [152, 1] +// +// lint warn - Name starts with package name +type Color256 [2]uint8 +type Bit8Color = Color256 // alias + +var emptyC256 = Color256{1: 99} + +// Bit8 create a color256 +func Bit8(val uint8, isBg ...bool) Color256 { + return C256(val, isBg...) +} + +// C256 create a color256 +func C256(val uint8, isBg ...bool) Color256 { + bc := Color256{val} + + // mark is bg color + if len(isBg) > 0 && isBg[0] { + bc[1] = AsBg + } + + return bc +} + +// Set terminal by 256 color code +func (c Color256) Set() error { + return SetTerminal(c.String()) +} + +// Reset terminal. alias of the ResetTerminal() +func (c Color256) Reset() error { + return ResetTerminal() +} + +// Print print message +func (c Color256) Print(a ...any) { + doPrintV2(c.String(), fmt.Sprint(a...)) +} + +// Printf format and print message +func (c Color256) Printf(format string, a ...any) { + doPrintV2(c.String(), fmt.Sprintf(format, a...)) +} + +// Println print message with newline +func (c Color256) Println(a ...any) { + doPrintlnV2(c.String(), a) +} + +// Sprint returns rendered message +func (c Color256) Sprint(a ...any) string { + return RenderCode(c.String(), a...) +} + +// Sprintf returns format and rendered message +func (c Color256) Sprintf(format string, a ...any) string { + return RenderString(c.String(), fmt.Sprintf(format, a...)) +} + +// C16 convert color-256 to 16 color. +func (c Color256) C16() Color { + return c.Basic() +} + +// Basic convert color-256 to basic 16 color. +func (c Color256) Basic() Color { + return Color(c[0]) // TODO +} + +// RGB convert color-256 to RGB color. +func (c Color256) RGB() RGBColor { + return RGBFromSlice(C256ToRgb(c[0]), c[1] == AsBg) +} + +// RGBColor convert color-256 to RGB color. +func (c Color256) RGBColor() RGBColor { + return c.RGB() +} + +// Value return color value +func (c Color256) Value() uint8 { + return c[0] +} + +// Code convert to color code string. eg: "12" +func (c Color256) Code() string { + return strconv.Itoa(int(c[0])) +} + +// FullCode convert to color code string with prefix. eg: "38;5;12" +func (c Color256) FullCode() string { + return c.String() +} + +// String convert to color code string with prefix. eg: "38;5;12" +func (c Color256) String() string { + if c[1] == AsFg { // 0 is Fg + return Fg256Pfx + strconv.Itoa(int(c[0])) + } + + if c[1] == AsBg { // 1 is Bg + return Bg256Pfx + strconv.Itoa(int(c[0])) + } + return "" // empty +} + +// IsFg color +func (c Color256) IsFg() bool { return c[1] == AsFg } + +// ToFg 256 color +func (c Color256) ToFg() Color256 { + c[1] = AsFg + return c +} + +// IsBg color +func (c Color256) IsBg() bool { return c[1] == AsBg } + +// ToBg 256 color +func (c Color256) ToBg() Color256 { + c[1] = AsBg + return c +} + +// IsEmpty value +func (c Color256) IsEmpty() bool { return c[1] > 1 } + +/************************************************************* + * 8bit(256) Style + *************************************************************/ + +// Style256 definition +// +// 前/背景色 +// 都是由两位uint8组成, 第一位是色彩值; +// 第二位与 Bit8Color 不一样的是,在这里表示是否设置了值 0 未设置 !=0 已设置 +type Style256 struct { + // Name of the style + Name string + // color options of the style + opts Opts + // fg and bg color + fg, bg Color256 +} + +// S256 create a color256 style +// +// Usage: +// +// s := color.S256() +// s := color.S256(132) // fg +// s := color.S256(132, 203) // fg and bg +func S256(fgAndBg ...uint8) *Style256 { + s := &Style256{} + vl := len(fgAndBg) + if vl > 0 { // with fg + s.fg = Color256{fgAndBg[0], 1} + + if vl > 1 { // and with bg + s.bg = Color256{fgAndBg[1], 1} + } + } + + return s +} + +// Set fg and bg color value, can also with color options +func (s *Style256) Set(fgVal, bgVal uint8, opts ...Color) *Style256 { + s.fg = Color256{fgVal, 1} + s.bg = Color256{bgVal, 1} + s.opts.Add(opts...) + return s +} + +// SetBg set bg color value +func (s *Style256) SetBg(bgVal uint8) *Style256 { + s.bg = Color256{bgVal, 1} + return s +} + +// SetFg set fg color value +func (s *Style256) SetFg(fgVal uint8) *Style256 { + s.fg = Color256{fgVal, 1} + return s +} + +// SetOpts set options +func (s *Style256) SetOpts(opts Opts) *Style256 { + s.opts = opts + return s +} + +// AddOpts add options +func (s *Style256) AddOpts(opts ...Color) *Style256 { + s.opts.Add(opts...) + return s +} + +// Print message +func (s *Style256) Print(a ...any) { + doPrintV2(s.String(), fmt.Sprint(a...)) +} + +// Printf format and print message +func (s *Style256) Printf(format string, a ...any) { + doPrintV2(s.String(), fmt.Sprintf(format, a...)) +} + +// Println print message with newline +func (s *Style256) Println(a ...any) { + doPrintlnV2(s.String(), a) +} + +// Sprint returns rendered message +func (s *Style256) Sprint(a ...any) string { + return RenderCode(s.Code(), a...) +} + +// Sprintf returns format and rendered message +func (s *Style256) Sprintf(format string, a ...any) string { + return RenderString(s.Code(), fmt.Sprintf(format, a...)) +} + +// Code convert to color code string +func (s *Style256) Code() string { + return s.String() +} + +// String convert to color code string +func (s *Style256) String() string { + var ss []string + if s.fg[1] > 0 { + ss = append(ss, Fg256Pfx+strconv.FormatInt(int64(s.fg[0]), 10)) + } + + if s.bg[1] > 0 { + ss = append(ss, Bg256Pfx+strconv.FormatInt(int64(s.bg[0]), 10)) + } + + if s.opts.IsValid() { + ss = append(ss, s.opts.String()) + } + return strings.Join(ss, ";") +} diff --git a/vendor/github.com/gookit/color/color_rgb.go b/vendor/github.com/gookit/color/color_rgb.go new file mode 100644 index 0000000..bc129b7 --- /dev/null +++ b/vendor/github.com/gookit/color/color_rgb.go @@ -0,0 +1,443 @@ +package color + +import ( + "fmt" + "strconv" + "strings" +) + +// 24 bit RGB color +// RGB: +// +// R 0-255 G 0-255 B 0-255 +// R 00-FF G 00-FF B 00-FF (16进制) +// +// Format: +// +// ESC[ … 38;2;<r>;<g>;<b> … m // Select RGB foreground color +// ESC[ … 48;2;<r>;<g>;<b> … m // Choose RGB background color +// +// links: +// +// https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#24位 +// +// example: +// +// fg: \x1b[38;2;30;144;255mMESSAGE\x1b[0m +// bg: \x1b[48;2;30;144;255mMESSAGE\x1b[0m +// both: \x1b[38;2;233;90;203;48;2;30;144;255mMESSAGE\x1b[0m +const ( + TplFgRGB = "38;2;%d;%d;%d" + TplBgRGB = "48;2;%d;%d;%d" + FgRGBPfx = "38;2;" + BgRGBPfx = "48;2;" +) + +// mark color is fg or bg. +const ( + AsFg uint8 = iota + AsBg +) + +/************************************************************* + * RGB Color(Bit24Color, TrueColor) + *************************************************************/ + +// RGBColor definition. +// Support RGB color on Windows CMD, PowerShell +// +// The first to third digits represent the color value. +// The last digit represents the foreground(0), background(1), >1 is unset value +// +// Usage: +// +// // 0, 1, 2 is R,G,B. +// // 3rd: Fg=0, Bg=1, >1: unset value +// RGBColor{30,144,255, 0} +// RGBColor{30,144,255, 1} +type RGBColor [4]uint8 + +// create an empty RGBColor +var emptyRGBColor = RGBColor{3: 99} + +// RGB color create. +// +// Usage: +// +// c := RGB(30,144,255) +// c := RGB(30,144,255, true) +// c.Print("message") +func RGB(r, g, b uint8, isBg ...bool) RGBColor { + rgb := RGBColor{r, g, b} + if len(isBg) > 0 && isBg[0] { + rgb[3] = AsBg + } + + return rgb +} + +// Rgb alias of the RGB() +func Rgb(r, g, b uint8, isBg ...bool) RGBColor { return RGB(r, g, b, isBg...) } + +// Bit24 alias of the RGB() +func Bit24(r, g, b uint8, isBg ...bool) RGBColor { return RGB(r, g, b, isBg...) } + +// RgbFromInt create instance from int r,g,b value +func RgbFromInt(r, g, b int, isBg ...bool) RGBColor { + return RGB(uint8(r), uint8(g), uint8(b), isBg...) +} + +// RgbFromInts create instance from []int r,g,b value +func RgbFromInts(rgb []int, isBg ...bool) RGBColor { + return RGB(uint8(rgb[0]), uint8(rgb[1]), uint8(rgb[2]), isBg...) +} + +// HEX create RGB color from a HEX color string. +// +// Usage: +// +// c := HEX("ccc") // rgb: [204 204 204] +// c := HEX("aabbcc") // rgb: [170 187 204] +// c := HEX("#aabbcc") +// c := HEX("0xaabbcc") +// c.Print("message") +func HEX(hex string, isBg ...bool) RGBColor { + if rgb := HexToRgb(hex); len(rgb) > 0 { + return RGB(uint8(rgb[0]), uint8(rgb[1]), uint8(rgb[2]), isBg...) + } + + // mark is empty + return emptyRGBColor +} + +// Hex alias of the HEX() +func Hex(hex string, isBg ...bool) RGBColor { return HEX(hex, isBg...) } + +// RGBFromHEX quick RGBColor from hex string, alias of HEX() +func RGBFromHEX(hex string, isBg ...bool) RGBColor { return HEX(hex, isBg...) } + +// HSL create RGB color from a hsl value. +// more see HslToRgb() +func HSL(h, s, l float64, isBg ...bool) RGBColor { + rgb := HslToRgb(h, s, l) + return RGB(rgb[0], rgb[1], rgb[2], isBg...) +} + +// Hsl alias of the HSL() +func Hsl(h, s, l float64, isBg ...bool) RGBColor { return HSL(h, s, l, isBg...) } + +// HSLInt create RGB color from a hsl int value. +// more see HslIntToRgb() +func HSLInt(h, s, l int, isBg ...bool) RGBColor { + rgb := HslIntToRgb(h, s, l) + return RGB(rgb[0], rgb[1], rgb[2], isBg...) +} + +// HslInt alias of the HSLInt() +func HslInt(h, s, l int, isBg ...bool) RGBColor { return HSLInt(h, s, l, isBg...) } + +// RGBFromSlice quick RGBColor from slice +func RGBFromSlice(rgb []uint8, isBg ...bool) RGBColor { + return RGB(rgb[0], rgb[1], rgb[2], isBg...) +} + +// RGBFromString create RGB color from a string. +// Support use color name in the {namedRgbMap} +// +// Usage: +// +// c := RGBFromString("170,187,204") +// c.Print("message") +// +// c := RGBFromString("brown") +// c.Print("message with color brown") +func RGBFromString(rgb string, isBg ...bool) RGBColor { + // use color name in the {namedRgbMap} + if rgbVal, ok := namedRgbMap[rgb]; ok { + rgb = rgbVal + } + + // use rgb string. + ss := stringToArr(rgb, ",") + if len(ss) != 3 { + return emptyRGBColor + } + + var ar [3]uint8 + for i, val := range ss { + iv, err := strconv.Atoi(val) + if err != nil || !isValidUint8(iv) { + return emptyRGBColor + } + + ar[i] = uint8(iv) + } + + return RGB(ar[0], ar[1], ar[2], isBg...) +} + +// Set terminal by rgb/true color code +func (c RGBColor) Set() error { + return SetTerminal(c.String()) +} + +// Reset terminal. alias of the ResetTerminal() +func (c RGBColor) Reset() error { + return ResetTerminal() +} + +// Print print message +func (c RGBColor) Print(a ...any) { + doPrintV2(c.String(), fmt.Sprint(a...)) +} + +// Printf format and print message +func (c RGBColor) Printf(format string, a ...any) { + doPrintV2(c.String(), fmt.Sprintf(format, a...)) +} + +// Println print message with newline +func (c RGBColor) Println(a ...any) { + doPrintlnV2(c.String(), a) +} + +// Sprint returns rendered message +func (c RGBColor) Sprint(a ...any) string { + return RenderCode(c.String(), a...) +} + +// Sprintf returns format and rendered message +func (c RGBColor) Sprintf(format string, a ...any) string { + return RenderString(c.String(), fmt.Sprintf(format, a...)) +} + +// Values to RGB values +func (c RGBColor) Values() []int { + return []int{int(c[0]), int(c[1]), int(c[2])} +} + +// Code to color code string without prefix. eg: "204;123;56" +func (c RGBColor) Code() string { + return fmt.Sprintf("%d;%d;%d", c[0], c[1], c[2]) +} + +// Hex color rgb to hex string. as in "ff0080". +func (c RGBColor) Hex() string { + return fmt.Sprintf("%02x%02x%02x", c[0], c[1], c[2]) +} + +// RgbString to color code string without prefix. eg: "204,123,56" +func (c RGBColor) RgbString() string { + return fmt.Sprintf("%d,%d,%d", c[0], c[1], c[2]) +} + +// FullCode to color code string with prefix +func (c RGBColor) FullCode() string { + return c.String() +} + +// String to color code string with prefix. eg: "38;2;204;123;56" +func (c RGBColor) String() string { + if c[3] == AsFg { + return fmt.Sprintf(TplFgRGB, c[0], c[1], c[2]) + } + + if c[3] == AsBg { + return fmt.Sprintf(TplBgRGB, c[0], c[1], c[2]) + } + + // c[3] > 1 is empty + return "" +} + +// ToBg convert to background color +func (c RGBColor) ToBg() RGBColor { + c[3] = AsBg + return c +} + +// ToFg convert to foreground color +func (c RGBColor) ToFg() RGBColor { + c[3] = AsFg + return c +} + +// IsEmpty value +func (c RGBColor) IsEmpty() bool { + return c[3] > AsBg +} + +// IsValid value +// func (c RGBColor) IsValid() bool { +// return c[3] <= AsBg +// } + +// C256 returns the closest approximate 256 (8 bit) color +func (c RGBColor) C256() Color256 { + return C256(RgbTo256(c[0], c[1], c[2]), c[3] == AsBg) +} + +// Basic returns the closest approximate 16 (4 bit) color +func (c RGBColor) Basic() Color { + // return Color(RgbToAnsi(c[0], c[1], c[2], c[3] == AsBg)) + return Color(Rgb2basic(c[0], c[1], c[2], c[3] == AsBg)) +} + +// Color returns the closest approximate 16 (4 bit) color +func (c RGBColor) Color() Color { return c.Basic() } + +// C16 returns the closest approximate 16 (4 bit) color +func (c RGBColor) C16() Color { return c.Basic() } + +/************************************************************* + * RGB Style + *************************************************************/ + +// RGBStyle supports set foreground and background color +// +// All are composed of 4 digits uint8, the first three digits are the color value; +// The last bit is different from RGBColor, here it indicates whether the value is set. +// +// 1 Has been set +// ^1 Not set +type RGBStyle struct { + // Name of the style + Name string + // color options of the style + opts Opts + // fg and bg color + fg, bg RGBColor +} + +// NewRGBStyle create a RGBStyle. +func NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle { + s := &RGBStyle{} + if len(bg) > 0 { + s.SetBg(bg[0]) + } + + return s.SetFg(fg) +} + +// HEXStyle create a RGBStyle from HEX color string. +// +// Usage: +// +// s := HEXStyle("aabbcc", "eee") +// s.Print("message") +func HEXStyle(fg string, bg ...string) *RGBStyle { + s := &RGBStyle{} + if len(bg) > 0 { + s.SetBg(HEX(bg[0])) + } + + if len(fg) > 0 { + s.SetFg(HEX(fg)) + } + return s +} + +// RGBStyleFromString create a RGBStyle from color value string. +// +// Usage: +// +// s := RGBStyleFromString("170,187,204", "70,87,4") +// s.Print("message") +func RGBStyleFromString(fg string, bg ...string) *RGBStyle { + s := &RGBStyle{} + if len(bg) > 0 { + s.SetBg(RGBFromString(bg[0])) + } + + return s.SetFg(RGBFromString(fg)) +} + +// Set fg and bg color, can also with color options +func (s *RGBStyle) Set(fg, bg RGBColor, opts ...Color) *RGBStyle { + return s.SetFg(fg).SetBg(bg).SetOpts(opts) +} + +// SetFg set fg color +func (s *RGBStyle) SetFg(fg RGBColor) *RGBStyle { + fg[3] = 1 // add fixed value, mark is valid + s.fg = fg + return s +} + +// SetBg set bg color +func (s *RGBStyle) SetBg(bg RGBColor) *RGBStyle { + bg[3] = 1 // add fixed value, mark is valid + s.bg = bg + return s +} + +// SetOpts set color options +func (s *RGBStyle) SetOpts(opts Opts) *RGBStyle { + s.opts = opts + return s +} + +// AddOpts add options +func (s *RGBStyle) AddOpts(opts ...Color) *RGBStyle { + s.opts.Add(opts...) + return s +} + +// Print print message +func (s *RGBStyle) Print(a ...any) { + doPrintV2(s.String(), fmt.Sprint(a...)) +} + +// Printf format and print message +func (s *RGBStyle) Printf(format string, a ...any) { + doPrintV2(s.String(), fmt.Sprintf(format, a...)) +} + +// Println print message with newline +func (s *RGBStyle) Println(a ...any) { + doPrintlnV2(s.String(), a) +} + +// Sprint returns rendered message +func (s *RGBStyle) Sprint(a ...any) string { + return RenderCode(s.String(), a...) +} + +// Sprintf returns format and rendered message +func (s *RGBStyle) Sprintf(format string, a ...any) string { + return RenderString(s.String(), fmt.Sprintf(format, a...)) +} + +// Code convert to color code string +func (s *RGBStyle) Code() string { + return s.String() +} + +// FullCode convert to color code string +func (s *RGBStyle) FullCode() string { + return s.String() +} + +// String convert to color code string +func (s *RGBStyle) String() string { + var ss []string + // last value ensure is enable. + if s.fg[3] == 1 { + ss = append(ss, fmt.Sprintf(TplFgRGB, s.fg[0], s.fg[1], s.fg[2])) + } + + if s.bg[3] == 1 { + ss = append(ss, fmt.Sprintf(TplBgRGB, s.bg[0], s.bg[1], s.bg[2])) + } + + if s.opts.IsValid() { + ss = append(ss, s.opts.String()) + } + + return strings.Join(ss, ";") +} + +// IsEmpty style +func (s *RGBStyle) IsEmpty() bool { + return s.fg[3] != 1 && s.bg[3] != 1 +} diff --git a/vendor/github.com/gookit/color/color_tag.go b/vendor/github.com/gookit/color/color_tag.go new file mode 100644 index 0000000..1d2b9d3 --- /dev/null +++ b/vendor/github.com/gookit/color/color_tag.go @@ -0,0 +1,567 @@ +package color + +import ( + "fmt" + "regexp" + "strings" +) + +// output colored text like use html tag. (not support windows cmd) +const ( + // MatchExpr regex to match color tags + // + // Notice: golang 不支持反向引用. 即不支持使用 \1 引用第一个匹配 ([a-z=;]+) + // MatchExpr = `<([a-z=;]+)>(.*?)<\/\1>` + // 所以调整一下 统一使用 `</>` 来结束标签,例如 "<info>some text</>" + // + // allow custom attrs, eg: "<fg=white;bg=blue;op=bold>content</>" + // (?s:...) s - 让 "." 匹配换行 + MatchExpr = `<([0-9a-zA-Z_=,;]+)>(?s:(.*?))<\/>` + + // AttrExpr regex to match custom color attributes + // eg: "<fg=white;bg=blue;op=bold>content</>" + AttrExpr = `(fg|bg|op)[\s]*=[\s]*([0-9a-zA-Z,]+);?` + + // StripExpr regex used for removing color tags + // StripExpr = `<[\/]?[a-zA-Z=;]+>` + // 随着上面的做一些调整 + StripExpr = `<[\/]?[0-9a-zA-Z_=,;]*>` +) + +var ( + attrRegex = regexp.MustCompile(AttrExpr) + matchRegex = regexp.MustCompile(MatchExpr) + stripRegex = regexp.MustCompile(StripExpr) +) + +/************************************************************* + * internal defined color tags + *************************************************************/ + +// There are internal defined fg color tags +// +// Usage: +// +// <tag>content text</> +// +// @notice 加 0 在前面是为了防止之前的影响到现在的设置 +var colorTags = map[string]string{ + // basic tags + "red": "0;31", + "red1": "1;31", // with bold + "redB": "1;31", + "red_b": "1;31", + "blue": "0;34", + "blue1": "1;34", // with bold + "blueB": "1;34", + "blue_b": "1;34", + "cyan": "0;36", + "cyan1": "1;36", // with bold + "cyanB": "1;36", + "cyan_b": "1;36", + "green": "0;32", + "green1": "1;32", // with bold + "greenB": "1;32", + "green_b": "1;32", + "black": "0;30", + "white": "1;37", + "default": "0;39", // no color + "normal": "0;39", // no color + "brown": "0;33", // #A52A2A + "yellow": "0;33", + "ylw0": "0;33", + "yellowB": "1;33", // with bold + "ylw1": "1;33", + "ylwB": "1;33", + "magenta": "0;35", + "mga": "0;35", // short name + "magentaB": "1;35", // with bold + "magenta1": "1;35", + "mgb": "1;35", + "mga1": "1;35", + "mgaB": "1;35", + + // light/hi tags + + "gray": "0;90", + "darkGray": "0;90", + "dark_gray": "0;90", + "lightYellow": "0;93", + "light_yellow": "0;93", + "hiYellow": "0;93", + "hi_yellow": "0;93", + "hiYellowB": "1;93", // with bold + "hi_yellow_b": "1;93", + "lightMagenta": "0;95", + "light_magenta": "0;95", + "hiMagenta": "0;95", + "hi_magenta": "0;95", + "lightMagenta1": "1;95", // with bold + "hiMagentaB": "1;95", // with bold + "hi_magenta_b": "1;95", + "lightRed": "0;91", + "light_red": "0;91", + "hiRed": "0;91", + "hi_red": "0;91", + "lightRedB": "1;91", // with bold + "light_red_b": "1;91", + "hi_red_b": "1;91", + "lightGreen": "0;92", + "light_green": "0;92", + "hiGreen": "0;92", + "hi_green": "0;92", + "lightGreenB": "1;92", + "light_green_b": "1;92", + "hi_green_b": "1;92", + "lightBlue": "0;94", + "light_blue": "0;94", + "hiBlue": "0;94", + "hi_blue": "0;94", + "lightBlueB": "1;94", + "light_blue_b": "1;94", + "hi_blue_b": "1;94", + "lightCyan": "0;96", + "light_cyan": "0;96", + "hiCyan": "0;96", + "hi_cyan": "0;96", + "lightCyanB": "1;96", + "light_cyan_b": "1;96", + "hi_cyan_b": "1;96", + "lightWhite": "0;97;40", + "light_white": "0;97;40", + + // option + "bold": "1", + "b": "1", + "italic": "3", + "i": "3", // italic + "underscore": "4", + "us": "4", // short name for 'underscore' + "blink": "5", + "fb": "6", // fast blink + "reverse": "7", + "st": "9", // strikethrough + + // alert tags, like bootstrap's alert + "suc": "1;32", // same "green" and "bold" + "success": "1;32", + "info": "0;32", // same "green", + "comment": "0;33", // same "brown" + "note": "36;1", + "notice": "36;4", + "warn": "0;1;33", + "warning": "0;30;43", + "primary": "0;34", + "danger": "1;31", // same "red" but add bold + "err": "97;41", + "error": "97;41", // fg light white; bg red +} + +/************************************************************* + * internal defined tag attributes + *************************************************************/ + +// built-in attributes for fg,bg 16-colors and op codes. +var ( + attrFgs = map[string]string{ + // basic colors + + "black": FgBlack.Code(), + "red": "31", + "green": "32", + "brown": "33", // #A52A2A + "yellow": "33", + "ylw": "33", + "blue": "34", + "cyan": "36", + "magenta": "35", + "mga": "35", + "white": FgWhite.Code(), + "default": "39", // no color + "normal": "39", // no color + + // light/hi colors + + "darkGray": FgDarkGray.Code(), + "dark_gray": "90", + "gray": "90", + "lightYellow": "93", + "light_yellow": "93", + "hiYellow": "93", + "hi_yellow": "93", + "lightMagenta": "95", + "light_magenta": "95", + "hiMagenta": "95", + "hi_magenta": "95", + "hi_mga": "95", + "lightRed": "91", + "light_red": "91", + "hiRed": "91", + "hi_red": "91", + "lightGreen": "92", + "light_green": "92", + "hiGreen": "92", + "hi_green": "92", + "lightBlue": "94", + "light_blue": "94", + "hiBlue": "94", + "hi_blue": "94", + "lightCyan": "96", + "light_cyan": "96", + "hiCyan": "96", + "hi_cyan": "96", + "lightWhite": "97", + "light_white": "97", + } + + attrBgs = map[string]string{ + // basic colors + + "black": BgBlack.Code(), + "red": "41", + "green": "42", + "brown": "43", // #A52A2A + "yellow": "43", + "ylw": "43", + "blue": "44", + "cyan": "46", + "magenta": "45", + "mga": "45", + "white": FgWhite.Code(), + "default": "49", // no color + "normal": "49", // no color + + // light/hi colors + + "darkGray": BgDarkGray.Code(), + "dark_gray": "100", + "gray": "100", + "lightYellow": "103", + "light_yellow": "103", + "hiYellow": "103", + "hi_yellow": "103", + "lightMagenta": "105", + "light_magenta": "105", + "hiMagenta": "105", + "hi_magenta": "105", + "hi_mga": "105", + "lightRed": "101", + "light_red": "101", + "hiRed": "101", + "hi_red": "101", + "lightGreen": "102", + "light_green": "102", + "hiGreen": "102", + "hi_green": "102", + "lightBlue": "104", + "light_blue": "104", + "hiBlue": "104", + "hi_blue": "104", + "lightCyan": "106", + "light_cyan": "106", + "hiCyan": "106", + "hi_cyan": "106", + "lightWhite": BgLightWhite.Code(), + "light_white": "107", + } + + attrOpts = map[string]string{ + "reset": OpReset.Code(), + "bold": OpBold.Code(), + "b": OpBold.Code(), + "fuzzy": OpFuzzy.Code(), + "italic": OpItalic.Code(), + "i": OpItalic.Code(), + "underscore": OpUnderscore.Code(), + "us": OpUnderscore.Code(), + "u": OpUnderscore.Code(), + "blink": OpBlink.Code(), + "fastblink": OpFastBlink.Code(), + "fb": OpFastBlink.Code(), + "reverse": OpReverse.Code(), + "concealed": OpConcealed.Code(), + "strikethrough": OpStrikethrough.Code(), + "st": OpStrikethrough.Code(), + } +) + +/************************************************************* + * parse color tags + *************************************************************/ + +var ( + tagParser = TagParser{} + // regex for match color 256 code + rxNumStr = regexp.MustCompile("^[0-9]{1,3}$") + rxHexCode = regexp.MustCompile("^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$") +) + +// TagParser struct +type TagParser struct { + disable bool +} + +// NewTagParser create +func NewTagParser() *TagParser { + return &TagParser{} +} + +// func (tp *TagParser) Disable() *TagParser { +// tp.disable = true +// return tp +// } + +// ParseByEnv parse given string. will check package setting. +func (tp *TagParser) ParseByEnv(str string) string { + // disable handler TAG + if !RenderTag { + return str + } + + // disable OR not support color + if !Enable || !SupportColor() { + return ClearTag(str) + } + return tp.Parse(str) +} + +// Parse given string, replace color tag and return rendered string +// +// Use built in tags: +// +// <TAG_NAME>CONTENT</> +// // e.g: `<info>message</>` +// +// Custom tag attributes: +// +// `<fg=VALUE;bg=VALUE;op=VALUES>CONTENT</>` +// // e.g: `<fg=167;bg=232>wel</>` +func (tp *TagParser) Parse(str string) string { + // not contains color tag + if !strings.Contains(str, "</>") { + return str + } + + // find color tags by regex. str eg: "<fg=white;bg=blue;op=bold>content</>" + matched := matchRegex.FindAllStringSubmatch(str, -1) + + // item: 0 full text 1 tag name 2 tag content + for _, item := range matched { + full, tag, body := item[0], item[1], item[2] + + // use defined color tag name: "<info>content</>" -> tag: "info" + if !strings.ContainsRune(tag, '=') { + if code := colorTags[tag]; len(code) > 0 { + str = strings.Replace(str, full, RenderString(code, body), 1) + } else if code, ok := namedRgbMap[tag]; ok { + code = strings.Replace(code, ",", ";", -1) + now := RenderString(FgRGBPfx+code, body) + str = strings.Replace(str, full, now, 1) + } + continue + } + + // custom color in tag + // - basic: "fg=white;bg=blue;op=bold" + if code := ParseCodeFromAttr(tag); len(code) > 0 { + str = strings.Replace(str, full, RenderString(code, body), 1) + } + } + + return str +} + +// ReplaceTag parse string, replace color tag and return rendered string +func ReplaceTag(str string) string { + return tagParser.ParseByEnv(str) +} + +// ParseCodeFromAttr parse color attributes. +// +// attr format: +// +// // VALUE please see var: FgColors, BgColors, AllOptions +// "fg=VALUE;bg=VALUE;op=VALUE" +// +// 16 color: +// +// "fg=yellow" +// "bg=red" +// "op=bold,underscore" // option is allow multi value +// "fg=white;bg=blue;op=bold" +// "fg=white;op=bold,underscore" +// +// 256 color: +// +// "fg=167" +// "fg=167;bg=23" +// "fg=167;bg=23;op=bold" +// +// True color: +// +// // hex +// "fg=fc1cac" +// "fg=fc1cac;bg=c2c3c4" +// // r,g,b +// "fg=23,45,214" +// "fg=23,45,214;bg=109,99,88" +func ParseCodeFromAttr(attr string) (code string) { + if !strings.ContainsRune(attr, '=') { + return + } + + attr = strings.Trim(attr, ";=,") + if len(attr) == 0 { + return + } + + var codes []string + matched := attrRegex.FindAllStringSubmatch(attr, -1) + + for _, item := range matched { + pos, val := item[1], item[2] + switch pos { + case "fg": + if code, ok := attrFgs[val]; ok { // attr fg + codes = append(codes, code) + } else if code := rgbHex256toCode(val, false); code != "" { + codes = append(codes, code) + } + case "bg": + if code, ok := attrBgs[val]; ok { // attr bg + codes = append(codes, code) + } else if code := rgbHex256toCode(val, true); code != "" { + codes = append(codes, code) + } + case "op": // options allow multi value + if strings.Contains(val, ",") { + ns := strings.Split(val, ",") + for _, n := range ns { + if code, ok := attrOpts[n]; ok { // attr ops + codes = append(codes, code) + } + } + } else if code, ok := attrOpts[val]; ok { + codes = append(codes, code) + } + } + } + + return strings.Join(codes, ";") +} + +func rgbHex256toCode(val string, isBg bool) (code string) { + if len(val) == 6 && rxHexCode.MatchString(val) { // hex: "fc1cac" + code = HEX(val, isBg).String() + } else if strings.ContainsRune(val, ',') { // rgb: "231,178,161" + code = strings.Replace(val, ",", ";", -1) + if isBg { + code = BgRGBPfx + code + } else { + code = FgRGBPfx + code + } + } else if len(val) < 4 && rxNumStr.MatchString(val) { // 256 code + if isBg { + code = Bg256Pfx + val + } else { + code = Fg256Pfx + val + } + } + return +} + +// ClearTag clear all tag for a string +func ClearTag(s string) string { + if !strings.Contains(s, "</>") { + return s + } + return stripRegex.ReplaceAllString(s, "") +} + +/************************************************************* + * helper methods + *************************************************************/ + +// GetTagCode get color code by tag name +func GetTagCode(name string) string { return colorTags[name] } + +// ApplyTag for messages +func ApplyTag(tag string, a ...any) string { + return RenderCode(GetTagCode(tag), a...) +} + +// WrapTag wrap a tag for a string "<tag>content</>" +func WrapTag(s string, tag string) string { + if s == "" || tag == "" { + return s + } + return fmt.Sprintf("<%s>%s</>", tag, s) +} + +// GetColorTags get all internal color tags +func GetColorTags() map[string]string { + return colorTags +} + +// IsDefinedTag is defined tag name +func IsDefinedTag(name string) bool { + _, ok := colorTags[name] + return ok +} + +/************************************************************* + * Tag extra + *************************************************************/ + +// Tag value is a defined style name +// Usage: +// +// Tag("info").Println("message") +type Tag string + +// Print messages +func (tg Tag) Print(a ...any) { + name := string(tg) + str := fmt.Sprint(a...) + + if stl := GetStyle(name); !stl.IsEmpty() { + stl.Print(str) + } else { + doPrintV2(GetTagCode(name), str) + } +} + +// Printf format and print messages +func (tg Tag) Printf(format string, a ...any) { + name := string(tg) + str := fmt.Sprintf(format, a...) + + if stl := GetStyle(name); !stl.IsEmpty() { + stl.Print(str) + } else { + doPrintV2(GetTagCode(name), str) + } +} + +// Println messages line +func (tg Tag) Println(a ...any) { + name := string(tg) + if stl := GetStyle(name); !stl.IsEmpty() { + stl.Println(a...) + } else { + doPrintlnV2(GetTagCode(name), a) + } +} + +// Sprint render messages +func (tg Tag) Sprint(a ...any) string { + return RenderCode(GetTagCode(string(tg)), a...) +} + +// Sprintf format and render messages +func (tg Tag) Sprintf(format string, a ...any) string { + tag := string(tg) + str := fmt.Sprintf(format, a...) + + return RenderString(GetTagCode(tag), str) +} diff --git a/vendor/github.com/gookit/color/convert.go b/vendor/github.com/gookit/color/convert.go new file mode 100644 index 0000000..c710353 --- /dev/null +++ b/vendor/github.com/gookit/color/convert.go @@ -0,0 +1,966 @@ +package color + +import ( + "fmt" + "math" + "sort" + "strconv" + "strings" +) + +// values from https://github.com/go-terminfo/terminfo +// var ( +// RgbaBlack = image_color.RGBA{0, 0, 0, 255} +// Red = color.RGBA{205, 0, 0, 255} +// Green = color.RGBA{0, 205, 0, 255} +// Orange = color.RGBA{205, 205, 0, 255} +// Blue = color.RGBA{0, 0, 238, 255} +// Magenta = color.RGBA{205, 0, 205, 255} +// Cyan = color.RGBA{0, 205, 205, 255} +// LightGrey = color.RGBA{229, 229, 229, 255} +// +// DarkGrey = color.RGBA{127, 127, 127, 255} +// LightRed = color.RGBA{255, 0, 0, 255} +// LightGreen = color.RGBA{0, 255, 0, 255} +// Yellow = color.RGBA{255, 255, 0, 255} +// LightBlue = color.RGBA{92, 92, 255, 255} +// LightMagenta = color.RGBA{255, 0, 255, 255} +// LightCyan = color.RGBA{0, 255, 255, 255} +// White = color.RGBA{255, 255, 255, 255} +// ) + +var ( + // ---------- basic(16) <=> 256 color convert ---------- + basicTo256Map = map[uint8]uint8{ + 30: 0, // black 000000 + 31: 160, // red c51e14 + 32: 34, // green 1dc121 + 33: 184, // yellow c7c329 + 34: 20, // blue 0a2fc4 + 35: 170, // magenta c839c5 + 36: 44, // cyan 20c5c6 + 37: 188, // white c7c7c7 + 90: 59, // lightBlack 686868 + 91: 203, // lightRed fd6f6b + 92: 83, // lightGreen 67f86f + 93: 227, // lightYellow fffa72 + 94: 69, // lightBlue 6a76fb + 95: 213, // lightMagenta fd7cfc + 96: 87, // lightCyan 68fdfe + 97: 15, // lightWhite ffffff + } + + // ---------- basic(16) <=> RGB color convert ---------- + // refer from Hyper app + // Tip: only keep foreground color, background color need convert to foreground color for convert to RGB + basic2hexMap = map[uint8]string{ + 30: "000000", // black + 31: "c51e14", // red + 32: "1dc121", // green + 33: "c7c329", // yellow + 34: "0a2fc4", // blue + 35: "c839c5", // magenta + 36: "20c5c6", // cyan + 37: "c7c7c7", // white + // - don't add bg color, convert to fg color for convert to RGB + // 40: "000000", // black + // 41: "c51e14", // red + // 42: "1dc121", // green + // 43: "c7c329", // yellow + // 44: "0a2fc4", // blue + // 45: "c839c5", // magenta + // 46: "20c5c6", // cyan + // 47: "c7c7c7", // white + 90: "686868", // lightBlack/darkGray + 91: "fd6f6b", // lightRed + 92: "67f86f", // lightGreen + 93: "fffa72", // lightYellow + 94: "6a76fb", // lightBlue + 95: "fd7cfc", // lightMagenta + 96: "68fdfe", // lightCyan + 97: "ffffff", // lightWhite + // - don't add bg color + // 100: "686868", // lightBlack/darkGray + // 101: "fd6f6b", // lightRed + // 102: "67f86f", // lightGreen + // 103: "fffa72", // lightYellow + // 104: "6a76fb", // lightBlue + // 105: "fd7cfc", // lightMagenta + // 106: "68fdfe", // lightCyan + // 107: "ffffff", // lightWhite + } + // will convert data from basic2hexMap + hex2basicMap = initHex2basicMap() + + // ---------- 256 <=> RGB color convert ---------- + // adapted from https://gist.github.com/MicahElliott/719710 + + c256ToHexMap = init256ToHexMap() + + // rgb to 256 color look-up table + // RGB hex => 256 code + hexTo256Table = map[string]uint8{ + // Primary 3-bit (8 colors). Unique representation! + "000000": 0, + "800000": 1, + "008000": 2, + "808000": 3, + "000080": 4, + "800080": 5, + "008080": 6, + "c0c0c0": 7, + + // Equivalent "bright" versions of original 8 colors. + "808080": 8, + "ff0000": 9, + "00ff00": 10, + "ffff00": 11, + "0000ff": 12, + "ff00ff": 13, + "00ffff": 14, + "ffffff": 15, + + // values commented out below are duplicates from the prior sections + + // Strictly ascending. + // "000000": 16, + "000001": 16, // up: avoid key conflicts, value + 1 + "00005f": 17, + "000087": 18, + "0000af": 19, + "0000d7": 20, + // "0000ff": 21, + "0000fe": 21, // up: avoid key conflicts, value - 1 + "005f00": 22, + "005f5f": 23, + "005f87": 24, + "005faf": 25, + "005fd7": 26, + "005fff": 27, + "008700": 28, + "00875f": 29, + "008787": 30, + "0087af": 31, + "0087d7": 32, + "0087ff": 33, + "00af00": 34, + "00af5f": 35, + "00af87": 36, + "00afaf": 37, + "00afd7": 38, + "00afff": 39, + "00d700": 40, + "00d75f": 41, + "00d787": 42, + "00d7af": 43, + "00d7d7": 44, + "00d7ff": 45, + // "00ff00": 46, + "00ff01": 46, // up: avoid key conflicts, value + 1 + "00ff5f": 47, + "00ff87": 48, + "00ffaf": 49, + "00ffd7": 50, + // "00ffff": 51, + "00fffe": 51, // up: avoid key conflicts, value - 1 + "5f0000": 52, + "5f005f": 53, + "5f0087": 54, + "5f00af": 55, + "5f00d7": 56, + "5f00ff": 57, + "5f5f00": 58, + "5f5f5f": 59, + "5f5f87": 60, + "5f5faf": 61, + "5f5fd7": 62, + "5f5fff": 63, + "5f8700": 64, + "5f875f": 65, + "5f8787": 66, + "5f87af": 67, + "5f87d7": 68, + "5f87ff": 69, + "5faf00": 70, + "5faf5f": 71, + "5faf87": 72, + "5fafaf": 73, + "5fafd7": 74, + "5fafff": 75, + "5fd700": 76, + "5fd75f": 77, + "5fd787": 78, + "5fd7af": 79, + "5fd7d7": 80, + "5fd7ff": 81, + "5fff00": 82, + "5fff5f": 83, + "5fff87": 84, + "5fffaf": 85, + "5fffd7": 86, + "5fffff": 87, + "870000": 88, + "87005f": 89, + "870087": 90, + "8700af": 91, + "8700d7": 92, + "8700ff": 93, + "875f00": 94, + "875f5f": 95, + "875f87": 96, + "875faf": 97, + "875fd7": 98, + "875fff": 99, + "878700": 100, + "87875f": 101, + "878787": 102, + "8787af": 103, + "8787d7": 104, + "8787ff": 105, + "87af00": 106, + "87af5f": 107, + "87af87": 108, + "87afaf": 109, + "87afd7": 110, + "87afff": 111, + "87d700": 112, + "87d75f": 113, + "87d787": 114, + "87d7af": 115, + "87d7d7": 116, + "87d7ff": 117, + "87ff00": 118, + "87ff5f": 119, + "87ff87": 120, + "87ffaf": 121, + "87ffd7": 122, + "87ffff": 123, + "af0000": 124, + "af005f": 125, + "af0087": 126, + "af00af": 127, + "af00d7": 128, + "af00ff": 129, + "af5f00": 130, + "af5f5f": 131, + "af5f87": 132, + "af5faf": 133, + "af5fd7": 134, + "af5fff": 135, + "af8700": 136, + "af875f": 137, + "af8787": 138, + "af87af": 139, + "af87d7": 140, + "af87ff": 141, + "afaf00": 142, + "afaf5f": 143, + "afaf87": 144, + "afafaf": 145, + "afafd7": 146, + "afafff": 147, + "afd700": 148, + "afd75f": 149, + "afd787": 150, + "afd7af": 151, + "afd7d7": 152, + "afd7ff": 153, + "afff00": 154, + "afff5f": 155, + "afff87": 156, + "afffaf": 157, + "afffd7": 158, + "afffff": 159, + "d70000": 160, + "d7005f": 161, + "d70087": 162, + "d700af": 163, + "d700d7": 164, + "d700ff": 165, + "d75f00": 166, + "d75f5f": 167, + "d75f87": 168, + "d75faf": 169, + "d75fd7": 170, + "d75fff": 171, + "d78700": 172, + "d7875f": 173, + "d78787": 174, + "d787af": 175, + "d787d7": 176, + "d787ff": 177, + "d7af00": 178, + "d7af5f": 179, + "d7af87": 180, + "d7afaf": 181, + "d7afd7": 182, + "d7afff": 183, + "d7d700": 184, + "d7d75f": 185, + "d7d787": 186, + "d7d7af": 187, + "d7d7d7": 188, + "d7d7ff": 189, + "d7ff00": 190, + "d7ff5f": 191, + "d7ff87": 192, + "d7ffaf": 193, + "d7ffd7": 194, + "d7ffff": 195, + // "ff0000": 196, + "ff0001": 196, // up: avoid key conflicts, value + 1 + "ff005f": 197, + "ff0087": 198, + "ff00af": 199, + "ff00d7": 200, + // "ff00ff": 201, + "ff00fe": 201, // up: avoid key conflicts, value - 1 + "ff5f00": 202, + "ff5f5f": 203, + "ff5f87": 204, + "ff5faf": 205, + "ff5fd7": 206, + "ff5fff": 207, + "ff8700": 208, + "ff875f": 209, + "ff8787": 210, + "ff87af": 211, + "ff87d7": 212, + "ff87ff": 213, + "ffaf00": 214, + "ffaf5f": 215, + "ffaf87": 216, + "ffafaf": 217, + "ffafd7": 218, + "ffafff": 219, + "ffd700": 220, + "ffd75f": 221, + "ffd787": 222, + "ffd7af": 223, + "ffd7d7": 224, + "ffd7ff": 225, + // "ffff00": 226, + "ffff01": 226, // up: avoid key conflicts, value + 1 + "ffff5f": 227, + "ffff87": 228, + "ffffaf": 229, + "ffffd7": 230, + // "ffffff": 231, + "fffffe": 231, // up: avoid key conflicts, value - 1 + + // Gray-scale range. + "080808": 232, + "121212": 233, + "1c1c1c": 234, + "262626": 235, + "303030": 236, + "3a3a3a": 237, + "444444": 238, + "4e4e4e": 239, + "585858": 240, + "626262": 241, + "6c6c6c": 242, + "767676": 243, + // "808080": 244, + "808081": 244, // up: avoid key conflicts, value + 1 + "8a8a8a": 245, + "949494": 246, + "9e9e9e": 247, + "a8a8a8": 248, + "b2b2b2": 249, + "bcbcbc": 250, + "c6c6c6": 251, + "d0d0d0": 252, + "dadada": 253, + "e4e4e4": 254, + "eeeeee": 255, + } + + incs = []uint8{0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff} +) + +func initHex2basicMap() map[string]uint8 { + h2b := make(map[string]uint8, len(basic2hexMap)) + // ini data map + for u, s := range basic2hexMap { + h2b[s] = u + } + return h2b +} + +func init256ToHexMap() map[uint8]string { + c256toh := make(map[uint8]string, len(hexTo256Table)) + // ini data map + for hex, c256 := range hexTo256Table { + c256toh[c256] = hex + } + return c256toh +} + +// RgbTo256Table mapping data +func RgbTo256Table() map[string]uint8 { + return hexTo256Table +} + +// Colors2code convert colors to code. return like "32;45;3" +func Colors2code(colors ...Color) string { + if len(colors) == 0 { + return "" + } + + var codes []string + for _, color := range colors { + codes = append(codes, color.String()) + } + + return strings.Join(codes, ";") +} + +/************************************************************* + * HEX code <=> RGB/True color code + *************************************************************/ + +// Hex2rgb alias of the HexToRgb() +func Hex2rgb(hex string) []int { return HexToRgb(hex) } + +// HexToRGB alias of the HexToRgb() +func HexToRGB(hex string) []int { return HexToRgb(hex) } + +// HexToRgb convert hex color string to RGB numbers +// +// Usage: +// +// rgb := HexToRgb("ccc") // rgb: [204 204 204] +// rgb := HexToRgb("aabbcc") // rgb: [170 187 204] +// rgb := HexToRgb("#aabbcc") // rgb: [170 187 204] +// rgb := HexToRgb("0xad99c0") // rgb: [170 187 204] +func HexToRgb(hex string) (rgb []int) { + hex = strings.TrimSpace(hex) + if hex == "" { + return + } + + // like from css. eg "#ccc" "#ad99c0" + if hex[0] == '#' { + hex = hex[1:] + } + + hex = strings.ToLower(hex) + switch len(hex) { + case 3: // "ccc" + hex = string([]byte{hex[0], hex[0], hex[1], hex[1], hex[2], hex[2]}) + case 8: // "0xad99c0" + hex = strings.TrimPrefix(hex, "0x") + } + + // recheck + if len(hex) != 6 { + return + } + + // convert string to int64 + if i64, err := strconv.ParseInt(hex, 16, 32); err == nil { + color := int(i64) + // parse int + rgb = make([]int, 3) + rgb[0] = color >> 16 + rgb[1] = (color & 0x00FF00) >> 8 + rgb[2] = color & 0x0000FF + } + return +} + +// Rgb2hex alias of the RgbToHex() +func Rgb2hex(rgb []int) string { return RgbToHex(rgb) } + +// RgbToHex convert RGB-code to hex-code +// +// Usage: +// +// hex := RgbToHex([]int{170, 187, 204}) // hex: "aabbcc" +func RgbToHex(rgb []int) string { + hexNodes := make([]string, len(rgb)) + + for _, v := range rgb { + hexNodes = append(hexNodes, strconv.FormatInt(int64(v), 16)) + } + return strings.Join(hexNodes, "") +} + +/************************************************************* + * 4bit(16) color <=> RGB/True color + *************************************************************/ + +// BasicToHex convert basic color to hex string. +func BasicToHex(val uint8) string { + val = Bg2Fg(val) + return basic2hexMap[val] +} + +// Basic2hex convert basic color to hex string. +func Basic2hex(val uint8) string { + return BasicToHex(val) +} + +// Hex2basic convert hex string to basic color code. +func Hex2basic(hex string, asBg ...bool) uint8 { + val := hex2basicMap[hex] + + if len(asBg) > 0 && asBg[0] { + return Fg2Bg(val) + } + return val +} + +// Rgb2basic alias of the RgbToAnsi() +func Rgb2basic(r, g, b uint8, isBg bool) uint8 { + // is basic color, direct use static map data. + hex := RgbToHex([]int{int(r), int(g), int(b)}) + if val, ok := hex2basicMap[hex]; ok { + if isBg { + return val + 10 + } + return val + } + + return RgbToAnsi(r, g, b, isBg) +} + +// Rgb2ansi convert RGB-code to 16-code, alias of the RgbToAnsi() +func Rgb2ansi(r, g, b uint8, isBg bool) uint8 { + return RgbToAnsi(r, g, b, isBg) +} + +// RgbToAnsi convert RGB-code to 16-code +// refer https://github.com/radareorg/radare2/blob/master/libr/cons/rgb.c#L249-L271 +func RgbToAnsi(r, g, b uint8, isBg bool) uint8 { + var bright, c, k uint8 + base := compareVal(isBg, BgBase, FgBase) + + // eco bright-specific + if r == 0x80 && g == 0x80 && b == 0x80 { // 0x80=128 + bright = 53 + } else if r == 0xff || g == 0xff || b == 0xff { // 0xff=255 + bright = 60 + } // else bright = 0 + + if r == g && g == b { + // 0x7f=127 + // r = (r > 0x7f) ? 1 : 0; + r = compareVal(r > 0x7f, 1, 0) + g = compareVal(g > 0x7f, 1, 0) + b = compareVal(b > 0x7f, 1, 0) + } else { + k = (r + g + b) / 3 + + // r = (r >= k) ? 1 : 0; + r = compareVal(r >= k, 1, 0) + g = compareVal(g >= k, 1, 0) + b = compareVal(b >= k, 1, 0) + } + + // c = (r ? 1 : 0) + (g ? (b ? 6 : 2) : (b ? 4 : 0)) + c = compareVal(r > 0, 1, 0) + + if g > 0 { + c += compareVal(b > 0, 6, 2) + } else { + c += compareVal(b > 0, 4, 0) + } + return base + bright + c +} + +/************************************************************* + * 8bit(256) color <=> RGB/True color + *************************************************************/ + +// Rgb2short convert RGB-code to 256-code +func Rgb2short(r, g, b uint8) uint8 { + return RgbTo256(r, g, b) +} + +// RgbTo256 convert RGB-code to 256-code +func RgbTo256(r, g, b uint8) uint8 { + res := make([]uint8, 3) + for partI, part := range [3]uint8{r, g, b} { + i := 0 + for i < len(incs)-1 { + s, b := incs[i], incs[i+1] // smaller, bigger + if s <= part && part <= b { + s1 := math.Abs(float64(s) - float64(part)) + b1 := math.Abs(float64(b) - float64(part)) + var closest uint8 + if s1 < b1 { + closest = s + } else { + closest = b + } + res[partI] = closest + break + } + i++ + } + } + hex := fmt.Sprintf("%02x%02x%02x", res[0], res[1], res[2]) + equiv := hexTo256Table[hex] + return equiv +} + +// C256ToRgb convert an 256 color code to RGB numbers +func C256ToRgb(val uint8) (rgb []uint8) { + hex := c256ToHexMap[val] + // convert to rgb code + rgbInts := Hex2rgb(hex) + + return []uint8{ + uint8(rgbInts[0]), + uint8(rgbInts[1]), + uint8(rgbInts[2]), + } +} + +// C256ToRgbV1 convert an 256 color code to RGB numbers +// refer https://github.com/torvalds/linux/commit/cec5b2a97a11ade56a701e83044d0a2a984c67b4 +func C256ToRgbV1(val uint8) (rgb []uint8) { + var r, g, b uint8 + if val < 8 { // Standard colours. + // r = val&1 ? 0xaa : 0x00; + r = compareVal(val&1 == 1, 0xaa, 0x00) + g = compareVal(val&2 == 2, 0xaa, 0x00) + b = compareVal(val&4 == 4, 0xaa, 0x00) + } else if val < 16 { + // r = val & 1 ? 0xff : 0x55; + r = compareVal(val&1 == 1, 0xff, 0x55) + g = compareVal(val&2 == 2, 0xff, 0x55) + b = compareVal(val&4 == 4, 0xff, 0x55) + } else if val < 232 { /* 6x6x6 colour cube. */ + r = (val - 16) / 36 * 85 / 2 + g = (val - 16) / 6 % 6 * 85 / 2 + b = (val - 16) % 6 * 85 / 2 + } else { /* Grayscale ramp. */ + nv := uint8(int(val)*10 - 2312) + // set value + r, g, b = nv, nv, nv + } + + return []uint8{r, g, b} +} + +/************************************************************** + * HSL color <=> RGB/True color + ************************************************************ + * h,s,l = Hue, Saturation, Lightness + * + * refers + * http://en.wikipedia.org/wiki/HSL_color_space + * https://www.w3.org/TR/css-color-3/#hsl-color + * https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion + * https://github.com/less/less.js/blob/master/packages/less/src/less/functions/color.js + * https://github.com/d3/d3-color/blob/v3.0.1/README.md#hsl + * + * examples: + * color: hsl(0, 100%, 50%) // red + * color: hsl(120, 100%, 50%) // lime + * color: hsl(120, 100%, 25%) // dark green + * color: hsl(120, 100%, 75%) // light green + * color: hsl(120, 75%, 75%) // pastel green, and so on + */ + +// HslIntToRgb Converts an HSL color value to RGB +// Assumes h: 0-360, s: 0-100, l: 0-100 +// returns r, g, and b in the set [0, 255]. +// +// Usage: +// +// HslIntToRgb(0, 100, 50) // red +// HslIntToRgb(120, 100, 50) // lime +// HslIntToRgb(120, 100, 25) // dark green +// HslIntToRgb(120, 100, 75) // light green +func HslIntToRgb(h, s, l int) (rgb []uint8) { + return HslToRgb(float64(h)/360, float64(s)/100, float64(l)/100) +} + +// HslToRgb Converts an HSL color value to RGB. Conversion formula +// adapted from http://en.wikipedia.org/wiki/HSL_color_space. +// Assumes h, s, and l are contained in the set [0, 1] +// returns r, g, and b in the set [0, 255]. +// +// Usage: +// +// rgbVals := HslToRgb(0, 1, 0.5) // red +func HslToRgb(h, s, l float64) (rgb []uint8) { + var r, g, b float64 + + if s == 0 { // achromatic + r, g, b = l, l, l + } else { + var hue2rgb = func(p, q, t float64) float64 { + if t < 0.0 { + t += 1 + } + if t > 1.0 { + t -= 1 + } + + if t < 1.0/6.0 { + return p + (q-p)*6.0*t + } + + if t < 1.0/2.0 { + return q + } + + if t < 2.0/3.0 { + return p + (q-p)*(2.0/3.0-t)*6.0 + } + return p + } + + // q = l < 0.5 ? l * (1 + s) : l + s - l*s + var q float64 + if l < 0.5 { + q = l * (1.0 + s) + } else { + q = l + s - l*s + } + + var p = 2.0*l - q + + r = hue2rgb(p, q, h+1.0/3.0) + g = hue2rgb(p, q, h) + b = hue2rgb(p, q, h-1.0/3.0) + } + + // return []uint8{uint8(r * 255), uint8(g * 255), uint8(b * 255)} + return []uint8{ + uint8(math.Round(r * 255)), + uint8(math.Round(g * 255)), + uint8(math.Round(b * 255)), + } +} + +// RgbToHslInt Converts an RGB color value to HSL. Conversion formula +// Assumes r, g, and b are contained in the set [0, 255] and +// returns [h,s,l] h: 0-360, s: 0-100, l: 0-100. +func RgbToHslInt(r, g, b uint8) []int { + f64s := RgbToHsl(r, g, b) + + return []int{int(f64s[0] * 360), int(f64s[1] * 100), int(f64s[2] * 100)} +} + +// RgbToHsl Converts an RGB color value to HSL. Conversion formula +// +// adapted from http://en.wikipedia.org/wiki/HSL_color_space. +// +// Assumes r, g, and b are contained in the set [0, 255] and +// returns h, s, and l in the set [0, 1]. +func RgbToHsl(r, g, b uint8) []float64 { + // to float64 + fr, fg, fb := float64(r), float64(g), float64(b) + // percentage + pr, pg, pb := float64(r)/255.0, float64(g)/255.0, float64(b)/255.0 + + ps := []float64{pr, pg, pb} + sort.Float64s(ps) + + min, max := ps[0], ps[2] + // max := math.Max(math.Max(pr, pg), pb) + // min := math.Min(math.Min(pr, pg), pb) + mid := (max + min) / 2 + + h, s, l := mid, mid, mid + if max == min { + h, s = 0, 0 // achromatic + } else { + var d = max - min + // s = l > 0.5 ? d / (2 - max - min) : d / (max + min) + s = compareF64Val(l > 0.5, d/(2-max-min), d/(max+min)) + + switch max { + case fr: + // h = (g - b) / d + (g < b ? 6 : 0) + h = (fg - fb) / d + h += compareF64Val(g < b, 6, 0) + case fg: + h = (fb-fr)/d + 2 + case fb: + h = (fr-fg)/d + 4 + } + + h /= 6 + } + + return []float64{h, s, l} +} + +/************************************************************** + * HSV color <=> RGB/True color + ************************************************************ + * h,s,l = Hue, Saturation, Value(Brightness) + * + * refers + * https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion + * https://github.com/less/less.js/blob/master/packages/less/src/less/functions/color.js + * https://github.com/d3/d3-color/blob/v3.0.1/README.md#hsl + */ + +// HsvToRgb Converts an HSL color value to RGB. Conversion formula +// adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB +// Assumes h: 0-360, s: 0-100, l: 0-100 +// returns r, g, and b in the set [0, 255]. +func HsvToRgb(h, s, v int) (rgb []uint8) { + // TODO ... + return +} + +// Named rgb colors +// https://www.w3.org/TR/css-color-3/#svg-color +var namedRgbMap = map[string]string{ + "aliceblue": "240,248,255", // #F0F8FF + "antiquewhite": "250,235,215", // #FAEBD7 + "aqua": "0,255,255", // #00FFFF + "aquamarine": "127,255,212", // #7FFFD4 + "azure": "240,255,255", // #F0FFFF + "beige": "245,245,220", // #F5F5DC + "bisque": "255,228,196", // #FFE4C4 + "black": "0,0,0", // #000000 + "blanchedalmond": "255,235,205", // #FFEBCD + "blue": "0,0,255", // #0000FF + "blueviolet": "138,43,226", // #8A2BE2 + "brown": "165,42,42", // #A52A2A + "burlywood": "222,184,135", // #DEB887 + "cadetblue": "95,158,160", // #5F9EA0 + "chartreuse": "127,255,0", // #7FFF00 + "chocolate": "210,105,30", // #D2691E + "coral": "255,127,80", // #FF7F50 + "cornflowerblue": "100,149,237", // #6495ED + "cornsilk": "255,248,220", // #FFF8DC + "crimson": "220,20,60", // #DC143C + "cyan": "0,255,255", // #00FFFF + "darkblue": "0,0,139", // #00008B + "darkcyan": "0,139,139", // #008B8B + "darkgoldenrod": "184,134,11", // #B8860B + "darkgray": "169,169,169", // #A9A9A9 + "darkgreen": "0,100,0", // #006400 + "darkgrey": "169,169,169", // #A9A9A9 + "darkkhaki": "189,183,107", // #BDB76B + "darkmagenta": "139,0,139", // #8B008B + "darkolivegreen": "85,107,47", // #556B2F + "darkorange": "255,140,0", // #FF8C00 + "darkorchid": "153,50,204", // #9932CC + "darkred": "139,0,0", // #8B0000 + "darksalmon": "233,150,122", // #E9967A + "darkseagreen": "143,188,143", // #8FBC8F + "darkslateblue": "72,61,139", // #483D8B + "darkslategray": "47,79,79", // #2F4F4F + "darkslategrey": "47,79,79", // #2F4F4F + "darkturquoise": "0,206,209", // #00CED1 + "darkviolet": "148,0,211", // #9400D3 + "deeppink": "255,20,147", // #FF1493 + "deepskyblue": "0,191,255", // #00BFFF + "dimgray": "105,105,105", // #696969 + "dimgrey": "105,105,105", // #696969 + "dodgerblue": "30,144,255", // #1E90FF + "firebrick": "178,34,34", // #B22222 + "floralwhite": "255,250,240", // #FFFAF0 + "forestgreen": "34,139,34", // #228B22 + "fuchsia": "255,0,255", // #FF00FF + "gainsboro": "220,220,220", // #DCDCDC + "ghostwhite": "248,248,255", // #F8F8FF + "gold": "255,215,0", // #FFD700 + "goldenrod": "218,165,32", // #DAA520 + "gray": "128,128,128", // #808080 + "green": "0,128,0", // #008000 + "greenyellow": "173,255,47", // #ADFF2F + "grey": "128,128,128", // #808080 + "honeydew": "240,255,240", // #F0FFF0 + "hotpink": "255,105,180", // #FF69B4 + "indianred": "205,92,92", // #CD5C5C + "indigo": "75,0,130", // #4B0082 + "ivory": "255,255,240", // #FFFFF0 + "khaki": "240,230,140", // #F0E68C + "lavender": "230,230,250", // #E6E6FA + "lavenderblush": "255,240,245", // #FFF0F5 + "lawngreen": "124,252,0", // #7CFC00 + "lemonchiffon": "255,250,205", // #FFFACD + "lightblue": "173,216,230", // #ADD8E6 + "lightcoral": "240,128,128", // #F08080 + "lightcyan": "224,255,255", // #E0FFFF + "lightgoldenrodyellow": "250,250,210", // #FAFAD2 + "lightgray": "211,211,211", // #D3D3D3 + "lightgreen": "144,238,144", // #90EE90 + "lightgrey": "211,211,211", // #D3D3D3 + "lightpink": "255,182,193", // #FFB6C1 + "lightsalmon": "255,160,122", // #FFA07A + "lightseagreen": "32,178,170", // #20B2AA + "lightskyblue": "135,206,250", // #87CEFA + "lightslategray": "119,136,153", // #778899 + "lightslategrey": "119,136,153", // #778899 + "lightsteelblue": "176,196,222", // #B0C4DE + "lightyellow": "255,255,224", // #FFFFE0 + "lime": "0,255,0", // #00FF00 + "limegreen": "50,205,50", // #32CD32 + "linen": "250,240,230", // #FAF0E6 + "magenta": "255,0,255", // #FF00FF + "maroon": "128,0,0", // #800000 + "mediumaquamarine": "102,205,170", // #66CDAA + "mediumblue": "0,0,205", // #0000CD + "mediumorchid": "186,85,211", // #BA55D3 + "mediumpurple": "147,112,219", // #9370DB + "mediumseagreen": "60,179,113", // #3CB371 + "mediumslateblue": "123,104,238", // #7B68EE + "mediumspringgreen": "0,250,154", // #00FA9A + "mediumturquoise": "72,209,204", // #48D1CC + "mediumvioletred": "199,21,133", // #C71585 + "midnightblue": "25,25,112", // #191970 + "mintcream": "245,255,250", // #F5FFFA + "mistyrose": "255,228,225", // #FFE4E1 + "moccasin": "255,228,181", // #FFE4B5 + "navajowhite": "255,222,173", // #FFDEAD + "navy": "0,0,128", // #000080 + "oldlace": "253,245,230", // #FDF5E6 + "olive": "128,128,0", // #808000 + "olivedrab": "107,142,35", // #6B8E23 + "orange": "255,165,0", // #FFA500 + "orangered": "255,69,0", // #FF4500 + "orchid": "218,112,214", // #DA70D6 + "palegoldenrod": "238,232,170", // #EEE8AA + "palegreen": "152,251,152", // #98FB98 + "paleturquoise": "175,238,238", // #AFEEEE + "palevioletred": "219,112,147", // #DB7093 + "papayawhip": "255,239,213", // #FFEFD5 + "peachpuff": "255,218,185", // #FFDAB9 + "peru": "205,133,63", // #CD853F + "pink": "255,192,203", // #FFC0CB + "plum": "221,160,221", // #DDA0DD + "powderblue": "176,224,230", // #B0E0E6 + "purple": "128,0,128", // #800080 + "red": "255,0,0", // #FF0000 + "rosybrown": "188,143,143", // #BC8F8F + "royalblue": "65,105,225", // #4169E1 + "saddlebrown": "139,69,19", // #8B4513 + "salmon": "250,128,114", // #FA8072 + "sandybrown": "244,164,96", // #F4A460 + "seagreen": "46,139,87", // #2E8B57 + "seashell": "255,245,238", // #FFF5EE + "sienna": "160,82,45", // #A0522D + "silver": "192,192,192", // #C0C0C0 + "skyblue": "135,206,235", // #87CEEB + "slateblue": "106,90,205", // #6A5ACD + "slategray": "112,128,144", // #708090 + "slategrey": "112,128,144", // #708090 + "snow": "255,250,250", // #FFFAFA + "springgreen": "0,255,127", // #00FF7F + "steelblue": "70,130,180", // #4682B4 + "tan": "210,180,140", // #D2B48C + "teal": "0,128,128", // #008080 + "thistle": "216,191,216", // #D8BFD8 + "tomato": "255,99,71", // #FF6347 + "turquoise": "64,224,208", // #40E0D0 + "violet": "238,130,238", // #EE82EE + "wheat": "245,222,179", // #F5DEB3 + "white": "255,255,255", // #FFFFFF + "whitesmoke": "245,245,245", // #F5F5F5 + "yellow": "255,255,0", // #FFFF00 + "yellowgreen": "154,205,50", // #9ACD32 +} diff --git a/vendor/github.com/gookit/color/detect_env.go b/vendor/github.com/gookit/color/detect_env.go new file mode 100644 index 0000000..7fd8d81 --- /dev/null +++ b/vendor/github.com/gookit/color/detect_env.go @@ -0,0 +1,291 @@ +package color + +import ( + "io" + "os" + "runtime" + "strconv" + "strings" + "syscall" + + "github.com/xo/terminfo" +) + +// Level is the color level supported by a terminal. +type Level = terminfo.ColorLevel + +// terminal color available level alias of the terminfo.ColorLevel* +const ( + LevelNo = terminfo.ColorLevelNone // not support color. + Level16 = terminfo.ColorLevelBasic // basic - 3/4 bit color supported + Level256 = terminfo.ColorLevelHundreds // hundreds - 8-bit color supported + LevelRgb = terminfo.ColorLevelMillions // millions - (24 bit)true color supported +) + +/************************************************************* + * helper methods for detect color supports + *************************************************************/ + +// DetectColorLevel for current env +// +// NOTICE: The method will detect terminal info each times, +// if only want to get current color level, please direct call SupportColor() or TermColorLevel() +func DetectColorLevel() Level { + level, _ := detectTermColorLevel() + return level +} + +// detect terminal color support level +// +// refer https://github.com/Delta456/box-cli-maker +func detectTermColorLevel() (level Level, needVTP bool) { + // on windows WSL: + // - runtime.GOOS == "Linux" + // - support true-color + // env: + // WSL_DISTRO_NAME=Debian + if val := os.Getenv("WSL_DISTRO_NAME"); val != "" { + // detect WSL as it has True Color support + if detectWSL() { + debugf("True Color support on WSL environment") + return terminfo.ColorLevelMillions, false + } + } + + isWin := runtime.GOOS == "windows" + termVal := os.Getenv("TERM") + + // on TERM=screen: not support true-color + if termVal != "screen" { + // On JetBrains Terminal + // - support true-color + // env: + // TERMINAL_EMULATOR=JetBrains-JediTerm + val := os.Getenv("TERMINAL_EMULATOR") + if val == "JetBrains-JediTerm" { + debugf("True Color support on JetBrains-JediTerm, is win: %v", isWin) + return terminfo.ColorLevelMillions, isWin + } + } + + // level, err = terminfo.ColorLevelFromEnv() + level = detectColorLevelFromEnv(termVal, isWin) + debugf("color level by detectColorLevelFromEnv: %s", level.String()) + + // fallback: simple detect by TERM value string. + if level == terminfo.ColorLevelNone { + debugf("level none - fallback check special term color support") + // on Windows: enable VTP as it has True Color support + level, needVTP = detectSpecialTermColor(termVal) + } + return +} + +// detectColorFromEnv returns the color level COLORTERM, FORCE_COLOR, +// TERM_PROGRAM, or determined from the TERM environment variable. +// +// refer the terminfo.ColorLevelFromEnv() +// https://en.wikipedia.org/wiki/Terminfo +func detectColorLevelFromEnv(termVal string, isWin bool) Level { + // check for overriding environment variables + colorTerm, termProg, forceColor := os.Getenv("COLORTERM"), os.Getenv("TERM_PROGRAM"), os.Getenv("FORCE_COLOR") + switch { + case strings.Contains(colorTerm, "truecolor") || strings.Contains(colorTerm, "24bit"): + if termVal == "screen" { // on TERM=screen: not support true-color + return terminfo.ColorLevelHundreds + } + return terminfo.ColorLevelMillions + case colorTerm != "" || forceColor != "": + return terminfo.ColorLevelBasic + case termProg == "Apple_Terminal": + return terminfo.ColorLevelHundreds + case termProg == "Terminus" || termProg == "Hyper": + if termVal == "screen" { // on TERM=screen: not support true-color + return terminfo.ColorLevelHundreds + } + return terminfo.ColorLevelMillions + case termProg == "iTerm.app": + if termVal == "screen" { // on TERM=screen: not support true-color + return terminfo.ColorLevelHundreds + } + + // check iTerm version + ver := os.Getenv("TERM_PROGRAM_VERSION") + if ver != "" { + i, err := strconv.Atoi(strings.Split(ver, ".")[0]) + if err != nil { + saveInternalError(terminfo.ErrInvalidTermProgramVersion) + // return terminfo.ColorLevelNone + return terminfo.ColorLevelHundreds + } + if i == 3 { + return terminfo.ColorLevelMillions + } + } + return terminfo.ColorLevelHundreds + } + + // otherwise determine from TERM's max_colors capability + if !isWin && termVal != "" { + debugf("TERM=%s - check color level by load terminfo file", termVal) + ti, err := terminfo.Load(termVal) + if err != nil { + saveInternalError(err) + return terminfo.ColorLevelNone + } + + debugf("the loaded term info file is: %s", ti.File) + v, ok := ti.Nums[terminfo.MaxColors] + switch { + case !ok || v <= 16: + return terminfo.ColorLevelNone + case ok && v >= 256: + return terminfo.ColorLevelHundreds + } + return terminfo.ColorLevelBasic + } + + // no TERM env value. default return none level + return terminfo.ColorLevelNone + // return terminfo.ColorLevelBasic +} + +var detectedWSL bool +var wslContents string + +// https://github.com/Microsoft/WSL/issues/423#issuecomment-221627364 +func detectWSL() bool { + if !detectedWSL { + detectedWSL = true + + b := make([]byte, 1024) + // `cat /proc/version` + // on mac: + // !not the file! + // on linux(debian,ubuntu,alpine): + // Linux version 4.19.121-linuxkit (root@18b3f92ade35) (gcc version 9.2.0 (Alpine 9.2.0)) #1 SMP Thu Jan 21 15:36:34 UTC 2021 + // on win git bash, conEmu: + // MINGW64_NT-10.0-19042 version 3.1.7-340.x86_64 (@WIN-N0G619FD3UK) (gcc version 9.3.0 (GCC) ) 2020-10-23 13:08 UTC + // on WSL: + // Linux version 4.4.0-19041-Microsoft (Microsoft@Microsoft.com) (gcc version 5.4.0 (GCC) ) #488-Microsoft Mon Sep 01 13:43:00 PST 2020 + f, err := os.Open("/proc/version") + if err == nil { + _, _ = f.Read(b) // ignore error + if err = f.Close(); err != nil { + saveInternalError(err) + } + + wslContents = string(b) + return strings.Contains(wslContents, "Microsoft") + } + } + return false +} + +/* +// refer +// https://github.com/Delta456/box-cli-maker/blob/7b5a1ad8a016ce181e7d8b05e24b54ff60b4b38a/detect_unix.go#L27-L45 +// detect WSL as it has True Color support +func isWSL() bool { + // on windows WSL: + // - runtime.GOOS == "Linux" + // - support true-color + // WSL_DISTRO_NAME=Debian + if val := os.Getenv("WSL_DISTRO_NAME"); val == "" { + return false + } + + // `cat /proc/sys/kernel/osrelease` + // on mac: + // !not the file! + // on linux: + // 4.19.121-linuxkit + // on WSL Output: + // 4.4.0-19041-Microsoft + wsl, err := ioutil.ReadFile("/proc/sys/kernel/osrelease") + if err != nil { + saveInternalError(err) + return false + } + + // it gives "Microsoft" for WSL and "microsoft" for WSL 2 + // it supports True-color + content := strings.ToLower(string(wsl)) + return strings.Contains(content, "microsoft") +} +*/ + +/************************************************************* + * helper methods for check env + *************************************************************/ + +// IsWindows OS env +func IsWindows() bool { + return runtime.GOOS == "windows" +} + +// IsConsole Determine whether w is one of stderr, stdout, stdin +func IsConsole(w io.Writer) bool { + o, ok := w.(*os.File) + if !ok { + return false + } + + fd := o.Fd() + + // fix: cannot use 'o == os.Stdout' to compare + return fd == uintptr(syscall.Stdout) || fd == uintptr(syscall.Stdin) || fd == uintptr(syscall.Stderr) +} + +// IsMSys msys(MINGW64) environment, does not necessarily support color +func IsMSys() bool { + // like "MSYSTEM=MINGW64" + return len(os.Getenv("MSYSTEM")) > 0 +} + +// IsSupportColor check current console is support color. +// +// NOTICE: The method will detect terminal info each times, +// if only want get current color level, please direct call SupportColor() or TermColorLevel() +func IsSupportColor() bool { + return IsSupport16Color() +} + +// IsSupport16Color check current console is support color. +// +// NOTICE: The method will detect terminal info each times, +// if only want get current color level, please direct call SupportColor() or TermColorLevel() +func IsSupport16Color() bool { + level, _ := detectTermColorLevel() + return level > terminfo.ColorLevelNone +} + +// IsSupport256Color render check +// +// NOTICE: The method will detect terminal info each times, +// if only want to get current color level, please direct call SupportColor() or TermColorLevel() +func IsSupport256Color() bool { + level, _ := detectTermColorLevel() + return level > terminfo.ColorLevelBasic +} + +// IsSupportRGBColor check. alias of the IsSupportTrueColor() +// +// NOTICE: The method will detect terminal info each times, +// if only want get current color level, please direct call SupportColor() or TermColorLevel() +func IsSupportRGBColor() bool { + return IsSupportTrueColor() +} + +// IsSupportTrueColor render check. +// +// NOTICE: The method will detect terminal info each times, +// if only want get current color level, please direct call SupportColor() or TermColorLevel() +// +// ENV: +// "COLORTERM=truecolor" +// "COLORTERM=24bit" +func IsSupportTrueColor() bool { + level, _ := detectTermColorLevel() + return level > terminfo.ColorLevelHundreds +} diff --git a/vendor/github.com/gookit/color/detect_nonwin.go b/vendor/github.com/gookit/color/detect_nonwin.go new file mode 100644 index 0000000..26f1090 --- /dev/null +++ b/vendor/github.com/gookit/color/detect_nonwin.go @@ -0,0 +1,49 @@ +//go:build !windows +// +build !windows + +// The method in the file has no effect +// Only for compatibility with non-Windows systems + +package color + +import ( + "strings" + "syscall" + + "github.com/xo/terminfo" +) + +// detect special term color support +func detectSpecialTermColor(termVal string) (Level, bool) { + if termVal == "" { + return terminfo.ColorLevelNone, false + } + + debugf("terminfo check fail - fallback detect color by check TERM value") + + // on TERM=screen: + // - support 256, not support true-color. test on macOS + if termVal == "screen" { + return terminfo.ColorLevelHundreds, false + } + + if strings.Contains(termVal, "256color") { + return terminfo.ColorLevelHundreds, false + } + + if strings.Contains(termVal, "xterm") { + return terminfo.ColorLevelHundreds, false + // return terminfo.ColorLevelBasic, false + } + + // return terminfo.ColorLevelNone, nil + return terminfo.ColorLevelBasic, false +} + +// IsTerminal returns true if the given file descriptor is a terminal. +// +// Usage: +// IsTerminal(os.Stdout.Fd()) +func IsTerminal(fd uintptr) bool { + return fd == uintptr(syscall.Stdout) || fd == uintptr(syscall.Stdin) || fd == uintptr(syscall.Stderr) +} diff --git a/vendor/github.com/gookit/color/detect_windows.go b/vendor/github.com/gookit/color/detect_windows.go new file mode 100644 index 0000000..df538b2 --- /dev/null +++ b/vendor/github.com/gookit/color/detect_windows.go @@ -0,0 +1,250 @@ +//go:build windows +// +build windows + +// Display color on Windows +// +// refer: +// +// golang.org/x/sys/windows +// golang.org/x/crypto/ssh/terminal +// https://docs.microsoft.com/en-us/windows/console +package color + +import ( + "os" + "syscall" + "unsafe" + + "github.com/xo/terminfo" + "golang.org/x/sys/windows" +) + +// related docs +// https://docs.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences +// https://docs.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences#samples +var ( + // isMSys bool + kernel32 *syscall.LazyDLL + + procGetConsoleMode *syscall.LazyProc + procSetConsoleMode *syscall.LazyProc +) + +func init() { + if !SupportColor() { + isLikeInCmd = true + return + } + + // if disabled. + if !Enable { + return + } + + // if at Windows's ConEmu, Cmder, putty ... terminals not need VTP + + // -------- try force enable colors on windows terminal ------- + tryEnableVTP(needVTP) + + // fetch console screen buffer info + // err := getConsoleScreenBufferInfo(uintptr(syscall.Stdout), &defScreenInfo) +} + +// try force enable colors on Windows terminal +func tryEnableVTP(enable bool) bool { + if !enable { + return false + } + + debugf("True-Color by enable VirtualTerminalProcessing on windows") + + initKernel32Proc() + + // enable colors on Windows terminal + if tryEnableOnCONOUT() { + return true + } + + return tryEnableOnStdout() +} + +func initKernel32Proc() { + if kernel32 != nil { + return + } + + // load related Windows dll + // https://docs.microsoft.com/en-us/windows/console/setconsolemode + kernel32 = syscall.NewLazyDLL("kernel32.dll") + + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + procSetConsoleMode = kernel32.NewProc("SetConsoleMode") +} + +func tryEnableOnCONOUT() bool { + outHandle, err := syscall.Open("CONOUT$", syscall.O_RDWR, 0) + if err != nil { + saveInternalError(err) + return false + } + + err = EnableVirtualTerminalProcessing(outHandle, true) + if err != nil { + saveInternalError(err) + return false + } + + return true +} + +func tryEnableOnStdout() bool { + // try direct open syscall.Stdout + err := EnableVirtualTerminalProcessing(syscall.Stdout, true) + if err != nil { + saveInternalError(err) + return false + } + + return true +} + +// Get the Windows Version and Build Number +var ( + winVersion, _, buildNumber = windows.RtlGetNtVersionNumbers() +) + +// refer +// +// https://github.com/Delta456/box-cli-maker/blob/7b5a1ad8a016ce181e7d8b05e24b54ff60b4b38a/detect_windows.go#L30-L57 +// https://github.com/gookit/color/issues/25#issuecomment-738727917 +// +// detects the color level supported on Windows: cmd, powerShell +func detectSpecialTermColor(termVal string) (tl Level, needVTP bool) { + if os.Getenv("ConEmuANSI") == "ON" { + debugf("support True Color by ConEmuANSI=ON") + // ConEmuANSI is "ON" for generic ANSI support + // but True Color option is enabled by default + // I am just assuming that people wouldn't have disabled it + // Even if it is not enabled then ConEmu will auto round off + // accordingly + return terminfo.ColorLevelMillions, false + } + + // Before Windows 10 Build Number 10586, console never supported ANSI Colors + if buildNumber < 10586 || winVersion < 10 { + // Detect if using ANSICON on older systems + if os.Getenv("ANSICON") != "" { + conVersion := os.Getenv("ANSICON_VER") + // 8-bit Colors were only supported after v1.81 release + if conVersion >= "181" { + return terminfo.ColorLevelHundreds, false + } + return terminfo.ColorLevelBasic, false + } + + return terminfo.ColorLevelNone, false + } + + // True Color is not available before build 14931 so fallback to 8-bit color. + if buildNumber < 14931 { + return terminfo.ColorLevelHundreds, true + } + + // Windows 10 build 14931 is the first release that supports 16m/TrueColor + debugf("support True Color on windows version is >= build 14931") + return terminfo.ColorLevelMillions, true +} + +/************************************************************* + * render full color code on Windows(8,16,24bit color) + *************************************************************/ + +// docs https://docs.microsoft.com/zh-cn/windows/console/getconsolemode#parameters +const ( + // equals to docs page's ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 + EnableVirtualTerminalProcessingMode uint32 = 0x4 +) + +// EnableVirtualTerminalProcessing Enable virtual terminal processing +// +// ref from github.com/konsorten/go-windows-terminal-sequences +// doc https://docs.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences#samples +// +// Usage: +// +// err := EnableVirtualTerminalProcessing(syscall.Stdout, true) +// // support print color text +// err = EnableVirtualTerminalProcessing(syscall.Stdout, false) +func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error { + var mode uint32 + // Check if it is currently in the terminal + // err := syscall.GetConsoleMode(syscall.Stdout, &mode) + err := syscall.GetConsoleMode(stream, &mode) + if err != nil { + // fmt.Println("EnableVirtualTerminalProcessing", err) + return err + } + + if enable { + mode |= EnableVirtualTerminalProcessingMode + } else { + mode &^= EnableVirtualTerminalProcessingMode + } + + ret, _, err := procSetConsoleMode.Call(uintptr(stream), uintptr(mode)) + if ret == 0 { + return err + } + + return nil +} + +// renderColorCodeOnCmd enable cmd color render. +// func renderColorCodeOnCmd(fn func()) { +// err := EnableVirtualTerminalProcessing(syscall.Stdout, true) +// // if is not in terminal, will clear color tag. +// if err != nil { +// // panic(err) +// fn() +// return +// } +// +// // force open color render +// old := ForceOpenColor() +// fn() +// // revert color setting +// supportColor = old +// +// err = EnableVirtualTerminalProcessing(syscall.Stdout, false) +// if err != nil { +// panic(err) +// } +// } + +/************************************************************* + * render simple color code on Windows + *************************************************************/ + +// IsTty returns true if the given file descriptor is a terminal. +func IsTty(fd uintptr) bool { + initKernel32Proc() + + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 +} + +// IsTerminal returns true if the given file descriptor is a terminal. +// +// Usage: +// +// fd := os.Stdout.Fd() +// fd := uintptr(syscall.Stdout) // for Windows +// IsTerminal(fd) +func IsTerminal(fd uintptr) bool { + initKernel32Proc() + + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 +} diff --git a/vendor/github.com/gookit/color/index.html b/vendor/github.com/gookit/color/index.html new file mode 100644 index 0000000..19e8e9a --- /dev/null +++ b/vendor/github.com/gookit/color/index.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html lang=""> +<head> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width,initial-scale=1"> + <meta charset="UTF-8"> + <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/themes/vue.css"> + <title>Color - A command-line color library with true color support, universal API methods and Windows support.</title> +</head> +<body> +<div id="app"></div> +<script> + window.$docsify = { + repo: 'gookit/color', + maxLevel: 3, + // 加载 _navbar.md + // loadNavbar: true, + loadNavbar: '_examples/navbar.md', + // 加载 _sidebar.md + // loadSidebar: true, + } +</script> +<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script> +</body> +</html> diff --git a/vendor/github.com/gookit/color/printer.go b/vendor/github.com/gookit/color/printer.go new file mode 100644 index 0000000..985a0b6 --- /dev/null +++ b/vendor/github.com/gookit/color/printer.go @@ -0,0 +1,133 @@ +package color + +import "fmt" + +/************************************************************* + * colored message Printer + *************************************************************/ + +// PrinterFace interface +type PrinterFace interface { + fmt.Stringer + Sprint(a ...any) string + Sprintf(format string, a ...any) string + Print(a ...any) + Printf(format string, a ...any) + Println(a ...any) +} + +// Printer a generic color message printer. +// +// Usage: +// +// p := &Printer{Code: "32;45;3"} +// p.Print("message") +type Printer struct { + // NoColor disable color. + NoColor bool + // Code color code string. eg "32;45;3" + Code string +} + +// NewPrinter instance +func NewPrinter(colorCode string) *Printer { + return &Printer{Code: colorCode} +} + +// String returns color code string. eg: "32;45;3" +func (p *Printer) String() string { + // panic("implement me") + return p.Code +} + +// Sprint returns rendering colored messages +func (p *Printer) Sprint(a ...any) string { + return RenderCode(p.String(), a...) +} + +// Sprintf returns format and rendering colored messages +func (p *Printer) Sprintf(format string, a ...any) string { + return RenderString(p.String(), fmt.Sprintf(format, a...)) +} + +// Print rendering colored messages +func (p *Printer) Print(a ...any) { + doPrintV2(p.String(), fmt.Sprint(a...)) +} + +// Printf format and rendering colored messages +func (p *Printer) Printf(format string, a ...any) { + doPrintV2(p.String(), fmt.Sprintf(format, a...)) +} + +// Println rendering colored messages with newline +func (p *Printer) Println(a ...any) { + doPrintlnV2(p.Code, a) +} + +// IsEmpty color code +func (p *Printer) IsEmpty() bool { + return p.Code == "" +} + +/************************************************************* + * SimplePrinter struct + *************************************************************/ + +// SimplePrinter use for quick use color print on inject to struct +type SimplePrinter struct{} + +// Print message +func (s *SimplePrinter) Print(v ...any) { + Print(v...) +} + +// Printf message +func (s *SimplePrinter) Printf(format string, v ...any) { + Printf(format, v...) +} + +// Println message +func (s *SimplePrinter) Println(v ...any) { + Println(v...) +} + +// Successf message +func (s *SimplePrinter) Successf(format string, a ...any) { + Success.Printf(format, a...) +} + +// Successln message +func (s *SimplePrinter) Successln(a ...any) { + Success.Println(a...) +} + +// Infof message +func (s *SimplePrinter) Infof(format string, a ...any) { + Info.Printf(format, a...) +} + +// Infoln message +func (s *SimplePrinter) Infoln(a ...any) { + Info.Println(a...) +} + +// Warnf message +func (s *SimplePrinter) Warnf(format string, a ...any) { + Warn.Printf(format, a...) +} + +// Warnln message +func (s *SimplePrinter) Warnln(a ...any) { + Warn.Println(a...) +} + +// Errorf message +func (s *SimplePrinter) Errorf(format string, a ...any) { + Error.Printf(format, a...) +} + +// Errorln message +func (s *SimplePrinter) Errorln(a ...any) { + Error.Println(a...) +} diff --git a/vendor/github.com/gookit/color/quickstart.go b/vendor/github.com/gookit/color/quickstart.go new file mode 100644 index 0000000..b368b8a --- /dev/null +++ b/vendor/github.com/gookit/color/quickstart.go @@ -0,0 +1,108 @@ +package color + +/************************************************************* + * quick use color print message + *************************************************************/ + +// Redp print message with Red color +func Redp(a ...any) { Red.Print(a...) } + +// Redf print message with Red color +func Redf(format string, a ...any) { Red.Printf(format, a...) } + +// Redln print message line with Red color +func Redln(a ...any) { Red.Println(a...) } + +// Bluep print message with Blue color +func Bluep(a ...any) { Blue.Print(a...) } + +// Bluef print message with Blue color +func Bluef(format string, a ...any) { Blue.Printf(format, a...) } + +// Blueln print message line with Blue color +func Blueln(a ...any) { Blue.Println(a...) } + +// Cyanp print message with Cyan color +func Cyanp(a ...any) { Cyan.Print(a...) } + +// Cyanf print message with Cyan color +func Cyanf(format string, a ...any) { Cyan.Printf(format, a...) } + +// Cyanln print message line with Cyan color +func Cyanln(a ...any) { Cyan.Println(a...) } + +// Grayp print message with Gray color +func Grayp(a ...any) { Gray.Print(a...) } + +// Grayf print message with Gray color +func Grayf(format string, a ...any) { Gray.Printf(format, a...) } + +// Grayln print message line with Gray color +func Grayln(a ...any) { Gray.Println(a...) } + +// Greenp print message with Green color +func Greenp(a ...any) { Green.Print(a...) } + +// Greenf print message with Green color +func Greenf(format string, a ...any) { Green.Printf(format, a...) } + +// Greenln print message line with Green color +func Greenln(a ...any) { Green.Println(a...) } + +// Yellowp print message with Yellow color +func Yellowp(a ...any) { Yellow.Print(a...) } + +// Yellowf print message with Yellow color +func Yellowf(format string, a ...any) { Yellow.Printf(format, a...) } + +// Yellowln print message line with Yellow color +func Yellowln(a ...any) { Yellow.Println(a...) } + +// Magentap print message with Magenta color +func Magentap(a ...any) { Magenta.Print(a...) } + +// Magentaf print message with Magenta color +func Magentaf(format string, a ...any) { Magenta.Printf(format, a...) } + +// Magentaln print message line with Magenta color +func Magentaln(a ...any) { Magenta.Println(a...) } + +/************************************************************* + * quick use style print message + *************************************************************/ + +// Infop print message with Info color +func Infop(a ...any) { Info.Print(a...) } + +// Infof print message with Info style +func Infof(format string, a ...any) { Info.Printf(format, a...) } + +// Infoln print message with Info style +func Infoln(a ...any) { Info.Println(a...) } + +// Successp print message with success color +func Successp(a ...any) { Success.Print(a...) } + +// Successf print message with success style +func Successf(format string, a ...any) { Success.Printf(format, a...) } + +// Successln print message with success style +func Successln(a ...any) { Success.Println(a...) } + +// Errorp print message with Error color +func Errorp(a ...any) { Error.Print(a...) } + +// Errorf print message with Error style +func Errorf(format string, a ...any) { Error.Printf(format, a...) } + +// Errorln print message with Error style +func Errorln(a ...any) { Error.Println(a...) } + +// Warnp print message with Warn color +func Warnp(a ...any) { Warn.Print(a...) } + +// Warnf print message with Warn style +func Warnf(format string, a ...any) { Warn.Printf(format, a...) } + +// Warnln print message with Warn style +func Warnln(a ...any) { Warn.Println(a...) } diff --git a/vendor/github.com/gookit/color/style.go b/vendor/github.com/gookit/color/style.go new file mode 100644 index 0000000..353d39f --- /dev/null +++ b/vendor/github.com/gookit/color/style.go @@ -0,0 +1,324 @@ +package color + +import ( + "fmt" + "strings" +) + +/************************************************************* + * 16 color Style + *************************************************************/ + +// Style a 16 color style. can add: fg color, bg color, color options +// +// Example: +// +// color.Style{color.FgGreen}.Print("message") +type Style []Color + +// New create a custom style +// +// Usage: +// +// color.New(color.FgGreen).Print("message") +// equals to: +// color.Style{color.FgGreen}.Print("message") +func New(colors ...Color) Style { + return colors +} + +// Save to global styles map +func (s Style) Save(name string) { + AddStyle(name, s) +} + +// Add to global styles map +func (s *Style) Add(cs ...Color) { + *s = append(*s, cs...) +} + +// Render colored text +// +// Usage: +// +// color.New(color.FgGreen).Render("text") +// color.New(color.FgGreen, color.BgBlack, color.OpBold).Render("text") +func (s Style) Render(a ...any) string { + return RenderCode(s.String(), a...) +} + +// Renderln render text with newline. +// like Println, will add spaces for each argument +// +// Usage: +// +// color.New(color.FgGreen).Renderln("text", "more") +// color.New(color.FgGreen, color.BgBlack, color.OpBold).Render("text", "more") +func (s Style) Renderln(a ...any) string { + return RenderWithSpaces(s.String(), a...) +} + +// Sprint is alias of the 'Render' +func (s Style) Sprint(a ...any) string { + return RenderCode(s.String(), a...) +} + +// Sprintf format and render message. +func (s Style) Sprintf(format string, a ...any) string { + return RenderString(s.String(), fmt.Sprintf(format, a...)) +} + +// Print render and Print text +func (s Style) Print(a ...any) { + doPrintV2(s.String(), fmt.Sprint(a...)) +} + +// Printf render and print text +func (s Style) Printf(format string, a ...any) { + doPrintV2(s.Code(), fmt.Sprintf(format, a...)) +} + +// Println render and print text line +func (s Style) Println(a ...any) { + doPrintlnV2(s.String(), a) +} + +// Code convert to code string. returns like "32;45;3" +func (s Style) Code() string { + return s.String() +} + +// String convert to code string. returns like "32;45;3" +func (s Style) String() string { + return Colors2code(s...) +} + +// IsEmpty style +func (s Style) IsEmpty() bool { + return len(s) == 0 +} + +/************************************************************* + * Theme(extended Style) + *************************************************************/ + +// Theme definition. extends from Style +type Theme struct { + // Name theme name + Name string + // Style for the theme + Style +} + +// NewTheme instance +func NewTheme(name string, style Style) *Theme { + return &Theme{name, style} +} + +// Save to themes map +func (t *Theme) Save() { + AddTheme(t.Name, t.Style) +} + +// Tips use name as title, only apply style for name +func (t *Theme) Tips(format string, a ...any) { + // only apply style for name + t.Print(strings.ToUpper(t.Name) + ": ") + Printf(format+"\n", a...) +} + +// Prompt use name as title, and apply style for message +func (t *Theme) Prompt(format string, a ...any) { + title := strings.ToUpper(t.Name) + ":" + t.Println(title, fmt.Sprintf(format, a...)) +} + +// Block like Prompt, but will wrap a empty line +func (t *Theme) Block(format string, a ...any) { + title := strings.ToUpper(t.Name) + ":\n" + + t.Println(title, fmt.Sprintf(format, a...)) +} + +/************************************************************* + * Theme: internal themes + *************************************************************/ + +// internal themes(like bootstrap style) +// Usage: +// +// color.Info.Print("message") +// color.Info.Printf("a %s message", "test") +// color.Warn.Println("message") +// color.Error.Println("message") +var ( + // Info color style + Info = &Theme{"info", Style{OpReset, FgGreen}} + // Note color style + Note = &Theme{"note", Style{OpBold, FgLightCyan}} + // Warn color style + Warn = &Theme{"warning", Style{OpBold, FgYellow}} + // Light color style + Light = &Theme{"light", Style{FgLightWhite, BgBlack}} + // Error color style + Error = &Theme{"error", Style{FgLightWhite, BgRed}} + // Danger color style + Danger = &Theme{"danger", Style{OpBold, FgRed}} + // Debug color style + Debug = &Theme{"debug", Style{OpReset, FgCyan}} + // Notice color style + Notice = &Theme{"notice", Style{OpBold, FgCyan}} + // Comment color style + Comment = &Theme{"comment", Style{OpReset, FgYellow}} + // Success color style + Success = &Theme{"success", Style{OpBold, FgGreen}} + // Primary color style + Primary = &Theme{"primary", Style{OpReset, FgBlue}} + // Question color style + Question = &Theme{"question", Style{OpReset, FgMagenta}} + // Secondary color style + Secondary = &Theme{"secondary", Style{FgDarkGray}} +) + +// Themes internal defined themes. +// Usage: +// +// color.Themes["info"].Println("message") +var Themes = map[string]*Theme{ + "info": Info, + "note": Note, + "light": Light, + "error": Error, + + "debug": Debug, + "danger": Danger, + "notice": Notice, + "success": Success, + "comment": Comment, + "primary": Primary, + "warning": Warn, + + "question": Question, + "secondary": Secondary, +} + +// AddTheme add a theme and style +func AddTheme(name string, style Style) { + Themes[name] = NewTheme(name, style) + Styles[name] = style +} + +// GetTheme get defined theme by name +func GetTheme(name string) *Theme { + return Themes[name] +} + +/************************************************************* + * internal styles + *************************************************************/ + +// Styles internal defined styles, like bootstrap styles. +// Usage: +// +// color.Styles["info"].Println("message") +var Styles = map[string]Style{ + "info": {OpReset, FgGreen}, + "note": {OpBold, FgLightCyan}, + "light": {FgLightWhite, BgRed}, + "error": {FgLightWhite, BgRed}, + + "danger": {OpBold, FgRed}, + "notice": {OpBold, FgCyan}, + "success": {OpBold, FgGreen}, + "comment": {OpReset, FgMagenta}, + "primary": {OpReset, FgBlue}, + "warning": {OpBold, FgYellow}, + + "question": {OpReset, FgMagenta}, + "secondary": {FgDarkGray}, +} + +// some style name alias +var styleAliases = map[string]string{ + "err": "error", + "suc": "success", + "warn": "warning", +} + +// AddStyle add a style +func AddStyle(name string, s Style) { + Styles[name] = s +} + +// GetStyle get defined style by name +func GetStyle(name string) Style { + if s, ok := Styles[name]; ok { + return s + } + + if realName, ok := styleAliases[name]; ok { + return Styles[realName] + } + + // empty style + return New() +} + +/************************************************************* + * color scheme + *************************************************************/ + +// Scheme struct +type Scheme struct { + Name string + Styles map[string]Style +} + +// NewScheme create new Scheme +func NewScheme(name string, styles map[string]Style) *Scheme { + return &Scheme{Name: name, Styles: styles} +} + +// NewDefaultScheme create an defuault color Scheme +func NewDefaultScheme(name string) *Scheme { + return NewScheme(name, map[string]Style{ + "info": {OpReset, FgGreen}, + "warn": {OpBold, FgYellow}, + "error": {FgLightWhite, BgRed}, + }) +} + +// Style get by name +func (s *Scheme) Style(name string) Style { + return s.Styles[name] +} + +// Infof message print +func (s *Scheme) Infof(format string, a ...any) { + s.Styles["info"].Printf(format, a...) +} + +// Infoln message print +func (s *Scheme) Infoln(v ...any) { + s.Styles["info"].Println(v...) +} + +// Warnf message print +func (s *Scheme) Warnf(format string, a ...any) { + s.Styles["warn"].Printf(format, a...) +} + +// Warnln message print +func (s *Scheme) Warnln(v ...any) { + s.Styles["warn"].Println(v...) +} + +// Errorf message print +func (s *Scheme) Errorf(format string, a ...any) { + s.Styles["error"].Printf(format, a...) +} + +// Errorln message print +func (s *Scheme) Errorln(v ...any) { + s.Styles["error"].Println(v...) +} diff --git a/vendor/github.com/gookit/color/utils.go b/vendor/github.com/gookit/color/utils.go new file mode 100644 index 0000000..b6920f6 --- /dev/null +++ b/vendor/github.com/gookit/color/utils.go @@ -0,0 +1,209 @@ +package color + +import ( + "fmt" + "io" + "log" + "strings" +) + +// SetTerminal by given code. +func SetTerminal(code string) error { + if !Enable || !SupportColor() { + return nil + } + + _, err := fmt.Fprintf(output, SettingTpl, code) + return err +} + +// ResetTerminal terminal setting. +func ResetTerminal() error { + if !Enable || !SupportColor() { + return nil + } + + _, err := fmt.Fprint(output, ResetSet) + return err +} + +/************************************************************* + * print methods(will auto parse color tags) + *************************************************************/ + +// Print render color tag and print messages +func Print(a ...any) { + Fprint(output, a...) +} + +// Printf format and print messages +func Printf(format string, a ...any) { + Fprintf(output, format, a...) +} + +// Println messages with new line +func Println(a ...any) { + Fprintln(output, a...) +} + +// Fprint print rendered messages to writer +// +// Notice: will ignore print error +func Fprint(w io.Writer, a ...any) { + _, err := fmt.Fprint(w, Render(a...)) + saveInternalError(err) +} + +// Fprintf print format and rendered messages to writer. +// Notice: will ignore print error +func Fprintf(w io.Writer, format string, a ...any) { + str := fmt.Sprintf(format, a...) + _, err := fmt.Fprint(w, ReplaceTag(str)) + saveInternalError(err) +} + +// Fprintln print rendered messages line to writer +// Notice: will ignore print error +func Fprintln(w io.Writer, a ...any) { + str := formatArgsForPrintln(a) + _, err := fmt.Fprintln(w, ReplaceTag(str)) + saveInternalError(err) +} + +// Lprint passes colored messages to a log.Logger for printing. +// Notice: should be goroutine safe +func Lprint(l *log.Logger, a ...any) { + l.Print(Render(a...)) +} + +// Render parse color tags, return rendered string. +// +// Usage: +// +// text := Render("<info>hello</> <cyan>world</>!") +// fmt.Println(text) +func Render(a ...any) string { + if len(a) == 0 { + return "" + } + return ReplaceTag(fmt.Sprint(a...)) +} + +// Sprint parse color tags, return rendered string +func Sprint(a ...any) string { + if len(a) == 0 { + return "" + } + return ReplaceTag(fmt.Sprint(a...)) +} + +// Sprintf format and return rendered string +func Sprintf(format string, a ...any) string { + return ReplaceTag(fmt.Sprintf(format, a...)) +} + +// String alias of the ReplaceTag +func String(s string) string { return ReplaceTag(s) } + +// Text alias of the ReplaceTag +func Text(s string) string { return ReplaceTag(s) } + +// Uint8sToInts convert []uint8 to []int +// func Uint8sToInts(u8s []uint8 ) []int { +// ints := make([]int, len(u8s)) +// for i, u8 := range u8s { +// ints[i] = int(u8) +// } +// return ints +// } + +/************************************************************* + * helper methods for print + *************************************************************/ + +// new implementation, support render full color code on pwsh.exe, cmd.exe +func doPrintV2(code, str string) { + _, err := fmt.Fprint(output, RenderString(code, str)) + saveInternalError(err) +} + +// new implementation, support render full color code on pwsh.exe, cmd.exe +func doPrintlnV2(code string, args []any) { + str := formatArgsForPrintln(args) + _, err := fmt.Fprintln(output, RenderString(code, str)) + saveInternalError(err) +} + +// use Println, will add spaces for each arg +func formatArgsForPrintln(args []any) (message string) { + if ln := len(args); ln == 0 { + message = "" + } else if ln == 1 { + message = fmt.Sprint(args[0]) + } else { + message = fmt.Sprintln(args...) + // clear last "\n" + message = message[:len(message)-1] + } + return +} + +/************************************************************* + * helper methods + *************************************************************/ + +// is on debug mode +// func isDebugMode() bool { +// return debugMode == "on" +// } + +func debugf(f string, v ...any) { + if debugMode { + fmt.Print("COLOR_DEBUG: ") + fmt.Printf(f, v...) + fmt.Println() + } +} + +// equals: return ok ? val1 : val2 +func isValidUint8(val int) bool { + return val >= 0 && val < 256 +} + +// equals: return ok ? val1 : val2 +func compareVal(ok bool, val1, val2 uint8) uint8 { + if ok { + return val1 + } + return val2 +} + +// equals: return ok ? val1 : val2 +func compareF64Val(ok bool, val1, val2 float64) float64 { + if ok { + return val1 + } + return val2 +} + +func saveInternalError(err error) { + if err != nil { + debugf("inner error: %s", err.Error()) + innerErrs = append(innerErrs, err) + } +} + +func stringToArr(str, sep string) (arr []string) { + str = strings.TrimSpace(str) + if str == "" { + return + } + + ss := strings.Split(str, sep) + for _, val := range ss { + if val = strings.TrimSpace(val); val != "" { + arr = append(arr, val) + } + } + return +} |
