`, styleAttr)
+ }
+
+ return ``
+ },
+ end: func(code bool) string {
+ if code {
+ return ``
+ }
+
+ return ``
+ },
+ }
+ }
+}
+
+// WithPreWrapper allows control of the surrounding pre tags.
+func WithPreWrapper(wrapper PreWrapper) Option {
+ return func(f *Formatter) {
+ f.preWrapper = wrapper
+ }
+}
+
+// WrapLongLines wraps long lines.
+func WrapLongLines(b bool) Option {
+ return func(f *Formatter) {
+ f.wrapLongLines = b
+ }
+}
+
+// WithLineNumbers formats output with line numbers.
+func WithLineNumbers(b bool) Option {
+ return func(f *Formatter) {
+ f.lineNumbers = b
+ }
+}
+
+// LineNumbersInTable will, when combined with WithLineNumbers, separate the line numbers
+// and code in table td's, which make them copy-and-paste friendly.
+func LineNumbersInTable(b bool) Option {
+ return func(f *Formatter) {
+ f.lineNumbersInTable = b
+ }
+}
+
+// WithLinkableLineNumbers decorates the line numbers HTML elements with an "id"
+// attribute so they can be linked.
+func WithLinkableLineNumbers(b bool, prefix string) Option {
+ return func(f *Formatter) {
+ f.linkableLineNumbers = b
+ f.lineNumbersIDPrefix = prefix
+ }
+}
+
+// HighlightLines higlights the given line ranges with the Highlight style.
+//
+// A range is the beginning and ending of a range as 1-based line numbers, inclusive.
+func HighlightLines(ranges [][2]int) Option {
+ return func(f *Formatter) {
+ f.highlightRanges = ranges
+ sort.Sort(f.highlightRanges)
+ }
+}
+
+// BaseLineNumber sets the initial number to start line numbering at. Defaults to 1.
+func BaseLineNumber(n int) Option {
+ return func(f *Formatter) {
+ f.baseLineNumber = n
+ }
+}
+
+// New HTML formatter.
+func New(options ...Option) *Formatter {
+ f := &Formatter{
+ baseLineNumber: 1,
+ preWrapper: defaultPreWrapper,
+ }
+ f.styleCache = newStyleCache(f)
+ for _, option := range options {
+ option(f)
+ }
+ return f
+}
+
+// PreWrapper defines the operations supported in WithPreWrapper.
+type PreWrapper interface {
+ // Start is called to write a start element. + // The code flag tells whether this block surrounds + // highlighted code. This will be false when surrounding + // line numbers. + Start(code bool, styleAttr string) string + + // End is called to write the endelement. + End(code bool) string +} + +type preWrapper struct { + start func(code bool, styleAttr string) string + end func(code bool) string +} + +func (p preWrapper) Start(code bool, styleAttr string) string { + return p.start(code, styleAttr) +} + +func (p preWrapper) End(code bool) string { + return p.end(code) +} + +var ( + nopPreWrapper = preWrapper{ + start: func(code bool, styleAttr string) string { return "" }, + end: func(code bool) string { return "" }, + } + defaultPreWrapper = preWrapper{ + start: func(code bool, styleAttr string) string { + if code { + return fmt.Sprintf(`
`, styleAttr)
+ }
+
+ return fmt.Sprintf(``, styleAttr)
+ },
+ end: func(code bool) string {
+ if code {
+ return ``
+ }
+
+ return ``
+ },
+ }
+)
+
+// Formatter that generates HTML.
+type Formatter struct {
+ styleCache *styleCache
+ standalone bool
+ prefix string
+ Classes bool // Exported field to detect when classes are being used
+ allClasses bool
+ customCSS map[chroma.TokenType]string
+ preWrapper PreWrapper
+ inlineCode bool
+ preventSurroundingPre bool
+ tabWidth int
+ wrapLongLines bool
+ lineNumbers bool
+ lineNumbersInTable bool
+ linkableLineNumbers bool
+ lineNumbersIDPrefix string
+ highlightRanges highlightRanges
+ baseLineNumber int
+}
+
+type highlightRanges [][2]int
+
+func (h highlightRanges) Len() int { return len(h) }
+func (h highlightRanges) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
+func (h highlightRanges) Less(i, j int) bool { return h[i][0] < h[j][0] }
+
+func (f *Formatter) Format(w io.Writer, style *chroma.Style, iterator chroma.Iterator) (err error) {
+ return f.writeHTML(w, style, iterator.Tokens())
+}
+
+// We deliberately don't use html/template here because it is two orders of magnitude slower (benchmarked).
+//
+// OTOH we need to be super careful about correct escaping...
+func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.Token) (err error) { // nolint: gocyclo
+ css := f.styleCache.get(style, true)
+ if f.standalone {
+ fmt.Fprint(w, "\n")
+ if f.Classes {
+ fmt.Fprint(w, "")
+ }
+ fmt.Fprintf(w, "\n", f.styleAttr(css, chroma.Background))
+ }
+
+ wrapInTable := f.lineNumbers && f.lineNumbersInTable
+
+ lines := chroma.SplitTokensIntoLines(tokens)
+ lineDigits := len(strconv.Itoa(f.baseLineNumber + len(lines) - 1))
+ highlightIndex := 0
+
+ if wrapInTable {
+ // List line numbers in its own | \n", f.styleAttr(css, chroma.LineTableTD)) + fmt.Fprintf(w, "%s", f.preWrapper.Start(false, f.styleAttr(css, chroma.PreWrapper))) + for index := range lines { + line := f.baseLineNumber + index + highlight, next := f.shouldHighlight(highlightIndex, line) + if next { + highlightIndex++ + } + if highlight { + fmt.Fprintf(w, "", f.styleAttr(css, chroma.LineHighlight)) + } + + fmt.Fprintf(w, "%s\n", f.styleAttr(css, chroma.LineNumbersTable), f.lineIDAttribute(line), f.lineTitleWithLinkIfNeeded(css, lineDigits, line)) + + if highlight { + fmt.Fprintf(w, "") + } + } + fmt.Fprint(w, f.preWrapper.End(false)) + fmt.Fprint(w, " | \n") + fmt.Fprintf(w, "\n", f.styleAttr(css, chroma.LineTableTD, "width:100%")) + } + + fmt.Fprintf(w, "%s", f.preWrapper.Start(true, f.styleAttr(css, chroma.PreWrapper))) + + highlightIndex = 0 + for index, tokens := range lines { + // 1-based line number. + line := f.baseLineNumber + index + highlight, next := f.shouldHighlight(highlightIndex, line) + if next { + highlightIndex++ + } + + if !(f.preventSurroundingPre || f.inlineCode) { + // Start of Line + fmt.Fprint(w, ``) + } else { + fmt.Fprintf(w, "%s>", f.styleAttr(css, chroma.Line)) + } + + // Line number + if f.lineNumbers && !wrapInTable { + fmt.Fprintf(w, "%s", f.styleAttr(css, chroma.LineNumbers), f.lineIDAttribute(line), f.lineTitleWithLinkIfNeeded(css, lineDigits, line)) + } + + fmt.Fprintf(w, ``, f.styleAttr(css, chroma.CodeLine)) + } + + for _, token := range tokens { + html := html.EscapeString(token.String()) + attr := f.styleAttr(css, token.Type) + if attr != "" { + html = fmt.Sprintf("%s", attr, html) + } + fmt.Fprint(w, html) + } + + if !(f.preventSurroundingPre || f.inlineCode) { + fmt.Fprint(w, ``) // End of CodeLine + + fmt.Fprint(w, ``) // End of Line + } + } + fmt.Fprintf(w, "%s", f.preWrapper.End(true)) + + if wrapInTable { + fmt.Fprint(w, " |
, B, ...
+ {
+ `(?[CBIUDTKRPAELZVMSXN])(?<+|«)`,
+ ByGroups(Keyword, Punctuation),
+ findBrackets(rakuPodFormatter),
+ },
+ },
+ "pod-formatter": {
+ // Placeholder rule, will be replaced by mutators. DO NOT REMOVE!
+ {`>`, Punctuation, Pop(1)},
+ Include("pre-pod-formatter"),
+ // Placeholder rule, will be replaced by mutators. DO NOT REMOVE!
+ {`.+?`, StringOther, nil},
+ },
+ "variable": {
+ {variablePattern, NameVariable, Push("name-adverb")},
+ {globalVariablePattern, NameVariableGlobal, Push("name-adverb")},
+ {`[$@]<[^>]+>`, NameVariable, nil},
+ {`\$[/!¢]`, NameVariable, nil},
+ {`[$@%]`, NameVariable, nil},
+ },
+ "single-quote": {
+ {`(?>(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+|\s+\[))`, Punctuation, Pop(1)},
+ Include("ww"),
+ },
+ "«": {
+ {`»(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+|\s+\[))`, Punctuation, Pop(1)},
+ Include("ww"),
+ },
+ "ww": {
+ Include("single-quote"),
+ Include("qq"),
+ },
+ "qq": {
+ Include("qq-variable"),
+ Include("closure"),
+ Include(`escape-char`),
+ Include("escape-hexadecimal"),
+ Include("escape-c-name"),
+ Include("escape-qq"),
+ {`.+?`, StringDouble, nil},
+ },
+ "qq-variable": {
+ {
+ `(?\.)(?` + namePattern + `)` + colonPairLookahead + `\()`,
+ ByGroupNames(map[string]Emitter{
+ `operator`: Operator,
+ `method_name`: NameFunction,
+ }),
+ Push(`name-adverb`),
+ },
+ // Function/Signature
+ {
+ `\(`, Punctuation, replaceRule(
+ ruleReplacingConfig{
+ delimiter: []rune(`)`),
+ tokenType: Punctuation,
+ stateName: `root`,
+ pushState: true,
+ }),
+ },
+ Default(Pop(1)),
+ },
+ "Q": {
+ Include("escape-qq"),
+ {`.+?`, String, nil},
+ },
+ "Q-closure": {
+ Include("escape-qq"),
+ Include("closure"),
+ {`.+?`, String, nil},
+ },
+ "Q-variable": {
+ Include("escape-qq"),
+ Include("qq-variable"),
+ {`.+?`, String, nil},
+ },
+ "closure": {
+ {`(? -1 {
+ idx = utf8.RuneCountInString(text[:idx])
+
+ // Search again if the substr is escaped with backslash
+ if (idx > 1 && strFromPos[idx-1] == '\\' && strFromPos[idx-2] != '\\') ||
+ (idx == 1 && strFromPos[idx-1] == '\\') {
+ idx = indexAt(str[pos:], substr, idx+1)
+
+ idx = utf8.RuneCountInString(text[:idx])
+
+ if idx < 0 {
+ return idx
+ }
+ }
+ idx += pos
+ }
+
+ return idx
+}
+
+// Tells if an array of string contains a string
+func contains(s []string, e string) bool {
+ for _, value := range s {
+ if value == e {
+ return true
+ }
+ }
+ return false
+}
+
+type rulePosition int
+
+const (
+ topRule rulePosition = 0 - iota
+ bottomRule
+)
+
+type ruleMakingConfig struct {
+ delimiter []rune
+ pattern string
+ tokenType Emitter
+ mutator Mutator
+ numberOfDelimiterChars int
+}
+
+type ruleReplacingConfig struct {
+ delimiter []rune
+ pattern string
+ tokenType Emitter
+ numberOfDelimiterChars int
+ mutator Mutator
+ appendMutator Mutator
+ rulePosition rulePosition
+ stateName string
+ pop bool
+ popState bool
+ pushState bool
+}
+
+// Pops rule from state-stack and replaces the rule with the previous rule
+func popRule(rule ruleReplacingConfig) MutatorFunc {
+ return func(state *LexerState) error {
+ stackName := genStackName(rule.stateName, rule.rulePosition)
+
+ stack, ok := state.Get(stackName).([]ruleReplacingConfig)
+
+ if ok && len(stack) > 0 {
+ // Pop from stack
+ stack = stack[:len(stack)-1]
+ lastRule := stack[len(stack)-1]
+ lastRule.pushState = false
+ lastRule.popState = false
+ lastRule.pop = true
+ state.Set(stackName, stack)
+
+ // Call replaceRule to use the last rule
+ err := replaceRule(lastRule)(state)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ return nil
+ }
+}
+
+// Replaces a state's rule based on the rule config and position
+func replaceRule(rule ruleReplacingConfig) MutatorFunc {
+ return func(state *LexerState) error {
+ stateName := rule.stateName
+ stackName := genStackName(rule.stateName, rule.rulePosition)
+
+ stack, ok := state.Get(stackName).([]ruleReplacingConfig)
+ if !ok {
+ stack = []ruleReplacingConfig{}
+ }
+
+ // If state-stack is empty fill it with the placeholder rule
+ if len(stack) == 0 {
+ stack = []ruleReplacingConfig{
+ {
+ // Placeholder, will be overwritten by mutators, DO NOT REMOVE!
+ pattern: `\A\z`,
+ tokenType: nil,
+ mutator: nil,
+ stateName: stateName,
+ rulePosition: rule.rulePosition,
+ },
+ }
+ state.Set(stackName, stack)
+ }
+
+ var mutator Mutator
+ mutators := []Mutator{}
+
+ switch {
+ case rule.rulePosition == topRule && rule.mutator == nil:
+ // Default mutator for top rule
+ mutators = []Mutator{Pop(1), popRule(rule)}
+ case rule.rulePosition == topRule && rule.mutator != nil:
+ // Default mutator for top rule, when rule.mutator is set
+ mutators = []Mutator{rule.mutator, popRule(rule)}
+ case rule.mutator != nil:
+ mutators = []Mutator{rule.mutator}
+ }
+
+ if rule.appendMutator != nil {
+ mutators = append(mutators, rule.appendMutator)
+ }
+
+ if len(mutators) > 0 {
+ mutator = Mutators(mutators...)
+ } else {
+ mutator = nil
+ }
+
+ ruleConfig := ruleMakingConfig{
+ pattern: rule.pattern,
+ delimiter: rule.delimiter,
+ numberOfDelimiterChars: rule.numberOfDelimiterChars,
+ tokenType: rule.tokenType,
+ mutator: mutator,
+ }
+
+ cRule := makeRule(ruleConfig)
+
+ switch rule.rulePosition {
+ case topRule:
+ state.Rules[stateName][0] = cRule
+ case bottomRule:
+ state.Rules[stateName][len(state.Rules[stateName])-1] = cRule
+ }
+
+ // Pop state name from stack if asked. State should be popped first before Pushing
+ if rule.popState {
+ err := Pop(1).Mutate(state)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ // Push state name to stack if asked
+ if rule.pushState {
+ err := Push(stateName).Mutate(state)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ if !rule.pop {
+ state.Set(stackName, append(stack, rule))
+ }
+
+ return nil
+ }
+}
+
+// Generates rule replacing stack using state name and rule position
+func genStackName(stateName string, rulePosition rulePosition) (stackName string) {
+ switch rulePosition {
+ case topRule:
+ stackName = stateName + `-top-stack`
+ case bottomRule:
+ stackName = stateName + `-bottom-stack`
+ }
+ return
+}
+
+// Makes a compiled rule and returns it
+func makeRule(config ruleMakingConfig) *CompiledRule {
+ var rePattern string
+
+ if len(config.delimiter) > 0 {
+ delimiter := string(config.delimiter)
+
+ if config.numberOfDelimiterChars > 1 {
+ delimiter = strings.Repeat(delimiter, config.numberOfDelimiterChars)
+ }
+
+ rePattern = `(? 1 {
+ lang = langMatch[1]
+ }
+
+ // Tokenise code based on lang property
+ sublexer := Get(lang)
+ if sublexer != nil {
+ iterator, err := sublexer.Tokenise(nil, state.NamedGroups[`value`])
+
+ if err != nil {
+ panic(err)
+ } else {
+ iterators = append(iterators, iterator)
+ }
+ } else {
+ iterators = append(iterators, Literator(tokens[4]))
+ }
+
+ // Append the rest of the tokens
+ iterators = append(iterators, Literator(tokens[5:]...))
+
+ return Concaterator(iterators...)
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/rst.go b/vendor/github.com/alecthomas/chroma/v2/lexers/rst.go
new file mode 100644
index 00000000..66ec03cd
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/rst.go
@@ -0,0 +1,89 @@
+package lexers
+
+import (
+ "strings"
+
+ . "github.com/alecthomas/chroma/v2" // nolint
+)
+
+// Restructuredtext lexer.
+var Restructuredtext = Register(MustNewLexer(
+ &Config{
+ Name: "reStructuredText",
+ Aliases: []string{"rst", "rest", "restructuredtext"},
+ Filenames: []string{"*.rst", "*.rest"},
+ MimeTypes: []string{"text/x-rst", "text/prs.fallenstein.rst"},
+ },
+ restructuredtextRules,
+))
+
+func restructuredtextRules() Rules {
+ return Rules{
+ "root": {
+ {"^(=+|-+|`+|:+|\\.+|\\'+|\"+|~+|\\^+|_+|\\*+|\\++|#+)([ \\t]*\\n)(.+)(\\n)(\\1)(\\n)", ByGroups(GenericHeading, Text, GenericHeading, Text, GenericHeading, Text), nil},
+ {"^(\\S.*)(\\n)(={3,}|-{3,}|`{3,}|:{3,}|\\.{3,}|\\'{3,}|\"{3,}|~{3,}|\\^{3,}|_{3,}|\\*{3,}|\\+{3,}|#{3,})(\\n)", ByGroups(GenericHeading, Text, GenericHeading, Text), nil},
+ {`^(\s*)([-*+])( .+\n(?:\1 .+\n)*)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil},
+ {`^(\s*)([0-9#ivxlcmIVXLCM]+\.)( .+\n(?:\1 .+\n)*)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil},
+ {`^(\s*)(\(?[0-9#ivxlcmIVXLCM]+\))( .+\n(?:\1 .+\n)*)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil},
+ {`^(\s*)([A-Z]+\.)( .+\n(?:\1 .+\n)+)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil},
+ {`^(\s*)(\(?[A-Za-z]+\))( .+\n(?:\1 .+\n)+)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil},
+ {`^(\s*)(\|)( .+\n(?:\| .+\n)*)`, ByGroups(Text, Operator, UsingSelf("inline")), nil},
+ {`^( *\.\.)(\s*)((?:source)?code(?:-block)?)(::)([ \t]*)([^\n]+)(\n[ \t]*\n)([ \t]+)(.*)(\n)((?:(?:\8.*|)\n)+)`, EmitterFunc(rstCodeBlock), nil},
+ {`^( *\.\.)(\s*)([\w:-]+?)(::)(?:([ \t]*)(.*))`, ByGroups(Punctuation, Text, OperatorWord, Punctuation, Text, UsingSelf("inline")), nil},
+ {`^( *\.\.)(\s*)(_(?:[^:\\]|\\.)+:)(.*?)$`, ByGroups(Punctuation, Text, NameTag, UsingSelf("inline")), nil},
+ {`^( *\.\.)(\s*)(\[.+\])(.*?)$`, ByGroups(Punctuation, Text, NameTag, UsingSelf("inline")), nil},
+ {`^( *\.\.)(\s*)(\|.+\|)(\s*)([\w:-]+?)(::)(?:([ \t]*)(.*))`, ByGroups(Punctuation, Text, NameTag, Text, OperatorWord, Punctuation, Text, UsingSelf("inline")), nil},
+ {`^ *\.\..*(\n( +.*\n|\n)+)?`, CommentPreproc, nil},
+ {`^( *)(:[a-zA-Z-]+:)(\s*)$`, ByGroups(Text, NameClass, Text), nil},
+ {`^( *)(:.*?:)([ \t]+)(.*?)$`, ByGroups(Text, NameClass, Text, NameFunction), nil},
+ {`^(\S.*(?)(`__?)", ByGroups(LiteralString, LiteralStringInterpol, LiteralString), nil},
+ {"`.+?`__?", LiteralString, nil},
+ {"(`.+?`)(:[a-zA-Z0-9:-]+?:)?", ByGroups(NameVariable, NameAttribute), nil},
+ {"(:[a-zA-Z0-9:-]+?:)(`.+?`)", ByGroups(NameAttribute, NameVariable), nil},
+ {`\*\*.+?\*\*`, GenericStrong, nil},
+ {`\*.+?\*`, GenericEmph, nil},
+ {`\[.*?\]_`, LiteralString, nil},
+ {`<.+?>`, NameTag, nil},
+ {"[^\\\\\\n\\[*`:]+", Text, nil},
+ {`.`, Text, nil},
+ },
+ "literal": {
+ {"[^`]+", LiteralString, nil},
+ {"``((?=$)|(?=[-/:.,; \\n\\x00\\\u2010\\\u2011\\\u2012\\\u2013\\\u2014\\\u00a0\\'\\\"\\)\\]\\}\\>\\\u2019\\\u201d\\\u00bb\\!\\?]))", LiteralString, Pop(1)},
+ {"`", LiteralString, nil},
+ },
+ }
+}
+
+func rstCodeBlock(groups []string, state *LexerState) Iterator {
+ iterators := []Iterator{}
+ tokens := []Token{
+ {Punctuation, groups[1]},
+ {Text, groups[2]},
+ {OperatorWord, groups[3]},
+ {Punctuation, groups[4]},
+ {Text, groups[5]},
+ {Keyword, groups[6]},
+ {Text, groups[7]},
+ }
+ code := strings.Join(groups[8:], "")
+ lexer := Get(groups[6])
+ if lexer == nil {
+ tokens = append(tokens, Token{String, code})
+ iterators = append(iterators, Literator(tokens...))
+ } else {
+ sub, err := lexer.Tokenise(nil, code)
+ if err != nil {
+ panic(err)
+ }
+ iterators = append(iterators, Literator(tokens...), sub)
+ }
+ return Concaterator(iterators...)
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/svelte.go b/vendor/github.com/alecthomas/chroma/v2/lexers/svelte.go
new file mode 100644
index 00000000..39211c4f
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/svelte.go
@@ -0,0 +1,70 @@
+package lexers
+
+import (
+ . "github.com/alecthomas/chroma/v2" // nolint
+)
+
+// Svelte lexer.
+var Svelte = Register(DelegatingLexer(HTML, MustNewLexer(
+ &Config{
+ Name: "Svelte",
+ Aliases: []string{"svelte"},
+ Filenames: []string{"*.svelte"},
+ MimeTypes: []string{"application/x-svelte"},
+ DotAll: true,
+ },
+ svelteRules,
+)))
+
+func svelteRules() Rules {
+ return Rules{
+ "root": {
+ // Let HTML handle the comments, including comments containing script and style tags
+ {``, Other, Pop(1)},
+ {`.+?`, Other, nil},
+ },
+ "templates": {
+ {`}`, Punctuation, Pop(1)},
+ // Let TypeScript handle strings and the curly braces inside them
+ {`(?]*>`, Using("TypoScriptHTMLData"), nil},
+ {`&[^;\n]*;`, LiteralString, nil},
+ {`(_CSS_DEFAULT_STYLE)(\s*)(\()(?s)(.*(?=\n\)))`, ByGroups(NameClass, Text, LiteralStringSymbol, Using("TypoScriptCSSData")), nil},
+ },
+ "literal": {
+ {`0x[0-9A-Fa-f]+t?`, LiteralNumberHex, nil},
+ {`[0-9]+`, LiteralNumberInteger, nil},
+ {`(###\w+###)`, NameConstant, nil},
+ },
+ "label": {
+ {`(EXT|FILE|LLL):[^}\n"]*`, LiteralString, nil},
+ {`(?![^\w\-])([\w\-]+(?:/[\w\-]+)+/?)(\S*\n)`, ByGroups(LiteralString, LiteralString), nil},
+ },
+ "punctuation": {
+ {`[,.]`, Punctuation, nil},
+ },
+ "operator": {
+ {`[<>,:=.*%+|]`, Operator, nil},
+ },
+ "structure": {
+ {`[{}()\[\]\\]`, LiteralStringSymbol, nil},
+ },
+ "constant": {
+ {`(\{)(\$)((?:[\w\-]+\.)*)([\w\-]+)(\})`, ByGroups(LiteralStringSymbol, Operator, NameConstant, NameConstant, LiteralStringSymbol), nil},
+ {`(\{)([\w\-]+)(\s*:\s*)([\w\-]+)(\})`, ByGroups(LiteralStringSymbol, NameConstant, Operator, NameConstant, LiteralStringSymbol), nil},
+ {`(#[a-fA-F0-9]{6}\b|#[a-fA-F0-9]{3}\b)`, LiteralStringChar, nil},
+ },
+ "comment": {
+ {`(? 0 {
+ // Exhaust the iterator stack, if any.
+ for len(l.iteratorStack) > 0 {
+ n := len(l.iteratorStack) - 1
+ t := l.iteratorStack[n]()
+ if t.Type == Ignore {
+ continue
+ }
+ if t == EOF {
+ l.iteratorStack = l.iteratorStack[:n]
+ continue
+ }
+ return t
+ }
+
+ l.State = l.Stack[len(l.Stack)-1]
+ if l.Lexer.trace {
+ fmt.Fprintf(os.Stderr, "%s: pos=%d, text=%q\n", l.State, l.Pos, string(l.Text[l.Pos:]))
+ }
+ selectedRule, ok := l.Rules[l.State]
+ if !ok {
+ panic("unknown state " + l.State)
+ }
+ ruleIndex, rule, groups, namedGroups := matchRules(l.Text, l.Pos, selectedRule)
+ // No match.
+ if groups == nil {
+ // From Pygments :\
+ //
+ // If the RegexLexer encounters a newline that is flagged as an error token, the stack is
+ // emptied and the lexer continues scanning in the 'root' state. This can help producing
+ // error-tolerant highlighting for erroneous input, e.g. when a single-line string is not
+ // closed.
+ if l.Text[l.Pos] == '\n' && l.State != l.options.State {
+ l.Stack = []string{l.options.State}
+ continue
+ }
+ l.Pos++
+ return Token{Error, string(l.Text[l.Pos-1 : l.Pos])}
+ }
+ l.Rule = ruleIndex
+ l.Groups = groups
+ l.NamedGroups = namedGroups
+ l.Pos += utf8.RuneCountInString(groups[0])
+ if rule.Mutator != nil {
+ if err := rule.Mutator.Mutate(l); err != nil {
+ panic(err)
+ }
+ }
+ if rule.Type != nil {
+ l.iteratorStack = append(l.iteratorStack, rule.Type.Emit(l.Groups, l))
+ }
+ }
+ // Exhaust the IteratorStack, if any.
+ // Duplicate code, but eh.
+ for len(l.iteratorStack) > 0 {
+ n := len(l.iteratorStack) - 1
+ t := l.iteratorStack[n]()
+ if t.Type == Ignore {
+ continue
+ }
+ if t == EOF {
+ l.iteratorStack = l.iteratorStack[:n]
+ continue
+ }
+ return t
+ }
+
+ // If we get to here and we still have text, return it as an error.
+ if l.Pos != len(l.Text) && len(l.Stack) == 0 {
+ value := string(l.Text[l.Pos:])
+ l.Pos = len(l.Text)
+ return Token{Type: Error, Value: value}
+ }
+ return EOF
+}
+
+// RegexLexer is the default lexer implementation used in Chroma.
+type RegexLexer struct {
+ registry *LexerRegistry // The LexerRegistry this Lexer is associated with, if any.
+ config *Config
+ analyser func(text string) float32
+ trace bool
+
+ mu sync.Mutex
+ compiled bool
+ rawRules Rules
+ rules map[string][]*CompiledRule
+ fetchRulesFunc func() (Rules, error)
+ compileOnce sync.Once
+}
+
+func (r *RegexLexer) String() string {
+ return r.config.Name
+}
+
+// Rules in the Lexer.
+func (r *RegexLexer) Rules() (Rules, error) {
+ if err := r.needRules(); err != nil {
+ return nil, err
+ }
+ return r.rawRules, nil
+}
+
+// SetRegistry the lexer will use to lookup other lexers if necessary.
+func (r *RegexLexer) SetRegistry(registry *LexerRegistry) Lexer {
+ r.registry = registry
+ return r
+}
+
+// SetAnalyser sets the analyser function used to perform content inspection.
+func (r *RegexLexer) SetAnalyser(analyser func(text string) float32) Lexer {
+ r.analyser = analyser
+ return r
+}
+
+// AnalyseText scores how likely a fragment of text is to match this lexer, between 0.0 and 1.0.
+func (r *RegexLexer) AnalyseText(text string) float32 {
+ if r.analyser != nil {
+ return r.analyser(text)
+ }
+ return 0
+}
+
+// SetConfig replaces the Config for this Lexer.
+func (r *RegexLexer) SetConfig(config *Config) *RegexLexer {
+ r.config = config
+ return r
+}
+
+// Config returns the Config for this Lexer.
+func (r *RegexLexer) Config() *Config {
+ return r.config
+}
+
+// Regex compilation is deferred until the lexer is used. This is to avoid significant init() time costs.
+func (r *RegexLexer) maybeCompile() (err error) {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+ if r.compiled {
+ return nil
+ }
+ for state, rules := range r.rules {
+ for i, rule := range rules {
+ if rule.Regexp == nil {
+ pattern := "(?:" + rule.Pattern + ")"
+ if rule.flags != "" {
+ pattern = "(?" + rule.flags + ")" + pattern
+ }
+ pattern = `\G` + pattern
+ rule.Regexp, err = regexp2.Compile(pattern, 0)
+ if err != nil {
+ return fmt.Errorf("failed to compile rule %s.%d: %s", state, i, err)
+ }
+ rule.Regexp.MatchTimeout = time.Millisecond * 250
+ }
+ }
+ }
+restart:
+ seen := map[LexerMutator]bool{}
+ for state := range r.rules {
+ for i := range len(r.rules[state]) {
+ rule := r.rules[state][i]
+ if compile, ok := rule.Mutator.(LexerMutator); ok {
+ if seen[compile] {
+ return fmt.Errorf("saw mutator %T twice; this should not happen", compile)
+ }
+ seen[compile] = true
+ if err := compile.MutateLexer(r.rules, state, i); err != nil {
+ return err
+ }
+ // Process the rules again in case the mutator added/removed rules.
+ //
+ // This sounds bad, but shouldn't be significant in practice.
+ goto restart
+ }
+ }
+ }
+ r.compiled = true
+ return nil
+}
+
+func (r *RegexLexer) fetchRules() error {
+ rules, err := r.fetchRulesFunc()
+ if err != nil {
+ return fmt.Errorf("%s: failed to compile rules: %w", r.config.Name, err)
+ }
+ if _, ok := rules["root"]; !ok {
+ return fmt.Errorf("no \"root\" state")
+ }
+ compiledRules := map[string][]*CompiledRule{}
+ for state, rules := range rules {
+ compiledRules[state] = nil
+ for _, rule := range rules {
+ flags := ""
+ if !r.config.NotMultiline {
+ flags += "m"
+ }
+ if r.config.CaseInsensitive {
+ flags += "i"
+ }
+ if r.config.DotAll {
+ flags += "s"
+ }
+ compiledRules[state] = append(compiledRules[state], &CompiledRule{Rule: rule, flags: flags})
+ }
+ }
+
+ r.rawRules = rules
+ r.rules = compiledRules
+ return nil
+}
+
+func (r *RegexLexer) needRules() error {
+ var err error
+ if r.fetchRulesFunc != nil {
+ r.compileOnce.Do(func() {
+ err = r.fetchRules()
+ })
+ }
+ if err := r.maybeCompile(); err != nil {
+ return err
+ }
+ return err
+}
+
+// Tokenise text using lexer, returning an iterator.
+func (r *RegexLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) {
+ err := r.needRules()
+ if err != nil {
+ return nil, err
+ }
+ if options == nil {
+ options = defaultOptions
+ }
+ if options.EnsureLF {
+ text = ensureLF(text)
+ }
+ newlineAdded := false
+ if !options.Nested && r.config.EnsureNL && !strings.HasSuffix(text, "\n") {
+ text += "\n"
+ newlineAdded = true
+ }
+ state := &LexerState{
+ Registry: r.registry,
+ newlineAdded: newlineAdded,
+ options: options,
+ Lexer: r,
+ Text: []rune(text),
+ Stack: []string{options.State},
+ Rules: r.rules,
+ MutatorContext: map[interface{}]interface{}{},
+ }
+ return state.Iterator, nil
+}
+
+// MustRules is like Rules() but will panic on error.
+func (r *RegexLexer) MustRules() Rules {
+ rules, err := r.Rules()
+ if err != nil {
+ panic(err)
+ }
+ return rules
+}
+
+func matchRules(text []rune, pos int, rules []*CompiledRule) (int, *CompiledRule, []string, map[string]string) {
+ for i, rule := range rules {
+ match, err := rule.Regexp.FindRunesMatchStartingAt(text, pos)
+ if match != nil && err == nil && match.Index == pos {
+ groups := []string{}
+ namedGroups := make(map[string]string)
+ for _, g := range match.Groups() {
+ namedGroups[g.Name] = g.String()
+ groups = append(groups, g.String())
+ }
+ return i, rule, groups, namedGroups
+ }
+ }
+ return 0, &CompiledRule{}, nil, nil
+}
+
+// replace \r and \r\n with \n
+// same as strings.ReplaceAll but more efficient
+func ensureLF(text string) string {
+ buf := make([]byte, len(text))
+ var j int
+ for i := range len(text) {
+ c := text[i]
+ if c == '\r' {
+ if i < len(text)-1 && text[i+1] == '\n' {
+ continue
+ }
+ c = '\n'
+ }
+ buf[j] = c
+ j++
+ }
+ return string(buf[:j])
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/registry.go b/vendor/github.com/alecthomas/chroma/v2/registry.go
new file mode 100644
index 00000000..a309af9d
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/registry.go
@@ -0,0 +1,228 @@
+package chroma
+
+import (
+ "path/filepath"
+ "sort"
+ "strings"
+)
+
+var (
+ ignoredSuffixes = [...]string{
+ // Editor backups
+ "~", ".bak", ".old", ".orig",
+ // Debian and derivatives apt/dpkg/ucf backups
+ ".dpkg-dist", ".dpkg-old", ".ucf-dist", ".ucf-new", ".ucf-old",
+ // Red Hat and derivatives rpm backups
+ ".rpmnew", ".rpmorig", ".rpmsave",
+ // Build system input/template files
+ ".in",
+ }
+)
+
+// LexerRegistry is a registry of Lexers.
+type LexerRegistry struct {
+ Lexers Lexers
+ byName map[string]Lexer
+ byAlias map[string]Lexer
+}
+
+// NewLexerRegistry creates a new LexerRegistry of Lexers.
+func NewLexerRegistry() *LexerRegistry {
+ return &LexerRegistry{
+ byName: map[string]Lexer{},
+ byAlias: map[string]Lexer{},
+ }
+}
+
+// Names of all lexers, optionally including aliases.
+func (l *LexerRegistry) Names(withAliases bool) []string {
+ out := []string{}
+ for _, lexer := range l.Lexers {
+ config := lexer.Config()
+ out = append(out, config.Name)
+ if withAliases {
+ out = append(out, config.Aliases...)
+ }
+ }
+ sort.Strings(out)
+ return out
+}
+
+// Aliases of all the lexers, and skip those lexers who do not have any aliases,
+// or show their name instead
+func (l *LexerRegistry) Aliases(skipWithoutAliases bool) []string {
+ out := []string{}
+ for _, lexer := range l.Lexers {
+ config := lexer.Config()
+ if len(config.Aliases) == 0 {
+ if skipWithoutAliases {
+ continue
+ }
+ out = append(out, config.Name)
+ }
+ out = append(out, config.Aliases...)
+ }
+ sort.Strings(out)
+ return out
+}
+
+// Get a Lexer by name, alias or file extension.
+func (l *LexerRegistry) Get(name string) Lexer {
+ if lexer := l.byName[name]; lexer != nil {
+ return lexer
+ }
+ if lexer := l.byAlias[name]; lexer != nil {
+ return lexer
+ }
+ if lexer := l.byName[strings.ToLower(name)]; lexer != nil {
+ return lexer
+ }
+ if lexer := l.byAlias[strings.ToLower(name)]; lexer != nil {
+ return lexer
+ }
+
+ candidates := PrioritisedLexers{}
+ // Try file extension.
+ if lexer := l.Match("filename." + name); lexer != nil {
+ candidates = append(candidates, lexer)
+ }
+ // Try exact filename.
+ if lexer := l.Match(name); lexer != nil {
+ candidates = append(candidates, lexer)
+ }
+ if len(candidates) == 0 {
+ return nil
+ }
+ sort.Sort(candidates)
+ return candidates[0]
+}
+
+// MatchMimeType attempts to find a lexer for the given MIME type.
+func (l *LexerRegistry) MatchMimeType(mimeType string) Lexer {
+ matched := PrioritisedLexers{}
+ for _, l := range l.Lexers {
+ for _, lmt := range l.Config().MimeTypes {
+ if mimeType == lmt {
+ matched = append(matched, l)
+ }
+ }
+ }
+ if len(matched) != 0 {
+ sort.Sort(matched)
+ return matched[0]
+ }
+ return nil
+}
+
+// Match returns the first lexer matching filename.
+//
+// Note that this iterates over all file patterns in all lexers, so is not fast.
+func (l *LexerRegistry) Match(filename string) Lexer {
+ filename = filepath.Base(filename)
+ matched := PrioritisedLexers{}
+ // First, try primary filename matches.
+ for _, lexer := range l.Lexers {
+ config := lexer.Config()
+ for _, glob := range config.Filenames {
+ ok, err := filepath.Match(glob, filename)
+ if err != nil { // nolint
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ } else {
+ for _, suf := range &ignoredSuffixes {
+ ok, err := filepath.Match(glob+suf, filename)
+ if err != nil {
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ break
+ }
+ }
+ }
+ }
+ }
+ if len(matched) > 0 {
+ sort.Sort(matched)
+ return matched[0]
+ }
+ matched = nil
+ // Next, try filename aliases.
+ for _, lexer := range l.Lexers {
+ config := lexer.Config()
+ for _, glob := range config.AliasFilenames {
+ ok, err := filepath.Match(glob, filename)
+ if err != nil { // nolint
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ } else {
+ for _, suf := range &ignoredSuffixes {
+ ok, err := filepath.Match(glob+suf, filename)
+ if err != nil {
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ break
+ }
+ }
+ }
+ }
+ }
+ if len(matched) > 0 {
+ sort.Sort(matched)
+ return matched[0]
+ }
+ return nil
+}
+
+// Analyse text content and return the "best" lexer..
+func (l *LexerRegistry) Analyse(text string) Lexer {
+ var picked Lexer
+ highest := float32(0.0)
+ for _, lexer := range l.Lexers {
+ if analyser, ok := lexer.(Analyser); ok {
+ weight := analyser.AnalyseText(text)
+ if weight > highest {
+ picked = lexer
+ highest = weight
+ }
+ }
+ }
+ return picked
+}
+
+// Register a Lexer with the LexerRegistry. If the lexer is already registered
+// it will be replaced.
+func (l *LexerRegistry) Register(lexer Lexer) Lexer {
+ lexer.SetRegistry(l)
+ config := lexer.Config()
+
+ l.byName[config.Name] = lexer
+ l.byName[strings.ToLower(config.Name)] = lexer
+
+ for _, alias := range config.Aliases {
+ l.byAlias[alias] = lexer
+ l.byAlias[strings.ToLower(alias)] = lexer
+ }
+
+ l.Lexers = add(l.Lexers, lexer)
+
+ return lexer
+}
+
+// add adds a lexer to a slice of lexers if it doesn't already exist, or if found will replace it.
+func add(lexers Lexers, lexer Lexer) Lexers {
+ for i, val := range lexers {
+ if val == nil {
+ continue
+ }
+
+ if val.Config().Name == lexer.Config().Name {
+ lexers[i] = lexer
+ return lexers
+ }
+ }
+
+ return append(lexers, lexer)
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/remap.go b/vendor/github.com/alecthomas/chroma/v2/remap.go
new file mode 100644
index 00000000..bcf5e66d
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/remap.go
@@ -0,0 +1,94 @@
+package chroma
+
+type remappingLexer struct {
+ lexer Lexer
+ mapper func(Token) []Token
+}
+
+// RemappingLexer remaps a token to a set of, potentially empty, tokens.
+func RemappingLexer(lexer Lexer, mapper func(Token) []Token) Lexer {
+ return &remappingLexer{lexer, mapper}
+}
+
+func (r *remappingLexer) AnalyseText(text string) float32 {
+ return r.lexer.AnalyseText(text)
+}
+
+func (r *remappingLexer) SetAnalyser(analyser func(text string) float32) Lexer {
+ r.lexer.SetAnalyser(analyser)
+ return r
+}
+
+func (r *remappingLexer) SetRegistry(registry *LexerRegistry) Lexer {
+ r.lexer.SetRegistry(registry)
+ return r
+}
+
+func (r *remappingLexer) Config() *Config {
+ return r.lexer.Config()
+}
+
+func (r *remappingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) {
+ it, err := r.lexer.Tokenise(options, text)
+ if err != nil {
+ return nil, err
+ }
+ var buffer []Token
+ return func() Token {
+ for {
+ if len(buffer) > 0 {
+ t := buffer[0]
+ buffer = buffer[1:]
+ return t
+ }
+ t := it()
+ if t == EOF {
+ return t
+ }
+ buffer = r.mapper(t)
+ }
+ }, nil
+}
+
+// TypeMapping defines type maps for the TypeRemappingLexer.
+type TypeMapping []struct {
+ From, To TokenType
+ Words []string
+}
+
+// TypeRemappingLexer remaps types of tokens coming from a parent Lexer.
+//
+// eg. Map "defvaralias" tokens of type NameVariable to NameFunction:
+//
+// mapping := TypeMapping{
+// {NameVariable, NameFunction, []string{"defvaralias"},
+// }
+// lexer = TypeRemappingLexer(lexer, mapping)
+func TypeRemappingLexer(lexer Lexer, mapping TypeMapping) Lexer {
+ // Lookup table for fast remapping.
+ lut := map[TokenType]map[string]TokenType{}
+ for _, rt := range mapping {
+ km, ok := lut[rt.From]
+ if !ok {
+ km = map[string]TokenType{}
+ lut[rt.From] = km
+ }
+ if len(rt.Words) == 0 {
+ km[""] = rt.To
+ } else {
+ for _, k := range rt.Words {
+ km[k] = rt.To
+ }
+ }
+ }
+ return RemappingLexer(lexer, func(t Token) []Token {
+ if k, ok := lut[t.Type]; ok {
+ if tt, ok := k[t.Value]; ok {
+ t.Type = tt
+ } else if tt, ok := k[""]; ok {
+ t.Type = tt
+ }
+ }
+ return []Token{t}
+ })
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/renovate.json5 b/vendor/github.com/alecthomas/chroma/v2/renovate.json5
new file mode 100644
index 00000000..77c7b016
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/renovate.json5
@@ -0,0 +1,18 @@
+{
+ $schema: "https://docs.renovatebot.com/renovate-schema.json",
+ extends: [
+ "config:recommended",
+ ":semanticCommits",
+ ":semanticCommitTypeAll(chore)",
+ ":semanticCommitScope(deps)",
+ "group:allNonMajor",
+ "schedule:earlyMondays", // Run once a week.
+ ],
+ packageRules: [
+ {
+ matchPackageNames: ["golangci-lint"],
+ matchManagers: ["hermit"],
+ enabled: false,
+ },
+ ],
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/serialise.go b/vendor/github.com/alecthomas/chroma/v2/serialise.go
new file mode 100644
index 00000000..645a5faa
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/serialise.go
@@ -0,0 +1,479 @@
+package chroma
+
+import (
+ "compress/gzip"
+ "encoding/xml"
+ "errors"
+ "fmt"
+ "io"
+ "io/fs"
+ "math"
+ "path/filepath"
+ "reflect"
+ "regexp"
+ "strings"
+
+ "github.com/dlclark/regexp2"
+)
+
+// Serialisation of Chroma rules to XML. The format is:
+//
+//
+//
+//
+// [<$EMITTER ...>]
+// [<$MUTATOR ...>]
+//
+//
+//
+//
+// eg. Include("String") would become:
+//
+//
+//
+//
+//
+// [null, null, {"kind": "include", "state": "String"}]
+//
+// eg. Rule{`\d+`, Text, nil} would become:
+//
+//
+//
+//
+//
+// eg. Rule{`"`, String, Push("String")}
+//
+//
+//
+//
+//
+//
+// eg. Rule{`(\w+)(\n)`, ByGroups(Keyword, Whitespace), nil},
+//
+//
+//
+//
+//
+var (
+ // ErrNotSerialisable is returned if a lexer contains Rules that cannot be serialised.
+ ErrNotSerialisable = fmt.Errorf("not serialisable")
+ emitterTemplates = func() map[string]SerialisableEmitter {
+ out := map[string]SerialisableEmitter{}
+ for _, emitter := range []SerialisableEmitter{
+ &byGroupsEmitter{},
+ &usingSelfEmitter{},
+ TokenType(0),
+ &usingEmitter{},
+ &usingByGroup{},
+ } {
+ out[emitter.EmitterKind()] = emitter
+ }
+ return out
+ }()
+ mutatorTemplates = func() map[string]SerialisableMutator {
+ out := map[string]SerialisableMutator{}
+ for _, mutator := range []SerialisableMutator{
+ &includeMutator{},
+ &combinedMutator{},
+ &multiMutator{},
+ &pushMutator{},
+ &popMutator{},
+ } {
+ out[mutator.MutatorKind()] = mutator
+ }
+ return out
+ }()
+)
+
+// fastUnmarshalConfig unmarshals only the Config from a serialised lexer.
+func fastUnmarshalConfig(from fs.FS, path string) (*Config, error) {
+ r, err := from.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer r.Close()
+ dec := xml.NewDecoder(r)
+ for {
+ token, err := dec.Token()
+ if err != nil {
+ if errors.Is(err, io.EOF) {
+ return nil, fmt.Errorf("could not find element")
+ }
+ return nil, err
+ }
+ switch se := token.(type) {
+ case xml.StartElement:
+ if se.Name.Local != "config" {
+ break
+ }
+
+ var config Config
+ err = dec.DecodeElement(&config, &se)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %w", path, err)
+ }
+ return &config, nil
+ }
+ }
+}
+
+// MustNewXMLLexer constructs a new RegexLexer from an XML file or panics.
+func MustNewXMLLexer(from fs.FS, path string) *RegexLexer {
+ lex, err := NewXMLLexer(from, path)
+ if err != nil {
+ panic(err)
+ }
+ return lex
+}
+
+// NewXMLLexer creates a new RegexLexer from a serialised RegexLexer.
+func NewXMLLexer(from fs.FS, path string) (*RegexLexer, error) {
+ config, err := fastUnmarshalConfig(from, path)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, glob := range append(config.Filenames, config.AliasFilenames...) {
+ _, err := filepath.Match(glob, "")
+ if err != nil {
+ return nil, fmt.Errorf("%s: %q is not a valid glob: %w", config.Name, glob, err)
+ }
+ }
+
+ var analyserFn func(string) float32
+
+ if config.Analyse != nil {
+ type regexAnalyse struct {
+ re *regexp2.Regexp
+ score float32
+ }
+
+ regexAnalysers := make([]regexAnalyse, 0, len(config.Analyse.Regexes))
+
+ for _, ra := range config.Analyse.Regexes {
+ re, err := regexp2.Compile(ra.Pattern, regexp2.None)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %q is not a valid analyser regex: %w", config.Name, ra.Pattern, err)
+ }
+
+ regexAnalysers = append(regexAnalysers, regexAnalyse{re, ra.Score})
+ }
+
+ analyserFn = func(text string) float32 {
+ var score float32
+
+ for _, ra := range regexAnalysers {
+ ok, err := ra.re.MatchString(text)
+ if err != nil {
+ return 0
+ }
+
+ if ok && config.Analyse.First {
+ return float32(math.Min(float64(ra.score), 1.0))
+ }
+
+ if ok {
+ score += ra.score
+ }
+ }
+
+ return float32(math.Min(float64(score), 1.0))
+ }
+ }
+
+ return &RegexLexer{
+ config: config,
+ analyser: analyserFn,
+ fetchRulesFunc: func() (Rules, error) {
+ var lexer struct {
+ Config
+ Rules Rules `xml:"rules"`
+ }
+ // Try to open .xml fallback to .xml.gz
+ fr, err := from.Open(path)
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ path += ".gz"
+ fr, err = from.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ return nil, err
+ }
+ }
+ defer fr.Close()
+ var r io.Reader = fr
+ if strings.HasSuffix(path, ".gz") {
+ r, err = gzip.NewReader(r)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %w", path, err)
+ }
+ }
+ err = xml.NewDecoder(r).Decode(&lexer)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %w", path, err)
+ }
+ return lexer.Rules, nil
+ },
+ }, nil
+}
+
+// Marshal a RegexLexer to XML.
+func Marshal(l *RegexLexer) ([]byte, error) {
+ type lexer struct {
+ Config Config `xml:"config"`
+ Rules Rules `xml:"rules"`
+ }
+
+ rules, err := l.Rules()
+ if err != nil {
+ return nil, err
+ }
+ root := &lexer{
+ Config: *l.Config(),
+ Rules: rules,
+ }
+ data, err := xml.MarshalIndent(root, "", " ")
+ if err != nil {
+ return nil, err
+ }
+ re := regexp.MustCompile(`>[a-zA-Z]+>`)
+ data = re.ReplaceAll(data, []byte(`/>`))
+ return data, nil
+}
+
+// Unmarshal a RegexLexer from XML.
+func Unmarshal(data []byte) (*RegexLexer, error) {
+ type lexer struct {
+ Config Config `xml:"config"`
+ Rules Rules `xml:"rules"`
+ }
+ root := &lexer{}
+ err := xml.Unmarshal(data, root)
+ if err != nil {
+ return nil, fmt.Errorf("invalid Lexer XML: %w", err)
+ }
+ lex, err := NewLexer(&root.Config, func() Rules { return root.Rules })
+ if err != nil {
+ return nil, err
+ }
+ return lex, nil
+}
+
+func marshalMutator(e *xml.Encoder, mutator Mutator) error {
+ if mutator == nil {
+ return nil
+ }
+ smutator, ok := mutator.(SerialisableMutator)
+ if !ok {
+ return fmt.Errorf("unsupported mutator: %w", ErrNotSerialisable)
+ }
+ return e.EncodeElement(mutator, xml.StartElement{Name: xml.Name{Local: smutator.MutatorKind()}})
+}
+
+func unmarshalMutator(d *xml.Decoder, start xml.StartElement) (Mutator, error) {
+ kind := start.Name.Local
+ mutator, ok := mutatorTemplates[kind]
+ if !ok {
+ return nil, fmt.Errorf("unknown mutator %q: %w", kind, ErrNotSerialisable)
+ }
+ value, target := newFromTemplate(mutator)
+ if err := d.DecodeElement(target, &start); err != nil {
+ return nil, err
+ }
+ return value().(SerialisableMutator), nil
+}
+
+func marshalEmitter(e *xml.Encoder, emitter Emitter) error {
+ if emitter == nil {
+ return nil
+ }
+ semitter, ok := emitter.(SerialisableEmitter)
+ if !ok {
+ return fmt.Errorf("unsupported emitter %T: %w", emitter, ErrNotSerialisable)
+ }
+ return e.EncodeElement(emitter, xml.StartElement{
+ Name: xml.Name{Local: semitter.EmitterKind()},
+ })
+}
+
+func unmarshalEmitter(d *xml.Decoder, start xml.StartElement) (Emitter, error) {
+ kind := start.Name.Local
+ mutator, ok := emitterTemplates[kind]
+ if !ok {
+ return nil, fmt.Errorf("unknown emitter %q: %w", kind, ErrNotSerialisable)
+ }
+ value, target := newFromTemplate(mutator)
+ if err := d.DecodeElement(target, &start); err != nil {
+ return nil, err
+ }
+ return value().(SerialisableEmitter), nil
+}
+
+func (r Rule) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
+ start := xml.StartElement{
+ Name: xml.Name{Local: "rule"},
+ }
+ if r.Pattern != "" {
+ start.Attr = append(start.Attr, xml.Attr{
+ Name: xml.Name{Local: "pattern"},
+ Value: r.Pattern,
+ })
+ }
+ if err := e.EncodeToken(start); err != nil {
+ return err
+ }
+ if err := marshalEmitter(e, r.Type); err != nil {
+ return err
+ }
+ if err := marshalMutator(e, r.Mutator); err != nil {
+ return err
+ }
+ return e.EncodeToken(xml.EndElement{Name: start.Name})
+}
+
+func (r *Rule) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ for _, attr := range start.Attr {
+ if attr.Name.Local == "pattern" {
+ r.Pattern = attr.Value
+ break
+ }
+ }
+ for {
+ token, err := d.Token()
+ if err != nil {
+ return err
+ }
+ switch token := token.(type) {
+ case xml.StartElement:
+ mutator, err := unmarshalMutator(d, token)
+ if err != nil && !errors.Is(err, ErrNotSerialisable) {
+ return err
+ } else if err == nil {
+ if r.Mutator != nil {
+ return fmt.Errorf("duplicate mutator")
+ }
+ r.Mutator = mutator
+ continue
+ }
+ emitter, err := unmarshalEmitter(d, token)
+ if err != nil && !errors.Is(err, ErrNotSerialisable) { // nolint: gocritic
+ return err
+ } else if err == nil {
+ if r.Type != nil {
+ return fmt.Errorf("duplicate emitter")
+ }
+ r.Type = emitter
+ continue
+ } else {
+ return err
+ }
+
+ case xml.EndElement:
+ return nil
+ }
+ }
+}
+
+type xmlRuleState struct {
+ Name string `xml:"name,attr"`
+ Rules []Rule `xml:"rule"`
+}
+
+type xmlRules struct {
+ States []xmlRuleState `xml:"state"`
+}
+
+func (r Rules) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
+ xr := xmlRules{}
+ for state, rules := range r {
+ xr.States = append(xr.States, xmlRuleState{
+ Name: state,
+ Rules: rules,
+ })
+ }
+ return e.EncodeElement(xr, xml.StartElement{Name: xml.Name{Local: "rules"}})
+}
+
+func (r *Rules) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ xr := xmlRules{}
+ if err := d.DecodeElement(&xr, &start); err != nil {
+ return err
+ }
+ if *r == nil {
+ *r = Rules{}
+ }
+ for _, state := range xr.States {
+ (*r)[state.Name] = state.Rules
+ }
+ return nil
+}
+
+type xmlTokenType struct {
+ Type string `xml:"type,attr"`
+}
+
+func (t *TokenType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ el := xmlTokenType{}
+ if err := d.DecodeElement(&el, &start); err != nil {
+ return err
+ }
+ tt, err := TokenTypeString(el.Type)
+ if err != nil {
+ return err
+ }
+ *t = tt
+ return nil
+}
+
+func (t TokenType) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "type"}, Value: t.String()})
+ if err := e.EncodeToken(start); err != nil {
+ return err
+ }
+ return e.EncodeToken(xml.EndElement{Name: start.Name})
+}
+
+// This hijinks is a bit unfortunate but without it we can't deserialise into TokenType.
+func newFromTemplate(template interface{}) (value func() interface{}, target interface{}) {
+ t := reflect.TypeOf(template)
+ if t.Kind() == reflect.Ptr {
+ v := reflect.New(t.Elem())
+ return v.Interface, v.Interface()
+ }
+ v := reflect.New(t)
+ return func() interface{} { return v.Elem().Interface() }, v.Interface()
+}
+
+func (b *Emitters) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ for {
+ token, err := d.Token()
+ if err != nil {
+ return err
+ }
+ switch token := token.(type) {
+ case xml.StartElement:
+ emitter, err := unmarshalEmitter(d, token)
+ if err != nil {
+ return err
+ }
+ *b = append(*b, emitter)
+
+ case xml.EndElement:
+ return nil
+ }
+ }
+}
+
+func (b Emitters) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ if err := e.EncodeToken(start); err != nil {
+ return err
+ }
+ for _, m := range b {
+ if err := marshalEmitter(e, m); err != nil {
+ return err
+ }
+ }
+ return e.EncodeToken(xml.EndElement{Name: start.Name})
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/style.go b/vendor/github.com/alecthomas/chroma/v2/style.go
new file mode 100644
index 00000000..cc8d9a60
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/style.go
@@ -0,0 +1,481 @@
+package chroma
+
+import (
+ "encoding/xml"
+ "fmt"
+ "io"
+ "sort"
+ "strings"
+)
+
+// Trilean value for StyleEntry value inheritance.
+type Trilean uint8
+
+// Trilean states.
+const (
+ Pass Trilean = iota
+ Yes
+ No
+)
+
+func (t Trilean) String() string {
+ switch t {
+ case Yes:
+ return "Yes"
+ case No:
+ return "No"
+ default:
+ return "Pass"
+ }
+}
+
+// Prefix returns s with "no" as a prefix if Trilean is no.
+func (t Trilean) Prefix(s string) string {
+ if t == Yes {
+ return s
+ } else if t == No {
+ return "no" + s
+ }
+ return ""
+}
+
+// A StyleEntry in the Style map.
+type StyleEntry struct {
+ // Hex colours.
+ Colour Colour
+ Background Colour
+ Border Colour
+
+ Bold Trilean
+ Italic Trilean
+ Underline Trilean
+ NoInherit bool
+}
+
+func (s StyleEntry) MarshalText() ([]byte, error) {
+ return []byte(s.String()), nil
+}
+
+func (s StyleEntry) String() string {
+ out := []string{}
+ if s.Bold != Pass {
+ out = append(out, s.Bold.Prefix("bold"))
+ }
+ if s.Italic != Pass {
+ out = append(out, s.Italic.Prefix("italic"))
+ }
+ if s.Underline != Pass {
+ out = append(out, s.Underline.Prefix("underline"))
+ }
+ if s.NoInherit {
+ out = append(out, "noinherit")
+ }
+ if s.Colour.IsSet() {
+ out = append(out, s.Colour.String())
+ }
+ if s.Background.IsSet() {
+ out = append(out, "bg:"+s.Background.String())
+ }
+ if s.Border.IsSet() {
+ out = append(out, "border:"+s.Border.String())
+ }
+ return strings.Join(out, " ")
+}
+
+// Sub subtracts e from s where elements match.
+func (s StyleEntry) Sub(e StyleEntry) StyleEntry {
+ out := StyleEntry{}
+ if e.Colour != s.Colour {
+ out.Colour = s.Colour
+ }
+ if e.Background != s.Background {
+ out.Background = s.Background
+ }
+ if e.Bold != s.Bold {
+ out.Bold = s.Bold
+ }
+ if e.Italic != s.Italic {
+ out.Italic = s.Italic
+ }
+ if e.Underline != s.Underline {
+ out.Underline = s.Underline
+ }
+ if e.Border != s.Border {
+ out.Border = s.Border
+ }
+ return out
+}
+
+// Inherit styles from ancestors.
+//
+// Ancestors should be provided from oldest to newest.
+func (s StyleEntry) Inherit(ancestors ...StyleEntry) StyleEntry {
+ out := s
+ for i := len(ancestors) - 1; i >= 0; i-- {
+ if out.NoInherit {
+ return out
+ }
+ ancestor := ancestors[i]
+ if !out.Colour.IsSet() {
+ out.Colour = ancestor.Colour
+ }
+ if !out.Background.IsSet() {
+ out.Background = ancestor.Background
+ }
+ if !out.Border.IsSet() {
+ out.Border = ancestor.Border
+ }
+ if out.Bold == Pass {
+ out.Bold = ancestor.Bold
+ }
+ if out.Italic == Pass {
+ out.Italic = ancestor.Italic
+ }
+ if out.Underline == Pass {
+ out.Underline = ancestor.Underline
+ }
+ }
+ return out
+}
+
+func (s StyleEntry) IsZero() bool {
+ return s.Colour == 0 && s.Background == 0 && s.Border == 0 && s.Bold == Pass && s.Italic == Pass &&
+ s.Underline == Pass && !s.NoInherit
+}
+
+// A StyleBuilder is a mutable structure for building styles.
+//
+// Once built, a Style is immutable.
+type StyleBuilder struct {
+ entries map[TokenType]string
+ name string
+ parent *Style
+}
+
+func NewStyleBuilder(name string) *StyleBuilder {
+ return &StyleBuilder{name: name, entries: map[TokenType]string{}}
+}
+
+func (s *StyleBuilder) AddAll(entries StyleEntries) *StyleBuilder {
+ for ttype, entry := range entries {
+ s.entries[ttype] = entry
+ }
+ return s
+}
+
+func (s *StyleBuilder) Get(ttype TokenType) StyleEntry {
+ // This is less than ideal, but it's the price for not having to check errors on each Add().
+ entry, _ := ParseStyleEntry(s.entries[ttype])
+ if s.parent != nil {
+ entry = entry.Inherit(s.parent.Get(ttype))
+ }
+ return entry
+}
+
+// Add an entry to the Style map.
+//
+// See http://pygments.org/docs/styles/#style-rules for details.
+func (s *StyleBuilder) Add(ttype TokenType, entry string) *StyleBuilder { // nolint: gocyclo
+ s.entries[ttype] = entry
+ return s
+}
+
+func (s *StyleBuilder) AddEntry(ttype TokenType, entry StyleEntry) *StyleBuilder {
+ s.entries[ttype] = entry.String()
+ return s
+}
+
+// Transform passes each style entry currently defined in the builder to the supplied
+// function and saves the returned value. This can be used to adjust a style's colours;
+// see Colour's ClampBrightness function, for example.
+func (s *StyleBuilder) Transform(transform func(StyleEntry) StyleEntry) *StyleBuilder {
+ types := make(map[TokenType]struct{})
+ for tt := range s.entries {
+ types[tt] = struct{}{}
+ }
+ if s.parent != nil {
+ for _, tt := range s.parent.Types() {
+ types[tt] = struct{}{}
+ }
+ }
+ for tt := range types {
+ s.AddEntry(tt, transform(s.Get(tt)))
+ }
+ return s
+}
+
+func (s *StyleBuilder) Build() (*Style, error) {
+ style := &Style{
+ Name: s.name,
+ entries: map[TokenType]StyleEntry{},
+ parent: s.parent,
+ }
+ for ttype, descriptor := range s.entries {
+ entry, err := ParseStyleEntry(descriptor)
+ if err != nil {
+ return nil, fmt.Errorf("invalid entry for %s: %s", ttype, err)
+ }
+ style.entries[ttype] = entry
+ }
+ return style, nil
+}
+
+// StyleEntries mapping TokenType to colour definition.
+type StyleEntries map[TokenType]string
+
+// NewXMLStyle parses an XML style definition.
+func NewXMLStyle(r io.Reader) (*Style, error) {
+ dec := xml.NewDecoder(r)
+ style := &Style{}
+ return style, dec.Decode(style)
+}
+
+// MustNewXMLStyle is like NewXMLStyle but panics on error.
+func MustNewXMLStyle(r io.Reader) *Style {
+ style, err := NewXMLStyle(r)
+ if err != nil {
+ panic(err)
+ }
+ return style
+}
+
+// NewStyle creates a new style definition.
+func NewStyle(name string, entries StyleEntries) (*Style, error) {
+ return NewStyleBuilder(name).AddAll(entries).Build()
+}
+
+// MustNewStyle creates a new style or panics.
+func MustNewStyle(name string, entries StyleEntries) *Style {
+ style, err := NewStyle(name, entries)
+ if err != nil {
+ panic(err)
+ }
+ return style
+}
+
+// A Style definition.
+//
+// See http://pygments.org/docs/styles/ for details. Semantics are intended to be identical.
+type Style struct {
+ Name string
+ entries map[TokenType]StyleEntry
+ parent *Style
+}
+
+func (s *Style) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ if s.parent != nil {
+ return fmt.Errorf("cannot marshal style with parent")
+ }
+ start.Name = xml.Name{Local: "style"}
+ start.Attr = []xml.Attr{{Name: xml.Name{Local: "name"}, Value: s.Name}}
+ if err := e.EncodeToken(start); err != nil {
+ return err
+ }
+ sorted := make([]TokenType, 0, len(s.entries))
+ for ttype := range s.entries {
+ sorted = append(sorted, ttype)
+ }
+ sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] })
+ for _, ttype := range sorted {
+ entry := s.entries[ttype]
+ el := xml.StartElement{Name: xml.Name{Local: "entry"}}
+ el.Attr = []xml.Attr{
+ {Name: xml.Name{Local: "type"}, Value: ttype.String()},
+ {Name: xml.Name{Local: "style"}, Value: entry.String()},
+ }
+ if err := e.EncodeToken(el); err != nil {
+ return err
+ }
+ if err := e.EncodeToken(xml.EndElement{Name: el.Name}); err != nil {
+ return err
+ }
+ }
+ return e.EncodeToken(xml.EndElement{Name: start.Name})
+}
+
+func (s *Style) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ for _, attr := range start.Attr {
+ if attr.Name.Local == "name" {
+ s.Name = attr.Value
+ } else {
+ return fmt.Errorf("unexpected attribute %s", attr.Name.Local)
+ }
+ }
+ if s.Name == "" {
+ return fmt.Errorf("missing style name attribute")
+ }
+ s.entries = map[TokenType]StyleEntry{}
+ for {
+ tok, err := d.Token()
+ if err != nil {
+ return err
+ }
+ switch el := tok.(type) {
+ case xml.StartElement:
+ if el.Name.Local != "entry" {
+ return fmt.Errorf("unexpected element %s", el.Name.Local)
+ }
+ var ttype TokenType
+ var entry StyleEntry
+ for _, attr := range el.Attr {
+ switch attr.Name.Local {
+ case "type":
+ ttype, err = TokenTypeString(attr.Value)
+ if err != nil {
+ return err
+ }
+
+ case "style":
+ entry, err = ParseStyleEntry(attr.Value)
+ if err != nil {
+ return err
+ }
+
+ default:
+ return fmt.Errorf("unexpected attribute %s", attr.Name.Local)
+ }
+ }
+ s.entries[ttype] = entry
+
+ case xml.EndElement:
+ if el.Name.Local == start.Name.Local {
+ return nil
+ }
+ }
+ }
+}
+
+// Types that are styled.
+func (s *Style) Types() []TokenType {
+ dedupe := map[TokenType]bool{}
+ for tt := range s.entries {
+ dedupe[tt] = true
+ }
+ if s.parent != nil {
+ for _, tt := range s.parent.Types() {
+ dedupe[tt] = true
+ }
+ }
+ out := make([]TokenType, 0, len(dedupe))
+ for tt := range dedupe {
+ out = append(out, tt)
+ }
+ return out
+}
+
+// Builder creates a mutable builder from this Style.
+//
+// The builder can then be safely modified. This is a cheap operation.
+func (s *Style) Builder() *StyleBuilder {
+ return &StyleBuilder{
+ name: s.Name,
+ entries: map[TokenType]string{},
+ parent: s,
+ }
+}
+
+// Has checks if an exact style entry match exists for a token type.
+//
+// This is distinct from Get() which will merge parent tokens.
+func (s *Style) Has(ttype TokenType) bool {
+ return !s.get(ttype).IsZero() || s.synthesisable(ttype)
+}
+
+// Get a style entry. Will try sub-category or category if an exact match is not found, and
+// finally return the Background.
+func (s *Style) Get(ttype TokenType) StyleEntry {
+ return s.get(ttype).Inherit(
+ s.get(Background),
+ s.get(Text),
+ s.get(ttype.Category()),
+ s.get(ttype.SubCategory()))
+}
+
+func (s *Style) get(ttype TokenType) StyleEntry {
+ out := s.entries[ttype]
+ if out.IsZero() && s.parent != nil {
+ return s.parent.get(ttype)
+ }
+ if out.IsZero() && s.synthesisable(ttype) {
+ out = s.synthesise(ttype)
+ }
+ return out
+}
+
+func (s *Style) synthesise(ttype TokenType) StyleEntry {
+ bg := s.get(Background)
+ text := StyleEntry{Colour: bg.Colour}
+ text.Colour = text.Colour.BrightenOrDarken(0.5)
+
+ switch ttype {
+ // If we don't have a line highlight colour, make one that is 10% brighter/darker than the background.
+ case LineHighlight:
+ return StyleEntry{Background: bg.Background.BrightenOrDarken(0.1)}
+
+ // If we don't have line numbers, use the text colour but 20% brighter/darker
+ case LineNumbers, LineNumbersTable:
+ return text
+
+ default:
+ return StyleEntry{}
+ }
+}
+
+func (s *Style) synthesisable(ttype TokenType) bool {
+ return ttype == LineHighlight || ttype == LineNumbers || ttype == LineNumbersTable
+}
+
+// MustParseStyleEntry parses a Pygments style entry or panics.
+func MustParseStyleEntry(entry string) StyleEntry {
+ out, err := ParseStyleEntry(entry)
+ if err != nil {
+ panic(err)
+ }
+ return out
+}
+
+// ParseStyleEntry parses a Pygments style entry.
+func ParseStyleEntry(entry string) (StyleEntry, error) { // nolint: gocyclo
+ out := StyleEntry{}
+ parts := strings.Fields(entry)
+ for _, part := range parts {
+ switch {
+ case part == "italic":
+ out.Italic = Yes
+ case part == "noitalic":
+ out.Italic = No
+ case part == "bold":
+ out.Bold = Yes
+ case part == "nobold":
+ out.Bold = No
+ case part == "underline":
+ out.Underline = Yes
+ case part == "nounderline":
+ out.Underline = No
+ case part == "inherit":
+ out.NoInherit = false
+ case part == "noinherit":
+ out.NoInherit = true
+ case part == "bg:":
+ out.Background = 0
+ case strings.HasPrefix(part, "bg:#"):
+ out.Background = ParseColour(part[3:])
+ if !out.Background.IsSet() {
+ return StyleEntry{}, fmt.Errorf("invalid background colour %q", part)
+ }
+ case strings.HasPrefix(part, "border:#"):
+ out.Border = ParseColour(part[7:])
+ if !out.Border.IsSet() {
+ return StyleEntry{}, fmt.Errorf("invalid border colour %q", part)
+ }
+ case strings.HasPrefix(part, "#"):
+ out.Colour = ParseColour(part)
+ if !out.Colour.IsSet() {
+ return StyleEntry{}, fmt.Errorf("invalid colour %q", part)
+ }
+ default:
+ return StyleEntry{}, fmt.Errorf("unknown style element %q", part)
+ }
+ }
+ return out, nil
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/abap.xml b/vendor/github.com/alecthomas/chroma/v2/styles/abap.xml
new file mode 100644
index 00000000..36ea2f1d
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/abap.xml
@@ -0,0 +1,11 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/algol.xml b/vendor/github.com/alecthomas/chroma/v2/styles/algol.xml
new file mode 100644
index 00000000..e8a6dc1b
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/algol.xml
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/algol_nu.xml b/vendor/github.com/alecthomas/chroma/v2/styles/algol_nu.xml
new file mode 100644
index 00000000..7fa340f3
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/algol_nu.xml
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/api.go b/vendor/github.com/alecthomas/chroma/v2/styles/api.go
new file mode 100644
index 00000000..e26d6f0a
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/api.go
@@ -0,0 +1,65 @@
+package styles
+
+import (
+ "embed"
+ "io/fs"
+ "sort"
+
+ "github.com/alecthomas/chroma/v2"
+)
+
+//go:embed *.xml
+var embedded embed.FS
+
+// Registry of Styles.
+var Registry = func() map[string]*chroma.Style {
+ registry := map[string]*chroma.Style{}
+ // Register all embedded styles.
+ files, err := fs.ReadDir(embedded, ".")
+ if err != nil {
+ panic(err)
+ }
+ for _, file := range files {
+ if file.IsDir() {
+ continue
+ }
+ r, err := embedded.Open(file.Name())
+ if err != nil {
+ panic(err)
+ }
+ style, err := chroma.NewXMLStyle(r)
+ if err != nil {
+ panic(err)
+ }
+ registry[style.Name] = style
+ _ = r.Close()
+ }
+ return registry
+}()
+
+// Fallback style. Reassign to change the default fallback style.
+var Fallback = Registry["swapoff"]
+
+// Register a chroma.Style.
+func Register(style *chroma.Style) *chroma.Style {
+ Registry[style.Name] = style
+ return style
+}
+
+// Names of all available styles.
+func Names() []string {
+ out := []string{}
+ for name := range Registry {
+ out = append(out, name)
+ }
+ sort.Strings(out)
+ return out
+}
+
+// Get named style, or Fallback.
+func Get(name string) *chroma.Style {
+ if style, ok := Registry[name]; ok {
+ return style
+ }
+ return Fallback
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/arduino.xml b/vendor/github.com/alecthomas/chroma/v2/styles/arduino.xml
new file mode 100644
index 00000000..d9891dc5
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/arduino.xml
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/autumn.xml b/vendor/github.com/alecthomas/chroma/v2/styles/autumn.xml
new file mode 100644
index 00000000..74d2eae9
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/autumn.xml
@@ -0,0 +1,36 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/average.xml b/vendor/github.com/alecthomas/chroma/v2/styles/average.xml
new file mode 100644
index 00000000..79bdb95f
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/average.xml
@@ -0,0 +1,74 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/base16-snazzy.xml b/vendor/github.com/alecthomas/chroma/v2/styles/base16-snazzy.xml
new file mode 100644
index 00000000..a05ba24e
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/base16-snazzy.xml
@@ -0,0 +1,74 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/borland.xml b/vendor/github.com/alecthomas/chroma/v2/styles/borland.xml
new file mode 100644
index 00000000..0d8f574c
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/borland.xml
@@ -0,0 +1,26 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/bw.xml b/vendor/github.com/alecthomas/chroma/v2/styles/bw.xml
new file mode 100644
index 00000000..fb0e868d
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/bw.xml
@@ -0,0 +1,23 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-frappe.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-frappe.xml
new file mode 100644
index 00000000..0adf1ba9
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-frappe.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-latte.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-latte.xml
new file mode 100644
index 00000000..3ea767fd
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-latte.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-macchiato.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-macchiato.xml
new file mode 100644
index 00000000..6b500284
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-macchiato.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-mocha.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-mocha.xml
new file mode 100644
index 00000000..9a401912
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-mocha.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/colorful.xml b/vendor/github.com/alecthomas/chroma/v2/styles/colorful.xml
new file mode 100644
index 00000000..32442d71
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/colorful.xml
@@ -0,0 +1,52 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/compat.go b/vendor/github.com/alecthomas/chroma/v2/styles/compat.go
new file mode 100644
index 00000000..4a6aaa66
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/compat.go
@@ -0,0 +1,66 @@
+package styles
+
+// Present for backwards compatibility.
+//
+// Deprecated: use styles.Get(name) instead.
+var (
+ Abap = Registry["abap"]
+ Algol = Registry["algol"]
+ AlgolNu = Registry["algol_nu"]
+ Arduino = Registry["arduino"]
+ Autumn = Registry["autumn"]
+ Average = Registry["average"]
+ Base16Snazzy = Registry["base16-snazzy"]
+ Borland = Registry["borland"]
+ BlackWhite = Registry["bw"]
+ CatppuccinFrappe = Registry["catppuccin-frappe"]
+ CatppuccinLatte = Registry["catppuccin-latte"]
+ CatppuccinMacchiato = Registry["catppuccin-macchiato"]
+ CatppuccinMocha = Registry["catppuccin-mocha"]
+ Colorful = Registry["colorful"]
+ DoomOne = Registry["doom-one"]
+ DoomOne2 = Registry["doom-one2"]
+ Dracula = Registry["dracula"]
+ Emacs = Registry["emacs"]
+ Friendly = Registry["friendly"]
+ Fruity = Registry["fruity"]
+ GitHubDark = Registry["github-dark"]
+ GitHub = Registry["github"]
+ GruvboxLight = Registry["gruvbox-light"]
+ Gruvbox = Registry["gruvbox"]
+ HrDark = Registry["hrdark"]
+ HrHighContrast = Registry["hr_high_contrast"]
+ Igor = Registry["igor"]
+ Lovelace = Registry["lovelace"]
+ Manni = Registry["manni"]
+ ModusOperandi = Registry["modus-operandi"]
+ ModusVivendi = Registry["modus-vivendi"]
+ Monokai = Registry["monokai"]
+ MonokaiLight = Registry["monokailight"]
+ Murphy = Registry["murphy"]
+ Native = Registry["native"]
+ Nord = Registry["nord"]
+ OnesEnterprise = Registry["onesenterprise"]
+ ParaisoDark = Registry["paraiso-dark"]
+ ParaisoLight = Registry["paraiso-light"]
+ Pastie = Registry["pastie"]
+ Perldoc = Registry["perldoc"]
+ Pygments = Registry["pygments"]
+ RainbowDash = Registry["rainbow_dash"]
+ RosePineDawn = Registry["rose-pine-dawn"]
+ RosePineMoon = Registry["rose-pine-moon"]
+ RosePine = Registry["rose-pine"]
+ Rrt = Registry["rrt"]
+ SolarizedDark = Registry["solarized-dark"]
+ SolarizedDark256 = Registry["solarized-dark256"]
+ SolarizedLight = Registry["solarized-light"]
+ SwapOff = Registry["swapoff"]
+ Tango = Registry["tango"]
+ Trac = Registry["trac"]
+ Vim = Registry["vim"]
+ VisualStudio = Registry["vs"]
+ Vulcan = Registry["vulcan"]
+ WitchHazel = Registry["witchhazel"]
+ XcodeDark = Registry["xcode-dark"]
+ Xcode = Registry["xcode"]
+)
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/doom-one.xml b/vendor/github.com/alecthomas/chroma/v2/styles/doom-one.xml
new file mode 100644
index 00000000..1f5127ef
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/doom-one.xml
@@ -0,0 +1,51 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/doom-one2.xml b/vendor/github.com/alecthomas/chroma/v2/styles/doom-one2.xml
new file mode 100644
index 00000000..f47debaf
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/doom-one2.xml
@@ -0,0 +1,64 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/dracula.xml b/vendor/github.com/alecthomas/chroma/v2/styles/dracula.xml
new file mode 100644
index 00000000..9df7da11
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/dracula.xml
@@ -0,0 +1,74 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/emacs.xml b/vendor/github.com/alecthomas/chroma/v2/styles/emacs.xml
new file mode 100644
index 00000000..981ce8e4
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/emacs.xml
@@ -0,0 +1,44 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/evergarden.xml b/vendor/github.com/alecthomas/chroma/v2/styles/evergarden.xml
new file mode 100644
index 00000000..da1d9b84
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/evergarden.xml
@@ -0,0 +1,33 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/friendly.xml b/vendor/github.com/alecthomas/chroma/v2/styles/friendly.xml
new file mode 100644
index 00000000..f4980104
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/friendly.xml
@@ -0,0 +1,44 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/fruity.xml b/vendor/github.com/alecthomas/chroma/v2/styles/fruity.xml
new file mode 100644
index 00000000..bcc06aa7
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/fruity.xml
@@ -0,0 +1,19 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml
new file mode 100644
index 00000000..711aeafc
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml
@@ -0,0 +1,45 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/github.xml b/vendor/github.com/alecthomas/chroma/v2/styles/github.xml
new file mode 100644
index 00000000..d747f653
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/github.xml
@@ -0,0 +1,39 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox-light.xml b/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox-light.xml
new file mode 100644
index 00000000..8c4f0642
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox-light.xml
@@ -0,0 +1,33 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox.xml b/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox.xml
new file mode 100644
index 00000000..2f6a0a2a
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox.xml
@@ -0,0 +1,33 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/hr_high_contrast.xml b/vendor/github.com/alecthomas/chroma/v2/styles/hr_high_contrast.xml
new file mode 100644
index 00000000..61cde204
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/hr_high_contrast.xml
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/hrdark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/hrdark.xml
new file mode 100644
index 00000000..bc7a6f31
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/hrdark.xml
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/igor.xml b/vendor/github.com/alecthomas/chroma/v2/styles/igor.xml
new file mode 100644
index 00000000..773c83b6
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/igor.xml
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/lovelace.xml b/vendor/github.com/alecthomas/chroma/v2/styles/lovelace.xml
new file mode 100644
index 00000000..e336c930
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/lovelace.xml
@@ -0,0 +1,53 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/manni.xml b/vendor/github.com/alecthomas/chroma/v2/styles/manni.xml
new file mode 100644
index 00000000..99324bd3
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/manni.xml
@@ -0,0 +1,44 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/modus-operandi.xml b/vendor/github.com/alecthomas/chroma/v2/styles/modus-operandi.xml
new file mode 100644
index 00000000..023137aa
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/modus-operandi.xml
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/modus-vivendi.xml b/vendor/github.com/alecthomas/chroma/v2/styles/modus-vivendi.xml
new file mode 100644
index 00000000..8da663dc
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/modus-vivendi.xml
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/monokai.xml b/vendor/github.com/alecthomas/chroma/v2/styles/monokai.xml
new file mode 100644
index 00000000..1a789dde
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/monokai.xml
@@ -0,0 +1,29 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/monokailight.xml b/vendor/github.com/alecthomas/chroma/v2/styles/monokailight.xml
new file mode 100644
index 00000000..85cd23e0
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/monokailight.xml
@@ -0,0 +1,26 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/murphy.xml b/vendor/github.com/alecthomas/chroma/v2/styles/murphy.xml
new file mode 100644
index 00000000..112d6205
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/murphy.xml
@@ -0,0 +1,52 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/native.xml b/vendor/github.com/alecthomas/chroma/v2/styles/native.xml
new file mode 100644
index 00000000..43eea7fd
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/native.xml
@@ -0,0 +1,35 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/nord.xml b/vendor/github.com/alecthomas/chroma/v2/styles/nord.xml
new file mode 100644
index 00000000..1c1d1ffb
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/nord.xml
@@ -0,0 +1,46 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/nordic.xml b/vendor/github.com/alecthomas/chroma/v2/styles/nordic.xml
new file mode 100644
index 00000000..4c36b8e4
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/nordic.xml
@@ -0,0 +1,46 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/onedark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/onedark.xml
new file mode 100644
index 00000000..6921eb5e
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/onedark.xml
@@ -0,0 +1,25 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/onesenterprise.xml b/vendor/github.com/alecthomas/chroma/v2/styles/onesenterprise.xml
new file mode 100644
index 00000000..ce86db3f
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/onesenterprise.xml
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-dark.xml
new file mode 100644
index 00000000..788db3f7
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-dark.xml
@@ -0,0 +1,37 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-light.xml b/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-light.xml
new file mode 100644
index 00000000..06a63bae
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-light.xml
@@ -0,0 +1,37 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/pastie.xml b/vendor/github.com/alecthomas/chroma/v2/styles/pastie.xml
new file mode 100644
index 00000000..a3b0abde
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/pastie.xml
@@ -0,0 +1,45 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/perldoc.xml b/vendor/github.com/alecthomas/chroma/v2/styles/perldoc.xml
new file mode 100644
index 00000000..9e5564c3
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/perldoc.xml
@@ -0,0 +1,37 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/pygments.xml b/vendor/github.com/alecthomas/chroma/v2/styles/pygments.xml
new file mode 100644
index 00000000..a3d0d8ba
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/pygments.xml
@@ -0,0 +1,42 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rainbow_dash.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rainbow_dash.xml
new file mode 100644
index 00000000..5b0fe49d
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/rainbow_dash.xml
@@ -0,0 +1,40 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-dawn.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-dawn.xml
new file mode 100644
index 00000000..788bd6f6
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-dawn.xml
@@ -0,0 +1,29 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-moon.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-moon.xml
new file mode 100644
index 00000000..f67b8043
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-moon.xml
@@ -0,0 +1,29 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine.xml
new file mode 100644
index 00000000..3fb70a5a
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine.xml
@@ -0,0 +1,29 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rrt.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rrt.xml
new file mode 100644
index 00000000..f2c5feb9
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/rrt.xml
@@ -0,0 +1,19 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark.xml
new file mode 100644
index 00000000..a3cf46fd
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark.xml
@@ -0,0 +1,39 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark256.xml b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark256.xml
new file mode 100644
index 00000000..977cfbe3
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark256.xml
@@ -0,0 +1,41 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml
new file mode 100644
index 00000000..4fbc1d4a
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/swapoff.xml b/vendor/github.com/alecthomas/chroma/v2/styles/swapoff.xml
new file mode 100644
index 00000000..8a398df8
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/swapoff.xml
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tango.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tango.xml
new file mode 100644
index 00000000..5ca46bb7
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/tango.xml
@@ -0,0 +1,72 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-day.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-day.xml
new file mode 100644
index 00000000..c20d9a41
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-day.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-moon.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-moon.xml
new file mode 100644
index 00000000..3312f029
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-moon.xml
@@ -0,0 +1,83 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-night.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-night.xml
new file mode 100644
index 00000000..c798bad4
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-night.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-storm.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-storm.xml
new file mode 100644
index 00000000..c0811524
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-storm.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/trac.xml b/vendor/github.com/alecthomas/chroma/v2/styles/trac.xml
new file mode 100644
index 00000000..9f1d2667
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/trac.xml
@@ -0,0 +1,35 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/vim.xml b/vendor/github.com/alecthomas/chroma/v2/styles/vim.xml
new file mode 100644
index 00000000..fec69343
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/vim.xml
@@ -0,0 +1,29 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/vs.xml b/vendor/github.com/alecthomas/chroma/v2/styles/vs.xml
new file mode 100644
index 00000000..56435015
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/vs.xml
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/vulcan.xml b/vendor/github.com/alecthomas/chroma/v2/styles/vulcan.xml
new file mode 100644
index 00000000..4e690945
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/vulcan.xml
@@ -0,0 +1,74 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/witchhazel.xml b/vendor/github.com/alecthomas/chroma/v2/styles/witchhazel.xml
new file mode 100644
index 00000000..52f22991
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/witchhazel.xml
@@ -0,0 +1,31 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/xcode-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/xcode-dark.xml
new file mode 100644
index 00000000..93439791
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/xcode-dark.xml
@@ -0,0 +1,31 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/xcode.xml b/vendor/github.com/alecthomas/chroma/v2/styles/xcode.xml
new file mode 100644
index 00000000..523d746c
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/xcode.xml
@@ -0,0 +1,22 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/table.py b/vendor/github.com/alecthomas/chroma/v2/table.py
new file mode 100644
index 00000000..ea4b7556
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/table.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+import re
+from collections import defaultdict
+from subprocess import check_output
+
+README_FILE = "README.md"
+
+lines = check_output(["chroma", "--list"]).decode("utf-8").splitlines()
+lines = [line.strip() for line in lines if line.startswith(" ") and not line.startswith(" ")]
+lines = sorted(lines, key=lambda l: l.lower())
+
+table = defaultdict(list)
+
+for line in lines:
+ table[line[0].upper()].append(line)
+
+rows = []
+for key, value in table.items():
+ rows.append("{} | {}".format(key, ", ".join(value)))
+tbody = "\n".join(rows)
+
+with open(README_FILE, "r") as f:
+ content = f.read()
+
+with open(README_FILE, "w") as f:
+ marker = re.compile(r"(?P:----: \\| --------\n).*?(?P\n\n)", re.DOTALL)
+ replacement = r"\g%s\g" % tbody
+ updated_content = marker.sub(replacement, content)
+ f.write(updated_content)
+
+print(tbody)
diff --git a/vendor/github.com/alecthomas/chroma/v2/tokentype_enumer.go b/vendor/github.com/alecthomas/chroma/v2/tokentype_enumer.go
new file mode 100644
index 00000000..c3b15f03
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/tokentype_enumer.go
@@ -0,0 +1,583 @@
+// Code generated by "enumer -text -type TokenType"; DO NOT EDIT.
+
+package chroma
+
+import (
+ "fmt"
+ "strings"
+)
+
+const _TokenTypeName = "IgnoreNoneOtherErrorCodeLineLineLinkLineTableTDLineTableLineHighlightLineNumbersTableLineNumbersLinePreWrapperBackgroundEOFTypeKeywordKeywordConstantKeywordDeclarationKeywordNamespaceKeywordPseudoKeywordReservedKeywordTypeNameNameAttributeNameClassNameConstantNameDecoratorNameEntityNameExceptionNameKeywordNameLabelNameNamespaceNameOperatorNameOtherNamePseudoNamePropertyNameTagNameBuiltinNameBuiltinPseudoNameVariableNameVariableAnonymousNameVariableClassNameVariableGlobalNameVariableInstanceNameVariableMagicNameFunctionNameFunctionMagicLiteralLiteralDateLiteralOtherLiteralStringLiteralStringAffixLiteralStringAtomLiteralStringBacktickLiteralStringBooleanLiteralStringCharLiteralStringDelimiterLiteralStringDocLiteralStringDoubleLiteralStringEscapeLiteralStringHeredocLiteralStringInterpolLiteralStringNameLiteralStringOtherLiteralStringRegexLiteralStringSingleLiteralStringSymbolLiteralNumberLiteralNumberBinLiteralNumberFloatLiteralNumberHexLiteralNumberIntegerLiteralNumberIntegerLongLiteralNumberOctLiteralNumberByteOperatorOperatorWordPunctuationCommentCommentHashbangCommentMultilineCommentSingleCommentSpecialCommentPreprocCommentPreprocFileGenericGenericDeletedGenericEmphGenericErrorGenericHeadingGenericInsertedGenericOutputGenericPromptGenericStrongGenericSubheadingGenericTracebackGenericUnderlineTextTextWhitespaceTextSymbolTextPunctuation"
+const _TokenTypeLowerName = "ignorenoneothererrorcodelinelinelinklinetabletdlinetablelinehighlightlinenumberstablelinenumberslineprewrapperbackgroundeoftypekeywordkeywordconstantkeyworddeclarationkeywordnamespacekeywordpseudokeywordreservedkeywordtypenamenameattributenameclassnameconstantnamedecoratornameentitynameexceptionnamekeywordnamelabelnamenamespacenameoperatornameothernamepseudonamepropertynametagnamebuiltinnamebuiltinpseudonamevariablenamevariableanonymousnamevariableclassnamevariableglobalnamevariableinstancenamevariablemagicnamefunctionnamefunctionmagicliteralliteraldateliteralotherliteralstringliteralstringaffixliteralstringatomliteralstringbacktickliteralstringbooleanliteralstringcharliteralstringdelimiterliteralstringdocliteralstringdoubleliteralstringescapeliteralstringheredocliteralstringinterpolliteralstringnameliteralstringotherliteralstringregexliteralstringsingleliteralstringsymbolliteralnumberliteralnumberbinliteralnumberfloatliteralnumberhexliteralnumberintegerliteralnumberintegerlongliteralnumberoctliteralnumberbyteoperatoroperatorwordpunctuationcommentcommenthashbangcommentmultilinecommentsinglecommentspecialcommentpreproccommentpreprocfilegenericgenericdeletedgenericemphgenericerrorgenericheadinggenericinsertedgenericoutputgenericpromptgenericstronggenericsubheadinggenerictracebackgenericunderlinetexttextwhitespacetextsymboltextpunctuation"
+
+var _TokenTypeMap = map[TokenType]string{
+ -14: _TokenTypeName[0:6],
+ -13: _TokenTypeName[6:10],
+ -12: _TokenTypeName[10:15],
+ -11: _TokenTypeName[15:20],
+ -10: _TokenTypeName[20:28],
+ -9: _TokenTypeName[28:36],
+ -8: _TokenTypeName[36:47],
+ -7: _TokenTypeName[47:56],
+ -6: _TokenTypeName[56:69],
+ -5: _TokenTypeName[69:85],
+ -4: _TokenTypeName[85:96],
+ -3: _TokenTypeName[96:100],
+ -2: _TokenTypeName[100:110],
+ -1: _TokenTypeName[110:120],
+ 0: _TokenTypeName[120:127],
+ 1000: _TokenTypeName[127:134],
+ 1001: _TokenTypeName[134:149],
+ 1002: _TokenTypeName[149:167],
+ 1003: _TokenTypeName[167:183],
+ 1004: _TokenTypeName[183:196],
+ 1005: _TokenTypeName[196:211],
+ 1006: _TokenTypeName[211:222],
+ 2000: _TokenTypeName[222:226],
+ 2001: _TokenTypeName[226:239],
+ 2002: _TokenTypeName[239:248],
+ 2003: _TokenTypeName[248:260],
+ 2004: _TokenTypeName[260:273],
+ 2005: _TokenTypeName[273:283],
+ 2006: _TokenTypeName[283:296],
+ 2007: _TokenTypeName[296:307],
+ 2008: _TokenTypeName[307:316],
+ 2009: _TokenTypeName[316:329],
+ 2010: _TokenTypeName[329:341],
+ 2011: _TokenTypeName[341:350],
+ 2012: _TokenTypeName[350:360],
+ 2013: _TokenTypeName[360:372],
+ 2014: _TokenTypeName[372:379],
+ 2100: _TokenTypeName[379:390],
+ 2101: _TokenTypeName[390:407],
+ 2200: _TokenTypeName[407:419],
+ 2201: _TokenTypeName[419:440],
+ 2202: _TokenTypeName[440:457],
+ 2203: _TokenTypeName[457:475],
+ 2204: _TokenTypeName[475:495],
+ 2205: _TokenTypeName[495:512],
+ 2300: _TokenTypeName[512:524],
+ 2301: _TokenTypeName[524:541],
+ 3000: _TokenTypeName[541:548],
+ 3001: _TokenTypeName[548:559],
+ 3002: _TokenTypeName[559:571],
+ 3100: _TokenTypeName[571:584],
+ 3101: _TokenTypeName[584:602],
+ 3102: _TokenTypeName[602:619],
+ 3103: _TokenTypeName[619:640],
+ 3104: _TokenTypeName[640:660],
+ 3105: _TokenTypeName[660:677],
+ 3106: _TokenTypeName[677:699],
+ 3107: _TokenTypeName[699:715],
+ 3108: _TokenTypeName[715:734],
+ 3109: _TokenTypeName[734:753],
+ 3110: _TokenTypeName[753:773],
+ 3111: _TokenTypeName[773:794],
+ 3112: _TokenTypeName[794:811],
+ 3113: _TokenTypeName[811:829],
+ 3114: _TokenTypeName[829:847],
+ 3115: _TokenTypeName[847:866],
+ 3116: _TokenTypeName[866:885],
+ 3200: _TokenTypeName[885:898],
+ 3201: _TokenTypeName[898:914],
+ 3202: _TokenTypeName[914:932],
+ 3203: _TokenTypeName[932:948],
+ 3204: _TokenTypeName[948:968],
+ 3205: _TokenTypeName[968:992],
+ 3206: _TokenTypeName[992:1008],
+ 3207: _TokenTypeName[1008:1025],
+ 4000: _TokenTypeName[1025:1033],
+ 4001: _TokenTypeName[1033:1045],
+ 5000: _TokenTypeName[1045:1056],
+ 6000: _TokenTypeName[1056:1063],
+ 6001: _TokenTypeName[1063:1078],
+ 6002: _TokenTypeName[1078:1094],
+ 6003: _TokenTypeName[1094:1107],
+ 6004: _TokenTypeName[1107:1121],
+ 6100: _TokenTypeName[1121:1135],
+ 6101: _TokenTypeName[1135:1153],
+ 7000: _TokenTypeName[1153:1160],
+ 7001: _TokenTypeName[1160:1174],
+ 7002: _TokenTypeName[1174:1185],
+ 7003: _TokenTypeName[1185:1197],
+ 7004: _TokenTypeName[1197:1211],
+ 7005: _TokenTypeName[1211:1226],
+ 7006: _TokenTypeName[1226:1239],
+ 7007: _TokenTypeName[1239:1252],
+ 7008: _TokenTypeName[1252:1265],
+ 7009: _TokenTypeName[1265:1282],
+ 7010: _TokenTypeName[1282:1298],
+ 7011: _TokenTypeName[1298:1314],
+ 8000: _TokenTypeName[1314:1318],
+ 8001: _TokenTypeName[1318:1332],
+ 8002: _TokenTypeName[1332:1342],
+ 8003: _TokenTypeName[1342:1357],
+}
+
+func (i TokenType) String() string {
+ if str, ok := _TokenTypeMap[i]; ok {
+ return str
+ }
+ return fmt.Sprintf("TokenType(%d)", i)
+}
+
+// An "invalid array index" compiler error signifies that the constant values have changed.
+// Re-run the stringer command to generate them again.
+func _TokenTypeNoOp() {
+ var x [1]struct{}
+ _ = x[Ignore-(-14)]
+ _ = x[None-(-13)]
+ _ = x[Other-(-12)]
+ _ = x[Error-(-11)]
+ _ = x[CodeLine-(-10)]
+ _ = x[LineLink-(-9)]
+ _ = x[LineTableTD-(-8)]
+ _ = x[LineTable-(-7)]
+ _ = x[LineHighlight-(-6)]
+ _ = x[LineNumbersTable-(-5)]
+ _ = x[LineNumbers-(-4)]
+ _ = x[Line-(-3)]
+ _ = x[PreWrapper-(-2)]
+ _ = x[Background-(-1)]
+ _ = x[EOFType-(0)]
+ _ = x[Keyword-(1000)]
+ _ = x[KeywordConstant-(1001)]
+ _ = x[KeywordDeclaration-(1002)]
+ _ = x[KeywordNamespace-(1003)]
+ _ = x[KeywordPseudo-(1004)]
+ _ = x[KeywordReserved-(1005)]
+ _ = x[KeywordType-(1006)]
+ _ = x[Name-(2000)]
+ _ = x[NameAttribute-(2001)]
+ _ = x[NameClass-(2002)]
+ _ = x[NameConstant-(2003)]
+ _ = x[NameDecorator-(2004)]
+ _ = x[NameEntity-(2005)]
+ _ = x[NameException-(2006)]
+ _ = x[NameKeyword-(2007)]
+ _ = x[NameLabel-(2008)]
+ _ = x[NameNamespace-(2009)]
+ _ = x[NameOperator-(2010)]
+ _ = x[NameOther-(2011)]
+ _ = x[NamePseudo-(2012)]
+ _ = x[NameProperty-(2013)]
+ _ = x[NameTag-(2014)]
+ _ = x[NameBuiltin-(2100)]
+ _ = x[NameBuiltinPseudo-(2101)]
+ _ = x[NameVariable-(2200)]
+ _ = x[NameVariableAnonymous-(2201)]
+ _ = x[NameVariableClass-(2202)]
+ _ = x[NameVariableGlobal-(2203)]
+ _ = x[NameVariableInstance-(2204)]
+ _ = x[NameVariableMagic-(2205)]
+ _ = x[NameFunction-(2300)]
+ _ = x[NameFunctionMagic-(2301)]
+ _ = x[Literal-(3000)]
+ _ = x[LiteralDate-(3001)]
+ _ = x[LiteralOther-(3002)]
+ _ = x[LiteralString-(3100)]
+ _ = x[LiteralStringAffix-(3101)]
+ _ = x[LiteralStringAtom-(3102)]
+ _ = x[LiteralStringBacktick-(3103)]
+ _ = x[LiteralStringBoolean-(3104)]
+ _ = x[LiteralStringChar-(3105)]
+ _ = x[LiteralStringDelimiter-(3106)]
+ _ = x[LiteralStringDoc-(3107)]
+ _ = x[LiteralStringDouble-(3108)]
+ _ = x[LiteralStringEscape-(3109)]
+ _ = x[LiteralStringHeredoc-(3110)]
+ _ = x[LiteralStringInterpol-(3111)]
+ _ = x[LiteralStringName-(3112)]
+ _ = x[LiteralStringOther-(3113)]
+ _ = x[LiteralStringRegex-(3114)]
+ _ = x[LiteralStringSingle-(3115)]
+ _ = x[LiteralStringSymbol-(3116)]
+ _ = x[LiteralNumber-(3200)]
+ _ = x[LiteralNumberBin-(3201)]
+ _ = x[LiteralNumberFloat-(3202)]
+ _ = x[LiteralNumberHex-(3203)]
+ _ = x[LiteralNumberInteger-(3204)]
+ _ = x[LiteralNumberIntegerLong-(3205)]
+ _ = x[LiteralNumberOct-(3206)]
+ _ = x[LiteralNumberByte-(3207)]
+ _ = x[Operator-(4000)]
+ _ = x[OperatorWord-(4001)]
+ _ = x[Punctuation-(5000)]
+ _ = x[Comment-(6000)]
+ _ = x[CommentHashbang-(6001)]
+ _ = x[CommentMultiline-(6002)]
+ _ = x[CommentSingle-(6003)]
+ _ = x[CommentSpecial-(6004)]
+ _ = x[CommentPreproc-(6100)]
+ _ = x[CommentPreprocFile-(6101)]
+ _ = x[Generic-(7000)]
+ _ = x[GenericDeleted-(7001)]
+ _ = x[GenericEmph-(7002)]
+ _ = x[GenericError-(7003)]
+ _ = x[GenericHeading-(7004)]
+ _ = x[GenericInserted-(7005)]
+ _ = x[GenericOutput-(7006)]
+ _ = x[GenericPrompt-(7007)]
+ _ = x[GenericStrong-(7008)]
+ _ = x[GenericSubheading-(7009)]
+ _ = x[GenericTraceback-(7010)]
+ _ = x[GenericUnderline-(7011)]
+ _ = x[Text-(8000)]
+ _ = x[TextWhitespace-(8001)]
+ _ = x[TextSymbol-(8002)]
+ _ = x[TextPunctuation-(8003)]
+}
+
+var _TokenTypeValues = []TokenType{Ignore, None, Other, Error, CodeLine, LineLink, LineTableTD, LineTable, LineHighlight, LineNumbersTable, LineNumbers, Line, PreWrapper, Background, EOFType, Keyword, KeywordConstant, KeywordDeclaration, KeywordNamespace, KeywordPseudo, KeywordReserved, KeywordType, Name, NameAttribute, NameClass, NameConstant, NameDecorator, NameEntity, NameException, NameKeyword, NameLabel, NameNamespace, NameOperator, NameOther, NamePseudo, NameProperty, NameTag, NameBuiltin, NameBuiltinPseudo, NameVariable, NameVariableAnonymous, NameVariableClass, NameVariableGlobal, NameVariableInstance, NameVariableMagic, NameFunction, NameFunctionMagic, Literal, LiteralDate, LiteralOther, LiteralString, LiteralStringAffix, LiteralStringAtom, LiteralStringBacktick, LiteralStringBoolean, LiteralStringChar, LiteralStringDelimiter, LiteralStringDoc, LiteralStringDouble, LiteralStringEscape, LiteralStringHeredoc, LiteralStringInterpol, LiteralStringName, LiteralStringOther, LiteralStringRegex, LiteralStringSingle, LiteralStringSymbol, LiteralNumber, LiteralNumberBin, LiteralNumberFloat, LiteralNumberHex, LiteralNumberInteger, LiteralNumberIntegerLong, LiteralNumberOct, LiteralNumberByte, Operator, OperatorWord, Punctuation, Comment, CommentHashbang, CommentMultiline, CommentSingle, CommentSpecial, CommentPreproc, CommentPreprocFile, Generic, GenericDeleted, GenericEmph, GenericError, GenericHeading, GenericInserted, GenericOutput, GenericPrompt, GenericStrong, GenericSubheading, GenericTraceback, GenericUnderline, Text, TextWhitespace, TextSymbol, TextPunctuation}
+
+var _TokenTypeNameToValueMap = map[string]TokenType{
+ _TokenTypeName[0:6]: Ignore,
+ _TokenTypeLowerName[0:6]: Ignore,
+ _TokenTypeName[6:10]: None,
+ _TokenTypeLowerName[6:10]: None,
+ _TokenTypeName[10:15]: Other,
+ _TokenTypeLowerName[10:15]: Other,
+ _TokenTypeName[15:20]: Error,
+ _TokenTypeLowerName[15:20]: Error,
+ _TokenTypeName[20:28]: CodeLine,
+ _TokenTypeLowerName[20:28]: CodeLine,
+ _TokenTypeName[28:36]: LineLink,
+ _TokenTypeLowerName[28:36]: LineLink,
+ _TokenTypeName[36:47]: LineTableTD,
+ _TokenTypeLowerName[36:47]: LineTableTD,
+ _TokenTypeName[47:56]: LineTable,
+ _TokenTypeLowerName[47:56]: LineTable,
+ _TokenTypeName[56:69]: LineHighlight,
+ _TokenTypeLowerName[56:69]: LineHighlight,
+ _TokenTypeName[69:85]: LineNumbersTable,
+ _TokenTypeLowerName[69:85]: LineNumbersTable,
+ _TokenTypeName[85:96]: LineNumbers,
+ _TokenTypeLowerName[85:96]: LineNumbers,
+ _TokenTypeName[96:100]: Line,
+ _TokenTypeLowerName[96:100]: Line,
+ _TokenTypeName[100:110]: PreWrapper,
+ _TokenTypeLowerName[100:110]: PreWrapper,
+ _TokenTypeName[110:120]: Background,
+ _TokenTypeLowerName[110:120]: Background,
+ _TokenTypeName[120:127]: EOFType,
+ _TokenTypeLowerName[120:127]: EOFType,
+ _TokenTypeName[127:134]: Keyword,
+ _TokenTypeLowerName[127:134]: Keyword,
+ _TokenTypeName[134:149]: KeywordConstant,
+ _TokenTypeLowerName[134:149]: KeywordConstant,
+ _TokenTypeName[149:167]: KeywordDeclaration,
+ _TokenTypeLowerName[149:167]: KeywordDeclaration,
+ _TokenTypeName[167:183]: KeywordNamespace,
+ _TokenTypeLowerName[167:183]: KeywordNamespace,
+ _TokenTypeName[183:196]: KeywordPseudo,
+ _TokenTypeLowerName[183:196]: KeywordPseudo,
+ _TokenTypeName[196:211]: KeywordReserved,
+ _TokenTypeLowerName[196:211]: KeywordReserved,
+ _TokenTypeName[211:222]: KeywordType,
+ _TokenTypeLowerName[211:222]: KeywordType,
+ _TokenTypeName[222:226]: Name,
+ _TokenTypeLowerName[222:226]: Name,
+ _TokenTypeName[226:239]: NameAttribute,
+ _TokenTypeLowerName[226:239]: NameAttribute,
+ _TokenTypeName[239:248]: NameClass,
+ _TokenTypeLowerName[239:248]: NameClass,
+ _TokenTypeName[248:260]: NameConstant,
+ _TokenTypeLowerName[248:260]: NameConstant,
+ _TokenTypeName[260:273]: NameDecorator,
+ _TokenTypeLowerName[260:273]: NameDecorator,
+ _TokenTypeName[273:283]: NameEntity,
+ _TokenTypeLowerName[273:283]: NameEntity,
+ _TokenTypeName[283:296]: NameException,
+ _TokenTypeLowerName[283:296]: NameException,
+ _TokenTypeName[296:307]: NameKeyword,
+ _TokenTypeLowerName[296:307]: NameKeyword,
+ _TokenTypeName[307:316]: NameLabel,
+ _TokenTypeLowerName[307:316]: NameLabel,
+ _TokenTypeName[316:329]: NameNamespace,
+ _TokenTypeLowerName[316:329]: NameNamespace,
+ _TokenTypeName[329:341]: NameOperator,
+ _TokenTypeLowerName[329:341]: NameOperator,
+ _TokenTypeName[341:350]: NameOther,
+ _TokenTypeLowerName[341:350]: NameOther,
+ _TokenTypeName[350:360]: NamePseudo,
+ _TokenTypeLowerName[350:360]: NamePseudo,
+ _TokenTypeName[360:372]: NameProperty,
+ _TokenTypeLowerName[360:372]: NameProperty,
+ _TokenTypeName[372:379]: NameTag,
+ _TokenTypeLowerName[372:379]: NameTag,
+ _TokenTypeName[379:390]: NameBuiltin,
+ _TokenTypeLowerName[379:390]: NameBuiltin,
+ _TokenTypeName[390:407]: NameBuiltinPseudo,
+ _TokenTypeLowerName[390:407]: NameBuiltinPseudo,
+ _TokenTypeName[407:419]: NameVariable,
+ _TokenTypeLowerName[407:419]: NameVariable,
+ _TokenTypeName[419:440]: NameVariableAnonymous,
+ _TokenTypeLowerName[419:440]: NameVariableAnonymous,
+ _TokenTypeName[440:457]: NameVariableClass,
+ _TokenTypeLowerName[440:457]: NameVariableClass,
+ _TokenTypeName[457:475]: NameVariableGlobal,
+ _TokenTypeLowerName[457:475]: NameVariableGlobal,
+ _TokenTypeName[475:495]: NameVariableInstance,
+ _TokenTypeLowerName[475:495]: NameVariableInstance,
+ _TokenTypeName[495:512]: NameVariableMagic,
+ _TokenTypeLowerName[495:512]: NameVariableMagic,
+ _TokenTypeName[512:524]: NameFunction,
+ _TokenTypeLowerName[512:524]: NameFunction,
+ _TokenTypeName[524:541]: NameFunctionMagic,
+ _TokenTypeLowerName[524:541]: NameFunctionMagic,
+ _TokenTypeName[541:548]: Literal,
+ _TokenTypeLowerName[541:548]: Literal,
+ _TokenTypeName[548:559]: LiteralDate,
+ _TokenTypeLowerName[548:559]: LiteralDate,
+ _TokenTypeName[559:571]: LiteralOther,
+ _TokenTypeLowerName[559:571]: LiteralOther,
+ _TokenTypeName[571:584]: LiteralString,
+ _TokenTypeLowerName[571:584]: LiteralString,
+ _TokenTypeName[584:602]: LiteralStringAffix,
+ _TokenTypeLowerName[584:602]: LiteralStringAffix,
+ _TokenTypeName[602:619]: LiteralStringAtom,
+ _TokenTypeLowerName[602:619]: LiteralStringAtom,
+ _TokenTypeName[619:640]: LiteralStringBacktick,
+ _TokenTypeLowerName[619:640]: LiteralStringBacktick,
+ _TokenTypeName[640:660]: LiteralStringBoolean,
+ _TokenTypeLowerName[640:660]: LiteralStringBoolean,
+ _TokenTypeName[660:677]: LiteralStringChar,
+ _TokenTypeLowerName[660:677]: LiteralStringChar,
+ _TokenTypeName[677:699]: LiteralStringDelimiter,
+ _TokenTypeLowerName[677:699]: LiteralStringDelimiter,
+ _TokenTypeName[699:715]: LiteralStringDoc,
+ _TokenTypeLowerName[699:715]: LiteralStringDoc,
+ _TokenTypeName[715:734]: LiteralStringDouble,
+ _TokenTypeLowerName[715:734]: LiteralStringDouble,
+ _TokenTypeName[734:753]: LiteralStringEscape,
+ _TokenTypeLowerName[734:753]: LiteralStringEscape,
+ _TokenTypeName[753:773]: LiteralStringHeredoc,
+ _TokenTypeLowerName[753:773]: LiteralStringHeredoc,
+ _TokenTypeName[773:794]: LiteralStringInterpol,
+ _TokenTypeLowerName[773:794]: LiteralStringInterpol,
+ _TokenTypeName[794:811]: LiteralStringName,
+ _TokenTypeLowerName[794:811]: LiteralStringName,
+ _TokenTypeName[811:829]: LiteralStringOther,
+ _TokenTypeLowerName[811:829]: LiteralStringOther,
+ _TokenTypeName[829:847]: LiteralStringRegex,
+ _TokenTypeLowerName[829:847]: LiteralStringRegex,
+ _TokenTypeName[847:866]: LiteralStringSingle,
+ _TokenTypeLowerName[847:866]: LiteralStringSingle,
+ _TokenTypeName[866:885]: LiteralStringSymbol,
+ _TokenTypeLowerName[866:885]: LiteralStringSymbol,
+ _TokenTypeName[885:898]: LiteralNumber,
+ _TokenTypeLowerName[885:898]: LiteralNumber,
+ _TokenTypeName[898:914]: LiteralNumberBin,
+ _TokenTypeLowerName[898:914]: LiteralNumberBin,
+ _TokenTypeName[914:932]: LiteralNumberFloat,
+ _TokenTypeLowerName[914:932]: LiteralNumberFloat,
+ _TokenTypeName[932:948]: LiteralNumberHex,
+ _TokenTypeLowerName[932:948]: LiteralNumberHex,
+ _TokenTypeName[948:968]: LiteralNumberInteger,
+ _TokenTypeLowerName[948:968]: LiteralNumberInteger,
+ _TokenTypeName[968:992]: LiteralNumberIntegerLong,
+ _TokenTypeLowerName[968:992]: LiteralNumberIntegerLong,
+ _TokenTypeName[992:1008]: LiteralNumberOct,
+ _TokenTypeLowerName[992:1008]: LiteralNumberOct,
+ _TokenTypeName[1008:1025]: LiteralNumberByte,
+ _TokenTypeLowerName[1008:1025]: LiteralNumberByte,
+ _TokenTypeName[1025:1033]: Operator,
+ _TokenTypeLowerName[1025:1033]: Operator,
+ _TokenTypeName[1033:1045]: OperatorWord,
+ _TokenTypeLowerName[1033:1045]: OperatorWord,
+ _TokenTypeName[1045:1056]: Punctuation,
+ _TokenTypeLowerName[1045:1056]: Punctuation,
+ _TokenTypeName[1056:1063]: Comment,
+ _TokenTypeLowerName[1056:1063]: Comment,
+ _TokenTypeName[1063:1078]: CommentHashbang,
+ _TokenTypeLowerName[1063:1078]: CommentHashbang,
+ _TokenTypeName[1078:1094]: CommentMultiline,
+ _TokenTypeLowerName[1078:1094]: CommentMultiline,
+ _TokenTypeName[1094:1107]: CommentSingle,
+ _TokenTypeLowerName[1094:1107]: CommentSingle,
+ _TokenTypeName[1107:1121]: CommentSpecial,
+ _TokenTypeLowerName[1107:1121]: CommentSpecial,
+ _TokenTypeName[1121:1135]: CommentPreproc,
+ _TokenTypeLowerName[1121:1135]: CommentPreproc,
+ _TokenTypeName[1135:1153]: CommentPreprocFile,
+ _TokenTypeLowerName[1135:1153]: CommentPreprocFile,
+ _TokenTypeName[1153:1160]: Generic,
+ _TokenTypeLowerName[1153:1160]: Generic,
+ _TokenTypeName[1160:1174]: GenericDeleted,
+ _TokenTypeLowerName[1160:1174]: GenericDeleted,
+ _TokenTypeName[1174:1185]: GenericEmph,
+ _TokenTypeLowerName[1174:1185]: GenericEmph,
+ _TokenTypeName[1185:1197]: GenericError,
+ _TokenTypeLowerName[1185:1197]: GenericError,
+ _TokenTypeName[1197:1211]: GenericHeading,
+ _TokenTypeLowerName[1197:1211]: GenericHeading,
+ _TokenTypeName[1211:1226]: GenericInserted,
+ _TokenTypeLowerName[1211:1226]: GenericInserted,
+ _TokenTypeName[1226:1239]: GenericOutput,
+ _TokenTypeLowerName[1226:1239]: GenericOutput,
+ _TokenTypeName[1239:1252]: GenericPrompt,
+ _TokenTypeLowerName[1239:1252]: GenericPrompt,
+ _TokenTypeName[1252:1265]: GenericStrong,
+ _TokenTypeLowerName[1252:1265]: GenericStrong,
+ _TokenTypeName[1265:1282]: GenericSubheading,
+ _TokenTypeLowerName[1265:1282]: GenericSubheading,
+ _TokenTypeName[1282:1298]: GenericTraceback,
+ _TokenTypeLowerName[1282:1298]: GenericTraceback,
+ _TokenTypeName[1298:1314]: GenericUnderline,
+ _TokenTypeLowerName[1298:1314]: GenericUnderline,
+ _TokenTypeName[1314:1318]: Text,
+ _TokenTypeLowerName[1314:1318]: Text,
+ _TokenTypeName[1318:1332]: TextWhitespace,
+ _TokenTypeLowerName[1318:1332]: TextWhitespace,
+ _TokenTypeName[1332:1342]: TextSymbol,
+ _TokenTypeLowerName[1332:1342]: TextSymbol,
+ _TokenTypeName[1342:1357]: TextPunctuation,
+ _TokenTypeLowerName[1342:1357]: TextPunctuation,
+}
+
+var _TokenTypeNames = []string{
+ _TokenTypeName[0:6],
+ _TokenTypeName[6:10],
+ _TokenTypeName[10:15],
+ _TokenTypeName[15:20],
+ _TokenTypeName[20:28],
+ _TokenTypeName[28:36],
+ _TokenTypeName[36:47],
+ _TokenTypeName[47:56],
+ _TokenTypeName[56:69],
+ _TokenTypeName[69:85],
+ _TokenTypeName[85:96],
+ _TokenTypeName[96:100],
+ _TokenTypeName[100:110],
+ _TokenTypeName[110:120],
+ _TokenTypeName[120:127],
+ _TokenTypeName[127:134],
+ _TokenTypeName[134:149],
+ _TokenTypeName[149:167],
+ _TokenTypeName[167:183],
+ _TokenTypeName[183:196],
+ _TokenTypeName[196:211],
+ _TokenTypeName[211:222],
+ _TokenTypeName[222:226],
+ _TokenTypeName[226:239],
+ _TokenTypeName[239:248],
+ _TokenTypeName[248:260],
+ _TokenTypeName[260:273],
+ _TokenTypeName[273:283],
+ _TokenTypeName[283:296],
+ _TokenTypeName[296:307],
+ _TokenTypeName[307:316],
+ _TokenTypeName[316:329],
+ _TokenTypeName[329:341],
+ _TokenTypeName[341:350],
+ _TokenTypeName[350:360],
+ _TokenTypeName[360:372],
+ _TokenTypeName[372:379],
+ _TokenTypeName[379:390],
+ _TokenTypeName[390:407],
+ _TokenTypeName[407:419],
+ _TokenTypeName[419:440],
+ _TokenTypeName[440:457],
+ _TokenTypeName[457:475],
+ _TokenTypeName[475:495],
+ _TokenTypeName[495:512],
+ _TokenTypeName[512:524],
+ _TokenTypeName[524:541],
+ _TokenTypeName[541:548],
+ _TokenTypeName[548:559],
+ _TokenTypeName[559:571],
+ _TokenTypeName[571:584],
+ _TokenTypeName[584:602],
+ _TokenTypeName[602:619],
+ _TokenTypeName[619:640],
+ _TokenTypeName[640:660],
+ _TokenTypeName[660:677],
+ _TokenTypeName[677:699],
+ _TokenTypeName[699:715],
+ _TokenTypeName[715:734],
+ _TokenTypeName[734:753],
+ _TokenTypeName[753:773],
+ _TokenTypeName[773:794],
+ _TokenTypeName[794:811],
+ _TokenTypeName[811:829],
+ _TokenTypeName[829:847],
+ _TokenTypeName[847:866],
+ _TokenTypeName[866:885],
+ _TokenTypeName[885:898],
+ _TokenTypeName[898:914],
+ _TokenTypeName[914:932],
+ _TokenTypeName[932:948],
+ _TokenTypeName[948:968],
+ _TokenTypeName[968:992],
+ _TokenTypeName[992:1008],
+ _TokenTypeName[1008:1025],
+ _TokenTypeName[1025:1033],
+ _TokenTypeName[1033:1045],
+ _TokenTypeName[1045:1056],
+ _TokenTypeName[1056:1063],
+ _TokenTypeName[1063:1078],
+ _TokenTypeName[1078:1094],
+ _TokenTypeName[1094:1107],
+ _TokenTypeName[1107:1121],
+ _TokenTypeName[1121:1135],
+ _TokenTypeName[1135:1153],
+ _TokenTypeName[1153:1160],
+ _TokenTypeName[1160:1174],
+ _TokenTypeName[1174:1185],
+ _TokenTypeName[1185:1197],
+ _TokenTypeName[1197:1211],
+ _TokenTypeName[1211:1226],
+ _TokenTypeName[1226:1239],
+ _TokenTypeName[1239:1252],
+ _TokenTypeName[1252:1265],
+ _TokenTypeName[1265:1282],
+ _TokenTypeName[1282:1298],
+ _TokenTypeName[1298:1314],
+ _TokenTypeName[1314:1318],
+ _TokenTypeName[1318:1332],
+ _TokenTypeName[1332:1342],
+ _TokenTypeName[1342:1357],
+}
+
+// TokenTypeString retrieves an enum value from the enum constants string name.
+// Throws an error if the param is not part of the enum.
+func TokenTypeString(s string) (TokenType, error) {
+ if val, ok := _TokenTypeNameToValueMap[s]; ok {
+ return val, nil
+ }
+
+ if val, ok := _TokenTypeNameToValueMap[strings.ToLower(s)]; ok {
+ return val, nil
+ }
+ return 0, fmt.Errorf("%s does not belong to TokenType values", s)
+}
+
+// TokenTypeValues returns all values of the enum
+func TokenTypeValues() []TokenType {
+ return _TokenTypeValues
+}
+
+// TokenTypeStrings returns a slice of all String values of the enum
+func TokenTypeStrings() []string {
+ strs := make([]string, len(_TokenTypeNames))
+ copy(strs, _TokenTypeNames)
+ return strs
+}
+
+// IsATokenType returns "true" if the value is listed in the enum definition. "false" otherwise
+func (i TokenType) IsATokenType() bool {
+ _, ok := _TokenTypeMap[i]
+ return ok
+}
+
+// MarshalText implements the encoding.TextMarshaler interface for TokenType
+func (i TokenType) MarshalText() ([]byte, error) {
+ return []byte(i.String()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface for TokenType
+func (i *TokenType) UnmarshalText(text []byte) error {
+ var err error
+ *i, err = TokenTypeString(string(text))
+ return err
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/types.go b/vendor/github.com/alecthomas/chroma/v2/types.go
new file mode 100644
index 00000000..3009f980
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/types.go
@@ -0,0 +1,355 @@
+package chroma
+
+//go:generate enumer -text -type TokenType
+
+// TokenType is the type of token to highlight.
+//
+// It is also an Emitter, emitting a single token of itself
+type TokenType int
+
+// Set of TokenTypes.
+//
+// Categories of types are grouped in ranges of 1000, while sub-categories are in ranges of 100. For
+// example, the literal category is in the range 3000-3999. The sub-category for literal strings is
+// in the range 3100-3199.
+
+// Meta token types.
+const (
+ // Default background style.
+ Background TokenType = -1 - iota
+ // PreWrapper style.
+ PreWrapper
+ // Line style.
+ Line
+ // Line numbers in output.
+ LineNumbers
+ // Line numbers in output when in table.
+ LineNumbersTable
+ // Line higlight style.
+ LineHighlight
+ // Line numbers table wrapper style.
+ LineTable
+ // Line numbers table TD wrapper style.
+ LineTableTD
+ // Line number links.
+ LineLink
+ // Code line wrapper style.
+ CodeLine
+ // Input that could not be tokenised.
+ Error
+ // Other is used by the Delegate lexer to indicate which tokens should be handled by the delegate.
+ Other
+ // No highlighting.
+ None
+ // Don't emit this token to the output.
+ Ignore
+ // Used as an EOF marker / nil token
+ EOFType TokenType = 0
+)
+
+// Keywords.
+const (
+ Keyword TokenType = 1000 + iota
+ KeywordConstant
+ KeywordDeclaration
+ KeywordNamespace
+ KeywordPseudo
+ KeywordReserved
+ KeywordType
+)
+
+// Names.
+const (
+ Name TokenType = 2000 + iota
+ NameAttribute
+ NameClass
+ NameConstant
+ NameDecorator
+ NameEntity
+ NameException
+ NameKeyword
+ NameLabel
+ NameNamespace
+ NameOperator
+ NameOther
+ NamePseudo
+ NameProperty
+ NameTag
+)
+
+// Builtin names.
+const (
+ NameBuiltin TokenType = 2100 + iota
+ NameBuiltinPseudo
+)
+
+// Variable names.
+const (
+ NameVariable TokenType = 2200 + iota
+ NameVariableAnonymous
+ NameVariableClass
+ NameVariableGlobal
+ NameVariableInstance
+ NameVariableMagic
+)
+
+// Function names.
+const (
+ NameFunction TokenType = 2300 + iota
+ NameFunctionMagic
+)
+
+// Literals.
+const (
+ Literal TokenType = 3000 + iota
+ LiteralDate
+ LiteralOther
+)
+
+// Strings.
+const (
+ LiteralString TokenType = 3100 + iota
+ LiteralStringAffix
+ LiteralStringAtom
+ LiteralStringBacktick
+ LiteralStringBoolean
+ LiteralStringChar
+ LiteralStringDelimiter
+ LiteralStringDoc
+ LiteralStringDouble
+ LiteralStringEscape
+ LiteralStringHeredoc
+ LiteralStringInterpol
+ LiteralStringName
+ LiteralStringOther
+ LiteralStringRegex
+ LiteralStringSingle
+ LiteralStringSymbol
+)
+
+// Literals.
+const (
+ LiteralNumber TokenType = 3200 + iota
+ LiteralNumberBin
+ LiteralNumberFloat
+ LiteralNumberHex
+ LiteralNumberInteger
+ LiteralNumberIntegerLong
+ LiteralNumberOct
+ LiteralNumberByte
+)
+
+// Operators.
+const (
+ Operator TokenType = 4000 + iota
+ OperatorWord
+)
+
+// Punctuation.
+const (
+ Punctuation TokenType = 5000 + iota
+)
+
+// Comments.
+const (
+ Comment TokenType = 6000 + iota
+ CommentHashbang
+ CommentMultiline
+ CommentSingle
+ CommentSpecial
+)
+
+// Preprocessor "comments".
+const (
+ CommentPreproc TokenType = 6100 + iota
+ CommentPreprocFile
+)
+
+// Generic tokens.
+const (
+ Generic TokenType = 7000 + iota
+ GenericDeleted
+ GenericEmph
+ GenericError
+ GenericHeading
+ GenericInserted
+ GenericOutput
+ GenericPrompt
+ GenericStrong
+ GenericSubheading
+ GenericTraceback
+ GenericUnderline
+)
+
+// Text.
+const (
+ Text TokenType = 8000 + iota
+ TextWhitespace
+ TextSymbol
+ TextPunctuation
+)
+
+// Aliases.
+const (
+ Whitespace = TextWhitespace
+
+ Date = LiteralDate
+
+ String = LiteralString
+ StringAffix = LiteralStringAffix
+ StringBacktick = LiteralStringBacktick
+ StringChar = LiteralStringChar
+ StringDelimiter = LiteralStringDelimiter
+ StringDoc = LiteralStringDoc
+ StringDouble = LiteralStringDouble
+ StringEscape = LiteralStringEscape
+ StringHeredoc = LiteralStringHeredoc
+ StringInterpol = LiteralStringInterpol
+ StringOther = LiteralStringOther
+ StringRegex = LiteralStringRegex
+ StringSingle = LiteralStringSingle
+ StringSymbol = LiteralStringSymbol
+
+ Number = LiteralNumber
+ NumberBin = LiteralNumberBin
+ NumberFloat = LiteralNumberFloat
+ NumberHex = LiteralNumberHex
+ NumberInteger = LiteralNumberInteger
+ NumberIntegerLong = LiteralNumberIntegerLong
+ NumberOct = LiteralNumberOct
+)
+
+var (
+ StandardTypes = map[TokenType]string{
+ Background: "bg",
+ PreWrapper: "chroma",
+ Line: "line",
+ LineNumbers: "ln",
+ LineNumbersTable: "lnt",
+ LineHighlight: "hl",
+ LineTable: "lntable",
+ LineTableTD: "lntd",
+ LineLink: "lnlinks",
+ CodeLine: "cl",
+ Text: "",
+ Whitespace: "w",
+ Error: "err",
+ Other: "x",
+ // I have no idea what this is used for...
+ // Escape: "esc",
+
+ Keyword: "k",
+ KeywordConstant: "kc",
+ KeywordDeclaration: "kd",
+ KeywordNamespace: "kn",
+ KeywordPseudo: "kp",
+ KeywordReserved: "kr",
+ KeywordType: "kt",
+
+ Name: "n",
+ NameAttribute: "na",
+ NameBuiltin: "nb",
+ NameBuiltinPseudo: "bp",
+ NameClass: "nc",
+ NameConstant: "no",
+ NameDecorator: "nd",
+ NameEntity: "ni",
+ NameException: "ne",
+ NameFunction: "nf",
+ NameFunctionMagic: "fm",
+ NameProperty: "py",
+ NameLabel: "nl",
+ NameNamespace: "nn",
+ NameOther: "nx",
+ NameTag: "nt",
+ NameVariable: "nv",
+ NameVariableClass: "vc",
+ NameVariableGlobal: "vg",
+ NameVariableInstance: "vi",
+ NameVariableMagic: "vm",
+
+ Literal: "l",
+ LiteralDate: "ld",
+
+ String: "s",
+ StringAffix: "sa",
+ StringBacktick: "sb",
+ StringChar: "sc",
+ StringDelimiter: "dl",
+ StringDoc: "sd",
+ StringDouble: "s2",
+ StringEscape: "se",
+ StringHeredoc: "sh",
+ StringInterpol: "si",
+ StringOther: "sx",
+ StringRegex: "sr",
+ StringSingle: "s1",
+ StringSymbol: "ss",
+
+ Number: "m",
+ NumberBin: "mb",
+ NumberFloat: "mf",
+ NumberHex: "mh",
+ NumberInteger: "mi",
+ NumberIntegerLong: "il",
+ NumberOct: "mo",
+
+ Operator: "o",
+ OperatorWord: "ow",
+
+ Punctuation: "p",
+
+ Comment: "c",
+ CommentHashbang: "ch",
+ CommentMultiline: "cm",
+ CommentPreproc: "cp",
+ CommentPreprocFile: "cpf",
+ CommentSingle: "c1",
+ CommentSpecial: "cs",
+
+ Generic: "g",
+ GenericDeleted: "gd",
+ GenericEmph: "ge",
+ GenericError: "gr",
+ GenericHeading: "gh",
+ GenericInserted: "gi",
+ GenericOutput: "go",
+ GenericPrompt: "gp",
+ GenericStrong: "gs",
+ GenericSubheading: "gu",
+ GenericTraceback: "gt",
+ GenericUnderline: "gl",
+ }
+)
+
+func (t TokenType) Parent() TokenType {
+ if t%100 != 0 {
+ return t / 100 * 100
+ }
+ if t%1000 != 0 {
+ return t / 1000 * 1000
+ }
+ return 0
+}
+
+func (t TokenType) Category() TokenType {
+ return t / 1000 * 1000
+}
+
+func (t TokenType) SubCategory() TokenType {
+ return t / 100 * 100
+}
+
+func (t TokenType) InCategory(other TokenType) bool {
+ return t/1000 == other/1000
+}
+
+func (t TokenType) InSubCategory(other TokenType) bool {
+ return t/100 == other/100
+}
+
+func (t TokenType) Emit(groups []string, _ *LexerState) Iterator {
+ return Literator(Token{Type: t, Value: groups[0]})
+}
+
+func (t TokenType) EmitterKind() string { return "token" }
diff --git a/vendor/github.com/alexkohler/nakedret/v2/README.md b/vendor/github.com/alexkohler/nakedret/v2/README.md
index e30a0cde..54f6ce6c 100644
--- a/vendor/github.com/alexkohler/nakedret/v2/README.md
+++ b/vendor/github.com/alexkohler/nakedret/v2/README.md
@@ -6,7 +6,7 @@ nakedret is a Go static analysis tool to find naked returns in functions greater
Install Nakedret via go install:
```cmd
-go install github.com/alexkohler/nakedret/cmd/nakedret@latest
+go install github.com/alexkohler/nakedret/v2/cmd/nakedret@latest
```
If you have not already added your `GOPATH/bin` directory to your `PATH` environment variable then you will need to do so.
diff --git a/vendor/github.com/alexkohler/nakedret/v2/nakedret.go b/vendor/github.com/alexkohler/nakedret/v2/nakedret.go
index a5573592..9f53d2a7 100644
--- a/vendor/github.com/alexkohler/nakedret/v2/nakedret.go
+++ b/vendor/github.com/alexkohler/nakedret/v2/nakedret.go
@@ -3,7 +3,6 @@ package nakedret
import (
"bytes"
"errors"
- "flag"
"fmt"
"go/ast"
"go/build"
@@ -22,19 +21,15 @@ import (
const pwd = "./"
-func NakedReturnAnalyzer(defaultLines uint, skipTestFiles bool) *analysis.Analyzer {
- nakedRet := &NakedReturnRunner{}
- flags := flag.NewFlagSet("nakedret", flag.ExitOnError)
- flags.UintVar(&nakedRet.MaxLength, "l", defaultLines, "maximum number of lines for a naked return function")
- flags.BoolVar(&nakedRet.SkipTestFiles, "skip-test-files", skipTestFiles, "set to true to skip test files")
- var analyzer = &analysis.Analyzer{
+func NakedReturnAnalyzer(nakedRet *NakedReturnRunner) *analysis.Analyzer {
+ a := &analysis.Analyzer{
Name: "nakedret",
Doc: "Checks that functions with naked returns are not longer than a maximum size (can be zero).",
Run: nakedRet.run,
- Flags: *flags,
Requires: []*analysis.Analyzer{inspect.Analyzer},
}
- return analyzer
+
+ return a
}
type NakedReturnRunner struct {
@@ -91,7 +86,7 @@ func checkNakedReturns(args []string, maxLength *uint, skipTestFiles bool, setEx
return errors.New("max length nil")
}
- analyzer := NakedReturnAnalyzer(*maxLength, skipTestFiles)
+ analyzer := NakedReturnAnalyzer(&NakedReturnRunner{MaxLength: *maxLength, SkipTestFiles: skipTestFiles})
pass := &analysis.Pass{
Analyzer: analyzer,
Fset: fset,
diff --git a/vendor/github.com/alingse/nilnesserr/.golangci.yaml b/vendor/github.com/alingse/nilnesserr/.golangci.yaml
index 1a2a270a..6882e0f3 100644
--- a/vendor/github.com/alingse/nilnesserr/.golangci.yaml
+++ b/vendor/github.com/alingse/nilnesserr/.golangci.yaml
@@ -18,6 +18,10 @@ linters-settings:
allow:
- $gostd
- github.com/alingse/nilnesserr
+ cyclop:
+ max-complexity: 12
+ lll:
+ line-length: 200
issues:
exclude-rules:
@@ -64,3 +68,8 @@ issues:
- text: "newAnalyzer"
linters:
- unparam
+
+ - text: "indent-error-flow"
+ path: nilness.go
+ linters:
+ - revive
diff --git a/vendor/github.com/alingse/nilnesserr/README.md b/vendor/github.com/alingse/nilnesserr/README.md
index 6b199b6c..2299488e 100644
--- a/vendor/github.com/alingse/nilnesserr/README.md
+++ b/vendor/github.com/alingse/nilnesserr/README.md
@@ -14,7 +14,33 @@ if err != nil {
}
err2 := do2()
if err2 != nil {
- return err // which should return err2 after check `err2 != nil`, but return a nil value error
+ return err // want `return a nil value error after check error`
+}
+```
+
+case 2
+
+```go
+err := do()
+if err != nil {
+ return err
+}
+_, err2 := do2()
+if err2 != nil {
+ return errors.Wrap(err) // want `call function with a nil value error after check error`
+}
+```
+
+case 3
+
+```go
+err := do()
+if err != nil {
+ return err
+}
+_, err2 := do2()
+if err2 != nil {
+ return fmt.Errorf("call do2 failed: %w",err) // want `call variadic function with a nil value error after check error`
}
```
@@ -23,6 +49,8 @@ if err2 != nil {
- https://github.com/alingse/sundrylint/issues/4
- https://github.com/alingse/nilnesserr/issues/1
+- https://github.com/alingse/nilnesserr/issues/11
+- https://github.com/alingse/nilnesserr/issues/15
We use https://github.com/alingse/go-linter-runner to run linter on GitHub Actions for public Go repos
@@ -35,7 +63,7 @@ go install github.com/alingse/nilnesserr/cmd/nilnesserr@latest
## TODO
-case 2
+case 3
```go
err := do()
@@ -49,19 +77,6 @@ if !ok {
```
-case 3
-
-```go
-err := do()
-if err != nil {
- return err
-}
-_, ok := do2()
-if !ok {
- return errors.Wrap(err)
-}
-```
-
maybe this is also a bug, should return a non-nil value error after the if
## License
diff --git a/vendor/github.com/alingse/nilnesserr/linter.go b/vendor/github.com/alingse/nilnesserr/linter.go
index 704e347e..2f572462 100644
--- a/vendor/github.com/alingse/nilnesserr/linter.go
+++ b/vendor/github.com/alingse/nilnesserr/linter.go
@@ -10,7 +10,9 @@ const (
linterDoc = `Reports constructs that checks for err != nil, but returns a different nil value error.
Powered by nilness and nilerr.`
- linterMessage = "return a nil value error after check error"
+ linterReturnMessage = "return a nil value error after check error"
+ linterCallMessage = "call function with a nil value error after check error"
+ linterVariadicCallMessage = "call variadic function with a nil value error after check error"
)
type LinterSetting struct{}
diff --git a/vendor/github.com/alingse/nilnesserr/nilerr.go b/vendor/github.com/alingse/nilnesserr/nilerr.go
index c05ec900..093fc1eb 100644
--- a/vendor/github.com/alingse/nilnesserr/nilerr.go
+++ b/vendor/github.com/alingse/nilnesserr/nilerr.go
@@ -55,29 +55,138 @@ func findLastNonnilValue(errors []errFact, res ssa.Value) ssa.Value {
}
func checkNilnesserr(pass *analysis.Pass, b *ssa.BasicBlock, errors []errFact, isNilnees func(value ssa.Value) bool) {
- for i := range b.Instrs {
- instr, ok := b.Instrs[i].(*ssa.Return)
- if !ok {
+ for _, instr := range b.Instrs {
+ pos := instr.Pos()
+ if !pos.IsValid() {
continue
}
- for _, res := range instr.Results {
- if !isErrType(res) || isConstNil(res) || !isNilnees(res) {
- continue
+ switch instr := instr.(type) {
+ case *ssa.Return:
+ for _, value := range instr.Results {
+ if checkSSAValue(value, errors, isNilnees) {
+ pass.Report(analysis.Diagnostic{
+ Pos: pos,
+ Message: linterReturnMessage,
+ })
+ }
+ }
+ case *ssa.Call:
+ for _, value := range instr.Call.Args {
+ if checkSSAValue(value, errors, isNilnees) {
+ pass.Report(analysis.Diagnostic{
+ Pos: pos,
+ Message: linterCallMessage,
+ })
+ }
}
- // check the lastValue error that is isnonnil
- lastValue := findLastNonnilValue(errors, res)
- if lastValue == nil {
+
+ // extra check for variadic arguments
+ variadicArgs := checkVariadicCall(instr)
+ for _, value := range variadicArgs {
+ if checkSSAValue(value, errors, isNilnees) {
+ pass.Report(analysis.Diagnostic{
+ Pos: pos,
+ Message: linterVariadicCallMessage,
+ })
+ }
+ }
+ }
+ }
+}
+
+func checkSSAValue(res ssa.Value, errors []errFact, isNilnees func(value ssa.Value) bool) bool {
+ if !isErrType(res) || isConstNil(res) || !isNilnees(res) {
+ return false
+ }
+ // check the lastValue error that is isnonnil
+ lastValue := findLastNonnilValue(errors, res)
+
+ return lastValue != nil
+}
+
+func checkVariadicCall(call *ssa.Call) []ssa.Value {
+ alloc := validateVariadicCall(call)
+ if alloc == nil {
+ return nil
+ }
+
+ return extractVariadicErrors(alloc)
+}
+
+/*
+example: fmt.Errorf("call Do2 got err %w", err)
+
+type *ssa.Alloc instr new [1]any (varargs)
+type *ssa.IndexAddr instr &t4[0:int]
+type *ssa.ChangeInterface instr change interface any <- error (t0)
+type *ssa.Store instr *t5 = t6
+...
+type *ssa.Slice instr slice t4[:]
+type *ssa.Call instr fmt.Errorf("call Do2 got err ...":string, t7...)
+*/
+func validateVariadicCall(call *ssa.Call) *ssa.Alloc {
+ fn, ok := call.Call.Value.(*ssa.Function)
+ if !ok {
+ return nil
+ }
+ if !fn.Signature.Variadic() {
+ return nil
+ }
+
+ if len(call.Call.Args) == 0 {
+ return nil
+ }
+ lastArg := call.Call.Args[len(call.Call.Args)-1]
+ slice, ok := lastArg.(*ssa.Slice)
+ if !ok {
+ return nil
+ }
+ // check is t[:]
+ if !(slice.Low == nil && slice.High == nil && slice.Max == nil) {
+ return nil
+ }
+ alloc, ok := slice.X.(*ssa.Alloc)
+ if !ok {
+ return nil
+ }
+ valueType, ok := alloc.Type().(*types.Pointer)
+ if !ok {
+ return nil
+ }
+
+ // check is array
+ _, ok = valueType.Elem().(*types.Array)
+ if !ok {
+ return nil
+ }
+
+ return alloc
+}
+
+// the Referrer chain is like this.
+// Alloc --> IndexAddr --> ChangeInterface --> Store ---> Slice.
+// Alloc --> IndexAddr --> Store --> Slice.
+func extractVariadicErrors(alloc *ssa.Alloc) []ssa.Value {
+ values := make([]ssa.Value, 0)
+
+ for _, instr := range *alloc.Referrers() {
+ indexAddr, ok := instr.(*ssa.IndexAddr)
+ if !ok {
+ continue
+ }
+ for _, instr2 := range *indexAddr.Referrers() {
+ store, ok := instr2.(*ssa.Store)
+ if !ok {
continue
}
- // report
- pos := instr.Pos()
- if pos.IsValid() {
- pass.Report(analysis.Diagnostic{
- Pos: pos,
- Message: linterMessage,
- })
+ value := store.Val
+ if change, ok := value.(*ssa.ChangeInterface); ok {
+ value = change.X
}
+ values = append(values, value)
}
}
+
+ return values
}
diff --git a/vendor/github.com/sivchari/tenv/LICENSE b/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE
similarity index 96%
rename from vendor/github.com/sivchari/tenv/LICENSE
rename to vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE
index 5185ec09..25cec1ed 100644
--- a/vendor/github.com/sivchari/tenv/LICENSE
+++ b/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2021 sivchari
+Copyright (c) 2022 Ayman Bagabas
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/github.com/aymanbagabas/go-osc52/v2/README.md b/vendor/github.com/aymanbagabas/go-osc52/v2/README.md
new file mode 100644
index 00000000..4de3a22d
--- /dev/null
+++ b/vendor/github.com/aymanbagabas/go-osc52/v2/README.md
@@ -0,0 +1,83 @@
+
+# go-osc52
+
+
+
+A Go library to work with the [ANSI OSC52](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands) terminal sequence.
+
+## Usage
+
+You can use this small library to construct an ANSI OSC52 sequence suitable for
+your terminal.
+
+
+### Example
+
+```go
+import (
+ "os"
+ "fmt"
+
+ "github.com/aymanbagabas/go-osc52/v2"
+)
+
+func main() {
+ s := "Hello World!"
+
+ // Copy `s` to system clipboard
+ osc52.New(s).WriteTo(os.Stderr)
+
+ // Copy `s` to primary clipboard (X11)
+ osc52.New(s).Primary().WriteTo(os.Stderr)
+
+ // Query the clipboard
+ osc52.Query().WriteTo(os.Stderr)
+
+ // Clear system clipboard
+ osc52.Clear().WriteTo(os.Stderr)
+
+ // Use the fmt.Stringer interface to copy `s` to system clipboard
+ fmt.Fprint(os.Stderr, osc52.New(s))
+
+ // Or to primary clipboard
+ fmt.Fprint(os.Stderr, osc52.New(s).Primary())
+}
+```
+
+## SSH Example
+
+You can use this over SSH using [gliderlabs/ssh](https://github.com/gliderlabs/ssh) for instance:
+
+```go
+var sshSession ssh.Session
+seq := osc52.New("Hello awesome!")
+// Check if term is screen or tmux
+pty, _, _ := s.Pty()
+if pty.Term == "screen" {
+ seq = seq.Screen()
+} else if isTmux {
+ seq = seq.Tmux()
+}
+seq.WriteTo(sshSession.Stderr())
+```
+
+## Tmux
+
+Make sure you have `set-clipboard on` in your config, otherwise, tmux won't
+allow your application to access the clipboard [^1].
+
+Using the tmux option, `osc52.TmuxMode` or `osc52.New(...).Tmux()`, wraps the
+OSC52 sequence in a special tmux DCS sequence and pass it to the outer
+terminal. This requires `allow-passthrough on` in your config.
+`allow-passthrough` is no longer enabled by default
+[since tmux 3.3a](https://github.com/tmux/tmux/issues/3218#issuecomment-1153089282) [^2].
+
+[^1]: See [tmux clipboard](https://github.com/tmux/tmux/wiki/Clipboard)
+[^2]: [What is allow-passthrough](https://github.com/tmux/tmux/wiki/FAQ#what-is-the-passthrough-escape-sequence-and-how-do-i-use-it)
+
+## Credits
+
+* [vim-oscyank](https://github.com/ojroques/vim-oscyank) this is heavily inspired by vim-oscyank.
diff --git a/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go b/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go
new file mode 100644
index 00000000..dc758d28
--- /dev/null
+++ b/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go
@@ -0,0 +1,305 @@
+// OSC52 is a terminal escape sequence that allows copying text to the clipboard.
+//
+// The sequence consists of the following:
+//
+// OSC 52 ; Pc ; Pd BEL
+//
+// Pc is the clipboard choice:
+//
+// c: clipboard
+// p: primary
+// q: secondary (not supported)
+// s: select (not supported)
+// 0-7: cut-buffers (not supported)
+//
+// Pd is the data to copy to the clipboard. This string should be encoded in
+// base64 (RFC-4648).
+//
+// If Pd is "?", the terminal replies to the host with the current contents of
+// the clipboard.
+//
+// If Pd is neither a base64 string nor "?", the terminal clears the clipboard.
+//
+// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+// where Ps = 52 => Manipulate Selection Data.
+//
+// Examples:
+//
+// // copy "hello world" to the system clipboard
+// fmt.Fprint(os.Stderr, osc52.New("hello world"))
+//
+// // copy "hello world" to the primary Clipboard
+// fmt.Fprint(os.Stderr, osc52.New("hello world").Primary())
+//
+// // limit the size of the string to copy 10 bytes
+// fmt.Fprint(os.Stderr, osc52.New("0123456789").Limit(10))
+//
+// // escape the OSC52 sequence for screen using DCS sequences
+// fmt.Fprint(os.Stderr, osc52.New("hello world").Screen())
+//
+// // escape the OSC52 sequence for Tmux
+// fmt.Fprint(os.Stderr, osc52.New("hello world").Tmux())
+//
+// // query the system Clipboard
+// fmt.Fprint(os.Stderr, osc52.Query())
+//
+// // query the primary clipboard
+// fmt.Fprint(os.Stderr, osc52.Query().Primary())
+//
+// // clear the system Clipboard
+// fmt.Fprint(os.Stderr, osc52.Clear())
+//
+// // clear the primary Clipboard
+// fmt.Fprint(os.Stderr, osc52.Clear().Primary())
+package osc52
+
+import (
+ "encoding/base64"
+ "fmt"
+ "io"
+ "strings"
+)
+
+// Clipboard is the clipboard buffer to use.
+type Clipboard rune
+
+const (
+ // SystemClipboard is the system clipboard buffer.
+ SystemClipboard Clipboard = 'c'
+ // PrimaryClipboard is the primary clipboard buffer (X11).
+ PrimaryClipboard = 'p'
+)
+
+// Mode is the mode to use for the OSC52 sequence.
+type Mode uint
+
+const (
+ // DefaultMode is the default OSC52 sequence mode.
+ DefaultMode Mode = iota
+ // ScreenMode escapes the OSC52 sequence for screen using DCS sequences.
+ ScreenMode
+ // TmuxMode escapes the OSC52 sequence for tmux. Not needed if tmux
+ // clipboard is set to `set-clipboard on`
+ TmuxMode
+)
+
+// Operation is the OSC52 operation.
+type Operation uint
+
+const (
+ // SetOperation is the copy operation.
+ SetOperation Operation = iota
+ // QueryOperation is the query operation.
+ QueryOperation
+ // ClearOperation is the clear operation.
+ ClearOperation
+)
+
+// Sequence is the OSC52 sequence.
+type Sequence struct {
+ str string
+ limit int
+ op Operation
+ mode Mode
+ clipboard Clipboard
+}
+
+var _ fmt.Stringer = Sequence{}
+
+var _ io.WriterTo = Sequence{}
+
+// String returns the OSC52 sequence.
+func (s Sequence) String() string {
+ var seq strings.Builder
+ // mode escape sequences start
+ seq.WriteString(s.seqStart())
+ // actual OSC52 sequence start
+ seq.WriteString(fmt.Sprintf("\x1b]52;%c;", s.clipboard))
+ switch s.op {
+ case SetOperation:
+ str := s.str
+ if s.limit > 0 && len(str) > s.limit {
+ return ""
+ }
+ b64 := base64.StdEncoding.EncodeToString([]byte(str))
+ switch s.mode {
+ case ScreenMode:
+ // Screen doesn't support OSC52 but will pass the contents of a DCS
+ // sequence to the outer terminal unchanged.
+ //
+ // Here, we split the encoded string into 76 bytes chunks and then
+ // join the chunks with sequences. Finally,
+ // wrap the whole thing in
+ // .
+ // s := strings.SplitN(b64, "", 76)
+ s := make([]string, 0, len(b64)/76+1)
+ for i := 0; i < len(b64); i += 76 {
+ end := i + 76
+ if end > len(b64) {
+ end = len(b64)
+ }
+ s = append(s, b64[i:end])
+ }
+ seq.WriteString(strings.Join(s, "\x1b\\\x1bP"))
+ default:
+ seq.WriteString(b64)
+ }
+ case QueryOperation:
+ // OSC52 queries the clipboard using "?"
+ seq.WriteString("?")
+ case ClearOperation:
+ // OSC52 clears the clipboard if the data is neither a base64 string nor "?"
+ // we're using "!" as a default
+ seq.WriteString("!")
+ }
+ // actual OSC52 sequence end
+ seq.WriteString("\x07")
+ // mode escape end
+ seq.WriteString(s.seqEnd())
+ return seq.String()
+}
+
+// WriteTo writes the OSC52 sequence to the writer.
+func (s Sequence) WriteTo(out io.Writer) (int64, error) {
+ n, err := out.Write([]byte(s.String()))
+ return int64(n), err
+}
+
+// Mode sets the mode for the OSC52 sequence.
+func (s Sequence) Mode(m Mode) Sequence {
+ s.mode = m
+ return s
+}
+
+// Tmux sets the mode to TmuxMode.
+// Used to escape the OSC52 sequence for `tmux`.
+//
+// Note: this is not needed if tmux clipboard is set to `set-clipboard on`. If
+// TmuxMode is used, tmux must have `allow-passthrough on` set.
+//
+// This is a syntactic sugar for s.Mode(TmuxMode).
+func (s Sequence) Tmux() Sequence {
+ return s.Mode(TmuxMode)
+}
+
+// Screen sets the mode to ScreenMode.
+// Used to escape the OSC52 sequence for `screen`.
+//
+// This is a syntactic sugar for s.Mode(ScreenMode).
+func (s Sequence) Screen() Sequence {
+ return s.Mode(ScreenMode)
+}
+
+// Clipboard sets the clipboard buffer for the OSC52 sequence.
+func (s Sequence) Clipboard(c Clipboard) Sequence {
+ s.clipboard = c
+ return s
+}
+
+// Primary sets the clipboard buffer to PrimaryClipboard.
+// This is the X11 primary clipboard.
+//
+// This is a syntactic sugar for s.Clipboard(PrimaryClipboard).
+func (s Sequence) Primary() Sequence {
+ return s.Clipboard(PrimaryClipboard)
+}
+
+// Limit sets the limit for the OSC52 sequence.
+// The default limit is 0 (no limit).
+//
+// Strings longer than the limit get ignored. Settting the limit to 0 or a
+// negative value disables the limit. Each terminal defines its own escapse
+// sequence limit.
+func (s Sequence) Limit(l int) Sequence {
+ if l < 0 {
+ s.limit = 0
+ } else {
+ s.limit = l
+ }
+ return s
+}
+
+// Operation sets the operation for the OSC52 sequence.
+// The default operation is SetOperation.
+func (s Sequence) Operation(o Operation) Sequence {
+ s.op = o
+ return s
+}
+
+// Clear sets the operation to ClearOperation.
+// This clears the clipboard.
+//
+// This is a syntactic sugar for s.Operation(ClearOperation).
+func (s Sequence) Clear() Sequence {
+ return s.Operation(ClearOperation)
+}
+
+// Query sets the operation to QueryOperation.
+// This queries the clipboard contents.
+//
+// This is a syntactic sugar for s.Operation(QueryOperation).
+func (s Sequence) Query() Sequence {
+ return s.Operation(QueryOperation)
+}
+
+// SetString sets the string for the OSC52 sequence. Strings are joined with a
+// space character.
+func (s Sequence) SetString(strs ...string) Sequence {
+ s.str = strings.Join(strs, " ")
+ return s
+}
+
+// New creates a new OSC52 sequence with the given string(s). Strings are
+// joined with a space character.
+func New(strs ...string) Sequence {
+ s := Sequence{
+ str: strings.Join(strs, " "),
+ limit: 0,
+ mode: DefaultMode,
+ clipboard: SystemClipboard,
+ op: SetOperation,
+ }
+ return s
+}
+
+// Query creates a new OSC52 sequence with the QueryOperation.
+// This returns a new OSC52 sequence to query the clipboard contents.
+//
+// This is a syntactic sugar for New().Query().
+func Query() Sequence {
+ return New().Query()
+}
+
+// Clear creates a new OSC52 sequence with the ClearOperation.
+// This returns a new OSC52 sequence to clear the clipboard.
+//
+// This is a syntactic sugar for New().Clear().
+func Clear() Sequence {
+ return New().Clear()
+}
+
+func (s Sequence) seqStart() string {
+ switch s.mode {
+ case TmuxMode:
+ // Write the start of a tmux escape sequence.
+ return "\x1bPtmux;\x1b"
+ case ScreenMode:
+ // Write the start of a DCS sequence.
+ return "\x1bP"
+ default:
+ return ""
+ }
+}
+
+func (s Sequence) seqEnd() string {
+ switch s.mode {
+ case TmuxMode:
+ // Terminate the tmux escape sequence.
+ return "\x1b\\"
+ case ScreenMode:
+ // Write the end of a DCS sequence.
+ return "\x1b\x5c"
+ default:
+ return ""
+ }
+}
diff --git a/vendor/github.com/bombsimon/wsl/v4/.golangci.yml b/vendor/github.com/bombsimon/wsl/v4/.golangci.yml
index bc79b839..f4948e05 100644
--- a/vendor/github.com/bombsimon/wsl/v4/.golangci.yml
+++ b/vendor/github.com/bombsimon/wsl/v4/.golangci.yml
@@ -1,58 +1,28 @@
---
-run:
- timeout: 1m
- issues-exit-code: 1
- tests: true
+version: "2"
output:
- print-issued-lines: false
- sort-results: true
formats:
- - format: colored-line-number
-
-linters-settings:
- gocognit:
- min-complexity: 10
-
- depguard:
- rules:
- main:
- deny:
- - pkg: "github.com/davecgh/go-spew/spew"
- desc: not allowed
-
- misspell:
- locale: US
-
- gocritic:
- # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run`
- # to see all tags and checks. Empty list by default. See
- # https://github.com/go-critic/go-critic#usage -> section "Tags".
- enabled-tags:
- - diagnostic
- - experimental
- - opinionated
- - performance
- - style
+ text:
+ path: stdout
+ print-issued-lines: false
linters:
- enable-all: true
+ default: all
disable:
- cyclop
- depguard
- dupl
- dupword
- exhaustruct
- - exportloopref
- forbidigo
- funlen
- - gci
- gocognit
- gocyclo
- godox
- - mnd
- lll
- maintidx
+ - mnd
- nakedret
- nestif
- nlreturn
@@ -64,8 +34,46 @@ linters:
- varnamelen
- wastedassign
+ settings:
+ depguard:
+ rules:
+ main:
+ deny:
+ - pkg: github.com/davecgh/go-spew/spew
+ desc: not allowed
+ gocognit:
+ min-complexity: 10
+ gocritic:
+ # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run`
+ # to see all tags and checks. Empty list by default. See
+ # https://github.com/go-critic/go-critic#usage -> section "Tags".
+ enabled-tags:
+ - diagnostic
+ - experimental
+ - opinionated
+ - performance
+ - style
+ misspell:
+ locale: US
+
+ exclusions:
+ presets:
+ - comments
+ - common-false-positives
+ - std-error-handling
+
issues:
- exclude-use-default: true
max-issues-per-linter: 0
max-same-issues: 0
+formatters:
+ enable:
+ - gofmt
+ - gofumpt
+ - goimports
+ settings:
+ gofmt:
+ rewrite-rules:
+ - pattern: 'interface{}'
+ replacement: 'any'
+
# vim: set sw=2 ts=2 et:
diff --git a/vendor/github.com/bombsimon/wsl/v4/README.md b/vendor/github.com/bombsimon/wsl/v4/README.md
index c9c42341..e98fe1b4 100644
--- a/vendor/github.com/bombsimon/wsl/v4/README.md
+++ b/vendor/github.com/bombsimon/wsl/v4/README.md
@@ -28,11 +28,6 @@ go install github.com/bombsimon/wsl/v4/cmd/wsl@master
## Usage
-> **Note**: This linter provides a fixer that can fix most issues with the
-> `--fix` flag. However, currently `golangci-lint` [does not support suggested
-> fixes](https://github.com/golangci/golangci-lint/issues/1779) so the `--fix`
-> flag in `golangci-lint` will **not** work.
-
`wsl` uses the [analysis](https://pkg.go.dev/golang.org/x/tools/go/analysis)
package meaning it will operate on package level with the default analysis flags
and way of working.
@@ -47,9 +42,12 @@ wsl --allow-cuddle-declarations --fix ./...
`wsl` is also integrated in [`golangci-lint`](https://golangci-lint.run)
```sh
-golangci-lint run --no-config --disable-all --enable wsl
+golangci-lint run --no-config --disable-all --enable wsl --fix
```
+> **Note**: If you're not sure what the diagnostic is trying to tell you, use
+> any of the fix approaches to fix the code for you.
+
## Issues and configuration
The linter suppers a few ways to configure it to satisfy more than one kind of
@@ -62,10 +60,6 @@ documentation](doc/configuration.md).
Below are the available checklist for any hit from `wsl`. If you do not see any,
feel free to raise an [issue](https://github.com/bombsimon/wsl/issues/new).
-> **Note**: this linter doesn't take in consideration the issues that will be
-> fixed with `go fmt -s` so ensure that the code is properly formatted before
-> use.
-
* [Anonymous switch statements should never be cuddled](doc/rules.md#anonymous-switch-statements-should-never-be-cuddled)
* [Append only allowed to cuddle with appended value](doc/rules.md#append-only-allowed-to-cuddle-with-appended-value)
* [Assignments should only be cuddled with other assignments](doc/rules.md#assignments-should-only-be-cuddled-with-other-assignments)
diff --git a/vendor/github.com/bombsimon/wsl/v4/analyzer.go b/vendor/github.com/bombsimon/wsl/v4/analyzer.go
index e51df89c..12adbfa7 100644
--- a/vendor/github.com/bombsimon/wsl/v4/analyzer.go
+++ b/vendor/github.com/bombsimon/wsl/v4/analyzer.go
@@ -37,6 +37,7 @@ func defaultConfig() *Configuration {
AllowCuddleWithRHS: []string{"Unlock", "RUnlock"},
ErrorVariableNames: []string{"err"},
ForceCaseTrailingWhitespaceLimit: 0,
+ AllowCuddleUsedInBlock: false,
}
}
@@ -68,6 +69,7 @@ func (wa *wslAnalyzer) flags() flag.FlagSet {
flags.BoolVar(&wa.config.ForceExclusiveShortDeclarations, "force-short-decl-cuddling", false, "Force short declarations to cuddle by themselves")
flags.BoolVar(&wa.config.StrictAppend, "strict-append", true, "Strict rules for append")
flags.BoolVar(&wa.config.IncludeGenerated, "include-generated", false, "Include generated files")
+ flags.BoolVar(&wa.config.AllowCuddleUsedInBlock, "allow-cuddle-used-in-block", false, "Allow cuddling of variables used in block statements")
flags.IntVar(&wa.config.ForceCaseTrailingWhitespaceLimit, "force-case-trailing-whitespace", 0, "Force newlines for case blocks > this number.")
flags.Var(&multiStringValue{slicePtr: &wa.config.AllowCuddleWithCalls}, "allow-cuddle-with-calls", "Comma separated list of idents that can have cuddles after")
@@ -77,16 +79,20 @@ func (wa *wslAnalyzer) flags() flag.FlagSet {
return *flags
}
-func (wa *wslAnalyzer) run(pass *analysis.Pass) (interface{}, error) {
+func (wa *wslAnalyzer) run(pass *analysis.Pass) (any, error) {
for _, file := range pass.Files {
filename := getFilename(pass.Fset, file)
if !strings.HasSuffix(filename, ".go") {
continue
}
- // if the file is related to cgo the filename of the unadjusted position is a not a '.go' file.
fn := pass.Fset.PositionFor(file.Pos(), false).Filename
+ // if the file is related to cgo the filename of the unadjusted position is a not a '.go' file.
+ if !strings.HasSuffix(fn, ".go") {
+ continue
+ }
+
// The file is skipped if the "unadjusted" file is a Go file, and it's a generated file (ex: "_test.go" file).
// The other non-Go files are skipped by the first 'if' with the adjusted position.
if !wa.config.IncludeGenerated && ast.IsGenerated(file) && strings.HasSuffix(fn, ".go") {
diff --git a/vendor/github.com/bombsimon/wsl/v4/wsl.go b/vendor/github.com/bombsimon/wsl/v4/wsl.go
index 44c7abe2..88693f54 100644
--- a/vendor/github.com/bombsimon/wsl/v4/wsl.go
+++ b/vendor/github.com/bombsimon/wsl/v4/wsl.go
@@ -179,6 +179,18 @@ type Configuration struct {
// errors even for generated files. Can be useful when developing
// generators.
IncludeGenerated bool
+
+ // AllowCuddleUsedInBlock will allowing cuddling of variables with block statements
+ // if they are used anywhere in the block. This defaults to false but setting
+ // it to true will allow the following example:
+ //
+ // var numbers []int
+ // for i := 0; i < 10; i++ {
+ // if 1 == 1 {
+ // numbers = append(numbers, i)
+ // }
+ // }
+ AllowCuddleUsedInBlock bool
}
// fix is a range to fixup.
@@ -304,12 +316,18 @@ func (p *processor) parseBlockStatements(statements []ast.Stmt) {
}
}
- // We could potentially have a block which require us to check the first
- // argument before ruling out an allowed cuddle.
- var calledOrAssignedFirstInBlock []string
+ // Contains the union of all variable names used anywhere
+ // within the block body (if applicable) and is used to check
+ // if a preceding statement's variables are actually used within
+ // the block. This helps enforce rules about allowed cuddling.
+ var identifiersUsedInBlock []string
if firstBodyStatement != nil {
- calledOrAssignedFirstInBlock = append(p.findLHS(firstBodyStatement), p.findRHS(firstBodyStatement)...)
+ if p.config.AllowCuddleUsedInBlock {
+ identifiersUsedInBlock = p.findUsedVariablesInStatement(stmt)
+ } else {
+ identifiersUsedInBlock = append(p.findLHS(firstBodyStatement), p.findRHS(firstBodyStatement)...)
+ }
}
var (
@@ -426,7 +444,7 @@ func (p *processor) parseBlockStatements(statements []ast.Stmt) {
reportNewlineTwoLinesAbove := func(n1, n2 ast.Node, reason string) {
if atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) ||
- atLeastOneInListsMatch(assignedOnLineAbove, calledOrAssignedFirstInBlock) {
+ atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) {
// If both the assignment on the line above _and_ the assignment
// two lines above is part of line or first in block, add the
// newline as if non were.
@@ -435,7 +453,7 @@ func (p *processor) parseBlockStatements(statements []ast.Stmt) {
if isAssignmentTwoLinesAbove &&
(atLeastOneInListsMatch(rightAndLeftHandSide, assignedTwoLinesAbove) ||
- atLeastOneInListsMatch(assignedTwoLinesAbove, calledOrAssignedFirstInBlock)) {
+ atLeastOneInListsMatch(assignedTwoLinesAbove, identifiersUsedInBlock)) {
p.addWhitespaceBeforeError(n1, reason)
} else {
// If the variable on the line above is allowed to be
@@ -507,7 +525,7 @@ func (p *processor) parseBlockStatements(statements []ast.Stmt) {
continue
}
- if atLeastOneInListsMatch(assignedOnLineAbove, calledOrAssignedFirstInBlock) {
+ if atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) {
continue
}
@@ -611,7 +629,7 @@ func (p *processor) parseBlockStatements(statements []ast.Stmt) {
}
if !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) {
- if !atLeastOneInListsMatch(assignedOnLineAbove, calledOrAssignedFirstInBlock) {
+ if !atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) {
p.addWhitespaceBeforeError(t, reasonRangeCuddledWithoutUse)
}
}
@@ -679,7 +697,7 @@ func (p *processor) parseBlockStatements(statements []ast.Stmt) {
}
}
- if atLeastOneInListsMatch(assignedOnLineAbove, calledOrAssignedFirstInBlock) {
+ if atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) {
continue
}
@@ -687,7 +705,7 @@ func (p *processor) parseBlockStatements(statements []ast.Stmt) {
p.addWhitespaceBeforeError(t, reasonDeferCuddledWithOtherVar)
}
case *ast.ForStmt:
- if len(rightAndLeftHandSide) == 0 {
+ if len(rightAndLeftHandSide) == 0 && !p.config.AllowCuddleUsedInBlock {
p.addWhitespaceBeforeError(t, reasonForWithoutCondition)
continue
}
@@ -701,7 +719,7 @@ func (p *processor) parseBlockStatements(statements []ast.Stmt) {
// comments regarding variable usages on the line before or as the
// first line in the block for details.
if !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) {
- if !atLeastOneInListsMatch(assignedOnLineAbove, calledOrAssignedFirstInBlock) {
+ if !atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) {
p.addWhitespaceBeforeError(t, reasonForCuddledAssignWithoutUse)
}
}
@@ -742,6 +760,10 @@ func (p *processor) parseBlockStatements(statements []ast.Stmt) {
if !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) {
if len(rightAndLeftHandSide) == 0 {
+ if p.config.AllowCuddleUsedInBlock {
+ continue
+ }
+
p.addWhitespaceBeforeError(t, reasonAnonSwitchCuddled)
} else {
p.addWhitespaceBeforeError(t, reasonSwitchCuddledWithoutUse)
@@ -757,7 +779,7 @@ func (p *processor) parseBlockStatements(statements []ast.Stmt) {
if !atLeastOneInListsMatch(rightHandSide, assignedOnLineAbove) {
// Allow type assertion on variables used in the first case
// immediately.
- if !atLeastOneInListsMatch(assignedOnLineAbove, calledOrAssignedFirstInBlock) {
+ if !atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) {
p.addWhitespaceBeforeError(t, reasonTypeSwitchCuddledWithoutUse)
}
}
@@ -839,6 +861,32 @@ func (p *processor) firstBodyStatement(i int, allStmt []ast.Stmt) ast.Node {
return firstBodyStatement
}
+// findUsedVariablesInStatement processes a statement,
+// returning a union of all variables used within it.
+func (p *processor) findUsedVariablesInStatement(stmt ast.Stmt) []string {
+ var (
+ used []string
+ seen = map[string]struct{}{}
+ )
+
+ // ast.Inspect walks the AST of the statement.
+ ast.Inspect(stmt, func(n ast.Node) bool {
+ // We're only interested in identifiers.
+ if ident, ok := n.(*ast.Ident); ok {
+ if _, exists := seen[ident.Name]; !exists {
+ seen[ident.Name] = struct{}{}
+
+ used = append(used, ident.Name)
+ }
+ }
+
+ // Continue walking the AST.
+ return true
+ })
+
+ return used
+}
+
func (p *processor) findLHS(node ast.Node) []string {
var lhs []string
@@ -1030,7 +1078,7 @@ func (p *processor) findBlockStmt(node ast.Node) []*ast.BlockStmt {
// Known fields with X that are handled:
// IndexExpr, ExprStmt, SelectorExpr, StarExpr, ParentExpr, TypeAssertExpr,
// RangeStmt, UnaryExpr, ParenExpr, SliceExpr, IncDecStmt.
-func maybeX(node interface{}) (ast.Node, bool) {
+func maybeX(node any) (ast.Node, bool) {
maybeHasX := reflect.Indirect(reflect.ValueOf(node)).FieldByName("X")
if !maybeHasX.IsValid() {
return nil, false
@@ -1407,7 +1455,7 @@ func (p *processor) addErrorRange(reportAt, start, end token.Pos, reason string)
p.result[reportAt] = report
}
-func (p *processor) addWarning(w string, pos token.Pos, t interface{}) {
+func (p *processor) addWarning(w string, pos token.Pos, t any) {
position := p.fileSet.Position(pos)
p.warnings = append(p.warnings,
diff --git a/vendor/github.com/butuzov/ireturn/analyzer/analyzer.go b/vendor/github.com/butuzov/ireturn/analyzer/analyzer.go
index ebf2a0db..86cc464c 100644
--- a/vendor/github.com/butuzov/ireturn/analyzer/analyzer.go
+++ b/vendor/github.com/butuzov/ireturn/analyzer/analyzer.go
@@ -203,6 +203,7 @@ func filterInterfaces(p *analysis.Pass, ft *ast.FuncType, di map[string]struct{}
typeParams = typeParams[:len(typeParams)-1]
}
+ // todo: write test for this (1.18&1.19 only?)
goVersion := runtime.Version()
if strings.HasPrefix(goVersion, "go1.18") || strings.HasPrefix(goVersion, "go1.19") {
typeParams = strings.ReplaceAll(typeParams, "|", " | ")
diff --git a/vendor/github.com/butuzov/ireturn/analyzer/std.go b/vendor/github.com/butuzov/ireturn/analyzer/std.go
index cac46461..ce007be8 100644
--- a/vendor/github.com/butuzov/ireturn/analyzer/std.go
+++ b/vendor/github.com/butuzov/ireturn/analyzer/std.go
@@ -200,4 +200,15 @@ var std = map[string]struct{}{
// added in Go v1.22 in compare to v1.21 (docker image)
"go/version": {},
"math/rand/v2": {},
+ // added in Go v1.23 in compare to v1.22 (docker image)
+ "iter": {},
+ "structs": {},
+ "unique": {},
+ // added in Go v1.24 in compare to v1.23 (docker image)
+ "crypto/fips140": {},
+ "crypto/hkdf": {},
+ "crypto/mlkem": {},
+ "crypto/pbkdf2": {},
+ "crypto/sha3": {},
+ "weak": {},
}
diff --git a/vendor/github.com/catenacyber/perfsprint/analyzer/analyzer.go b/vendor/github.com/catenacyber/perfsprint/analyzer/analyzer.go
index 866d1108..c40e84d4 100644
--- a/vendor/github.com/catenacyber/perfsprint/analyzer/analyzer.go
+++ b/vendor/github.com/catenacyber/perfsprint/analyzer/analyzer.go
@@ -54,6 +54,21 @@ func newPerfSprint() *perfSprint {
}
}
+const (
+ // checkerErrorFormat checks for error formatting.
+ checkerErrorFormat = "error-format"
+ // checkerIntegerFormat checks for integer formatting.
+ checkerIntegerFormat = "integer-format"
+ // checkerStringFormat checks for string formatting.
+ checkerStringFormat = "string-format"
+ // checkerBoolFormat checks for bool formatting.
+ checkerBoolFormat = "bool-format"
+ // checkerHexFormat checks for hexadecimal formatting.
+ checkerHexFormat = "hex-format"
+ // checkerFixImports fix needed imports from other fixes.
+ checkerFixImports = "fiximports"
+)
+
func New() *analysis.Analyzer {
n := newPerfSprint()
r := &analysis.Analyzer{
@@ -63,17 +78,19 @@ func New() *analysis.Analyzer {
Run: n.run,
Requires: []*analysis.Analyzer{inspect.Analyzer},
}
- r.Flags.BoolVar(&n.intFormat.enabled, "integer-format", n.intFormat.enabled, "enable/disable optimization of integer formatting")
+
+ r.Flags.BoolVar(&n.intFormat.enabled, checkerIntegerFormat, n.intFormat.enabled, "enable/disable optimization of integer formatting")
r.Flags.BoolVar(&n.intFormat.intConv, "int-conversion", n.intFormat.intConv, "optimizes even if it requires an int or uint type cast")
- r.Flags.BoolVar(&n.errFormat.enabled, "error-format", n.errFormat.enabled, "enable/disable optimization of error formatting")
+ r.Flags.BoolVar(&n.errFormat.enabled, checkerErrorFormat, n.errFormat.enabled, "enable/disable optimization of error formatting")
r.Flags.BoolVar(&n.errFormat.errError, "err-error", n.errFormat.errError, "optimizes into err.Error() even if it is only equivalent for non-nil errors")
r.Flags.BoolVar(&n.errFormat.errorf, "errorf", n.errFormat.errorf, "optimizes fmt.Errorf")
- r.Flags.BoolVar(&n.boolFormat, "bool-format", n.boolFormat, "enable/disable optimization of bool formatting")
- r.Flags.BoolVar(&n.hexFormat, "hex-format", n.hexFormat, "enable/disable optimization of hex formatting")
- r.Flags.BoolVar(&n.strFormat.enabled, "string-format", n.strFormat.enabled, "enable/disable optimization of string formatting")
+
+ r.Flags.BoolVar(&n.boolFormat, checkerBoolFormat, n.boolFormat, "enable/disable optimization of bool formatting")
+ r.Flags.BoolVar(&n.hexFormat, checkerHexFormat, n.hexFormat, "enable/disable optimization of hex formatting")
+ r.Flags.BoolVar(&n.strFormat.enabled, checkerStringFormat, n.strFormat.enabled, "enable/disable optimization of string formatting")
r.Flags.BoolVar(&n.strFormat.sprintf1, "sprintf1", n.strFormat.sprintf1, "optimizes fmt.Sprintf with only one argument")
r.Flags.BoolVar(&n.strFormat.strconcat, "strconcat", n.strFormat.strconcat, "optimizes into strings concatenation")
- r.Flags.BoolVar(&n.fiximports, "fiximports", n.fiximports, "fix needed imports from other fixes")
+ r.Flags.BoolVar(&n.fiximports, checkerFixImports, n.fiximports, "fix needed imports from other fixes")
return r
}
@@ -198,7 +215,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
if fn == "fmt.Errorf" && n.errFormat.enabled {
neededPackages[fname]["errors"] = struct{}{}
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerErrorFormat,
call,
fn+" can be replaced with errors.New",
[]analysis.SuggestedFix{
@@ -214,7 +231,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
)
} else if fn != "fmt.Errorf" && n.strFormat.enabled {
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerStringFormat,
call,
fn+" can be replaced with just using the string",
[]analysis.SuggestedFix{
@@ -236,7 +253,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
fname := pass.Fset.File(call.Pos()).Name()
removedFmtUsages[fname]++
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerErrorFormat,
call,
fn+" can be replaced with "+errMethodCall,
[]analysis.SuggestedFix{
@@ -259,7 +276,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
}
neededPackages[fname]["strconv"] = struct{}{}
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerBoolFormat,
call,
fn+" can be replaced with faster strconv.FormatBool",
[]analysis.SuggestedFix{
@@ -287,7 +304,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
}
neededPackages[fname]["encoding/hex"] = struct{}{}
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerHexFormat,
call,
fn+" can be replaced with faster hex.EncodeToString",
[]analysis.SuggestedFix{
@@ -316,7 +333,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
}
neededPackages[fname]["encoding/hex"] = struct{}{}
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerHexFormat,
call,
fn+" can be replaced with faster hex.EncodeToString",
[]analysis.SuggestedFix{
@@ -339,7 +356,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
}
neededPackages[fname]["strconv"] = struct{}{}
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerIntegerFormat,
call,
fn+" can be replaced with faster strconv.Itoa",
[]analysis.SuggestedFix{
@@ -368,7 +385,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
}
neededPackages[fname]["strconv"] = struct{}{}
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerIntegerFormat,
call,
fn+" can be replaced with faster strconv.Itoa",
[]analysis.SuggestedFix{
@@ -390,7 +407,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
}
neededPackages[fname]["strconv"] = struct{}{}
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerIntegerFormat,
call,
fn+" can be replaced with faster strconv.FormatInt",
[]analysis.SuggestedFix{
@@ -424,7 +441,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
}
neededPackages[fname]["strconv"] = struct{}{}
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerIntegerFormat,
call,
fn+" can be replaced with faster strconv.FormatUint",
[]analysis.SuggestedFix{
@@ -457,7 +474,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
}
neededPackages[fname]["strconv"] = struct{}{}
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerIntegerFormat,
call,
fn+" can be replaced with faster strconv.FormatUint",
[]analysis.SuggestedFix{
@@ -481,18 +498,18 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
case isBasicType(valueType, types.String) && fn == "fmt.Sprintf" && isConcatable(verb) && n.strFormat.enabled:
var fix string
if strings.HasSuffix(verb, "%s") {
- fix = strconv.Quote(verb[:len(verb)-2]) + "+" + formatNode(pass.Fset, value)
+ fix = strings.ReplaceAll(strconv.Quote(verb[:len(verb)-2]), "%%", "%") + "+" + formatNode(pass.Fset, value)
} else if strings.HasSuffix(verb, "%[1]s") {
- fix = strconv.Quote(verb[:len(verb)-5]) + "+" + formatNode(pass.Fset, value)
+ fix = strings.ReplaceAll(strconv.Quote(verb[:len(verb)-5]), "%%", "%") + "+" + formatNode(pass.Fset, value)
} else if strings.HasPrefix(verb, "%s") {
- fix = formatNode(pass.Fset, value) + "+" + strconv.Quote(verb[2:])
+ fix = formatNode(pass.Fset, value) + "+" + strings.ReplaceAll(strconv.Quote(verb[2:]), "%%", "%")
} else {
- fix = formatNode(pass.Fset, value) + "+" + strconv.Quote(verb[5:])
+ fix = formatNode(pass.Fset, value) + "+" + strings.ReplaceAll(strconv.Quote(verb[5:]), "%%", "%")
}
fname := pass.Fset.File(call.Pos()).Name()
removedFmtUsages[fname]++
d = newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerStringFormat,
call,
fn+" can be replaced with string concatenation",
[]analysis.SuggestedFix{
@@ -571,7 +588,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
fix = fix + "\n\t\"" + k + `"`
}
pass.Report(*newAnalysisDiagnostic(
- "", // TODO: precise checker
+ checkerFixImports,
gd,
"Fix imports",
[]analysis.SuggestedFix{
diff --git a/vendor/github.com/charmbracelet/colorprofile/.golangci-soft.yml b/vendor/github.com/charmbracelet/colorprofile/.golangci-soft.yml
new file mode 100644
index 00000000..d325d4fc
--- /dev/null
+++ b/vendor/github.com/charmbracelet/colorprofile/.golangci-soft.yml
@@ -0,0 +1,40 @@
+run:
+ tests: false
+ issues-exit-code: 0
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - exhaustive
+ - goconst
+ - godot
+ - godox
+ - mnd
+ - gomoddirectives
+ - goprintffuncname
+ - misspell
+ - nakedret
+ - nestif
+ - noctx
+ - nolintlint
+ - prealloc
+ - wrapcheck
+
+ # disable default linters, they are already enabled in .golangci.yml
+ disable:
+ - errcheck
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - unused
diff --git a/vendor/github.com/charmbracelet/colorprofile/.golangci.yml b/vendor/github.com/charmbracelet/colorprofile/.golangci.yml
new file mode 100644
index 00000000..d6789e01
--- /dev/null
+++ b/vendor/github.com/charmbracelet/colorprofile/.golangci.yml
@@ -0,0 +1,28 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - gofumpt
+ - goimports
+ - gosec
+ - nilerr
+ - revive
+ - rowserrcheck
+ - sqlclosecheck
+ - tparallel
+ - unconvert
+ - unparam
+ - whitespace
diff --git a/vendor/github.com/charmbracelet/colorprofile/.goreleaser.yml b/vendor/github.com/charmbracelet/colorprofile/.goreleaser.yml
new file mode 100644
index 00000000..40d9f298
--- /dev/null
+++ b/vendor/github.com/charmbracelet/colorprofile/.goreleaser.yml
@@ -0,0 +1,6 @@
+includes:
+ - from_url:
+ url: charmbracelet/meta/main/goreleaser-lib.yaml
+
+# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
+
diff --git a/vendor/github.com/charmbracelet/colorprofile/LICENSE b/vendor/github.com/charmbracelet/colorprofile/LICENSE
new file mode 100644
index 00000000..b7974b07
--- /dev/null
+++ b/vendor/github.com/charmbracelet/colorprofile/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020-2024 Charmbracelet, Inc
+
+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.
diff --git a/vendor/github.com/charmbracelet/colorprofile/README.md b/vendor/github.com/charmbracelet/colorprofile/README.md
new file mode 100644
index 00000000..c72b2f4b
--- /dev/null
+++ b/vendor/github.com/charmbracelet/colorprofile/README.md
@@ -0,0 +1,103 @@
+# Colorprofile
+
+
+
+A simple, powerful—and at times magical—package for detecting terminal color
+profiles and performing color (and CSI) degradation.
+
+## Detecting the terminal’s color profile
+
+Detecting the terminal’s color profile is easy.
+
+```go
+import "github.com/charmbracelet/colorprofile"
+
+// Detect the color profile. If you’re planning on writing to stderr you'd want
+// to use os.Stderr instead.
+p := colorprofile.Detect(os.Stdout, os.Environ())
+
+// Comment on the profile.
+fmt.Printf("You know, your colors are quite %s.", func() string {
+ switch p {
+ case colorprofile.TrueColor:
+ return "fancy"
+ case colorprofile.ANSI256:
+ return "1990s fancy"
+ case colorprofile.ANSI:
+ return "normcore"
+ case colorprofile.Ascii:
+ return "ancient"
+ case colorprofile.NoTTY:
+ return "naughty!"
+ }
+ return "...IDK" // this should never happen
+}())
+```
+
+## Downsampling colors
+
+When necessary, colors can be downsampled to a given profile, or manually
+downsampled to a specific profile.
+
+```go
+p := colorprofile.Detect(os.Stdout, os.Environ())
+c := color.RGBA{0x6b, 0x50, 0xff, 0xff} // #6b50ff
+
+// Downsample to the detected profile, when necessary.
+convertedColor := p.Convert(c)
+
+// Or manually convert to a given profile.
+ansi256Color := colorprofile.ANSI256.Convert(c)
+ansiColor := colorprofile.ANSI.Convert(c)
+noColor := colorprofile.Ascii.Convert(c)
+noANSI := colorprofile.NoTTY.Convert(c)
+```
+
+## Automatic downsampling with a Writer
+
+You can also magically downsample colors in ANSI output, when necessary. If
+output is not a TTY ANSI will be dropped entirely.
+
+```go
+myFancyANSI := "\x1b[38;2;107;80;255mCute \x1b[1;3mpuppy!!\x1b[m"
+
+// Automatically downsample for the terminal at stdout.
+w := colorprofile.NewWriter(os.Stdout, os.Environ())
+fmt.Fprintf(w, myFancyANSI)
+
+// Downsample to 4-bit ANSI.
+w.Profile = colorprofile.ANSI
+fmt.Fprintf(w, myFancyANSI)
+
+// Ascii-fy, no colors.
+w.Profile = colorprofile.Ascii
+fmt.Fprintf(w, myFancyANSI)
+
+// Strip ANSI altogether.
+w.Profile = colorprofile.NoTTY
+fmt.Fprintf(w, myFancyANSI) // not as fancy
+```
+
+## Feedback
+
+We’d love to hear your thoughts on this project. Feel free to drop us a note!
+
+- [Twitter](https://twitter.com/charmcli)
+- [The Fediverse](https://mastodon.social/@charmcli)
+- [Discord](https://charm.sh/chat)
+
+## License
+
+[MIT](https://github.com/charmbracelet/bubbletea/raw/master/LICENSE)
+
+---
+
+Part of [Charm](https://charm.sh).
+
+
+
+Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة
diff --git a/vendor/github.com/charmbracelet/colorprofile/env.go b/vendor/github.com/charmbracelet/colorprofile/env.go
new file mode 100644
index 00000000..8df3d8f7
--- /dev/null
+++ b/vendor/github.com/charmbracelet/colorprofile/env.go
@@ -0,0 +1,287 @@
+package colorprofile
+
+import (
+ "bytes"
+ "io"
+ "os/exec"
+ "runtime"
+ "strconv"
+ "strings"
+
+ "github.com/charmbracelet/x/term"
+ "github.com/xo/terminfo"
+)
+
+// Detect returns the color profile based on the terminal output, and
+// environment variables. This respects NO_COLOR, CLICOLOR, and CLICOLOR_FORCE
+// environment variables.
+//
+// The rules as follows:
+// - TERM=dumb is always treated as NoTTY unless CLICOLOR_FORCE=1 is set.
+// - If COLORTERM=truecolor, and the profile is not NoTTY, it gest upgraded to TrueColor.
+// - Using any 256 color terminal (e.g. TERM=xterm-256color) will set the profile to ANSI256.
+// - Using any color terminal (e.g. TERM=xterm-color) will set the profile to ANSI.
+// - Using CLICOLOR=1 without TERM defined should be treated as ANSI if the
+// output is a terminal.
+// - NO_COLOR takes precedence over CLICOLOR/CLICOLOR_FORCE, and will disable
+// colors but not text decoration, i.e. bold, italic, faint, etc.
+//
+// See https://no-color.org/ and https://bixense.com/clicolors/ for more information.
+func Detect(output io.Writer, env []string) Profile {
+ out, ok := output.(term.File)
+ isatty := ok && term.IsTerminal(out.Fd())
+ environ := newEnviron(env)
+ term := environ.get("TERM")
+ isDumb := term == "dumb"
+ envp := colorProfile(isatty, environ)
+ if envp == TrueColor || envNoColor(environ) {
+ // We already know we have TrueColor, or NO_COLOR is set.
+ return envp
+ }
+
+ if isatty && !isDumb {
+ tip := Terminfo(term)
+ tmuxp := tmux(environ)
+
+ // Color profile is the maximum of env, terminfo, and tmux.
+ return max(envp, max(tip, tmuxp))
+ }
+
+ return envp
+}
+
+// Env returns the color profile based on the terminal environment variables.
+// This respects NO_COLOR, CLICOLOR, and CLICOLOR_FORCE environment variables.
+//
+// The rules as follows:
+// - TERM=dumb is always treated as NoTTY unless CLICOLOR_FORCE=1 is set.
+// - If COLORTERM=truecolor, and the profile is not NoTTY, it gest upgraded to TrueColor.
+// - Using any 256 color terminal (e.g. TERM=xterm-256color) will set the profile to ANSI256.
+// - Using any color terminal (e.g. TERM=xterm-color) will set the profile to ANSI.
+// - Using CLICOLOR=1 without TERM defined should be treated as ANSI if the
+// output is a terminal.
+// - NO_COLOR takes precedence over CLICOLOR/CLICOLOR_FORCE, and will disable
+// colors but not text decoration, i.e. bold, italic, faint, etc.
+//
+// See https://no-color.org/ and https://bixense.com/clicolors/ for more information.
+func Env(env []string) (p Profile) {
+ return colorProfile(true, newEnviron(env))
+}
+
+func colorProfile(isatty bool, env environ) (p Profile) {
+ isDumb := env.get("TERM") == "dumb"
+ envp := envColorProfile(env)
+ if !isatty || isDumb {
+ // Check if the output is a terminal.
+ // Treat dumb terminals as NoTTY
+ p = NoTTY
+ } else {
+ p = envp
+ }
+
+ if envNoColor(env) && isatty {
+ if p > Ascii {
+ p = Ascii
+ }
+ return
+ }
+
+ if cliColorForced(env) {
+ if p < ANSI {
+ p = ANSI
+ }
+ if envp > p {
+ p = envp
+ }
+
+ return
+ }
+
+ if cliColor(env) {
+ if isatty && !isDumb && p < ANSI {
+ p = ANSI
+ }
+ }
+
+ return p
+}
+
+// envNoColor returns true if the environment variables explicitly disable color output
+// by setting NO_COLOR (https://no-color.org/).
+func envNoColor(env environ) bool {
+ noColor, _ := strconv.ParseBool(env.get("NO_COLOR"))
+ return noColor
+}
+
+func cliColor(env environ) bool {
+ cliColor, _ := strconv.ParseBool(env.get("CLICOLOR"))
+ return cliColor
+}
+
+func cliColorForced(env environ) bool {
+ cliColorForce, _ := strconv.ParseBool(env.get("CLICOLOR_FORCE"))
+ return cliColorForce
+}
+
+func colorTerm(env environ) bool {
+ colorTerm := strings.ToLower(env.get("COLORTERM"))
+ return colorTerm == "truecolor" || colorTerm == "24bit" ||
+ colorTerm == "yes" || colorTerm == "true"
+}
+
+// envColorProfile returns infers the color profile from the environment.
+func envColorProfile(env environ) (p Profile) {
+ term, ok := env.lookup("TERM")
+ if !ok || len(term) == 0 || term == "dumb" {
+ p = NoTTY
+ if runtime.GOOS == "windows" {
+ // Use Windows API to detect color profile. Windows Terminal and
+ // cmd.exe don't define $TERM.
+ if wcp, ok := windowsColorProfile(env); ok {
+ p = wcp
+ }
+ }
+ } else {
+ p = ANSI
+ }
+
+ parts := strings.Split(term, "-")
+ switch parts[0] {
+ case "alacritty",
+ "contour",
+ "foot",
+ "ghostty",
+ "kitty",
+ "rio",
+ "st",
+ "wezterm":
+ return TrueColor
+ case "xterm":
+ if len(parts) > 1 {
+ switch parts[1] {
+ case "ghostty", "kitty":
+ // These terminals can be defined as xterm-TERMNAME
+ return TrueColor
+ }
+ }
+ case "tmux", "screen":
+ if p < ANSI256 {
+ p = ANSI256
+ }
+ }
+
+ if isCloudShell, _ := strconv.ParseBool(env.get("GOOGLE_CLOUD_SHELL")); isCloudShell {
+ return TrueColor
+ }
+
+ // GNU Screen doesn't support TrueColor
+ // Tmux doesn't support $COLORTERM
+ if colorTerm(env) && !strings.HasPrefix(term, "screen") && !strings.HasPrefix(term, "tmux") {
+ return TrueColor
+ }
+
+ if strings.HasSuffix(term, "256color") && p < ANSI256 {
+ p = ANSI256
+ }
+
+ return
+}
+
+// Terminfo returns the color profile based on the terminal's terminfo
+// database. This relies on the Tc and RGB capabilities to determine if the
+// terminal supports TrueColor.
+// If term is empty or "dumb", it returns NoTTY.
+func Terminfo(term string) (p Profile) {
+ if len(term) == 0 || term == "dumb" {
+ return NoTTY
+ }
+
+ p = ANSI
+ ti, err := terminfo.Load(term)
+ if err != nil {
+ return
+ }
+
+ extbools := ti.ExtBoolCapsShort()
+ if _, ok := extbools["Tc"]; ok {
+ return TrueColor
+ }
+
+ if _, ok := extbools["RGB"]; ok {
+ return TrueColor
+ }
+
+ return
+}
+
+// Tmux returns the color profile based on `tmux info` output. Tmux supports
+// overriding the terminal's color capabilities, so this function will return
+// the color profile based on the tmux configuration.
+func Tmux(env []string) Profile {
+ return tmux(newEnviron(env))
+}
+
+// tmux returns the color profile based on the tmux environment variables.
+func tmux(env environ) (p Profile) {
+ if tmux, ok := env.lookup("TMUX"); !ok || len(tmux) == 0 {
+ // Not in tmux
+ return NoTTY
+ }
+
+ // Check if tmux has either Tc or RGB capabilities. Otherwise, return
+ // ANSI256.
+ p = ANSI256
+ cmd := exec.Command("tmux", "info")
+ out, err := cmd.Output()
+ if err != nil {
+ return
+ }
+
+ for _, line := range bytes.Split(out, []byte("\n")) {
+ if (bytes.Contains(line, []byte("Tc")) || bytes.Contains(line, []byte("RGB"))) &&
+ bytes.Contains(line, []byte("true")) {
+ return TrueColor
+ }
+ }
+
+ return
+}
+
+// environ is a map of environment variables.
+type environ map[string]string
+
+// newEnviron returns a new environment map from a slice of environment
+// variables.
+func newEnviron(environ []string) environ {
+ m := make(map[string]string, len(environ))
+ for _, e := range environ {
+ parts := strings.SplitN(e, "=", 2)
+ var value string
+ if len(parts) == 2 {
+ value = parts[1]
+ }
+ m[parts[0]] = value
+ }
+ return m
+}
+
+// lookup returns the value of an environment variable and a boolean indicating
+// if it exists.
+func (e environ) lookup(key string) (string, bool) {
+ v, ok := e[key]
+ return v, ok
+}
+
+// get returns the value of an environment variable and empty string if it
+// doesn't exist.
+func (e environ) get(key string) string {
+ v, _ := e.lookup(key)
+ return v
+}
+
+func max[T ~byte | ~int](a, b T) T {
+ if a > b {
+ return a
+ }
+ return b
+}
diff --git a/vendor/github.com/charmbracelet/colorprofile/env_other.go b/vendor/github.com/charmbracelet/colorprofile/env_other.go
new file mode 100644
index 00000000..080994bc
--- /dev/null
+++ b/vendor/github.com/charmbracelet/colorprofile/env_other.go
@@ -0,0 +1,8 @@
+//go:build !windows
+// +build !windows
+
+package colorprofile
+
+func windowsColorProfile(map[string]string) (Profile, bool) {
+ return 0, false
+}
diff --git a/vendor/github.com/charmbracelet/colorprofile/env_windows.go b/vendor/github.com/charmbracelet/colorprofile/env_windows.go
new file mode 100644
index 00000000..3b9c28f9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/colorprofile/env_windows.go
@@ -0,0 +1,45 @@
+//go:build windows
+// +build windows
+
+package colorprofile
+
+import (
+ "strconv"
+
+ "golang.org/x/sys/windows"
+)
+
+func windowsColorProfile(env map[string]string) (Profile, bool) {
+ if env["ConEmuANSI"] == "ON" {
+ return TrueColor, true
+ }
+
+ if len(env["WT_SESSION"]) > 0 {
+ // Windows Terminal supports TrueColor
+ return TrueColor, true
+ }
+
+ major, _, build := windows.RtlGetNtVersionNumbers()
+ if build < 10586 || major < 10 {
+ // No ANSI support before WindowsNT 10 build 10586
+ if len(env["ANSICON"]) > 0 {
+ ansiconVer := env["ANSICON_VER"]
+ cv, err := strconv.Atoi(ansiconVer)
+ if err != nil || cv < 181 {
+ // No 8 bit color support before ANSICON 1.81
+ return ANSI, true
+ }
+
+ return ANSI256, true
+ }
+
+ return NoTTY, true
+ }
+
+ if build < 14931 {
+ // No true color support before build 14931
+ return ANSI256, true
+ }
+
+ return TrueColor, true
+}
diff --git a/vendor/github.com/charmbracelet/colorprofile/profile.go b/vendor/github.com/charmbracelet/colorprofile/profile.go
new file mode 100644
index 00000000..97e37ac3
--- /dev/null
+++ b/vendor/github.com/charmbracelet/colorprofile/profile.go
@@ -0,0 +1,399 @@
+package colorprofile
+
+import (
+ "image/color"
+ "math"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+// Profile is a color profile: NoTTY, Ascii, ANSI, ANSI256, or TrueColor.
+type Profile byte
+
+const (
+ // NoTTY, not a terminal profile.
+ NoTTY Profile = iota
+ // Ascii, uncolored profile.
+ Ascii //nolint:revive
+ // ANSI, 4-bit color profile.
+ ANSI
+ // ANSI256, 8-bit color profile.
+ ANSI256
+ // TrueColor, 24-bit color profile.
+ TrueColor
+)
+
+// String returns the string representation of a Profile.
+func (p Profile) String() string {
+ switch p {
+ case TrueColor:
+ return "TrueColor"
+ case ANSI256:
+ return "ANSI256"
+ case ANSI:
+ return "ANSI"
+ case Ascii:
+ return "Ascii"
+ case NoTTY:
+ return "NoTTY"
+ }
+ return "Unknown"
+}
+
+// Convert transforms a given Color to a Color supported within the Profile.
+func (p Profile) Convert(c color.Color) color.Color {
+ if p <= Ascii {
+ return nil
+ }
+
+ switch c := c.(type) {
+ case ansi.BasicColor:
+ return c
+
+ case ansi.ExtendedColor:
+ if p == ANSI {
+ return ansi256ToANSIColor(c)
+ }
+ return c
+
+ case ansi.TrueColor, color.Color:
+ h, ok := colorful.MakeColor(c)
+ if !ok {
+ return nil
+ }
+ if p != TrueColor {
+ ac := hexToANSI256Color(h)
+ if p == ANSI {
+ return ansi256ToANSIColor(ac)
+ }
+ return ac
+ }
+ return c
+ }
+
+ return c
+}
+
+func hexToANSI256Color(c colorful.Color) ansi.ExtendedColor {
+ v2ci := func(v float64) int {
+ if v < 48 {
+ return 0
+ }
+ if v < 115 {
+ return 1
+ }
+ return int((v - 35) / 40)
+ }
+
+ // Calculate the nearest 0-based color index at 16..231
+ r := v2ci(c.R * 255.0) // 0..5 each
+ g := v2ci(c.G * 255.0)
+ b := v2ci(c.B * 255.0)
+ ci := 36*r + 6*g + b /* 0..215 */
+
+ // Calculate the represented colors back from the index
+ i2cv := [6]int{0, 0x5f, 0x87, 0xaf, 0xd7, 0xff}
+ cr := i2cv[r] // r/g/b, 0..255 each
+ cg := i2cv[g]
+ cb := i2cv[b]
+
+ // Calculate the nearest 0-based gray index at 232..255
+ var grayIdx int
+ average := (cr + cg + cb) / 3
+ if average > 238 {
+ grayIdx = 23
+ } else {
+ grayIdx = (average - 3) / 10 // 0..23
+ }
+ gv := 8 + 10*grayIdx // same value for r/g/b, 0..255
+
+ // Return the one which is nearer to the original input rgb value
+ c2 := colorful.Color{R: float64(cr) / 255.0, G: float64(cg) / 255.0, B: float64(cb) / 255.0}
+ g2 := colorful.Color{R: float64(gv) / 255.0, G: float64(gv) / 255.0, B: float64(gv) / 255.0}
+ colorDist := c.DistanceHSLuv(c2)
+ grayDist := c.DistanceHSLuv(g2)
+
+ if colorDist <= grayDist {
+ return ansi.ExtendedColor(16 + ci) //nolint:gosec
+ }
+ return ansi.ExtendedColor(232 + grayIdx) //nolint:gosec
+}
+
+func ansi256ToANSIColor(c ansi.ExtendedColor) ansi.BasicColor {
+ var r int
+ md := math.MaxFloat64
+
+ h, _ := colorful.Hex(ansiHex[c])
+ for i := 0; i <= 15; i++ {
+ hb, _ := colorful.Hex(ansiHex[i])
+ d := h.DistanceHSLuv(hb)
+
+ if d < md {
+ md = d
+ r = i
+ }
+ }
+
+ return ansi.BasicColor(r) //nolint:gosec
+}
+
+// RGB values of ANSI colors (0-255).
+var ansiHex = []string{
+ "#000000",
+ "#800000",
+ "#008000",
+ "#808000",
+ "#000080",
+ "#800080",
+ "#008080",
+ "#c0c0c0",
+ "#808080",
+ "#ff0000",
+ "#00ff00",
+ "#ffff00",
+ "#0000ff",
+ "#ff00ff",
+ "#00ffff",
+ "#ffffff",
+ "#000000",
+ "#00005f",
+ "#000087",
+ "#0000af",
+ "#0000d7",
+ "#0000ff",
+ "#005f00",
+ "#005f5f",
+ "#005f87",
+ "#005faf",
+ "#005fd7",
+ "#005fff",
+ "#008700",
+ "#00875f",
+ "#008787",
+ "#0087af",
+ "#0087d7",
+ "#0087ff",
+ "#00af00",
+ "#00af5f",
+ "#00af87",
+ "#00afaf",
+ "#00afd7",
+ "#00afff",
+ "#00d700",
+ "#00d75f",
+ "#00d787",
+ "#00d7af",
+ "#00d7d7",
+ "#00d7ff",
+ "#00ff00",
+ "#00ff5f",
+ "#00ff87",
+ "#00ffaf",
+ "#00ffd7",
+ "#00ffff",
+ "#5f0000",
+ "#5f005f",
+ "#5f0087",
+ "#5f00af",
+ "#5f00d7",
+ "#5f00ff",
+ "#5f5f00",
+ "#5f5f5f",
+ "#5f5f87",
+ "#5f5faf",
+ "#5f5fd7",
+ "#5f5fff",
+ "#5f8700",
+ "#5f875f",
+ "#5f8787",
+ "#5f87af",
+ "#5f87d7",
+ "#5f87ff",
+ "#5faf00",
+ "#5faf5f",
+ "#5faf87",
+ "#5fafaf",
+ "#5fafd7",
+ "#5fafff",
+ "#5fd700",
+ "#5fd75f",
+ "#5fd787",
+ "#5fd7af",
+ "#5fd7d7",
+ "#5fd7ff",
+ "#5fff00",
+ "#5fff5f",
+ "#5fff87",
+ "#5fffaf",
+ "#5fffd7",
+ "#5fffff",
+ "#870000",
+ "#87005f",
+ "#870087",
+ "#8700af",
+ "#8700d7",
+ "#8700ff",
+ "#875f00",
+ "#875f5f",
+ "#875f87",
+ "#875faf",
+ "#875fd7",
+ "#875fff",
+ "#878700",
+ "#87875f",
+ "#878787",
+ "#8787af",
+ "#8787d7",
+ "#8787ff",
+ "#87af00",
+ "#87af5f",
+ "#87af87",
+ "#87afaf",
+ "#87afd7",
+ "#87afff",
+ "#87d700",
+ "#87d75f",
+ "#87d787",
+ "#87d7af",
+ "#87d7d7",
+ "#87d7ff",
+ "#87ff00",
+ "#87ff5f",
+ "#87ff87",
+ "#87ffaf",
+ "#87ffd7",
+ "#87ffff",
+ "#af0000",
+ "#af005f",
+ "#af0087",
+ "#af00af",
+ "#af00d7",
+ "#af00ff",
+ "#af5f00",
+ "#af5f5f",
+ "#af5f87",
+ "#af5faf",
+ "#af5fd7",
+ "#af5fff",
+ "#af8700",
+ "#af875f",
+ "#af8787",
+ "#af87af",
+ "#af87d7",
+ "#af87ff",
+ "#afaf00",
+ "#afaf5f",
+ "#afaf87",
+ "#afafaf",
+ "#afafd7",
+ "#afafff",
+ "#afd700",
+ "#afd75f",
+ "#afd787",
+ "#afd7af",
+ "#afd7d7",
+ "#afd7ff",
+ "#afff00",
+ "#afff5f",
+ "#afff87",
+ "#afffaf",
+ "#afffd7",
+ "#afffff",
+ "#d70000",
+ "#d7005f",
+ "#d70087",
+ "#d700af",
+ "#d700d7",
+ "#d700ff",
+ "#d75f00",
+ "#d75f5f",
+ "#d75f87",
+ "#d75faf",
+ "#d75fd7",
+ "#d75fff",
+ "#d78700",
+ "#d7875f",
+ "#d78787",
+ "#d787af",
+ "#d787d7",
+ "#d787ff",
+ "#d7af00",
+ "#d7af5f",
+ "#d7af87",
+ "#d7afaf",
+ "#d7afd7",
+ "#d7afff",
+ "#d7d700",
+ "#d7d75f",
+ "#d7d787",
+ "#d7d7af",
+ "#d7d7d7",
+ "#d7d7ff",
+ "#d7ff00",
+ "#d7ff5f",
+ "#d7ff87",
+ "#d7ffaf",
+ "#d7ffd7",
+ "#d7ffff",
+ "#ff0000",
+ "#ff005f",
+ "#ff0087",
+ "#ff00af",
+ "#ff00d7",
+ "#ff00ff",
+ "#ff5f00",
+ "#ff5f5f",
+ "#ff5f87",
+ "#ff5faf",
+ "#ff5fd7",
+ "#ff5fff",
+ "#ff8700",
+ "#ff875f",
+ "#ff8787",
+ "#ff87af",
+ "#ff87d7",
+ "#ff87ff",
+ "#ffaf00",
+ "#ffaf5f",
+ "#ffaf87",
+ "#ffafaf",
+ "#ffafd7",
+ "#ffafff",
+ "#ffd700",
+ "#ffd75f",
+ "#ffd787",
+ "#ffd7af",
+ "#ffd7d7",
+ "#ffd7ff",
+ "#ffff00",
+ "#ffff5f",
+ "#ffff87",
+ "#ffffaf",
+ "#ffffd7",
+ "#ffffff",
+ "#080808",
+ "#121212",
+ "#1c1c1c",
+ "#262626",
+ "#303030",
+ "#3a3a3a",
+ "#444444",
+ "#4e4e4e",
+ "#585858",
+ "#626262",
+ "#6c6c6c",
+ "#767676",
+ "#808080",
+ "#8a8a8a",
+ "#949494",
+ "#9e9e9e",
+ "#a8a8a8",
+ "#b2b2b2",
+ "#bcbcbc",
+ "#c6c6c6",
+ "#d0d0d0",
+ "#dadada",
+ "#e4e4e4",
+ "#eeeeee",
+}
diff --git a/vendor/github.com/charmbracelet/colorprofile/writer.go b/vendor/github.com/charmbracelet/colorprofile/writer.go
new file mode 100644
index 00000000..d04b3b99
--- /dev/null
+++ b/vendor/github.com/charmbracelet/colorprofile/writer.go
@@ -0,0 +1,166 @@
+package colorprofile
+
+import (
+ "bytes"
+ "image/color"
+ "io"
+ "strconv"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// NewWriter creates a new color profile writer that downgrades color sequences
+// based on the detected color profile.
+//
+// If environ is nil, it will use os.Environ() to get the environment variables.
+//
+// It queries the given writer to determine if it supports ANSI escape codes.
+// If it does, along with the given environment variables, it will determine
+// the appropriate color profile to use for color formatting.
+//
+// This respects the NO_COLOR, CLICOLOR, and CLICOLOR_FORCE environment variables.
+func NewWriter(w io.Writer, environ []string) *Writer {
+ return &Writer{
+ Forward: w,
+ Profile: Detect(w, environ),
+ }
+}
+
+// Writer represents a color profile writer that writes ANSI sequences to the
+// underlying writer.
+type Writer struct {
+ Forward io.Writer
+ Profile Profile
+}
+
+// Write writes the given text to the underlying writer.
+func (w *Writer) Write(p []byte) (int, error) {
+ switch w.Profile {
+ case TrueColor:
+ return w.Forward.Write(p)
+ case NoTTY:
+ return io.WriteString(w.Forward, ansi.Strip(string(p)))
+ default:
+ return w.downsample(p)
+ }
+}
+
+// downsample downgrades the given text to the appropriate color profile.
+func (w *Writer) downsample(p []byte) (int, error) {
+ var buf bytes.Buffer
+ var state byte
+
+ parser := ansi.GetParser()
+ defer ansi.PutParser(parser)
+
+ for len(p) > 0 {
+ parser.Reset()
+ seq, _, read, newState := ansi.DecodeSequence(p, state, parser)
+
+ switch {
+ case ansi.HasCsiPrefix(seq) && parser.Command() == 'm':
+ handleSgr(w, parser, &buf)
+ default:
+ // If we're not a style SGR sequence, just write the bytes.
+ if n, err := buf.Write(seq); err != nil {
+ return n, err
+ }
+ }
+
+ p = p[read:]
+ state = newState
+ }
+
+ return w.Forward.Write(buf.Bytes())
+}
+
+// WriteString writes the given text to the underlying writer.
+func (w *Writer) WriteString(s string) (n int, err error) {
+ return w.Write([]byte(s))
+}
+
+func handleSgr(w *Writer, p *ansi.Parser, buf *bytes.Buffer) {
+ var style ansi.Style
+ params := p.Params()
+ for i := 0; i < len(params); i++ {
+ param := params[i]
+
+ switch param := param.Param(0); param {
+ case 0:
+ // SGR default parameter is 0. We use an empty string to reduce the
+ // number of bytes written to the buffer.
+ style = append(style, "")
+ case 30, 31, 32, 33, 34, 35, 36, 37: // 8-bit foreground color
+ if w.Profile < ANSI {
+ continue
+ }
+ style = style.ForegroundColor(
+ w.Profile.Convert(ansi.BasicColor(param - 30))) //nolint:gosec
+ case 38: // 16 or 24-bit foreground color
+ var c color.Color
+ if n := ansi.ReadStyleColor(params[i:], &c); n > 0 {
+ i += n - 1
+ }
+ if w.Profile < ANSI {
+ continue
+ }
+ style = style.ForegroundColor(w.Profile.Convert(c))
+ case 39: // default foreground color
+ if w.Profile < ANSI {
+ continue
+ }
+ style = style.DefaultForegroundColor()
+ case 40, 41, 42, 43, 44, 45, 46, 47: // 8-bit background color
+ if w.Profile < ANSI {
+ continue
+ }
+ style = style.BackgroundColor(
+ w.Profile.Convert(ansi.BasicColor(param - 40))) //nolint:gosec
+ case 48: // 16 or 24-bit background color
+ var c color.Color
+ if n := ansi.ReadStyleColor(params[i:], &c); n > 0 {
+ i += n - 1
+ }
+ if w.Profile < ANSI {
+ continue
+ }
+ style = style.BackgroundColor(w.Profile.Convert(c))
+ case 49: // default background color
+ if w.Profile < ANSI {
+ continue
+ }
+ style = style.DefaultBackgroundColor()
+ case 58: // 16 or 24-bit underline color
+ var c color.Color
+ if n := ansi.ReadStyleColor(params[i:], &c); n > 0 {
+ i += n - 1
+ }
+ if w.Profile < ANSI {
+ continue
+ }
+ style = style.UnderlineColor(w.Profile.Convert(c))
+ case 59: // default underline color
+ if w.Profile < ANSI {
+ continue
+ }
+ style = style.DefaultUnderlineColor()
+ case 90, 91, 92, 93, 94, 95, 96, 97: // 8-bit bright foreground color
+ if w.Profile < ANSI {
+ continue
+ }
+ style = style.ForegroundColor(
+ w.Profile.Convert(ansi.BasicColor(param - 90 + 8))) //nolint:gosec
+ case 100, 101, 102, 103, 104, 105, 106, 107: // 8-bit bright background color
+ if w.Profile < ANSI {
+ continue
+ }
+ style = style.BackgroundColor(
+ w.Profile.Convert(ansi.BasicColor(param - 100 + 8))) //nolint:gosec
+ default:
+ // If this is not a color attribute, just append it to the style.
+ style = append(style, strconv.Itoa(param))
+ }
+ }
+
+ _, _ = buf.WriteString(style.String())
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/.gitignore b/vendor/github.com/charmbracelet/lipgloss/.gitignore
new file mode 100644
index 00000000..db482015
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/.gitignore
@@ -0,0 +1,2 @@
+ssh_example_ed25519*
+dist/
diff --git a/vendor/github.com/charmbracelet/lipgloss/.golangci.yml b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml
new file mode 100644
index 00000000..90c5c08b
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml
@@ -0,0 +1,41 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - exhaustive
+ - goconst
+ - godot
+ - godox
+ - gofumpt
+ - goimports
+ - gomoddirectives
+ - goprintffuncname
+ - gosec
+ - misspell
+ - nakedret
+ - nestif
+ - nilerr
+ - noctx
+ - nolintlint
+ - prealloc
+ - revive
+ - rowserrcheck
+ - sqlclosecheck
+ - tparallel
+ - unconvert
+ - unparam
+ - whitespace
+ - wrapcheck
diff --git a/vendor/github.com/charmbracelet/lipgloss/.goreleaser.yml b/vendor/github.com/charmbracelet/lipgloss/.goreleaser.yml
new file mode 100644
index 00000000..3353d020
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/.goreleaser.yml
@@ -0,0 +1,5 @@
+# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
+version: 2
+includes:
+ - from_url:
+ url: charmbracelet/meta/main/goreleaser-lib.yaml
diff --git a/vendor/github.com/charmbracelet/lipgloss/LICENSE b/vendor/github.com/charmbracelet/lipgloss/LICENSE
new file mode 100644
index 00000000..6f5b1fa6
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021-2023 Charmbracelet, Inc
+
+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.
diff --git a/vendor/github.com/charmbracelet/lipgloss/README.md b/vendor/github.com/charmbracelet/lipgloss/README.md
new file mode 100644
index 00000000..cee2371c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/README.md
@@ -0,0 +1,815 @@
+# Lip Gloss
+
+
+
+Style definitions for nice terminal layouts. Built with TUIs in mind.
+
+
+
+Lip Gloss takes an expressive, declarative approach to terminal rendering.
+Users familiar with CSS will feel at home with Lip Gloss.
+
+```go
+
+import "github.com/charmbracelet/lipgloss"
+
+var style = lipgloss.NewStyle().
+ Bold(true).
+ Foreground(lipgloss.Color("#FAFAFA")).
+ Background(lipgloss.Color("#7D56F4")).
+ PaddingTop(2).
+ PaddingLeft(4).
+ Width(22)
+
+fmt.Println(style.Render("Hello, kitty"))
+```
+
+## Colors
+
+Lip Gloss supports the following color profiles:
+
+### ANSI 16 colors (4-bit)
+
+```go
+lipgloss.Color("5") // magenta
+lipgloss.Color("9") // red
+lipgloss.Color("12") // light blue
+```
+
+### ANSI 256 Colors (8-bit)
+
+```go
+lipgloss.Color("86") // aqua
+lipgloss.Color("201") // hot pink
+lipgloss.Color("202") // orange
+```
+
+### True Color (16,777,216 colors; 24-bit)
+
+```go
+lipgloss.Color("#0000FF") // good ol' 100% blue
+lipgloss.Color("#04B575") // a green
+lipgloss.Color("#3C3C3C") // a dark gray
+```
+
+...as well as a 1-bit ASCII profile, which is black and white only.
+
+The terminal's color profile will be automatically detected, and colors outside
+the gamut of the current palette will be automatically coerced to their closest
+available value.
+
+### Adaptive Colors
+
+You can also specify color options for light and dark backgrounds:
+
+```go
+lipgloss.AdaptiveColor{Light: "236", Dark: "248"}
+```
+
+The terminal's background color will automatically be detected and the
+appropriate color will be chosen at runtime.
+
+### Complete Colors
+
+CompleteColor specifies exact values for True Color, ANSI256, and ANSI color
+profiles.
+
+```go
+lipgloss.CompleteColor{TrueColor: "#0000FF", ANSI256: "86", ANSI: "5"}
+```
+
+Automatic color degradation will not be performed in this case and it will be
+based on the color specified.
+
+### Complete Adaptive Colors
+
+You can use `CompleteColor` with `AdaptiveColor` to specify the exact values for
+light and dark backgrounds without automatic color degradation.
+
+```go
+lipgloss.CompleteAdaptiveColor{
+ Light: CompleteColor{TrueColor: "#d7ffae", ANSI256: "193", ANSI: "11"},
+ Dark: CompleteColor{TrueColor: "#d75fee", ANSI256: "163", ANSI: "5"},
+}
+```
+
+## Inline Formatting
+
+Lip Gloss supports the usual ANSI text formatting options:
+
+```go
+var style = lipgloss.NewStyle().
+ Bold(true).
+ Italic(true).
+ Faint(true).
+ Blink(true).
+ Strikethrough(true).
+ Underline(true).
+ Reverse(true)
+```
+
+## Block-Level Formatting
+
+Lip Gloss also supports rules for block-level formatting:
+
+```go
+// Padding
+var style = lipgloss.NewStyle().
+ PaddingTop(2).
+ PaddingRight(4).
+ PaddingBottom(2).
+ PaddingLeft(4)
+
+// Margins
+var style = lipgloss.NewStyle().
+ MarginTop(2).
+ MarginRight(4).
+ MarginBottom(2).
+ MarginLeft(4)
+```
+
+There is also shorthand syntax for margins and padding, which follows the same
+format as CSS:
+
+```go
+// 2 cells on all sides
+lipgloss.NewStyle().Padding(2)
+
+// 2 cells on the top and bottom, 4 cells on the left and right
+lipgloss.NewStyle().Margin(2, 4)
+
+// 1 cell on the top, 4 cells on the sides, 2 cells on the bottom
+lipgloss.NewStyle().Padding(1, 4, 2)
+
+// Clockwise, starting from the top: 2 cells on the top, 4 on the right, 3 on
+// the bottom, and 1 on the left
+lipgloss.NewStyle().Margin(2, 4, 3, 1)
+```
+
+## Aligning Text
+
+You can align paragraphs of text to the left, right, or center.
+
+```go
+var style = lipgloss.NewStyle().
+ Width(24).
+ Align(lipgloss.Left). // align it left
+ Align(lipgloss.Right). // no wait, align it right
+ Align(lipgloss.Center) // just kidding, align it in the center
+```
+
+## Width and Height
+
+Setting a minimum width and height is simple and straightforward.
+
+```go
+var style = lipgloss.NewStyle().
+ SetString("What’s for lunch?").
+ Width(24).
+ Height(32).
+ Foreground(lipgloss.Color("63"))
+```
+
+## Borders
+
+Adding borders is easy:
+
+```go
+// Add a purple, rectangular border
+var style = lipgloss.NewStyle().
+ BorderStyle(lipgloss.NormalBorder()).
+ BorderForeground(lipgloss.Color("63"))
+
+// Set a rounded, yellow-on-purple border to the top and left
+var anotherStyle = lipgloss.NewStyle().
+ BorderStyle(lipgloss.RoundedBorder()).
+ BorderForeground(lipgloss.Color("228")).
+ BorderBackground(lipgloss.Color("63")).
+ BorderTop(true).
+ BorderLeft(true)
+
+// Make your own border
+var myCuteBorder = lipgloss.Border{
+ Top: "._.:*:",
+ Bottom: "._.:*:",
+ Left: "|*",
+ Right: "|*",
+ TopLeft: "*",
+ TopRight: "*",
+ BottomLeft: "*",
+ BottomRight: "*",
+}
+```
+
+There are also shorthand functions for defining borders, which follow a similar
+pattern to the margin and padding shorthand functions.
+
+```go
+// Add a thick border to the top and bottom
+lipgloss.NewStyle().
+ Border(lipgloss.ThickBorder(), true, false)
+
+// Add a double border to the top and left sides. Rules are set clockwise
+// from top.
+lipgloss.NewStyle().
+ Border(lipgloss.DoubleBorder(), true, false, false, true)
+```
+
+For more on borders see [the docs][docs].
+
+## Copying Styles
+
+Just use assignment:
+
+```go
+style := lipgloss.NewStyle().Foreground(lipgloss.Color("219"))
+
+copiedStyle := style // this is a true copy
+
+wildStyle := style.Blink(true) // this is also true copy, with blink added
+
+```
+
+Since `Style` data structures contains only primitive types, assigning a style
+to another effectively creates a new copy of the style without mutating the
+original.
+
+## Inheritance
+
+Styles can inherit rules from other styles. When inheriting, only unset rules
+on the receiver are inherited.
+
+```go
+var styleA = lipgloss.NewStyle().
+ Foreground(lipgloss.Color("229")).
+ Background(lipgloss.Color("63"))
+
+// Only the background color will be inherited here, because the foreground
+// color will have been already set:
+var styleB = lipgloss.NewStyle().
+ Foreground(lipgloss.Color("201")).
+ Inherit(styleA)
+```
+
+## Unsetting Rules
+
+All rules can be unset:
+
+```go
+var style = lipgloss.NewStyle().
+ Bold(true). // make it bold
+ UnsetBold(). // jk don't make it bold
+ Background(lipgloss.Color("227")). // yellow background
+ UnsetBackground() // never mind
+```
+
+When a rule is unset, it won't be inherited or copied.
+
+## Enforcing Rules
+
+Sometimes, such as when developing a component, you want to make sure style
+definitions respect their intended purpose in the UI. This is where `Inline`
+and `MaxWidth`, and `MaxHeight` come in:
+
+```go
+// Force rendering onto a single line, ignoring margins, padding, and borders.
+someStyle.Inline(true).Render("yadda yadda")
+
+// Also limit rendering to five cells
+someStyle.Inline(true).MaxWidth(5).Render("yadda yadda")
+
+// Limit rendering to a 5x5 cell block
+someStyle.MaxWidth(5).MaxHeight(5).Render("yadda yadda")
+```
+
+## Tabs
+
+The tab character (`\t`) is rendered differently in different terminals (often
+as 8 spaces, sometimes 4). Because of this inconsistency, Lip Gloss converts
+tabs to 4 spaces at render time. This behavior can be changed on a per-style
+basis, however:
+
+```go
+style := lipgloss.NewStyle() // tabs will render as 4 spaces, the default
+style = style.TabWidth(2) // render tabs as 2 spaces
+style = style.TabWidth(0) // remove tabs entirely
+style = style.TabWidth(lipgloss.NoTabConversion) // leave tabs intact
+```
+
+## Rendering
+
+Generally, you just call the `Render(string...)` method on a `lipgloss.Style`:
+
+```go
+style := lipgloss.NewStyle().Bold(true).SetString("Hello,")
+fmt.Println(style.Render("kitty.")) // Hello, kitty.
+fmt.Println(style.Render("puppy.")) // Hello, puppy.
+```
+
+But you could also use the Stringer interface:
+
+```go
+var style = lipgloss.NewStyle().SetString("你好,猫咪。").Bold(true)
+fmt.Println(style) // 你好,猫咪。
+```
+
+### Custom Renderers
+
+Custom renderers allow you to render to a specific outputs. This is
+particularly important when you want to render to different outputs and
+correctly detect the color profile and dark background status for each, such as
+in a server-client situation.
+
+```go
+func myLittleHandler(sess ssh.Session) {
+ // Create a renderer for the client.
+ renderer := lipgloss.NewRenderer(sess)
+
+ // Create a new style on the renderer.
+ style := renderer.NewStyle().Background(lipgloss.AdaptiveColor{Light: "63", Dark: "228"})
+
+ // Render. The color profile and dark background state will be correctly detected.
+ io.WriteString(sess, style.Render("Heyyyyyyy"))
+}
+```
+
+For an example on using a custom renderer over SSH with [Wish][wish] see the
+[SSH example][ssh-example].
+
+## Utilities
+
+In addition to pure styling, Lip Gloss also ships with some utilities to help
+assemble your layouts.
+
+### Joining Paragraphs
+
+Horizontally and vertically joining paragraphs is a cinch.
+
+```go
+// Horizontally join three paragraphs along their bottom edges
+lipgloss.JoinHorizontal(lipgloss.Bottom, paragraphA, paragraphB, paragraphC)
+
+// Vertically join two paragraphs along their center axes
+lipgloss.JoinVertical(lipgloss.Center, paragraphA, paragraphB)
+
+// Horizontally join three paragraphs, with the shorter ones aligning 20%
+// from the top of the tallest
+lipgloss.JoinHorizontal(0.2, paragraphA, paragraphB, paragraphC)
+```
+
+### Measuring Width and Height
+
+Sometimes you’ll want to know the width and height of text blocks when building
+your layouts.
+
+```go
+// Render a block of text.
+var style = lipgloss.NewStyle().
+ Width(40).
+ Padding(2)
+var block string = style.Render(someLongString)
+
+// Get the actual, physical dimensions of the text block.
+width := lipgloss.Width(block)
+height := lipgloss.Height(block)
+
+// Here's a shorthand function.
+w, h := lipgloss.Size(block)
+```
+
+### Placing Text in Whitespace
+
+Sometimes you’ll simply want to place a block of text in whitespace.
+
+```go
+// Center a paragraph horizontally in a space 80 cells wide. The height of
+// the block returned will be as tall as the input paragraph.
+block := lipgloss.PlaceHorizontal(80, lipgloss.Center, fancyStyledParagraph)
+
+// Place a paragraph at the bottom of a space 30 cells tall. The width of
+// the text block returned will be as wide as the input paragraph.
+block := lipgloss.PlaceVertical(30, lipgloss.Bottom, fancyStyledParagraph)
+
+// Place a paragraph in the bottom right corner of a 30x80 cell space.
+block := lipgloss.Place(30, 80, lipgloss.Right, lipgloss.Bottom, fancyStyledParagraph)
+```
+
+You can also style the whitespace. For details, see [the docs][docs].
+
+## Rendering Tables
+
+Lip Gloss ships with a table rendering sub-package.
+
+```go
+import "github.com/charmbracelet/lipgloss/table"
+```
+
+Define some rows of data.
+
+```go
+rows := [][]string{
+ {"Chinese", "您好", "你好"},
+ {"Japanese", "こんにちは", "やあ"},
+ {"Arabic", "أهلين", "أهلا"},
+ {"Russian", "Здравствуйте", "Привет"},
+ {"Spanish", "Hola", "¿Qué tal?"},
+}
+```
+
+Use the table package to style and render the table.
+
+```go
+var (
+ purple = lipgloss.Color("99")
+ gray = lipgloss.Color("245")
+ lightGray = lipgloss.Color("241")
+
+ headerStyle = lipgloss.NewStyle().Foreground(purple).Bold(true).Align(lipgloss.Center)
+ cellStyle = lipgloss.NewStyle().Padding(0, 1).Width(14)
+ oddRowStyle = cellStyle.Foreground(gray)
+ evenRowStyle = cellStyle.Foreground(lightGray)
+)
+
+t := table.New().
+ Border(lipgloss.NormalBorder()).
+ BorderStyle(lipgloss.NewStyle().Foreground(purple)).
+ StyleFunc(func(row, col int) lipgloss.Style {
+ switch {
+ case row == table.HeaderRow:
+ return headerStyle
+ case row%2 == 0:
+ return evenRowStyle
+ default:
+ return oddRowStyle
+ }
+ }).
+ Headers("LANGUAGE", "FORMAL", "INFORMAL").
+ Rows(rows...)
+
+// You can also add tables row-by-row
+t.Row("English", "You look absolutely fabulous.", "How's it going?")
+```
+
+Print the table.
+
+```go
+fmt.Println(t)
+```
+
+
+
+> [!WARNING]
+> Table `Rows` need to be declared before `Offset` otherwise it does nothing.
+
+### Table Borders
+
+There are helpers to generate tables in markdown or ASCII style:
+
+#### Markdown Table
+
+```go
+table.New().Border(lipgloss.MarkdownBorder()).BorderTop(false).BorderBottom(false)
+```
+
+```
+| LANGUAGE | FORMAL | INFORMAL |
+|----------|--------------|-----------|
+| Chinese | Nǐn hǎo | Nǐ hǎo |
+| French | Bonjour | Salut |
+| Russian | Zdravstvuyte | Privet |
+| Spanish | Hola | ¿Qué tal? |
+```
+
+#### ASCII Table
+
+```go
+table.New().Border(lipgloss.ASCIIBorder())
+```
+
+```
++----------+--------------+-----------+
+| LANGUAGE | FORMAL | INFORMAL |
++----------+--------------+-----------+
+| Chinese | Nǐn hǎo | Nǐ hǎo |
+| French | Bonjour | Salut |
+| Russian | Zdravstvuyte | Privet |
+| Spanish | Hola | ¿Qué tal? |
++----------+--------------+-----------+
+```
+
+For more on tables see [the docs](https://pkg.go.dev/github.com/charmbracelet/lipgloss?tab=doc) and [examples](https://github.com/charmbracelet/lipgloss/tree/master/examples/table).
+
+## Rendering Lists
+
+Lip Gloss ships with a list rendering sub-package.
+
+```go
+import "github.com/charmbracelet/lipgloss/list"
+```
+
+Define a new list.
+
+```go
+l := list.New("A", "B", "C")
+```
+
+Print the list.
+
+```go
+fmt.Println(l)
+
+// • A
+// • B
+// • C
+```
+
+Lists have the ability to nest.
+
+```go
+l := list.New(
+ "A", list.New("Artichoke"),
+ "B", list.New("Baking Flour", "Bananas", "Barley", "Bean Sprouts"),
+ "C", list.New("Cashew Apple", "Cashews", "Coconut Milk", "Curry Paste", "Currywurst"),
+ "D", list.New("Dill", "Dragonfruit", "Dried Shrimp"),
+ "E", list.New("Eggs"),
+ "F", list.New("Fish Cake", "Furikake"),
+ "J", list.New("Jicama"),
+ "K", list.New("Kohlrabi"),
+ "L", list.New("Leeks", "Lentils", "Licorice Root"),
+)
+```
+
+Print the list.
+
+```go
+fmt.Println(l)
+```
+
+
+
+
+
+Lists can be customized via their enumeration function as well as using
+`lipgloss.Style`s.
+
+```go
+enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("99")).MarginRight(1)
+itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")).MarginRight(1)
+
+l := list.New(
+ "Glossier",
+ "Claire’s Boutique",
+ "Nyx",
+ "Mac",
+ "Milk",
+ ).
+ Enumerator(list.Roman).
+ EnumeratorStyle(enumeratorStyle).
+ ItemStyle(itemStyle)
+```
+
+Print the list.
+
+
+
+
+
+In addition to the predefined enumerators (`Arabic`, `Alphabet`, `Roman`, `Bullet`, `Tree`),
+you may also define your own custom enumerator:
+
+```go
+l := list.New("Duck", "Duck", "Duck", "Duck", "Goose", "Duck", "Duck")
+
+func DuckDuckGooseEnumerator(l list.Items, i int) string {
+ if l.At(i).Value() == "Goose" {
+ return "Honk →"
+ }
+ return ""
+}
+
+l = l.Enumerator(DuckDuckGooseEnumerator)
+```
+
+Print the list:
+
+
+
+
+
+If you need, you can also build lists incrementally:
+
+```go
+l := list.New()
+
+for i := 0; i < repeat; i++ {
+ l.Item("Lip Gloss")
+}
+```
+
+## Rendering Trees
+
+Lip Gloss ships with a tree rendering sub-package.
+
+```go
+import "github.com/charmbracelet/lipgloss/tree"
+```
+
+Define a new tree.
+
+```go
+t := tree.Root(".").
+ Child("A", "B", "C")
+```
+
+Print the tree.
+
+```go
+fmt.Println(t)
+
+// .
+// ├── A
+// ├── B
+// └── C
+```
+
+Trees have the ability to nest.
+
+```go
+t := tree.Root(".").
+ Child("macOS").
+ Child(
+ tree.New().
+ Root("Linux").
+ Child("NixOS").
+ Child("Arch Linux (btw)").
+ Child("Void Linux"),
+ ).
+ Child(
+ tree.New().
+ Root("BSD").
+ Child("FreeBSD").
+ Child("OpenBSD"),
+ )
+```
+
+Print the tree.
+
+```go
+fmt.Println(t)
+```
+
+
+
+
+
+Trees can be customized via their enumeration function as well as using
+`lipgloss.Style`s.
+
+```go
+enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("63")).MarginRight(1)
+rootStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("35"))
+itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212"))
+
+t := tree.
+ Root("⁜ Makeup").
+ Child(
+ "Glossier",
+ "Fenty Beauty",
+ tree.New().Child(
+ "Gloss Bomb Universal Lip Luminizer",
+ "Hot Cheeks Velour Blushlighter",
+ ),
+ "Nyx",
+ "Mac",
+ "Milk",
+ ).
+ Enumerator(tree.RoundedEnumerator).
+ EnumeratorStyle(enumeratorStyle).
+ RootStyle(rootStyle).
+ ItemStyle(itemStyle)
+```
+
+Print the tree.
+
+
+
+
+
+The predefined enumerators for trees are `DefaultEnumerator` and `RoundedEnumerator`.
+
+If you need, you can also build trees incrementally:
+
+```go
+t := tree.New()
+
+for i := 0; i < repeat; i++ {
+ t.Child("Lip Gloss")
+}
+```
+
+---
+
+## FAQ
+
+
+
+Why are things misaligning? Why are borders at the wrong widths?
+
+This is most likely due to your locale and encoding, particularly with
+regard to Chinese, Japanese, and Korean (for example, zh_CN.UTF-8
+or ja_JP.UTF-8). The most direct way to fix this is to set
+RUNEWIDTH_EASTASIAN=0 in your environment.
+
+For details see https://github.com/charmbracelet/lipgloss/issues/40.
+
+
+
+
+Why isn't Lip Gloss displaying colors?
+
+Lip Gloss automatically degrades colors to the best available option in the
+given terminal, and if output's not a TTY it will remove color output entirely.
+This is common when running tests, CI, or when piping output elsewhere.
+
+If necessary, you can force a color profile in your tests with
+SetColorProfile.
+
+```go
+import (
+ "github.com/charmbracelet/lipgloss"
+ "github.com/muesli/termenv"
+)
+
+lipgloss.SetColorProfile(termenv.TrueColor)
+```
+
+_Note:_ this option limits the flexibility of your application and can cause
+ANSI escape codes to be output in cases where that might not be desired. Take
+careful note of your use case and environment before choosing to force a color
+profile.
+
+
+
+## What about [Bubble Tea][tea]?
+
+Lip Gloss doesn’t replace Bubble Tea. Rather, it is an excellent Bubble Tea
+companion. It was designed to make assembling terminal user interface views as
+simple and fun as possible so that you can focus on building your application
+instead of concerning yourself with low-level layout details.
+
+In simple terms, you can use Lip Gloss to help build your Bubble Tea views.
+
+[tea]: https://github.com/charmbracelet/tea
+
+## Under the Hood
+
+Lip Gloss is built on the excellent [Termenv][termenv] and [Reflow][reflow]
+libraries which deal with color and ANSI-aware text operations, respectively.
+For many use cases Termenv and Reflow will be sufficient for your needs.
+
+[termenv]: https://github.com/muesli/termenv
+[reflow]: https://github.com/muesli/reflow
+
+## Rendering Markdown
+
+For a more document-centric rendering solution with support for things like
+lists, tables, and syntax-highlighted code have a look at [Glamour][glamour],
+the stylesheet-based Markdown renderer.
+
+[glamour]: https://github.com/charmbracelet/glamour
+
+## Contributing
+
+See [contributing][contribute].
+
+[contribute]: https://github.com/charmbracelet/lipgloss/contribute
+
+## Feedback
+
+We’d love to hear your thoughts on this project. Feel free to drop us a note!
+
+- [Twitter](https://twitter.com/charmcli)
+- [The Fediverse](https://mastodon.social/@charmcli)
+- [Discord](https://charm.sh/chat)
+
+## License
+
+[MIT](https://github.com/charmbracelet/lipgloss/raw/master/LICENSE)
+
+---
+
+Part of [Charm](https://charm.sh).
+
+
+
+Charm热爱开源 • Charm loves open source
+
+[docs]: https://pkg.go.dev/github.com/charmbracelet/lipgloss?tab=doc
+[wish]: https://github.com/charmbracelet/wish
+[ssh-example]: examples/ssh
diff --git a/vendor/github.com/charmbracelet/lipgloss/Taskfile.yaml b/vendor/github.com/charmbracelet/lipgloss/Taskfile.yaml
new file mode 100644
index 00000000..0b4a7711
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/Taskfile.yaml
@@ -0,0 +1,19 @@
+# https://taskfile.dev
+
+version: '3'
+
+tasks:
+ lint:
+ desc: Run base linters
+ cmds:
+ - golangci-lint run
+
+ test:
+ desc: Run tests
+ cmds:
+ - go test ./... {{.CLI_ARGS}}
+
+ test:table:
+ desc: Run table tests
+ cmds:
+ - go test ./table {{.CLI_ARGS}}
diff --git a/vendor/github.com/charmbracelet/lipgloss/align.go b/vendor/github.com/charmbracelet/lipgloss/align.go
new file mode 100644
index 00000000..ce654b23
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/align.go
@@ -0,0 +1,83 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/muesli/termenv"
+)
+
+// Perform text alignment. If the string is multi-lined, we also make all lines
+// the same width by padding them with spaces. If a termenv style is passed,
+// use that to style the spaces added.
+func alignTextHorizontal(str string, pos Position, width int, style *termenv.Style) string {
+ lines, widestLine := getLines(str)
+ var b strings.Builder
+
+ for i, l := range lines {
+ lineWidth := ansi.StringWidth(l)
+
+ shortAmount := widestLine - lineWidth // difference from the widest line
+ shortAmount += max(0, width-(shortAmount+lineWidth)) // difference from the total width, if set
+
+ if shortAmount > 0 {
+ switch pos { //nolint:exhaustive
+ case Right:
+ s := strings.Repeat(" ", shortAmount)
+ if style != nil {
+ s = style.Styled(s)
+ }
+ l = s + l
+ case Center:
+ // Note: remainder goes on the right.
+ left := shortAmount / 2 //nolint:mnd
+ right := left + shortAmount%2 //nolint:mnd
+
+ leftSpaces := strings.Repeat(" ", left)
+ rightSpaces := strings.Repeat(" ", right)
+
+ if style != nil {
+ leftSpaces = style.Styled(leftSpaces)
+ rightSpaces = style.Styled(rightSpaces)
+ }
+ l = leftSpaces + l + rightSpaces
+ default: // Left
+ s := strings.Repeat(" ", shortAmount)
+ if style != nil {
+ s = style.Styled(s)
+ }
+ l += s
+ }
+ }
+
+ b.WriteString(l)
+ if i < len(lines)-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ return b.String()
+}
+
+func alignTextVertical(str string, pos Position, height int, _ *termenv.Style) string {
+ strHeight := strings.Count(str, "\n") + 1
+ if height < strHeight {
+ return str
+ }
+
+ switch pos {
+ case Top:
+ return str + strings.Repeat("\n", height-strHeight)
+ case Center:
+ topPadding, bottomPadding := (height-strHeight)/2, (height-strHeight)/2 //nolint:mnd
+ if strHeight+topPadding+bottomPadding > height {
+ topPadding--
+ } else if strHeight+topPadding+bottomPadding < height {
+ bottomPadding++
+ }
+ return strings.Repeat("\n", topPadding) + str + strings.Repeat("\n", bottomPadding)
+ case Bottom:
+ return strings.Repeat("\n", height-strHeight) + str
+ }
+ return str
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/ansi_unix.go b/vendor/github.com/charmbracelet/lipgloss/ansi_unix.go
new file mode 100644
index 00000000..d416b8c9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/ansi_unix.go
@@ -0,0 +1,7 @@
+//go:build !windows
+// +build !windows
+
+package lipgloss
+
+// enableLegacyWindowsANSI is only needed on Windows.
+func enableLegacyWindowsANSI() {}
diff --git a/vendor/github.com/charmbracelet/lipgloss/ansi_windows.go b/vendor/github.com/charmbracelet/lipgloss/ansi_windows.go
new file mode 100644
index 00000000..0cf56e4c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/ansi_windows.go
@@ -0,0 +1,22 @@
+//go:build windows
+// +build windows
+
+package lipgloss
+
+import (
+ "sync"
+
+ "github.com/muesli/termenv"
+)
+
+var enableANSI sync.Once
+
+// enableANSIColors enables support for ANSI color sequences in the Windows
+// default console (cmd.exe and the PowerShell application). Note that this
+// only works with Windows 10. Also note that Windows Terminal supports colors
+// by default.
+func enableLegacyWindowsANSI() {
+ enableANSI.Do(func() {
+ _, _ = termenv.EnableWindowsANSIConsole()
+ })
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/borders.go b/vendor/github.com/charmbracelet/lipgloss/borders.go
new file mode 100644
index 00000000..b36f8743
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/borders.go
@@ -0,0 +1,490 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/muesli/termenv"
+ "github.com/rivo/uniseg"
+)
+
+// Border contains a series of values which comprise the various parts of a
+// border.
+type Border struct {
+ Top string
+ Bottom string
+ Left string
+ Right string
+ TopLeft string
+ TopRight string
+ BottomLeft string
+ BottomRight string
+ MiddleLeft string
+ MiddleRight string
+ Middle string
+ MiddleTop string
+ MiddleBottom string
+}
+
+// GetTopSize returns the width of the top border. If borders contain runes of
+// varying widths, the widest rune is returned. If no border exists on the top
+// edge, 0 is returned.
+func (b Border) GetTopSize() int {
+ return getBorderEdgeWidth(b.TopLeft, b.Top, b.TopRight)
+}
+
+// GetRightSize returns the width of the right border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the right edge, 0 is returned.
+func (b Border) GetRightSize() int {
+ return getBorderEdgeWidth(b.TopRight, b.Right, b.BottomRight)
+}
+
+// GetBottomSize returns the width of the bottom border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the bottom edge, 0 is returned.
+func (b Border) GetBottomSize() int {
+ return getBorderEdgeWidth(b.BottomLeft, b.Bottom, b.BottomRight)
+}
+
+// GetLeftSize returns the width of the left border. If borders contain runes
+// of varying widths, the widest rune is returned. If no border exists on the
+// left edge, 0 is returned.
+func (b Border) GetLeftSize() int {
+ return getBorderEdgeWidth(b.TopLeft, b.Left, b.BottomLeft)
+}
+
+func getBorderEdgeWidth(borderParts ...string) (maxWidth int) {
+ for _, piece := range borderParts {
+ w := maxRuneWidth(piece)
+ if w > maxWidth {
+ maxWidth = w
+ }
+ }
+ return maxWidth
+}
+
+var (
+ noBorder = Border{}
+
+ normalBorder = Border{
+ Top: "─",
+ Bottom: "─",
+ Left: "│",
+ Right: "│",
+ TopLeft: "┌",
+ TopRight: "┐",
+ BottomLeft: "└",
+ BottomRight: "┘",
+ MiddleLeft: "├",
+ MiddleRight: "┤",
+ Middle: "┼",
+ MiddleTop: "┬",
+ MiddleBottom: "┴",
+ }
+
+ roundedBorder = Border{
+ Top: "─",
+ Bottom: "─",
+ Left: "│",
+ Right: "│",
+ TopLeft: "╭",
+ TopRight: "╮",
+ BottomLeft: "╰",
+ BottomRight: "╯",
+ MiddleLeft: "├",
+ MiddleRight: "┤",
+ Middle: "┼",
+ MiddleTop: "┬",
+ MiddleBottom: "┴",
+ }
+
+ blockBorder = Border{
+ Top: "█",
+ Bottom: "█",
+ Left: "█",
+ Right: "█",
+ TopLeft: "█",
+ TopRight: "█",
+ BottomLeft: "█",
+ BottomRight: "█",
+ MiddleLeft: "█",
+ MiddleRight: "█",
+ Middle: "█",
+ MiddleTop: "█",
+ MiddleBottom: "█",
+ }
+
+ outerHalfBlockBorder = Border{
+ Top: "▀",
+ Bottom: "▄",
+ Left: "▌",
+ Right: "▐",
+ TopLeft: "▛",
+ TopRight: "▜",
+ BottomLeft: "▙",
+ BottomRight: "▟",
+ }
+
+ innerHalfBlockBorder = Border{
+ Top: "▄",
+ Bottom: "▀",
+ Left: "▐",
+ Right: "▌",
+ TopLeft: "▗",
+ TopRight: "▖",
+ BottomLeft: "▝",
+ BottomRight: "▘",
+ }
+
+ thickBorder = Border{
+ Top: "━",
+ Bottom: "━",
+ Left: "┃",
+ Right: "┃",
+ TopLeft: "┏",
+ TopRight: "┓",
+ BottomLeft: "┗",
+ BottomRight: "┛",
+ MiddleLeft: "┣",
+ MiddleRight: "┫",
+ Middle: "╋",
+ MiddleTop: "┳",
+ MiddleBottom: "┻",
+ }
+
+ doubleBorder = Border{
+ Top: "═",
+ Bottom: "═",
+ Left: "║",
+ Right: "║",
+ TopLeft: "╔",
+ TopRight: "╗",
+ BottomLeft: "╚",
+ BottomRight: "╝",
+ MiddleLeft: "╠",
+ MiddleRight: "╣",
+ Middle: "╬",
+ MiddleTop: "╦",
+ MiddleBottom: "╩",
+ }
+
+ hiddenBorder = Border{
+ Top: " ",
+ Bottom: " ",
+ Left: " ",
+ Right: " ",
+ TopLeft: " ",
+ TopRight: " ",
+ BottomLeft: " ",
+ BottomRight: " ",
+ MiddleLeft: " ",
+ MiddleRight: " ",
+ Middle: " ",
+ MiddleTop: " ",
+ MiddleBottom: " ",
+ }
+
+ markdownBorder = Border{
+ Top: "-",
+ Bottom: "-",
+ Left: "|",
+ Right: "|",
+ TopLeft: "|",
+ TopRight: "|",
+ BottomLeft: "|",
+ BottomRight: "|",
+ MiddleLeft: "|",
+ MiddleRight: "|",
+ Middle: "|",
+ MiddleTop: "|",
+ MiddleBottom: "|",
+ }
+
+ asciiBorder = Border{
+ Top: "-",
+ Bottom: "-",
+ Left: "|",
+ Right: "|",
+ TopLeft: "+",
+ TopRight: "+",
+ BottomLeft: "+",
+ BottomRight: "+",
+ MiddleLeft: "+",
+ MiddleRight: "+",
+ Middle: "+",
+ MiddleTop: "+",
+ MiddleBottom: "+",
+ }
+)
+
+// NormalBorder returns a standard-type border with a normal weight and 90
+// degree corners.
+func NormalBorder() Border {
+ return normalBorder
+}
+
+// RoundedBorder returns a border with rounded corners.
+func RoundedBorder() Border {
+ return roundedBorder
+}
+
+// BlockBorder returns a border that takes the whole block.
+func BlockBorder() Border {
+ return blockBorder
+}
+
+// OuterHalfBlockBorder returns a half-block border that sits outside the frame.
+func OuterHalfBlockBorder() Border {
+ return outerHalfBlockBorder
+}
+
+// InnerHalfBlockBorder returns a half-block border that sits inside the frame.
+func InnerHalfBlockBorder() Border {
+ return innerHalfBlockBorder
+}
+
+// ThickBorder returns a border that's thicker than the one returned by
+// NormalBorder.
+func ThickBorder() Border {
+ return thickBorder
+}
+
+// DoubleBorder returns a border comprised of two thin strokes.
+func DoubleBorder() Border {
+ return doubleBorder
+}
+
+// HiddenBorder returns a border that renders as a series of single-cell
+// spaces. It's useful for cases when you want to remove a standard border but
+// maintain layout positioning. This said, you can still apply a background
+// color to a hidden border.
+func HiddenBorder() Border {
+ return hiddenBorder
+}
+
+// MarkdownBorder return a table border in markdown style.
+//
+// Make sure to disable top and bottom border for the best result. This will
+// ensure that the output is valid markdown.
+//
+// table.New().Border(lipgloss.MarkdownBorder()).BorderTop(false).BorderBottom(false)
+func MarkdownBorder() Border {
+ return markdownBorder
+}
+
+// ASCIIBorder returns a table border with ASCII characters.
+func ASCIIBorder() Border {
+ return asciiBorder
+}
+
+func (s Style) applyBorder(str string) string {
+ var (
+ border = s.getBorderStyle()
+ hasTop = s.getAsBool(borderTopKey, false)
+ hasRight = s.getAsBool(borderRightKey, false)
+ hasBottom = s.getAsBool(borderBottomKey, false)
+ hasLeft = s.getAsBool(borderLeftKey, false)
+
+ topFG = s.getAsColor(borderTopForegroundKey)
+ rightFG = s.getAsColor(borderRightForegroundKey)
+ bottomFG = s.getAsColor(borderBottomForegroundKey)
+ leftFG = s.getAsColor(borderLeftForegroundKey)
+
+ topBG = s.getAsColor(borderTopBackgroundKey)
+ rightBG = s.getAsColor(borderRightBackgroundKey)
+ bottomBG = s.getAsColor(borderBottomBackgroundKey)
+ leftBG = s.getAsColor(borderLeftBackgroundKey)
+ )
+
+ // If a border is set and no sides have been specifically turned on or off
+ // render borders on all sides.
+ if s.implicitBorders() {
+ hasTop = true
+ hasRight = true
+ hasBottom = true
+ hasLeft = true
+ }
+
+ // If no border is set or all borders are been disabled, abort.
+ if border == noBorder || (!hasTop && !hasRight && !hasBottom && !hasLeft) {
+ return str
+ }
+
+ lines, width := getLines(str)
+
+ if hasLeft {
+ if border.Left == "" {
+ border.Left = " "
+ }
+ width += maxRuneWidth(border.Left)
+ }
+
+ if hasRight && border.Right == "" {
+ border.Right = " "
+ }
+
+ // If corners should be rendered but are set with the empty string, fill them
+ // with a single space.
+ if hasTop && hasLeft && border.TopLeft == "" {
+ border.TopLeft = " "
+ }
+ if hasTop && hasRight && border.TopRight == "" {
+ border.TopRight = " "
+ }
+ if hasBottom && hasLeft && border.BottomLeft == "" {
+ border.BottomLeft = " "
+ }
+ if hasBottom && hasRight && border.BottomRight == "" {
+ border.BottomRight = " "
+ }
+
+ // Figure out which corners we should actually be using based on which
+ // sides are set to show.
+ if hasTop {
+ switch {
+ case !hasLeft && !hasRight:
+ border.TopLeft = ""
+ border.TopRight = ""
+ case !hasLeft:
+ border.TopLeft = ""
+ case !hasRight:
+ border.TopRight = ""
+ }
+ }
+ if hasBottom {
+ switch {
+ case !hasLeft && !hasRight:
+ border.BottomLeft = ""
+ border.BottomRight = ""
+ case !hasLeft:
+ border.BottomLeft = ""
+ case !hasRight:
+ border.BottomRight = ""
+ }
+ }
+
+ // For now, limit corners to one rune.
+ border.TopLeft = getFirstRuneAsString(border.TopLeft)
+ border.TopRight = getFirstRuneAsString(border.TopRight)
+ border.BottomRight = getFirstRuneAsString(border.BottomRight)
+ border.BottomLeft = getFirstRuneAsString(border.BottomLeft)
+
+ var out strings.Builder
+
+ // Render top
+ if hasTop {
+ top := renderHorizontalEdge(border.TopLeft, border.Top, border.TopRight, width)
+ top = s.styleBorder(top, topFG, topBG)
+ out.WriteString(top)
+ out.WriteRune('\n')
+ }
+
+ leftRunes := []rune(border.Left)
+ leftIndex := 0
+
+ rightRunes := []rune(border.Right)
+ rightIndex := 0
+
+ // Render sides
+ for i, l := range lines {
+ if hasLeft {
+ r := string(leftRunes[leftIndex])
+ leftIndex++
+ if leftIndex >= len(leftRunes) {
+ leftIndex = 0
+ }
+ out.WriteString(s.styleBorder(r, leftFG, leftBG))
+ }
+ out.WriteString(l)
+ if hasRight {
+ r := string(rightRunes[rightIndex])
+ rightIndex++
+ if rightIndex >= len(rightRunes) {
+ rightIndex = 0
+ }
+ out.WriteString(s.styleBorder(r, rightFG, rightBG))
+ }
+ if i < len(lines)-1 {
+ out.WriteRune('\n')
+ }
+ }
+
+ // Render bottom
+ if hasBottom {
+ bottom := renderHorizontalEdge(border.BottomLeft, border.Bottom, border.BottomRight, width)
+ bottom = s.styleBorder(bottom, bottomFG, bottomBG)
+ out.WriteRune('\n')
+ out.WriteString(bottom)
+ }
+
+ return out.String()
+}
+
+// Render the horizontal (top or bottom) portion of a border.
+func renderHorizontalEdge(left, middle, right string, width int) string {
+ if middle == "" {
+ middle = " "
+ }
+
+ leftWidth := ansi.StringWidth(left)
+ rightWidth := ansi.StringWidth(right)
+
+ runes := []rune(middle)
+ j := 0
+
+ out := strings.Builder{}
+ out.WriteString(left)
+ for i := leftWidth + rightWidth; i < width+rightWidth; {
+ out.WriteRune(runes[j])
+ j++
+ if j >= len(runes) {
+ j = 0
+ }
+ i += ansi.StringWidth(string(runes[j]))
+ }
+ out.WriteString(right)
+
+ return out.String()
+}
+
+// Apply foreground and background styling to a border.
+func (s Style) styleBorder(border string, fg, bg TerminalColor) string {
+ if fg == noColor && bg == noColor {
+ return border
+ }
+
+ style := termenv.Style{}
+
+ if fg != noColor {
+ style = style.Foreground(fg.color(s.r))
+ }
+ if bg != noColor {
+ style = style.Background(bg.color(s.r))
+ }
+
+ return style.Styled(border)
+}
+
+func maxRuneWidth(str string) int {
+ var width int
+
+ state := -1
+ for len(str) > 0 {
+ var w int
+ _, str, w, state = uniseg.FirstGraphemeClusterInString(str, state)
+ if w > width {
+ width = w
+ }
+ }
+
+ return width
+}
+
+func getFirstRuneAsString(str string) string {
+ if str == "" {
+ return str
+ }
+ r := []rune(str)
+ return string(r[0])
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/color.go b/vendor/github.com/charmbracelet/lipgloss/color.go
new file mode 100644
index 00000000..6caf3a3d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/color.go
@@ -0,0 +1,172 @@
+package lipgloss
+
+import (
+ "strconv"
+
+ "github.com/muesli/termenv"
+)
+
+// TerminalColor is a color intended to be rendered in the terminal.
+type TerminalColor interface {
+ color(*Renderer) termenv.Color
+ RGBA() (r, g, b, a uint32)
+}
+
+var noColor = NoColor{}
+
+// NoColor is used to specify the absence of color styling. When this is active
+// foreground colors will be rendered with the terminal's default text color,
+// and background colors will not be drawn at all.
+//
+// Example usage:
+//
+// var style = someStyle.Background(lipgloss.NoColor{})
+type NoColor struct{}
+
+func (NoColor) color(*Renderer) termenv.Color {
+ return termenv.NoColor{}
+}
+
+// RGBA returns the RGBA value of this color. Because we have to return
+// something, despite this color being the absence of color, we're returning
+// black with 100% opacity.
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+//
+// Deprecated.
+func (n NoColor) RGBA() (r, g, b, a uint32) {
+ return 0x0, 0x0, 0x0, 0xFFFF //nolint:mnd
+}
+
+// Color specifies a color by hex or ANSI value. For example:
+//
+// ansiColor := lipgloss.Color("21")
+// hexColor := lipgloss.Color("#0000ff")
+type Color string
+
+func (c Color) color(r *Renderer) termenv.Color {
+ return r.ColorProfile().Color(string(c))
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface. Note that on error we return black with 100% opacity, or:
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+//
+// Deprecated.
+func (c Color) RGBA() (r, g, b, a uint32) {
+ return termenv.ConvertToRGB(c.color(renderer)).RGBA()
+}
+
+// ANSIColor is a color specified by an ANSI color value. It's merely syntactic
+// sugar for the more general Color function. Invalid colors will render as
+// black.
+//
+// Example usage:
+//
+// // These two statements are equivalent.
+// colorA := lipgloss.ANSIColor(21)
+// colorB := lipgloss.Color("21")
+type ANSIColor uint
+
+func (ac ANSIColor) color(r *Renderer) termenv.Color {
+ return Color(strconv.FormatUint(uint64(ac), 10)).color(r)
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface. Note that on error we return black with 100% opacity, or:
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+//
+// Deprecated.
+func (ac ANSIColor) RGBA() (r, g, b, a uint32) {
+ cf := Color(strconv.FormatUint(uint64(ac), 10))
+ return cf.RGBA()
+}
+
+// AdaptiveColor provides color options for light and dark backgrounds. The
+// appropriate color will be returned at runtime based on the darkness of the
+// terminal background color.
+//
+// Example usage:
+//
+// color := lipgloss.AdaptiveColor{Light: "#0000ff", Dark: "#000099"}
+type AdaptiveColor struct {
+ Light string
+ Dark string
+}
+
+func (ac AdaptiveColor) color(r *Renderer) termenv.Color {
+ if r.HasDarkBackground() {
+ return Color(ac.Dark).color(r)
+ }
+ return Color(ac.Light).color(r)
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface. Note that on error we return black with 100% opacity, or:
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+//
+// Deprecated.
+func (ac AdaptiveColor) RGBA() (r, g, b, a uint32) {
+ return termenv.ConvertToRGB(ac.color(renderer)).RGBA()
+}
+
+// CompleteColor specifies exact values for truecolor, ANSI256, and ANSI color
+// profiles. Automatic color degradation will not be performed.
+type CompleteColor struct {
+ TrueColor string
+ ANSI256 string
+ ANSI string
+}
+
+func (c CompleteColor) color(r *Renderer) termenv.Color {
+ p := r.ColorProfile()
+ switch p { //nolint:exhaustive
+ case termenv.TrueColor:
+ return p.Color(c.TrueColor)
+ case termenv.ANSI256:
+ return p.Color(c.ANSI256)
+ case termenv.ANSI:
+ return p.Color(c.ANSI)
+ default:
+ return termenv.NoColor{}
+ }
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface. Note that on error we return black with 100% opacity, or:
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+// CompleteAdaptiveColor specifies exact values for truecolor, ANSI256, and ANSI color
+//
+// Deprecated.
+func (c CompleteColor) RGBA() (r, g, b, a uint32) {
+ return termenv.ConvertToRGB(c.color(renderer)).RGBA()
+}
+
+// CompleteAdaptiveColor specifies exact values for truecolor, ANSI256, and ANSI color
+// profiles, with separate options for light and dark backgrounds. Automatic
+// color degradation will not be performed.
+type CompleteAdaptiveColor struct {
+ Light CompleteColor
+ Dark CompleteColor
+}
+
+func (cac CompleteAdaptiveColor) color(r *Renderer) termenv.Color {
+ if r.HasDarkBackground() {
+ return cac.Dark.color(r)
+ }
+ return cac.Light.color(r)
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface. Note that on error we return black with 100% opacity, or:
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+//
+// Deprecated.
+func (cac CompleteAdaptiveColor) RGBA() (r, g, b, a uint32) {
+ return termenv.ConvertToRGB(cac.color(renderer)).RGBA()
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/get.go b/vendor/github.com/charmbracelet/lipgloss/get.go
new file mode 100644
index 00000000..422b4ce9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/get.go
@@ -0,0 +1,556 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// GetBold returns the style's bold value. If no value is set false is returned.
+func (s Style) GetBold() bool {
+ return s.getAsBool(boldKey, false)
+}
+
+// GetItalic returns the style's italic value. If no value is set false is
+// returned.
+func (s Style) GetItalic() bool {
+ return s.getAsBool(italicKey, false)
+}
+
+// GetUnderline returns the style's underline value. If no value is set false is
+// returned.
+func (s Style) GetUnderline() bool {
+ return s.getAsBool(underlineKey, false)
+}
+
+// GetStrikethrough returns the style's strikethrough value. If no value is set false
+// is returned.
+func (s Style) GetStrikethrough() bool {
+ return s.getAsBool(strikethroughKey, false)
+}
+
+// GetReverse returns the style's reverse value. If no value is set false is
+// returned.
+func (s Style) GetReverse() bool {
+ return s.getAsBool(reverseKey, false)
+}
+
+// GetBlink returns the style's blink value. If no value is set false is
+// returned.
+func (s Style) GetBlink() bool {
+ return s.getAsBool(blinkKey, false)
+}
+
+// GetFaint returns the style's faint value. If no value is set false is
+// returned.
+func (s Style) GetFaint() bool {
+ return s.getAsBool(faintKey, false)
+}
+
+// GetForeground returns the style's foreground color. If no value is set
+// NoColor{} is returned.
+func (s Style) GetForeground() TerminalColor {
+ return s.getAsColor(foregroundKey)
+}
+
+// GetBackground returns the style's background color. If no value is set
+// NoColor{} is returned.
+func (s Style) GetBackground() TerminalColor {
+ return s.getAsColor(backgroundKey)
+}
+
+// GetWidth returns the style's width setting. If no width is set 0 is
+// returned.
+func (s Style) GetWidth() int {
+ return s.getAsInt(widthKey)
+}
+
+// GetHeight returns the style's height setting. If no height is set 0 is
+// returned.
+func (s Style) GetHeight() int {
+ return s.getAsInt(heightKey)
+}
+
+// GetAlign returns the style's implicit horizontal alignment setting.
+// If no alignment is set Position.Left is returned.
+func (s Style) GetAlign() Position {
+ v := s.getAsPosition(alignHorizontalKey)
+ if v == Position(0) {
+ return Left
+ }
+ return v
+}
+
+// GetAlignHorizontal returns the style's implicit horizontal alignment setting.
+// If no alignment is set Position.Left is returned.
+func (s Style) GetAlignHorizontal() Position {
+ v := s.getAsPosition(alignHorizontalKey)
+ if v == Position(0) {
+ return Left
+ }
+ return v
+}
+
+// GetAlignVertical returns the style's implicit vertical alignment setting.
+// If no alignment is set Position.Top is returned.
+func (s Style) GetAlignVertical() Position {
+ v := s.getAsPosition(alignVerticalKey)
+ if v == Position(0) {
+ return Top
+ }
+ return v
+}
+
+// GetPadding returns the style's top, right, bottom, and left padding values,
+// in that order. 0 is returned for unset values.
+func (s Style) GetPadding() (top, right, bottom, left int) {
+ return s.getAsInt(paddingTopKey),
+ s.getAsInt(paddingRightKey),
+ s.getAsInt(paddingBottomKey),
+ s.getAsInt(paddingLeftKey)
+}
+
+// GetPaddingTop returns the style's top padding. If no value is set 0 is
+// returned.
+func (s Style) GetPaddingTop() int {
+ return s.getAsInt(paddingTopKey)
+}
+
+// GetPaddingRight returns the style's right padding. If no value is set 0 is
+// returned.
+func (s Style) GetPaddingRight() int {
+ return s.getAsInt(paddingRightKey)
+}
+
+// GetPaddingBottom returns the style's bottom padding. If no value is set 0 is
+// returned.
+func (s Style) GetPaddingBottom() int {
+ return s.getAsInt(paddingBottomKey)
+}
+
+// GetPaddingLeft returns the style's left padding. If no value is set 0 is
+// returned.
+func (s Style) GetPaddingLeft() int {
+ return s.getAsInt(paddingLeftKey)
+}
+
+// GetHorizontalPadding returns the style's left and right padding. Unset
+// values are measured as 0.
+func (s Style) GetHorizontalPadding() int {
+ return s.getAsInt(paddingLeftKey) + s.getAsInt(paddingRightKey)
+}
+
+// GetVerticalPadding returns the style's top and bottom padding. Unset values
+// are measured as 0.
+func (s Style) GetVerticalPadding() int {
+ return s.getAsInt(paddingTopKey) + s.getAsInt(paddingBottomKey)
+}
+
+// GetColorWhitespace returns the style's whitespace coloring setting. If no
+// value is set false is returned.
+func (s Style) GetColorWhitespace() bool {
+ return s.getAsBool(colorWhitespaceKey, false)
+}
+
+// GetMargin returns the style's top, right, bottom, and left margins, in that
+// order. 0 is returned for unset values.
+func (s Style) GetMargin() (top, right, bottom, left int) {
+ return s.getAsInt(marginTopKey),
+ s.getAsInt(marginRightKey),
+ s.getAsInt(marginBottomKey),
+ s.getAsInt(marginLeftKey)
+}
+
+// GetMarginTop returns the style's top margin. If no value is set 0 is
+// returned.
+func (s Style) GetMarginTop() int {
+ return s.getAsInt(marginTopKey)
+}
+
+// GetMarginRight returns the style's right margin. If no value is set 0 is
+// returned.
+func (s Style) GetMarginRight() int {
+ return s.getAsInt(marginRightKey)
+}
+
+// GetMarginBottom returns the style's bottom margin. If no value is set 0 is
+// returned.
+func (s Style) GetMarginBottom() int {
+ return s.getAsInt(marginBottomKey)
+}
+
+// GetMarginLeft returns the style's left margin. If no value is set 0 is
+// returned.
+func (s Style) GetMarginLeft() int {
+ return s.getAsInt(marginLeftKey)
+}
+
+// GetHorizontalMargins returns the style's left and right margins. Unset
+// values are measured as 0.
+func (s Style) GetHorizontalMargins() int {
+ return s.getAsInt(marginLeftKey) + s.getAsInt(marginRightKey)
+}
+
+// GetVerticalMargins returns the style's top and bottom margins. Unset values
+// are measured as 0.
+func (s Style) GetVerticalMargins() int {
+ return s.getAsInt(marginTopKey) + s.getAsInt(marginBottomKey)
+}
+
+// GetBorder returns the style's border style (type Border) and value for the
+// top, right, bottom, and left in that order. If no value is set for the
+// border style, Border{} is returned. For all other unset values false is
+// returned.
+func (s Style) GetBorder() (b Border, top, right, bottom, left bool) {
+ return s.getBorderStyle(),
+ s.getAsBool(borderTopKey, false),
+ s.getAsBool(borderRightKey, false),
+ s.getAsBool(borderBottomKey, false),
+ s.getAsBool(borderLeftKey, false)
+}
+
+// GetBorderStyle returns the style's border style (type Border). If no value
+// is set Border{} is returned.
+func (s Style) GetBorderStyle() Border {
+ return s.getBorderStyle()
+}
+
+// GetBorderTop returns the style's top border setting. If no value is set
+// false is returned.
+func (s Style) GetBorderTop() bool {
+ return s.getAsBool(borderTopKey, false)
+}
+
+// GetBorderRight returns the style's right border setting. If no value is set
+// false is returned.
+func (s Style) GetBorderRight() bool {
+ return s.getAsBool(borderRightKey, false)
+}
+
+// GetBorderBottom returns the style's bottom border setting. If no value is
+// set false is returned.
+func (s Style) GetBorderBottom() bool {
+ return s.getAsBool(borderBottomKey, false)
+}
+
+// GetBorderLeft returns the style's left border setting. If no value is
+// set false is returned.
+func (s Style) GetBorderLeft() bool {
+ return s.getAsBool(borderLeftKey, false)
+}
+
+// GetBorderTopForeground returns the style's border top foreground color. If
+// no value is set NoColor{} is returned.
+func (s Style) GetBorderTopForeground() TerminalColor {
+ return s.getAsColor(borderTopForegroundKey)
+}
+
+// GetBorderRightForeground returns the style's border right foreground color.
+// If no value is set NoColor{} is returned.
+func (s Style) GetBorderRightForeground() TerminalColor {
+ return s.getAsColor(borderRightForegroundKey)
+}
+
+// GetBorderBottomForeground returns the style's border bottom foreground
+// color. If no value is set NoColor{} is returned.
+func (s Style) GetBorderBottomForeground() TerminalColor {
+ return s.getAsColor(borderBottomForegroundKey)
+}
+
+// GetBorderLeftForeground returns the style's border left foreground
+// color. If no value is set NoColor{} is returned.
+func (s Style) GetBorderLeftForeground() TerminalColor {
+ return s.getAsColor(borderLeftForegroundKey)
+}
+
+// GetBorderTopBackground returns the style's border top background color. If
+// no value is set NoColor{} is returned.
+func (s Style) GetBorderTopBackground() TerminalColor {
+ return s.getAsColor(borderTopBackgroundKey)
+}
+
+// GetBorderRightBackground returns the style's border right background color.
+// If no value is set NoColor{} is returned.
+func (s Style) GetBorderRightBackground() TerminalColor {
+ return s.getAsColor(borderRightBackgroundKey)
+}
+
+// GetBorderBottomBackground returns the style's border bottom background
+// color. If no value is set NoColor{} is returned.
+func (s Style) GetBorderBottomBackground() TerminalColor {
+ return s.getAsColor(borderBottomBackgroundKey)
+}
+
+// GetBorderLeftBackground returns the style's border left background
+// color. If no value is set NoColor{} is returned.
+func (s Style) GetBorderLeftBackground() TerminalColor {
+ return s.getAsColor(borderLeftBackgroundKey)
+}
+
+// GetBorderTopWidth returns the width of the top border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the top edge, 0 is returned.
+//
+// Deprecated: This function simply calls Style.GetBorderTopSize.
+func (s Style) GetBorderTopWidth() int {
+ return s.GetBorderTopSize()
+}
+
+// GetBorderTopSize returns the width of the top border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the top edge, 0 is returned.
+func (s Style) GetBorderTopSize() int {
+ if !s.getAsBool(borderTopKey, false) && !s.implicitBorders() {
+ return 0
+ }
+ return s.getBorderStyle().GetTopSize()
+}
+
+// GetBorderLeftSize returns the width of the left border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the left edge, 0 is returned.
+func (s Style) GetBorderLeftSize() int {
+ if !s.getAsBool(borderLeftKey, false) && !s.implicitBorders() {
+ return 0
+ }
+ return s.getBorderStyle().GetLeftSize()
+}
+
+// GetBorderBottomSize returns the width of the bottom border. If borders
+// contain runes of varying widths, the widest rune is returned. If no border
+// exists on the left edge, 0 is returned.
+func (s Style) GetBorderBottomSize() int {
+ if !s.getAsBool(borderBottomKey, false) && !s.implicitBorders() {
+ return 0
+ }
+ return s.getBorderStyle().GetBottomSize()
+}
+
+// GetBorderRightSize returns the width of the right border. If borders
+// contain runes of varying widths, the widest rune is returned. If no border
+// exists on the right edge, 0 is returned.
+func (s Style) GetBorderRightSize() int {
+ if !s.getAsBool(borderRightKey, false) && !s.implicitBorders() {
+ return 0
+ }
+ return s.getBorderStyle().GetRightSize()
+}
+
+// GetHorizontalBorderSize returns the width of the horizontal borders. If
+// borders contain runes of varying widths, the widest rune is returned. If no
+// border exists on the horizontal edges, 0 is returned.
+func (s Style) GetHorizontalBorderSize() int {
+ return s.GetBorderLeftSize() + s.GetBorderRightSize()
+}
+
+// GetVerticalBorderSize returns the width of the vertical borders. If
+// borders contain runes of varying widths, the widest rune is returned. If no
+// border exists on the vertical edges, 0 is returned.
+func (s Style) GetVerticalBorderSize() int {
+ return s.GetBorderTopSize() + s.GetBorderBottomSize()
+}
+
+// GetInline returns the style's inline setting. If no value is set false is
+// returned.
+func (s Style) GetInline() bool {
+ return s.getAsBool(inlineKey, false)
+}
+
+// GetMaxWidth returns the style's max width setting. If no value is set 0 is
+// returned.
+func (s Style) GetMaxWidth() int {
+ return s.getAsInt(maxWidthKey)
+}
+
+// GetMaxHeight returns the style's max height setting. If no value is set 0 is
+// returned.
+func (s Style) GetMaxHeight() int {
+ return s.getAsInt(maxHeightKey)
+}
+
+// GetTabWidth returns the style's tab width setting. If no value is set 4 is
+// returned which is the implicit default.
+func (s Style) GetTabWidth() int {
+ return s.getAsInt(tabWidthKey)
+}
+
+// GetUnderlineSpaces returns whether or not the style is set to underline
+// spaces. If not value is set false is returned.
+func (s Style) GetUnderlineSpaces() bool {
+ return s.getAsBool(underlineSpacesKey, false)
+}
+
+// GetStrikethroughSpaces returns whether or not the style is set to strikethrough
+// spaces. If not value is set false is returned.
+func (s Style) GetStrikethroughSpaces() bool {
+ return s.getAsBool(strikethroughSpacesKey, false)
+}
+
+// GetHorizontalFrameSize returns the sum of the style's horizontal margins, padding
+// and border widths.
+//
+// Provisional: this method may be renamed.
+func (s Style) GetHorizontalFrameSize() int {
+ return s.GetHorizontalMargins() + s.GetHorizontalPadding() + s.GetHorizontalBorderSize()
+}
+
+// GetVerticalFrameSize returns the sum of the style's vertical margins, padding
+// and border widths.
+//
+// Provisional: this method may be renamed.
+func (s Style) GetVerticalFrameSize() int {
+ return s.GetVerticalMargins() + s.GetVerticalPadding() + s.GetVerticalBorderSize()
+}
+
+// GetFrameSize returns the sum of the margins, padding and border width for
+// both the horizontal and vertical margins.
+func (s Style) GetFrameSize() (x, y int) {
+ return s.GetHorizontalFrameSize(), s.GetVerticalFrameSize()
+}
+
+// GetTransform returns the transform set on the style. If no transform is set
+// nil is returned.
+func (s Style) GetTransform() func(string) string {
+ return s.getAsTransform(transformKey)
+}
+
+// Returns whether or not the given property is set.
+func (s Style) isSet(k propKey) bool {
+ return s.props.has(k)
+}
+
+func (s Style) getAsBool(k propKey, defaultVal bool) bool {
+ if !s.isSet(k) {
+ return defaultVal
+ }
+ return s.attrs&int(k) != 0
+}
+
+func (s Style) getAsColor(k propKey) TerminalColor {
+ if !s.isSet(k) {
+ return noColor
+ }
+
+ var c TerminalColor
+ switch k { //nolint:exhaustive
+ case foregroundKey:
+ c = s.fgColor
+ case backgroundKey:
+ c = s.bgColor
+ case marginBackgroundKey:
+ c = s.marginBgColor
+ case borderTopForegroundKey:
+ c = s.borderTopFgColor
+ case borderRightForegroundKey:
+ c = s.borderRightFgColor
+ case borderBottomForegroundKey:
+ c = s.borderBottomFgColor
+ case borderLeftForegroundKey:
+ c = s.borderLeftFgColor
+ case borderTopBackgroundKey:
+ c = s.borderTopBgColor
+ case borderRightBackgroundKey:
+ c = s.borderRightBgColor
+ case borderBottomBackgroundKey:
+ c = s.borderBottomBgColor
+ case borderLeftBackgroundKey:
+ c = s.borderLeftBgColor
+ }
+
+ if c != nil {
+ return c
+ }
+
+ return noColor
+}
+
+func (s Style) getAsInt(k propKey) int {
+ if !s.isSet(k) {
+ return 0
+ }
+ switch k { //nolint:exhaustive
+ case widthKey:
+ return s.width
+ case heightKey:
+ return s.height
+ case paddingTopKey:
+ return s.paddingTop
+ case paddingRightKey:
+ return s.paddingRight
+ case paddingBottomKey:
+ return s.paddingBottom
+ case paddingLeftKey:
+ return s.paddingLeft
+ case marginTopKey:
+ return s.marginTop
+ case marginRightKey:
+ return s.marginRight
+ case marginBottomKey:
+ return s.marginBottom
+ case marginLeftKey:
+ return s.marginLeft
+ case maxWidthKey:
+ return s.maxWidth
+ case maxHeightKey:
+ return s.maxHeight
+ case tabWidthKey:
+ return s.tabWidth
+ }
+ return 0
+}
+
+func (s Style) getAsPosition(k propKey) Position {
+ if !s.isSet(k) {
+ return Position(0)
+ }
+ switch k { //nolint:exhaustive
+ case alignHorizontalKey:
+ return s.alignHorizontal
+ case alignVerticalKey:
+ return s.alignVertical
+ }
+ return Position(0)
+}
+
+func (s Style) getBorderStyle() Border {
+ if !s.isSet(borderStyleKey) {
+ return noBorder
+ }
+ return s.borderStyle
+}
+
+// Returns whether or not the style has implicit borders. This happens when
+// a border style has been set but no border sides have been explicitly turned
+// on or off.
+func (s Style) implicitBorders() bool {
+ var (
+ borderStyle = s.getBorderStyle()
+ topSet = s.isSet(borderTopKey)
+ rightSet = s.isSet(borderRightKey)
+ bottomSet = s.isSet(borderBottomKey)
+ leftSet = s.isSet(borderLeftKey)
+ )
+ return borderStyle != noBorder && !(topSet || rightSet || bottomSet || leftSet)
+}
+
+func (s Style) getAsTransform(propKey) func(string) string {
+ if !s.isSet(transformKey) {
+ return nil
+ }
+ return s.transform
+}
+
+// Split a string into lines, additionally returning the size of the widest
+// line.
+func getLines(s string) (lines []string, widest int) {
+ lines = strings.Split(s, "\n")
+
+ for _, l := range lines {
+ w := ansi.StringWidth(l)
+ if widest < w {
+ widest = w
+ }
+ }
+
+ return lines, widest
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/join.go b/vendor/github.com/charmbracelet/lipgloss/join.go
new file mode 100644
index 00000000..b0a23a54
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/join.go
@@ -0,0 +1,175 @@
+package lipgloss
+
+import (
+ "math"
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// JoinHorizontal is a utility function for horizontally joining two
+// potentially multi-lined strings along a vertical axis. The first argument is
+// the position, with 0 being all the way at the top and 1 being all the way
+// at the bottom.
+//
+// If you just want to align to the top, center or bottom you may as well just
+// use the helper constants Top, Center, and Bottom.
+//
+// Example:
+//
+// blockB := "...\n...\n..."
+// blockA := "...\n...\n...\n...\n..."
+//
+// // Join 20% from the top
+// str := lipgloss.JoinHorizontal(0.2, blockA, blockB)
+//
+// // Join on the top edge
+// str := lipgloss.JoinHorizontal(lipgloss.Top, blockA, blockB)
+func JoinHorizontal(pos Position, strs ...string) string {
+ if len(strs) == 0 {
+ return ""
+ }
+ if len(strs) == 1 {
+ return strs[0]
+ }
+
+ var (
+ // Groups of strings broken into multiple lines
+ blocks = make([][]string, len(strs))
+
+ // Max line widths for the above text blocks
+ maxWidths = make([]int, len(strs))
+
+ // Height of the tallest block
+ maxHeight int
+ )
+
+ // Break text blocks into lines and get max widths for each text block
+ for i, str := range strs {
+ blocks[i], maxWidths[i] = getLines(str)
+ if len(blocks[i]) > maxHeight {
+ maxHeight = len(blocks[i])
+ }
+ }
+
+ // Add extra lines to make each side the same height
+ for i := range blocks {
+ if len(blocks[i]) >= maxHeight {
+ continue
+ }
+
+ extraLines := make([]string, maxHeight-len(blocks[i]))
+
+ switch pos { //nolint:exhaustive
+ case Top:
+ blocks[i] = append(blocks[i], extraLines...)
+
+ case Bottom:
+ blocks[i] = append(extraLines, blocks[i]...)
+
+ default: // Somewhere in the middle
+ n := len(extraLines)
+ split := int(math.Round(float64(n) * pos.value()))
+ top := n - split
+ bottom := n - top
+
+ blocks[i] = append(extraLines[top:], blocks[i]...)
+ blocks[i] = append(blocks[i], extraLines[bottom:]...)
+ }
+ }
+
+ // Merge lines
+ var b strings.Builder
+ for i := range blocks[0] { // remember, all blocks have the same number of members now
+ for j, block := range blocks {
+ b.WriteString(block[i])
+
+ // Also make lines the same length
+ b.WriteString(strings.Repeat(" ", maxWidths[j]-ansi.StringWidth(block[i])))
+ }
+ if i < len(blocks[0])-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ return b.String()
+}
+
+// JoinVertical is a utility function for vertically joining two potentially
+// multi-lined strings along a horizontal axis. The first argument is the
+// position, with 0 being all the way to the left and 1 being all the way to
+// the right.
+//
+// If you just want to align to the left, right or center you may as well just
+// use the helper constants Left, Center, and Right.
+//
+// Example:
+//
+// blockB := "...\n...\n..."
+// blockA := "...\n...\n...\n...\n..."
+//
+// // Join 20% from the top
+// str := lipgloss.JoinVertical(0.2, blockA, blockB)
+//
+// // Join on the right edge
+// str := lipgloss.JoinVertical(lipgloss.Right, blockA, blockB)
+func JoinVertical(pos Position, strs ...string) string {
+ if len(strs) == 0 {
+ return ""
+ }
+ if len(strs) == 1 {
+ return strs[0]
+ }
+
+ var (
+ blocks = make([][]string, len(strs))
+ maxWidth int
+ )
+
+ for i := range strs {
+ var w int
+ blocks[i], w = getLines(strs[i])
+ if w > maxWidth {
+ maxWidth = w
+ }
+ }
+
+ var b strings.Builder
+ for i, block := range blocks {
+ for j, line := range block {
+ w := maxWidth - ansi.StringWidth(line)
+
+ switch pos { //nolint:exhaustive
+ case Left:
+ b.WriteString(line)
+ b.WriteString(strings.Repeat(" ", w))
+
+ case Right:
+ b.WriteString(strings.Repeat(" ", w))
+ b.WriteString(line)
+
+ default: // Somewhere in the middle
+ if w < 1 {
+ b.WriteString(line)
+ break
+ }
+
+ split := int(math.Round(float64(w) * pos.value()))
+ right := w - split
+ left := w - right
+
+ b.WriteString(strings.Repeat(" ", left))
+ b.WriteString(line)
+ b.WriteString(strings.Repeat(" ", right))
+ }
+
+ // Write a newline as long as we're not on the last line of the
+ // last block.
+ if !(i == len(blocks)-1 && j == len(block)-1) {
+ b.WriteRune('\n')
+ }
+ }
+ }
+
+ return b.String()
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/position.go b/vendor/github.com/charmbracelet/lipgloss/position.go
new file mode 100644
index 00000000..185f5af3
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/position.go
@@ -0,0 +1,154 @@
+package lipgloss
+
+import (
+ "math"
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// Position represents a position along a horizontal or vertical axis. It's in
+// situations where an axis is involved, like alignment, joining, placement and
+// so on.
+//
+// A value of 0 represents the start (the left or top) and 1 represents the end
+// (the right or bottom). 0.5 represents the center.
+//
+// There are constants Top, Bottom, Center, Left and Right in this package that
+// can be used to aid readability.
+type Position float64
+
+func (p Position) value() float64 {
+ return math.Min(1, math.Max(0, float64(p)))
+}
+
+// Position aliases.
+const (
+ Top Position = 0.0
+ Bottom Position = 1.0
+ Center Position = 0.5
+ Left Position = 0.0
+ Right Position = 1.0
+)
+
+// Place places a string or text block vertically in an unstyled box of a given
+// width or height.
+func Place(width, height int, hPos, vPos Position, str string, opts ...WhitespaceOption) string {
+ return renderer.Place(width, height, hPos, vPos, str, opts...)
+}
+
+// Place places a string or text block vertically in an unstyled box of a given
+// width or height.
+func (r *Renderer) Place(width, height int, hPos, vPos Position, str string, opts ...WhitespaceOption) string {
+ return r.PlaceVertical(height, vPos, r.PlaceHorizontal(width, hPos, str, opts...), opts...)
+}
+
+// PlaceHorizontal places a string or text block horizontally in an unstyled
+// block of a given width. If the given width is shorter than the max width of
+// the string (measured by its longest line) this will be a noop.
+func PlaceHorizontal(width int, pos Position, str string, opts ...WhitespaceOption) string {
+ return renderer.PlaceHorizontal(width, pos, str, opts...)
+}
+
+// PlaceHorizontal places a string or text block horizontally in an unstyled
+// block of a given width. If the given width is shorter than the max width of
+// the string (measured by its longest line) this will be a noöp.
+func (r *Renderer) PlaceHorizontal(width int, pos Position, str string, opts ...WhitespaceOption) string {
+ lines, contentWidth := getLines(str)
+ gap := width - contentWidth
+
+ if gap <= 0 {
+ return str
+ }
+
+ ws := newWhitespace(r, opts...)
+
+ var b strings.Builder
+ for i, l := range lines {
+ // Is this line shorter than the longest line?
+ short := max(0, contentWidth-ansi.StringWidth(l))
+
+ switch pos { //nolint:exhaustive
+ case Left:
+ b.WriteString(l)
+ b.WriteString(ws.render(gap + short))
+
+ case Right:
+ b.WriteString(ws.render(gap + short))
+ b.WriteString(l)
+
+ default: // somewhere in the middle
+ totalGap := gap + short
+
+ split := int(math.Round(float64(totalGap) * pos.value()))
+ left := totalGap - split
+ right := totalGap - left
+
+ b.WriteString(ws.render(left))
+ b.WriteString(l)
+ b.WriteString(ws.render(right))
+ }
+
+ if i < len(lines)-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ return b.String()
+}
+
+// PlaceVertical places a string or text block vertically in an unstyled block
+// of a given height. If the given height is shorter than the height of the
+// string (measured by its newlines) then this will be a noop.
+func PlaceVertical(height int, pos Position, str string, opts ...WhitespaceOption) string {
+ return renderer.PlaceVertical(height, pos, str, opts...)
+}
+
+// PlaceVertical places a string or text block vertically in an unstyled block
+// of a given height. If the given height is shorter than the height of the
+// string (measured by its newlines) then this will be a noöp.
+func (r *Renderer) PlaceVertical(height int, pos Position, str string, opts ...WhitespaceOption) string {
+ contentHeight := strings.Count(str, "\n") + 1
+ gap := height - contentHeight
+
+ if gap <= 0 {
+ return str
+ }
+
+ ws := newWhitespace(r, opts...)
+
+ _, width := getLines(str)
+ emptyLine := ws.render(width)
+ b := strings.Builder{}
+
+ switch pos { //nolint:exhaustive
+ case Top:
+ b.WriteString(str)
+ b.WriteRune('\n')
+ for i := 0; i < gap; i++ {
+ b.WriteString(emptyLine)
+ if i < gap-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ case Bottom:
+ b.WriteString(strings.Repeat(emptyLine+"\n", gap))
+ b.WriteString(str)
+
+ default: // Somewhere in the middle
+ split := int(math.Round(float64(gap) * pos.value()))
+ top := gap - split
+ bottom := gap - top
+
+ b.WriteString(strings.Repeat(emptyLine+"\n", top))
+ b.WriteString(str)
+
+ for i := 0; i < bottom; i++ {
+ b.WriteRune('\n')
+ b.WriteString(emptyLine)
+ }
+ }
+
+ return b.String()
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/ranges.go b/vendor/github.com/charmbracelet/lipgloss/ranges.go
new file mode 100644
index 00000000..d1716998
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/ranges.go
@@ -0,0 +1,48 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// StyleRanges allows to, given a string, style ranges of it differently.
+// The function will take into account existing styles.
+// Ranges should not overlap.
+func StyleRanges(s string, ranges ...Range) string {
+ if len(ranges) == 0 {
+ return s
+ }
+
+ var buf strings.Builder
+ lastIdx := 0
+ stripped := ansi.Strip(s)
+
+ // Use Truncate and TruncateLeft to style match.MatchedIndexes without
+ // losing the original option style:
+ for _, rng := range ranges {
+ // Add the text before this match
+ if rng.Start > lastIdx {
+ buf.WriteString(ansi.Cut(s, lastIdx, rng.Start))
+ }
+ // Add the matched range with its highlight
+ buf.WriteString(rng.Style.Render(ansi.Cut(stripped, rng.Start, rng.End)))
+ lastIdx = rng.End
+ }
+
+ // Add any remaining text after the last match
+ buf.WriteString(ansi.TruncateLeft(s, lastIdx, ""))
+
+ return buf.String()
+}
+
+// NewRange returns a range that can be used with [StyleRanges].
+func NewRange(start, end int, style Style) Range {
+ return Range{start, end, style}
+}
+
+// Range to be used with [StyleRanges].
+type Range struct {
+ Start, End int
+ Style Style
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/renderer.go b/vendor/github.com/charmbracelet/lipgloss/renderer.go
new file mode 100644
index 00000000..233aa7c0
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/renderer.go
@@ -0,0 +1,181 @@
+package lipgloss
+
+import (
+ "io"
+ "sync"
+
+ "github.com/muesli/termenv"
+)
+
+// We're manually creating the struct here to avoid initializing the output and
+// query the terminal multiple times.
+var renderer = &Renderer{
+ output: termenv.DefaultOutput(),
+}
+
+// Renderer is a lipgloss terminal renderer.
+type Renderer struct {
+ output *termenv.Output
+ colorProfile termenv.Profile
+ hasDarkBackground bool
+
+ getColorProfile sync.Once
+ explicitColorProfile bool
+
+ getBackgroundColor sync.Once
+ explicitBackgroundColor bool
+
+ mtx sync.RWMutex
+}
+
+// DefaultRenderer returns the default renderer.
+func DefaultRenderer() *Renderer {
+ return renderer
+}
+
+// SetDefaultRenderer sets the default global renderer.
+func SetDefaultRenderer(r *Renderer) {
+ renderer = r
+}
+
+// NewRenderer creates a new Renderer.
+//
+// w will be used to determine the terminal's color capabilities.
+func NewRenderer(w io.Writer, opts ...termenv.OutputOption) *Renderer {
+ r := &Renderer{
+ output: termenv.NewOutput(w, opts...),
+ }
+ return r
+}
+
+// Output returns the termenv output.
+func (r *Renderer) Output() *termenv.Output {
+ r.mtx.RLock()
+ defer r.mtx.RUnlock()
+ return r.output
+}
+
+// SetOutput sets the termenv output.
+func (r *Renderer) SetOutput(o *termenv.Output) {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+ r.output = o
+}
+
+// ColorProfile returns the detected termenv color profile.
+func (r *Renderer) ColorProfile() termenv.Profile {
+ r.mtx.RLock()
+ defer r.mtx.RUnlock()
+
+ if !r.explicitColorProfile {
+ r.getColorProfile.Do(func() {
+ // NOTE: we don't need to lock here because sync.Once provides its
+ // own locking mechanism.
+ r.colorProfile = r.output.EnvColorProfile()
+ })
+ }
+
+ return r.colorProfile
+}
+
+// ColorProfile returns the detected termenv color profile.
+func ColorProfile() termenv.Profile {
+ return renderer.ColorProfile()
+}
+
+// SetColorProfile sets the color profile on the renderer. This function exists
+// mostly for testing purposes so that you can assure you're testing against
+// a specific profile.
+//
+// Outside of testing you likely won't want to use this function as the color
+// profile will detect and cache the terminal's color capabilities and choose
+// the best available profile.
+//
+// Available color profiles are:
+//
+// termenv.Ascii // no color, 1-bit
+// termenv.ANSI //16 colors, 4-bit
+// termenv.ANSI256 // 256 colors, 8-bit
+// termenv.TrueColor // 16,777,216 colors, 24-bit
+//
+// This function is thread-safe.
+func (r *Renderer) SetColorProfile(p termenv.Profile) {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.colorProfile = p
+ r.explicitColorProfile = true
+}
+
+// SetColorProfile sets the color profile on the default renderer. This
+// function exists mostly for testing purposes so that you can assure you're
+// testing against a specific profile.
+//
+// Outside of testing you likely won't want to use this function as the color
+// profile will detect and cache the terminal's color capabilities and choose
+// the best available profile.
+//
+// Available color profiles are:
+//
+// termenv.Ascii // no color, 1-bit
+// termenv.ANSI //16 colors, 4-bit
+// termenv.ANSI256 // 256 colors, 8-bit
+// termenv.TrueColor // 16,777,216 colors, 24-bit
+//
+// This function is thread-safe.
+func SetColorProfile(p termenv.Profile) {
+ renderer.SetColorProfile(p)
+}
+
+// HasDarkBackground returns whether or not the terminal has a dark background.
+func HasDarkBackground() bool {
+ return renderer.HasDarkBackground()
+}
+
+// HasDarkBackground returns whether or not the renderer will render to a dark
+// background. A dark background can either be auto-detected, or set explicitly
+// on the renderer.
+func (r *Renderer) HasDarkBackground() bool {
+ r.mtx.RLock()
+ defer r.mtx.RUnlock()
+
+ if !r.explicitBackgroundColor {
+ r.getBackgroundColor.Do(func() {
+ // NOTE: we don't need to lock here because sync.Once provides its
+ // own locking mechanism.
+ r.hasDarkBackground = r.output.HasDarkBackground()
+ })
+ }
+
+ return r.hasDarkBackground
+}
+
+// SetHasDarkBackground sets the background color detection value for the
+// default renderer. This function exists mostly for testing purposes so that
+// you can assure you're testing against a specific background color setting.
+//
+// Outside of testing you likely won't want to use this function as the
+// backgrounds value will be automatically detected and cached against the
+// terminal's current background color setting.
+//
+// This function is thread-safe.
+func SetHasDarkBackground(b bool) {
+ renderer.SetHasDarkBackground(b)
+}
+
+// SetHasDarkBackground sets the background color detection value on the
+// renderer. This function exists mostly for testing purposes so that you can
+// assure you're testing against a specific background color setting.
+//
+// Outside of testing you likely won't want to use this function as the
+// backgrounds value will be automatically detected and cached against the
+// terminal's current background color setting.
+//
+// This function is thread-safe.
+func (r *Renderer) SetHasDarkBackground(b bool) {
+ r.mtx.Lock()
+ defer r.mtx.Unlock()
+
+ r.hasDarkBackground = b
+ r.explicitBackgroundColor = true
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/runes.go b/vendor/github.com/charmbracelet/lipgloss/runes.go
new file mode 100644
index 00000000..7a49e326
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/runes.go
@@ -0,0 +1,43 @@
+package lipgloss
+
+import (
+ "strings"
+)
+
+// StyleRunes apply a given style to runes at the given indices in the string.
+// Note that you must provide styling options for both matched and unmatched
+// runes. Indices out of bounds will be ignored.
+func StyleRunes(str string, indices []int, matched, unmatched Style) string {
+ // Convert slice of indices to a map for easier lookups
+ m := make(map[int]struct{})
+ for _, i := range indices {
+ m[i] = struct{}{}
+ }
+
+ var (
+ out strings.Builder
+ group strings.Builder
+ style Style
+ runes = []rune(str)
+ )
+
+ for i, r := range runes {
+ group.WriteRune(r)
+
+ _, matches := m[i]
+ _, nextMatches := m[i+1]
+
+ if matches != nextMatches || i == len(runes)-1 {
+ // Flush
+ if matches {
+ style = matched
+ } else {
+ style = unmatched
+ }
+ out.WriteString(style.Render(group.String()))
+ group.Reset()
+ }
+ }
+
+ return out.String()
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/set.go b/vendor/github.com/charmbracelet/lipgloss/set.go
new file mode 100644
index 00000000..fde38fae
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/set.go
@@ -0,0 +1,799 @@
+package lipgloss
+
+// Set a value on the underlying rules map.
+func (s *Style) set(key propKey, value interface{}) {
+ // We don't allow negative integers on any of our other values, so just keep
+ // them at zero or above. We could use uints instead, but the
+ // conversions are a little tedious, so we're sticking with ints for
+ // sake of usability.
+ switch key { //nolint:exhaustive
+ case foregroundKey:
+ s.fgColor = colorOrNil(value)
+ case backgroundKey:
+ s.bgColor = colorOrNil(value)
+ case widthKey:
+ s.width = max(0, value.(int))
+ case heightKey:
+ s.height = max(0, value.(int))
+ case alignHorizontalKey:
+ s.alignHorizontal = value.(Position)
+ case alignVerticalKey:
+ s.alignVertical = value.(Position)
+ case paddingTopKey:
+ s.paddingTop = max(0, value.(int))
+ case paddingRightKey:
+ s.paddingRight = max(0, value.(int))
+ case paddingBottomKey:
+ s.paddingBottom = max(0, value.(int))
+ case paddingLeftKey:
+ s.paddingLeft = max(0, value.(int))
+ case marginTopKey:
+ s.marginTop = max(0, value.(int))
+ case marginRightKey:
+ s.marginRight = max(0, value.(int))
+ case marginBottomKey:
+ s.marginBottom = max(0, value.(int))
+ case marginLeftKey:
+ s.marginLeft = max(0, value.(int))
+ case marginBackgroundKey:
+ s.marginBgColor = colorOrNil(value)
+ case borderStyleKey:
+ s.borderStyle = value.(Border)
+ case borderTopForegroundKey:
+ s.borderTopFgColor = colorOrNil(value)
+ case borderRightForegroundKey:
+ s.borderRightFgColor = colorOrNil(value)
+ case borderBottomForegroundKey:
+ s.borderBottomFgColor = colorOrNil(value)
+ case borderLeftForegroundKey:
+ s.borderLeftFgColor = colorOrNil(value)
+ case borderTopBackgroundKey:
+ s.borderTopBgColor = colorOrNil(value)
+ case borderRightBackgroundKey:
+ s.borderRightBgColor = colorOrNil(value)
+ case borderBottomBackgroundKey:
+ s.borderBottomBgColor = colorOrNil(value)
+ case borderLeftBackgroundKey:
+ s.borderLeftBgColor = colorOrNil(value)
+ case maxWidthKey:
+ s.maxWidth = max(0, value.(int))
+ case maxHeightKey:
+ s.maxHeight = max(0, value.(int))
+ case tabWidthKey:
+ // TabWidth is the only property that may have a negative value (and
+ // that negative value can be no less than -1).
+ s.tabWidth = value.(int)
+ case transformKey:
+ s.transform = value.(func(string) string)
+ default:
+ if v, ok := value.(bool); ok { //nolint:nestif
+ if v {
+ s.attrs |= int(key)
+ } else {
+ s.attrs &^= int(key)
+ }
+ } else if attrs, ok := value.(int); ok {
+ // bool attrs
+ if attrs&int(key) != 0 {
+ s.attrs |= int(key)
+ } else {
+ s.attrs &^= int(key)
+ }
+ }
+ }
+
+ // Set the prop on
+ s.props = s.props.set(key)
+}
+
+// setFrom sets the property from another style.
+func (s *Style) setFrom(key propKey, i Style) {
+ switch key { //nolint:exhaustive
+ case foregroundKey:
+ s.set(foregroundKey, i.fgColor)
+ case backgroundKey:
+ s.set(backgroundKey, i.bgColor)
+ case widthKey:
+ s.set(widthKey, i.width)
+ case heightKey:
+ s.set(heightKey, i.height)
+ case alignHorizontalKey:
+ s.set(alignHorizontalKey, i.alignHorizontal)
+ case alignVerticalKey:
+ s.set(alignVerticalKey, i.alignVertical)
+ case paddingTopKey:
+ s.set(paddingTopKey, i.paddingTop)
+ case paddingRightKey:
+ s.set(paddingRightKey, i.paddingRight)
+ case paddingBottomKey:
+ s.set(paddingBottomKey, i.paddingBottom)
+ case paddingLeftKey:
+ s.set(paddingLeftKey, i.paddingLeft)
+ case marginTopKey:
+ s.set(marginTopKey, i.marginTop)
+ case marginRightKey:
+ s.set(marginRightKey, i.marginRight)
+ case marginBottomKey:
+ s.set(marginBottomKey, i.marginBottom)
+ case marginLeftKey:
+ s.set(marginLeftKey, i.marginLeft)
+ case marginBackgroundKey:
+ s.set(marginBackgroundKey, i.marginBgColor)
+ case borderStyleKey:
+ s.set(borderStyleKey, i.borderStyle)
+ case borderTopForegroundKey:
+ s.set(borderTopForegroundKey, i.borderTopFgColor)
+ case borderRightForegroundKey:
+ s.set(borderRightForegroundKey, i.borderRightFgColor)
+ case borderBottomForegroundKey:
+ s.set(borderBottomForegroundKey, i.borderBottomFgColor)
+ case borderLeftForegroundKey:
+ s.set(borderLeftForegroundKey, i.borderLeftFgColor)
+ case borderTopBackgroundKey:
+ s.set(borderTopBackgroundKey, i.borderTopBgColor)
+ case borderRightBackgroundKey:
+ s.set(borderRightBackgroundKey, i.borderRightBgColor)
+ case borderBottomBackgroundKey:
+ s.set(borderBottomBackgroundKey, i.borderBottomBgColor)
+ case borderLeftBackgroundKey:
+ s.set(borderLeftBackgroundKey, i.borderLeftBgColor)
+ case maxWidthKey:
+ s.set(maxWidthKey, i.maxWidth)
+ case maxHeightKey:
+ s.set(maxHeightKey, i.maxHeight)
+ case tabWidthKey:
+ s.set(tabWidthKey, i.tabWidth)
+ case transformKey:
+ s.set(transformKey, i.transform)
+ default:
+ // Set attributes for set bool properties
+ s.set(key, i.attrs)
+ }
+}
+
+func colorOrNil(c interface{}) TerminalColor {
+ if c, ok := c.(TerminalColor); ok {
+ return c
+ }
+ return nil
+}
+
+// Bold sets a bold formatting rule.
+func (s Style) Bold(v bool) Style {
+ s.set(boldKey, v)
+ return s
+}
+
+// Italic sets an italic formatting rule. In some terminal emulators this will
+// render with "reverse" coloring if not italic font variant is available.
+func (s Style) Italic(v bool) Style {
+ s.set(italicKey, v)
+ return s
+}
+
+// Underline sets an underline rule. By default, underlines will not be drawn on
+// whitespace like margins and padding. To change this behavior set
+// UnderlineSpaces.
+func (s Style) Underline(v bool) Style {
+ s.set(underlineKey, v)
+ return s
+}
+
+// Strikethrough sets a strikethrough rule. By default, strikes will not be
+// drawn on whitespace like margins and padding. To change this behavior set
+// StrikethroughSpaces.
+func (s Style) Strikethrough(v bool) Style {
+ s.set(strikethroughKey, v)
+ return s
+}
+
+// Reverse sets a rule for inverting foreground and background colors.
+func (s Style) Reverse(v bool) Style {
+ s.set(reverseKey, v)
+ return s
+}
+
+// Blink sets a rule for blinking foreground text.
+func (s Style) Blink(v bool) Style {
+ s.set(blinkKey, v)
+ return s
+}
+
+// Faint sets a rule for rendering the foreground color in a dimmer shade.
+func (s Style) Faint(v bool) Style {
+ s.set(faintKey, v)
+ return s
+}
+
+// Foreground sets a foreground color.
+//
+// // Sets the foreground to blue
+// s := lipgloss.NewStyle().Foreground(lipgloss.Color("#0000ff"))
+//
+// // Removes the foreground color
+// s.Foreground(lipgloss.NoColor)
+func (s Style) Foreground(c TerminalColor) Style {
+ s.set(foregroundKey, c)
+ return s
+}
+
+// Background sets a background color.
+func (s Style) Background(c TerminalColor) Style {
+ s.set(backgroundKey, c)
+ return s
+}
+
+// Width sets the width of the block before applying margins. The width, if
+// set, also determines where text will wrap.
+func (s Style) Width(i int) Style {
+ s.set(widthKey, i)
+ return s
+}
+
+// Height sets the height of the block before applying margins. If the height of
+// the text block is less than this value after applying padding (or not), the
+// block will be set to this height.
+func (s Style) Height(i int) Style {
+ s.set(heightKey, i)
+ return s
+}
+
+// Align is a shorthand method for setting horizontal and vertical alignment.
+//
+// With one argument, the position value is applied to the horizontal alignment.
+//
+// With two arguments, the value is applied to the horizontal and vertical
+// alignments, in that order.
+func (s Style) Align(p ...Position) Style {
+ if len(p) > 0 {
+ s.set(alignHorizontalKey, p[0])
+ }
+ if len(p) > 1 {
+ s.set(alignVerticalKey, p[1])
+ }
+ return s
+}
+
+// AlignHorizontal sets a horizontal text alignment rule.
+func (s Style) AlignHorizontal(p Position) Style {
+ s.set(alignHorizontalKey, p)
+ return s
+}
+
+// AlignVertical sets a vertical text alignment rule.
+func (s Style) AlignVertical(p Position) Style {
+ s.set(alignVerticalKey, p)
+ return s
+}
+
+// Padding is a shorthand method for setting padding on all sides at once.
+//
+// With one argument, the value is applied to all sides.
+//
+// With two arguments, the value is applied to the vertical and horizontal
+// sides, in that order.
+//
+// With three arguments, the value is applied to the top side, the horizontal
+// sides, and the bottom side, in that order.
+//
+// With four arguments, the value is applied clockwise starting from the top
+// side, followed by the right side, then the bottom, and finally the left.
+//
+// With more than four arguments no padding will be added.
+func (s Style) Padding(i ...int) Style {
+ top, right, bottom, left, ok := whichSidesInt(i...)
+ if !ok {
+ return s
+ }
+
+ s.set(paddingTopKey, top)
+ s.set(paddingRightKey, right)
+ s.set(paddingBottomKey, bottom)
+ s.set(paddingLeftKey, left)
+ return s
+}
+
+// PaddingLeft adds padding on the left.
+func (s Style) PaddingLeft(i int) Style {
+ s.set(paddingLeftKey, i)
+ return s
+}
+
+// PaddingRight adds padding on the right.
+func (s Style) PaddingRight(i int) Style {
+ s.set(paddingRightKey, i)
+ return s
+}
+
+// PaddingTop adds padding to the top of the block.
+func (s Style) PaddingTop(i int) Style {
+ s.set(paddingTopKey, i)
+ return s
+}
+
+// PaddingBottom adds padding to the bottom of the block.
+func (s Style) PaddingBottom(i int) Style {
+ s.set(paddingBottomKey, i)
+ return s
+}
+
+// ColorWhitespace determines whether or not the background color should be
+// applied to the padding. This is true by default as it's more than likely the
+// desired and expected behavior, but it can be disabled for certain graphic
+// effects.
+//
+// Deprecated: Just use margins and padding.
+func (s Style) ColorWhitespace(v bool) Style {
+ s.set(colorWhitespaceKey, v)
+ return s
+}
+
+// Margin is a shorthand method for setting margins on all sides at once.
+//
+// With one argument, the value is applied to all sides.
+//
+// With two arguments, the value is applied to the vertical and horizontal
+// sides, in that order.
+//
+// With three arguments, the value is applied to the top side, the horizontal
+// sides, and the bottom side, in that order.
+//
+// With four arguments, the value is applied clockwise starting from the top
+// side, followed by the right side, then the bottom, and finally the left.
+//
+// With more than four arguments no margin will be added.
+func (s Style) Margin(i ...int) Style {
+ top, right, bottom, left, ok := whichSidesInt(i...)
+ if !ok {
+ return s
+ }
+
+ s.set(marginTopKey, top)
+ s.set(marginRightKey, right)
+ s.set(marginBottomKey, bottom)
+ s.set(marginLeftKey, left)
+ return s
+}
+
+// MarginLeft sets the value of the left margin.
+func (s Style) MarginLeft(i int) Style {
+ s.set(marginLeftKey, i)
+ return s
+}
+
+// MarginRight sets the value of the right margin.
+func (s Style) MarginRight(i int) Style {
+ s.set(marginRightKey, i)
+ return s
+}
+
+// MarginTop sets the value of the top margin.
+func (s Style) MarginTop(i int) Style {
+ s.set(marginTopKey, i)
+ return s
+}
+
+// MarginBottom sets the value of the bottom margin.
+func (s Style) MarginBottom(i int) Style {
+ s.set(marginBottomKey, i)
+ return s
+}
+
+// MarginBackground sets the background color of the margin. Note that this is
+// also set when inheriting from a style with a background color. In that case
+// the background color on that style will set the margin color on this style.
+func (s Style) MarginBackground(c TerminalColor) Style {
+ s.set(marginBackgroundKey, c)
+ return s
+}
+
+// Border is shorthand for setting the border style and which sides should
+// have a border at once. The variadic argument sides works as follows:
+//
+// With one value, the value is applied to all sides.
+//
+// With two values, the values are applied to the vertical and horizontal
+// sides, in that order.
+//
+// With three values, the values are applied to the top side, the horizontal
+// sides, and the bottom side, in that order.
+//
+// With four values, the values are applied clockwise starting from the top
+// side, followed by the right side, then the bottom, and finally the left.
+//
+// With more than four arguments the border will be applied to all sides.
+//
+// Examples:
+//
+// // Applies borders to the top and bottom only
+// lipgloss.NewStyle().Border(lipgloss.NormalBorder(), true, false)
+//
+// // Applies rounded borders to the right and bottom only
+// lipgloss.NewStyle().Border(lipgloss.RoundedBorder(), false, true, true, false)
+func (s Style) Border(b Border, sides ...bool) Style {
+ s.set(borderStyleKey, b)
+
+ top, right, bottom, left, ok := whichSidesBool(sides...)
+ if !ok {
+ top = true
+ right = true
+ bottom = true
+ left = true
+ }
+
+ s.set(borderTopKey, top)
+ s.set(borderRightKey, right)
+ s.set(borderBottomKey, bottom)
+ s.set(borderLeftKey, left)
+
+ return s
+}
+
+// BorderStyle defines the Border on a style. A Border contains a series of
+// definitions for the sides and corners of a border.
+//
+// Note that if border visibility has not been set for any sides when setting
+// the border style, the border will be enabled for all sides during rendering.
+//
+// You can define border characters as you'd like, though several default
+// styles are included: NormalBorder(), RoundedBorder(), BlockBorder(),
+// OuterHalfBlockBorder(), InnerHalfBlockBorder(), ThickBorder(),
+// and DoubleBorder().
+//
+// Example:
+//
+// lipgloss.NewStyle().BorderStyle(lipgloss.ThickBorder())
+func (s Style) BorderStyle(b Border) Style {
+ s.set(borderStyleKey, b)
+ return s
+}
+
+// BorderTop determines whether or not to draw a top border.
+func (s Style) BorderTop(v bool) Style {
+ s.set(borderTopKey, v)
+ return s
+}
+
+// BorderRight determines whether or not to draw a right border.
+func (s Style) BorderRight(v bool) Style {
+ s.set(borderRightKey, v)
+ return s
+}
+
+// BorderBottom determines whether or not to draw a bottom border.
+func (s Style) BorderBottom(v bool) Style {
+ s.set(borderBottomKey, v)
+ return s
+}
+
+// BorderLeft determines whether or not to draw a left border.
+func (s Style) BorderLeft(v bool) Style {
+ s.set(borderLeftKey, v)
+ return s
+}
+
+// BorderForeground is a shorthand function for setting all of the
+// foreground colors of the borders at once. The arguments work as follows:
+//
+// With one argument, the argument is applied to all sides.
+//
+// With two arguments, the arguments are applied to the vertical and horizontal
+// sides, in that order.
+//
+// With three arguments, the arguments are applied to the top side, the
+// horizontal sides, and the bottom side, in that order.
+//
+// With four arguments, the arguments are applied clockwise starting from the
+// top side, followed by the right side, then the bottom, and finally the left.
+//
+// With more than four arguments nothing will be set.
+func (s Style) BorderForeground(c ...TerminalColor) Style {
+ if len(c) == 0 {
+ return s
+ }
+
+ top, right, bottom, left, ok := whichSidesColor(c...)
+ if !ok {
+ return s
+ }
+
+ s.set(borderTopForegroundKey, top)
+ s.set(borderRightForegroundKey, right)
+ s.set(borderBottomForegroundKey, bottom)
+ s.set(borderLeftForegroundKey, left)
+
+ return s
+}
+
+// BorderTopForeground set the foreground color for the top of the border.
+func (s Style) BorderTopForeground(c TerminalColor) Style {
+ s.set(borderTopForegroundKey, c)
+ return s
+}
+
+// BorderRightForeground sets the foreground color for the right side of the
+// border.
+func (s Style) BorderRightForeground(c TerminalColor) Style {
+ s.set(borderRightForegroundKey, c)
+ return s
+}
+
+// BorderBottomForeground sets the foreground color for the bottom of the
+// border.
+func (s Style) BorderBottomForeground(c TerminalColor) Style {
+ s.set(borderBottomForegroundKey, c)
+ return s
+}
+
+// BorderLeftForeground sets the foreground color for the left side of the
+// border.
+func (s Style) BorderLeftForeground(c TerminalColor) Style {
+ s.set(borderLeftForegroundKey, c)
+ return s
+}
+
+// BorderBackground is a shorthand function for setting all of the
+// background colors of the borders at once. The arguments work as follows:
+//
+// With one argument, the argument is applied to all sides.
+//
+// With two arguments, the arguments are applied to the vertical and horizontal
+// sides, in that order.
+//
+// With three arguments, the arguments are applied to the top side, the
+// horizontal sides, and the bottom side, in that order.
+//
+// With four arguments, the arguments are applied clockwise starting from the
+// top side, followed by the right side, then the bottom, and finally the left.
+//
+// With more than four arguments nothing will be set.
+func (s Style) BorderBackground(c ...TerminalColor) Style {
+ if len(c) == 0 {
+ return s
+ }
+
+ top, right, bottom, left, ok := whichSidesColor(c...)
+ if !ok {
+ return s
+ }
+
+ s.set(borderTopBackgroundKey, top)
+ s.set(borderRightBackgroundKey, right)
+ s.set(borderBottomBackgroundKey, bottom)
+ s.set(borderLeftBackgroundKey, left)
+
+ return s
+}
+
+// BorderTopBackground sets the background color of the top of the border.
+func (s Style) BorderTopBackground(c TerminalColor) Style {
+ s.set(borderTopBackgroundKey, c)
+ return s
+}
+
+// BorderRightBackground sets the background color of right side the border.
+func (s Style) BorderRightBackground(c TerminalColor) Style {
+ s.set(borderRightBackgroundKey, c)
+ return s
+}
+
+// BorderBottomBackground sets the background color of the bottom of the
+// border.
+func (s Style) BorderBottomBackground(c TerminalColor) Style {
+ s.set(borderBottomBackgroundKey, c)
+ return s
+}
+
+// BorderLeftBackground set the background color of the left side of the
+// border.
+func (s Style) BorderLeftBackground(c TerminalColor) Style {
+ s.set(borderLeftBackgroundKey, c)
+ return s
+}
+
+// Inline makes rendering output one line and disables the rendering of
+// margins, padding and borders. This is useful when you need a style to apply
+// only to font rendering and don't want it to change any physical dimensions.
+// It works well with Style.MaxWidth.
+//
+// Because this in intended to be used at the time of render, this method will
+// not mutate the style and instead return a copy.
+//
+// Example:
+//
+// var userInput string = "..."
+// var userStyle = text.Style{ /* ... */ }
+// fmt.Println(userStyle.Inline(true).Render(userInput))
+func (s Style) Inline(v bool) Style {
+ o := s // copy
+ o.set(inlineKey, v)
+ return o
+}
+
+// MaxWidth applies a max width to a given style. This is useful in enforcing
+// a certain width at render time, particularly with arbitrary strings and
+// styles.
+//
+// Because this in intended to be used at the time of render, this method will
+// not mutate the style and instead return a copy.
+//
+// Example:
+//
+// var userInput string = "..."
+// var userStyle = text.Style{ /* ... */ }
+// fmt.Println(userStyle.MaxWidth(16).Render(userInput))
+func (s Style) MaxWidth(n int) Style {
+ o := s // copy
+ o.set(maxWidthKey, n)
+ return o
+}
+
+// MaxHeight applies a max height to a given style. This is useful in enforcing
+// a certain height at render time, particularly with arbitrary strings and
+// styles.
+//
+// Because this in intended to be used at the time of render, this method will
+// not mutate the style and instead returns a copy.
+func (s Style) MaxHeight(n int) Style {
+ o := s // copy
+ o.set(maxHeightKey, n)
+ return o
+}
+
+// NoTabConversion can be passed to [Style.TabWidth] to disable the replacement
+// of tabs with spaces at render time.
+const NoTabConversion = -1
+
+// TabWidth sets the number of spaces that a tab (/t) should be rendered as.
+// When set to 0, tabs will be removed. To disable the replacement of tabs with
+// spaces entirely, set this to [NoTabConversion].
+//
+// By default, tabs will be replaced with 4 spaces.
+func (s Style) TabWidth(n int) Style {
+ if n <= -1 {
+ n = -1
+ }
+ s.set(tabWidthKey, n)
+ return s
+}
+
+// UnderlineSpaces determines whether to underline spaces between words. By
+// default, this is true. Spaces can also be underlined without underlining the
+// text itself.
+func (s Style) UnderlineSpaces(v bool) Style {
+ s.set(underlineSpacesKey, v)
+ return s
+}
+
+// StrikethroughSpaces determines whether to apply strikethroughs to spaces
+// between words. By default, this is true. Spaces can also be struck without
+// underlining the text itself.
+func (s Style) StrikethroughSpaces(v bool) Style {
+ s.set(strikethroughSpacesKey, v)
+ return s
+}
+
+// Transform applies a given function to a string at render time, allowing for
+// the string being rendered to be manipuated.
+//
+// Example:
+//
+// s := NewStyle().Transform(strings.ToUpper)
+// fmt.Println(s.Render("raow!") // "RAOW!"
+func (s Style) Transform(fn func(string) string) Style {
+ s.set(transformKey, fn)
+ return s
+}
+
+// Renderer sets the renderer for the style. This is useful for changing the
+// renderer for a style that is being used in a different context.
+func (s Style) Renderer(r *Renderer) Style {
+ s.r = r
+ return s
+}
+
+// whichSidesInt is a helper method for setting values on sides of a block based
+// on the number of arguments. It follows the CSS shorthand rules for blocks
+// like margin, padding. and borders. Here are how the rules work:
+//
+// 0 args: do nothing
+// 1 arg: all sides
+// 2 args: top -> bottom
+// 3 args: top -> horizontal -> bottom
+// 4 args: top -> right -> bottom -> left
+// 5+ args: do nothing.
+func whichSidesInt(i ...int) (top, right, bottom, left int, ok bool) {
+ switch len(i) {
+ case 1:
+ top = i[0]
+ bottom = i[0]
+ left = i[0]
+ right = i[0]
+ ok = true
+ case 2: //nolint:mnd
+ top = i[0]
+ bottom = i[0]
+ left = i[1]
+ right = i[1]
+ ok = true
+ case 3: //nolint:mnd
+ top = i[0]
+ left = i[1]
+ right = i[1]
+ bottom = i[2]
+ ok = true
+ case 4: //nolint:mnd
+ top = i[0]
+ right = i[1]
+ bottom = i[2]
+ left = i[3]
+ ok = true
+ }
+ return top, right, bottom, left, ok
+}
+
+// whichSidesBool is like whichSidesInt, except it operates on a series of
+// boolean values. See the comment on whichSidesInt for details on how this
+// works.
+func whichSidesBool(i ...bool) (top, right, bottom, left bool, ok bool) {
+ switch len(i) {
+ case 1:
+ top = i[0]
+ bottom = i[0]
+ left = i[0]
+ right = i[0]
+ ok = true
+ case 2: //nolint:mnd
+ top = i[0]
+ bottom = i[0]
+ left = i[1]
+ right = i[1]
+ ok = true
+ case 3: //nolint:mnd
+ top = i[0]
+ left = i[1]
+ right = i[1]
+ bottom = i[2]
+ ok = true
+ case 4: //nolint:mnd
+ top = i[0]
+ right = i[1]
+ bottom = i[2]
+ left = i[3]
+ ok = true
+ }
+ return top, right, bottom, left, ok
+}
+
+// whichSidesColor is like whichSides, except it operates on a series of
+// boolean values. See the comment on whichSidesInt for details on how this
+// works.
+func whichSidesColor(i ...TerminalColor) (top, right, bottom, left TerminalColor, ok bool) {
+ switch len(i) {
+ case 1:
+ top = i[0]
+ bottom = i[0]
+ left = i[0]
+ right = i[0]
+ ok = true
+ case 2: //nolint:mnd
+ top = i[0]
+ bottom = i[0]
+ left = i[1]
+ right = i[1]
+ ok = true
+ case 3: //nolint:mnd
+ top = i[0]
+ left = i[1]
+ right = i[1]
+ bottom = i[2]
+ ok = true
+ case 4: //nolint:mnd
+ top = i[0]
+ right = i[1]
+ bottom = i[2]
+ left = i[3]
+ ok = true
+ }
+ return top, right, bottom, left, ok
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/size.go b/vendor/github.com/charmbracelet/lipgloss/size.go
new file mode 100644
index 00000000..e169ff5e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/size.go
@@ -0,0 +1,41 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// Width returns the cell width of characters in the string. ANSI sequences are
+// ignored and characters wider than one cell (such as Chinese characters and
+// emojis) are appropriately measured.
+//
+// You should use this instead of len(string) len([]rune(string) as neither
+// will give you accurate results.
+func Width(str string) (width int) {
+ for _, l := range strings.Split(str, "\n") {
+ w := ansi.StringWidth(l)
+ if w > width {
+ width = w
+ }
+ }
+
+ return width
+}
+
+// Height returns height of a string in cells. This is done simply by
+// counting \n characters. If your strings use \r\n for newlines you should
+// convert them to \n first, or simply write a separate function for measuring
+// height.
+func Height(str string) int {
+ return strings.Count(str, "\n") + 1
+}
+
+// Size returns the width and height of the string in cells. ANSI sequences are
+// ignored and characters wider than one cell (such as Chinese characters and
+// emojis) are appropriately measured.
+func Size(str string) (width, height int) {
+ width = Width(str)
+ height = Height(str)
+ return width, height
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/style.go b/vendor/github.com/charmbracelet/lipgloss/style.go
new file mode 100644
index 00000000..59fa3ab2
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/style.go
@@ -0,0 +1,588 @@
+package lipgloss
+
+import (
+ "strings"
+ "unicode"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/charmbracelet/x/cellbuf"
+ "github.com/muesli/termenv"
+)
+
+const tabWidthDefault = 4
+
+// Property for a key.
+type propKey int64
+
+// Available properties.
+const (
+ // Boolean props come first.
+ boldKey propKey = 1 << iota
+ italicKey
+ underlineKey
+ strikethroughKey
+ reverseKey
+ blinkKey
+ faintKey
+ underlineSpacesKey
+ strikethroughSpacesKey
+ colorWhitespaceKey
+
+ // Non-boolean props.
+ foregroundKey
+ backgroundKey
+ widthKey
+ heightKey
+ alignHorizontalKey
+ alignVerticalKey
+
+ // Padding.
+ paddingTopKey
+ paddingRightKey
+ paddingBottomKey
+ paddingLeftKey
+
+ // Margins.
+ marginTopKey
+ marginRightKey
+ marginBottomKey
+ marginLeftKey
+ marginBackgroundKey
+
+ // Border runes.
+ borderStyleKey
+
+ // Border edges.
+ borderTopKey
+ borderRightKey
+ borderBottomKey
+ borderLeftKey
+
+ // Border foreground colors.
+ borderTopForegroundKey
+ borderRightForegroundKey
+ borderBottomForegroundKey
+ borderLeftForegroundKey
+
+ // Border background colors.
+ borderTopBackgroundKey
+ borderRightBackgroundKey
+ borderBottomBackgroundKey
+ borderLeftBackgroundKey
+
+ inlineKey
+ maxWidthKey
+ maxHeightKey
+ tabWidthKey
+
+ transformKey
+)
+
+// props is a set of properties.
+type props int64
+
+// set sets a property.
+func (p props) set(k propKey) props {
+ return p | props(k)
+}
+
+// unset unsets a property.
+func (p props) unset(k propKey) props {
+ return p &^ props(k)
+}
+
+// has checks if a property is set.
+func (p props) has(k propKey) bool {
+ return p&props(k) != 0
+}
+
+// NewStyle returns a new, empty Style. While it's syntactic sugar for the
+// Style{} primitive, it's recommended to use this function for creating styles
+// in case the underlying implementation changes. It takes an optional string
+// value to be set as the underlying string value for this style.
+func NewStyle() Style {
+ return renderer.NewStyle()
+}
+
+// NewStyle returns a new, empty Style. While it's syntactic sugar for the
+// Style{} primitive, it's recommended to use this function for creating styles
+// in case the underlying implementation changes. It takes an optional string
+// value to be set as the underlying string value for this style.
+func (r *Renderer) NewStyle() Style {
+ s := Style{r: r}
+ return s
+}
+
+// Style contains a set of rules that comprise a style as a whole.
+type Style struct {
+ r *Renderer
+ props props
+ value string
+
+ // we store bool props values here
+ attrs int
+
+ // props that have values
+ fgColor TerminalColor
+ bgColor TerminalColor
+
+ width int
+ height int
+
+ alignHorizontal Position
+ alignVertical Position
+
+ paddingTop int
+ paddingRight int
+ paddingBottom int
+ paddingLeft int
+
+ marginTop int
+ marginRight int
+ marginBottom int
+ marginLeft int
+ marginBgColor TerminalColor
+
+ borderStyle Border
+ borderTopFgColor TerminalColor
+ borderRightFgColor TerminalColor
+ borderBottomFgColor TerminalColor
+ borderLeftFgColor TerminalColor
+ borderTopBgColor TerminalColor
+ borderRightBgColor TerminalColor
+ borderBottomBgColor TerminalColor
+ borderLeftBgColor TerminalColor
+
+ maxWidth int
+ maxHeight int
+ tabWidth int
+
+ transform func(string) string
+}
+
+// joinString joins a list of strings into a single string separated with a
+// space.
+func joinString(strs ...string) string {
+ return strings.Join(strs, " ")
+}
+
+// SetString sets the underlying string value for this style. To render once
+// the underlying string is set, use the Style.String. This method is
+// a convenience for cases when having a stringer implementation is handy, such
+// as when using fmt.Sprintf. You can also simply define a style and render out
+// strings directly with Style.Render.
+func (s Style) SetString(strs ...string) Style {
+ s.value = joinString(strs...)
+ return s
+}
+
+// Value returns the raw, unformatted, underlying string value for this style.
+func (s Style) Value() string {
+ return s.value
+}
+
+// String implements stringer for a Style, returning the rendered result based
+// on the rules in this style. An underlying string value must be set with
+// Style.SetString prior to using this method.
+func (s Style) String() string {
+ return s.Render()
+}
+
+// Copy returns a copy of this style, including any underlying string values.
+//
+// Deprecated: to copy just use assignment (i.e. a := b). All methods also
+// return a new style.
+func (s Style) Copy() Style {
+ return s
+}
+
+// Inherit overlays the style in the argument onto this style by copying each explicitly
+// set value from the argument style onto this style if it is not already explicitly set.
+// Existing set values are kept intact and not overwritten.
+//
+// Margins, padding, and underlying string values are not inherited.
+func (s Style) Inherit(i Style) Style {
+ for k := boldKey; k <= transformKey; k <<= 1 {
+ if !i.isSet(k) {
+ continue
+ }
+
+ switch k { //nolint:exhaustive
+ case marginTopKey, marginRightKey, marginBottomKey, marginLeftKey:
+ // Margins are not inherited
+ continue
+ case paddingTopKey, paddingRightKey, paddingBottomKey, paddingLeftKey:
+ // Padding is not inherited
+ continue
+ case backgroundKey:
+ // The margins also inherit the background color
+ if !s.isSet(marginBackgroundKey) && !i.isSet(marginBackgroundKey) {
+ s.set(marginBackgroundKey, i.bgColor)
+ }
+ }
+
+ if s.isSet(k) {
+ continue
+ }
+
+ s.setFrom(k, i)
+ }
+ return s
+}
+
+// Render applies the defined style formatting to a given string.
+func (s Style) Render(strs ...string) string {
+ if s.r == nil {
+ s.r = renderer
+ }
+ if s.value != "" {
+ strs = append([]string{s.value}, strs...)
+ }
+
+ var (
+ str = joinString(strs...)
+
+ p = s.r.ColorProfile()
+ te = p.String()
+ teSpace = p.String()
+ teWhitespace = p.String()
+
+ bold = s.getAsBool(boldKey, false)
+ italic = s.getAsBool(italicKey, false)
+ underline = s.getAsBool(underlineKey, false)
+ strikethrough = s.getAsBool(strikethroughKey, false)
+ reverse = s.getAsBool(reverseKey, false)
+ blink = s.getAsBool(blinkKey, false)
+ faint = s.getAsBool(faintKey, false)
+
+ fg = s.getAsColor(foregroundKey)
+ bg = s.getAsColor(backgroundKey)
+
+ width = s.getAsInt(widthKey)
+ height = s.getAsInt(heightKey)
+ horizontalAlign = s.getAsPosition(alignHorizontalKey)
+ verticalAlign = s.getAsPosition(alignVerticalKey)
+
+ topPadding = s.getAsInt(paddingTopKey)
+ rightPadding = s.getAsInt(paddingRightKey)
+ bottomPadding = s.getAsInt(paddingBottomKey)
+ leftPadding = s.getAsInt(paddingLeftKey)
+
+ colorWhitespace = s.getAsBool(colorWhitespaceKey, true)
+ inline = s.getAsBool(inlineKey, false)
+ maxWidth = s.getAsInt(maxWidthKey)
+ maxHeight = s.getAsInt(maxHeightKey)
+
+ underlineSpaces = s.getAsBool(underlineSpacesKey, false) || (underline && s.getAsBool(underlineSpacesKey, true))
+ strikethroughSpaces = s.getAsBool(strikethroughSpacesKey, false) || (strikethrough && s.getAsBool(strikethroughSpacesKey, true))
+
+ // Do we need to style whitespace (padding and space outside
+ // paragraphs) separately?
+ styleWhitespace = reverse
+
+ // Do we need to style spaces separately?
+ useSpaceStyler = (underline && !underlineSpaces) || (strikethrough && !strikethroughSpaces) || underlineSpaces || strikethroughSpaces
+
+ transform = s.getAsTransform(transformKey)
+ )
+
+ if transform != nil {
+ str = transform(str)
+ }
+
+ if s.props == 0 {
+ return s.maybeConvertTabs(str)
+ }
+
+ // Enable support for ANSI on the legacy Windows cmd.exe console. This is a
+ // no-op on non-Windows systems and on Windows runs only once.
+ enableLegacyWindowsANSI()
+
+ if bold {
+ te = te.Bold()
+ }
+ if italic {
+ te = te.Italic()
+ }
+ if underline {
+ te = te.Underline()
+ }
+ if reverse {
+ teWhitespace = teWhitespace.Reverse()
+ te = te.Reverse()
+ }
+ if blink {
+ te = te.Blink()
+ }
+ if faint {
+ te = te.Faint()
+ }
+
+ if fg != noColor {
+ te = te.Foreground(fg.color(s.r))
+ if styleWhitespace {
+ teWhitespace = teWhitespace.Foreground(fg.color(s.r))
+ }
+ if useSpaceStyler {
+ teSpace = teSpace.Foreground(fg.color(s.r))
+ }
+ }
+
+ if bg != noColor {
+ te = te.Background(bg.color(s.r))
+ if colorWhitespace {
+ teWhitespace = teWhitespace.Background(bg.color(s.r))
+ }
+ if useSpaceStyler {
+ teSpace = teSpace.Background(bg.color(s.r))
+ }
+ }
+
+ if underline {
+ te = te.Underline()
+ }
+ if strikethrough {
+ te = te.CrossOut()
+ }
+
+ if underlineSpaces {
+ teSpace = teSpace.Underline()
+ }
+ if strikethroughSpaces {
+ teSpace = teSpace.CrossOut()
+ }
+
+ // Potentially convert tabs to spaces
+ str = s.maybeConvertTabs(str)
+ // carriage returns can cause strange behaviour when rendering.
+ str = strings.ReplaceAll(str, "\r\n", "\n")
+
+ // Strip newlines in single line mode
+ if inline {
+ str = strings.ReplaceAll(str, "\n", "")
+ }
+
+ // Word wrap
+ if !inline && width > 0 {
+ wrapAt := width - leftPadding - rightPadding
+ str = cellbuf.Wrap(str, wrapAt, "")
+ }
+
+ // Render core text
+ {
+ var b strings.Builder
+
+ l := strings.Split(str, "\n")
+ for i := range l {
+ if useSpaceStyler {
+ // Look for spaces and apply a different styler
+ for _, r := range l[i] {
+ if unicode.IsSpace(r) {
+ b.WriteString(teSpace.Styled(string(r)))
+ continue
+ }
+ b.WriteString(te.Styled(string(r)))
+ }
+ } else {
+ b.WriteString(te.Styled(l[i]))
+ }
+ if i != len(l)-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ str = b.String()
+ }
+
+ // Padding
+ if !inline { //nolint:nestif
+ if leftPadding > 0 {
+ var st *termenv.Style
+ if colorWhitespace || styleWhitespace {
+ st = &teWhitespace
+ }
+ str = padLeft(str, leftPadding, st)
+ }
+
+ if rightPadding > 0 {
+ var st *termenv.Style
+ if colorWhitespace || styleWhitespace {
+ st = &teWhitespace
+ }
+ str = padRight(str, rightPadding, st)
+ }
+
+ if topPadding > 0 {
+ str = strings.Repeat("\n", topPadding) + str
+ }
+
+ if bottomPadding > 0 {
+ str += strings.Repeat("\n", bottomPadding)
+ }
+ }
+
+ // Height
+ if height > 0 {
+ str = alignTextVertical(str, verticalAlign, height, nil)
+ }
+
+ // Set alignment. This will also pad short lines with spaces so that all
+ // lines are the same length, so we run it under a few different conditions
+ // beyond alignment.
+ {
+ numLines := strings.Count(str, "\n")
+
+ if numLines != 0 || width != 0 {
+ var st *termenv.Style
+ if colorWhitespace || styleWhitespace {
+ st = &teWhitespace
+ }
+ str = alignTextHorizontal(str, horizontalAlign, width, st)
+ }
+ }
+
+ if !inline {
+ str = s.applyBorder(str)
+ str = s.applyMargins(str, inline)
+ }
+
+ // Truncate according to MaxWidth
+ if maxWidth > 0 {
+ lines := strings.Split(str, "\n")
+
+ for i := range lines {
+ lines[i] = ansi.Truncate(lines[i], maxWidth, "")
+ }
+
+ str = strings.Join(lines, "\n")
+ }
+
+ // Truncate according to MaxHeight
+ if maxHeight > 0 {
+ lines := strings.Split(str, "\n")
+ height := min(maxHeight, len(lines))
+ if len(lines) > 0 {
+ str = strings.Join(lines[:height], "\n")
+ }
+ }
+
+ return str
+}
+
+func (s Style) maybeConvertTabs(str string) string {
+ tw := tabWidthDefault
+ if s.isSet(tabWidthKey) {
+ tw = s.getAsInt(tabWidthKey)
+ }
+ switch tw {
+ case -1:
+ return str
+ case 0:
+ return strings.ReplaceAll(str, "\t", "")
+ default:
+ return strings.ReplaceAll(str, "\t", strings.Repeat(" ", tw))
+ }
+}
+
+func (s Style) applyMargins(str string, inline bool) string {
+ var (
+ topMargin = s.getAsInt(marginTopKey)
+ rightMargin = s.getAsInt(marginRightKey)
+ bottomMargin = s.getAsInt(marginBottomKey)
+ leftMargin = s.getAsInt(marginLeftKey)
+
+ styler termenv.Style
+ )
+
+ bgc := s.getAsColor(marginBackgroundKey)
+ if bgc != noColor {
+ styler = styler.Background(bgc.color(s.r))
+ }
+
+ // Add left and right margin
+ str = padLeft(str, leftMargin, &styler)
+ str = padRight(str, rightMargin, &styler)
+
+ // Top/bottom margin
+ if !inline {
+ _, width := getLines(str)
+ spaces := strings.Repeat(" ", width)
+
+ if topMargin > 0 {
+ str = styler.Styled(strings.Repeat(spaces+"\n", topMargin)) + str
+ }
+ if bottomMargin > 0 {
+ str += styler.Styled(strings.Repeat("\n"+spaces, bottomMargin))
+ }
+ }
+
+ return str
+}
+
+// Apply left padding.
+func padLeft(str string, n int, style *termenv.Style) string {
+ return pad(str, -n, style)
+}
+
+// Apply right padding.
+func padRight(str string, n int, style *termenv.Style) string {
+ return pad(str, n, style)
+}
+
+// pad adds padding to either the left or right side of a string.
+// Positive values add to the right side while negative values
+// add to the left side.
+func pad(str string, n int, style *termenv.Style) string {
+ if n == 0 {
+ return str
+ }
+
+ sp := strings.Repeat(" ", abs(n))
+ if style != nil {
+ sp = style.Styled(sp)
+ }
+
+ b := strings.Builder{}
+ l := strings.Split(str, "\n")
+
+ for i := range l {
+ switch {
+ // pad right
+ case n > 0:
+ b.WriteString(l[i])
+ b.WriteString(sp)
+ // pad left
+ default:
+ b.WriteString(sp)
+ b.WriteString(l[i])
+ }
+
+ if i != len(l)-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ return b.String()
+}
+
+func max(a, b int) int { //nolint:unparam,predeclared
+ if a > b {
+ return a
+ }
+ return b
+}
+
+func min(a, b int) int { //nolint:predeclared
+ if a < b {
+ return a
+ }
+ return b
+}
+
+func abs(a int) int {
+ if a < 0 {
+ return -a
+ }
+
+ return a
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/unset.go b/vendor/github.com/charmbracelet/lipgloss/unset.go
new file mode 100644
index 00000000..1086e722
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/unset.go
@@ -0,0 +1,331 @@
+package lipgloss
+
+// unset unsets a property from a style.
+func (s *Style) unset(key propKey) {
+ s.props = s.props.unset(key)
+}
+
+// UnsetBold removes the bold style rule, if set.
+func (s Style) UnsetBold() Style {
+ s.unset(boldKey)
+ return s
+}
+
+// UnsetItalic removes the italic style rule, if set.
+func (s Style) UnsetItalic() Style {
+ s.unset(italicKey)
+ return s
+}
+
+// UnsetUnderline removes the underline style rule, if set.
+func (s Style) UnsetUnderline() Style {
+ s.unset(underlineKey)
+ return s
+}
+
+// UnsetStrikethrough removes the strikethrough style rule, if set.
+func (s Style) UnsetStrikethrough() Style {
+ s.unset(strikethroughKey)
+ return s
+}
+
+// UnsetReverse removes the reverse style rule, if set.
+func (s Style) UnsetReverse() Style {
+ s.unset(reverseKey)
+ return s
+}
+
+// UnsetBlink removes the blink style rule, if set.
+func (s Style) UnsetBlink() Style {
+ s.unset(blinkKey)
+ return s
+}
+
+// UnsetFaint removes the faint style rule, if set.
+func (s Style) UnsetFaint() Style {
+ s.unset(faintKey)
+ return s
+}
+
+// UnsetForeground removes the foreground style rule, if set.
+func (s Style) UnsetForeground() Style {
+ s.unset(foregroundKey)
+ return s
+}
+
+// UnsetBackground removes the background style rule, if set.
+func (s Style) UnsetBackground() Style {
+ s.unset(backgroundKey)
+ return s
+}
+
+// UnsetWidth removes the width style rule, if set.
+func (s Style) UnsetWidth() Style {
+ s.unset(widthKey)
+ return s
+}
+
+// UnsetHeight removes the height style rule, if set.
+func (s Style) UnsetHeight() Style {
+ s.unset(heightKey)
+ return s
+}
+
+// UnsetAlign removes the horizontal and vertical text alignment style rule, if set.
+func (s Style) UnsetAlign() Style {
+ s.unset(alignHorizontalKey)
+ s.unset(alignVerticalKey)
+ return s
+}
+
+// UnsetAlignHorizontal removes the horizontal text alignment style rule, if set.
+func (s Style) UnsetAlignHorizontal() Style {
+ s.unset(alignHorizontalKey)
+ return s
+}
+
+// UnsetAlignVertical removes the vertical text alignment style rule, if set.
+func (s Style) UnsetAlignVertical() Style {
+ s.unset(alignVerticalKey)
+ return s
+}
+
+// UnsetPadding removes all padding style rules.
+func (s Style) UnsetPadding() Style {
+ s.unset(paddingLeftKey)
+ s.unset(paddingRightKey)
+ s.unset(paddingTopKey)
+ s.unset(paddingBottomKey)
+ return s
+}
+
+// UnsetPaddingLeft removes the left padding style rule, if set.
+func (s Style) UnsetPaddingLeft() Style {
+ s.unset(paddingLeftKey)
+ return s
+}
+
+// UnsetPaddingRight removes the right padding style rule, if set.
+func (s Style) UnsetPaddingRight() Style {
+ s.unset(paddingRightKey)
+ return s
+}
+
+// UnsetPaddingTop removes the top padding style rule, if set.
+func (s Style) UnsetPaddingTop() Style {
+ s.unset(paddingTopKey)
+ return s
+}
+
+// UnsetPaddingBottom removes the bottom padding style rule, if set.
+func (s Style) UnsetPaddingBottom() Style {
+ s.unset(paddingBottomKey)
+ return s
+}
+
+// UnsetColorWhitespace removes the rule for coloring padding, if set.
+func (s Style) UnsetColorWhitespace() Style {
+ s.unset(colorWhitespaceKey)
+ return s
+}
+
+// UnsetMargins removes all margin style rules.
+func (s Style) UnsetMargins() Style {
+ s.unset(marginLeftKey)
+ s.unset(marginRightKey)
+ s.unset(marginTopKey)
+ s.unset(marginBottomKey)
+ return s
+}
+
+// UnsetMarginLeft removes the left margin style rule, if set.
+func (s Style) UnsetMarginLeft() Style {
+ s.unset(marginLeftKey)
+ return s
+}
+
+// UnsetMarginRight removes the right margin style rule, if set.
+func (s Style) UnsetMarginRight() Style {
+ s.unset(marginRightKey)
+ return s
+}
+
+// UnsetMarginTop removes the top margin style rule, if set.
+func (s Style) UnsetMarginTop() Style {
+ s.unset(marginTopKey)
+ return s
+}
+
+// UnsetMarginBottom removes the bottom margin style rule, if set.
+func (s Style) UnsetMarginBottom() Style {
+ s.unset(marginBottomKey)
+ return s
+}
+
+// UnsetMarginBackground removes the margin's background color. Note that the
+// margin's background color can be set from the background color of another
+// style during inheritance.
+func (s Style) UnsetMarginBackground() Style {
+ s.unset(marginBackgroundKey)
+ return s
+}
+
+// UnsetBorderStyle removes the border style rule, if set.
+func (s Style) UnsetBorderStyle() Style {
+ s.unset(borderStyleKey)
+ return s
+}
+
+// UnsetBorderTop removes the border top style rule, if set.
+func (s Style) UnsetBorderTop() Style {
+ s.unset(borderTopKey)
+ return s
+}
+
+// UnsetBorderRight removes the border right style rule, if set.
+func (s Style) UnsetBorderRight() Style {
+ s.unset(borderRightKey)
+ return s
+}
+
+// UnsetBorderBottom removes the border bottom style rule, if set.
+func (s Style) UnsetBorderBottom() Style {
+ s.unset(borderBottomKey)
+ return s
+}
+
+// UnsetBorderLeft removes the border left style rule, if set.
+func (s Style) UnsetBorderLeft() Style {
+ s.unset(borderLeftKey)
+ return s
+}
+
+// UnsetBorderForeground removes all border foreground color styles, if set.
+func (s Style) UnsetBorderForeground() Style {
+ s.unset(borderTopForegroundKey)
+ s.unset(borderRightForegroundKey)
+ s.unset(borderBottomForegroundKey)
+ s.unset(borderLeftForegroundKey)
+ return s
+}
+
+// UnsetBorderTopForeground removes the top border foreground color rule,
+// if set.
+func (s Style) UnsetBorderTopForeground() Style {
+ s.unset(borderTopForegroundKey)
+ return s
+}
+
+// UnsetBorderRightForeground removes the right border foreground color rule,
+// if set.
+func (s Style) UnsetBorderRightForeground() Style {
+ s.unset(borderRightForegroundKey)
+ return s
+}
+
+// UnsetBorderBottomForeground removes the bottom border foreground color
+// rule, if set.
+func (s Style) UnsetBorderBottomForeground() Style {
+ s.unset(borderBottomForegroundKey)
+ return s
+}
+
+// UnsetBorderLeftForeground removes the left border foreground color rule,
+// if set.
+func (s Style) UnsetBorderLeftForeground() Style {
+ s.unset(borderLeftForegroundKey)
+ return s
+}
+
+// UnsetBorderBackground removes all border background color styles, if
+// set.
+func (s Style) UnsetBorderBackground() Style {
+ s.unset(borderTopBackgroundKey)
+ s.unset(borderRightBackgroundKey)
+ s.unset(borderBottomBackgroundKey)
+ s.unset(borderLeftBackgroundKey)
+ return s
+}
+
+// UnsetBorderTopBackgroundColor removes the top border background color rule,
+// if set.
+//
+// Deprecated: This function simply calls Style.UnsetBorderTopBackground.
+func (s Style) UnsetBorderTopBackgroundColor() Style {
+ return s.UnsetBorderTopBackground()
+}
+
+// UnsetBorderTopBackground removes the top border background color rule,
+// if set.
+func (s Style) UnsetBorderTopBackground() Style {
+ s.unset(borderTopBackgroundKey)
+ return s
+}
+
+// UnsetBorderRightBackground removes the right border background color
+// rule, if set.
+func (s Style) UnsetBorderRightBackground() Style {
+ s.unset(borderRightBackgroundKey)
+ return s
+}
+
+// UnsetBorderBottomBackground removes the bottom border background color
+// rule, if set.
+func (s Style) UnsetBorderBottomBackground() Style {
+ s.unset(borderBottomBackgroundKey)
+ return s
+}
+
+// UnsetBorderLeftBackground removes the left border color rule, if set.
+func (s Style) UnsetBorderLeftBackground() Style {
+ s.unset(borderLeftBackgroundKey)
+ return s
+}
+
+// UnsetInline removes the inline style rule, if set.
+func (s Style) UnsetInline() Style {
+ s.unset(inlineKey)
+ return s
+}
+
+// UnsetMaxWidth removes the max width style rule, if set.
+func (s Style) UnsetMaxWidth() Style {
+ s.unset(maxWidthKey)
+ return s
+}
+
+// UnsetMaxHeight removes the max height style rule, if set.
+func (s Style) UnsetMaxHeight() Style {
+ s.unset(maxHeightKey)
+ return s
+}
+
+// UnsetTabWidth removes the tab width style rule, if set.
+func (s Style) UnsetTabWidth() Style {
+ s.unset(tabWidthKey)
+ return s
+}
+
+// UnsetUnderlineSpaces removes the value set by UnderlineSpaces.
+func (s Style) UnsetUnderlineSpaces() Style {
+ s.unset(underlineSpacesKey)
+ return s
+}
+
+// UnsetStrikethroughSpaces removes the value set by StrikethroughSpaces.
+func (s Style) UnsetStrikethroughSpaces() Style {
+ s.unset(strikethroughSpacesKey)
+ return s
+}
+
+// UnsetTransform removes the value set by Transform.
+func (s Style) UnsetTransform() Style {
+ s.unset(transformKey)
+ return s
+}
+
+// UnsetString sets the underlying string value to the empty string.
+func (s Style) UnsetString() Style {
+ s.value = ""
+ return s
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/whitespace.go b/vendor/github.com/charmbracelet/lipgloss/whitespace.go
new file mode 100644
index 00000000..040dc98e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/whitespace.go
@@ -0,0 +1,83 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/muesli/termenv"
+)
+
+// whitespace is a whitespace renderer.
+type whitespace struct {
+ re *Renderer
+ style termenv.Style
+ chars string
+}
+
+// newWhitespace creates a new whitespace renderer. The order of the options
+// matters, if you're using WithWhitespaceRenderer, make sure it comes first as
+// other options might depend on it.
+func newWhitespace(r *Renderer, opts ...WhitespaceOption) *whitespace {
+ w := &whitespace{
+ re: r,
+ style: r.ColorProfile().String(),
+ }
+ for _, opt := range opts {
+ opt(w)
+ }
+ return w
+}
+
+// Render whitespaces.
+func (w whitespace) render(width int) string {
+ if w.chars == "" {
+ w.chars = " "
+ }
+
+ r := []rune(w.chars)
+ j := 0
+ b := strings.Builder{}
+
+ // Cycle through runes and print them into the whitespace.
+ for i := 0; i < width; {
+ b.WriteRune(r[j])
+ j++
+ if j >= len(r) {
+ j = 0
+ }
+ i += ansi.StringWidth(string(r[j]))
+ }
+
+ // Fill any extra gaps white spaces. This might be necessary if any runes
+ // are more than one cell wide, which could leave a one-rune gap.
+ short := width - ansi.StringWidth(b.String())
+ if short > 0 {
+ b.WriteString(strings.Repeat(" ", short))
+ }
+
+ return w.style.Styled(b.String())
+}
+
+// WhitespaceOption sets a styling rule for rendering whitespace.
+type WhitespaceOption func(*whitespace)
+
+// WithWhitespaceForeground sets the color of the characters in the whitespace.
+func WithWhitespaceForeground(c TerminalColor) WhitespaceOption {
+ return func(w *whitespace) {
+ w.style = w.style.Foreground(c.color(w.re))
+ }
+}
+
+// WithWhitespaceBackground sets the background color of the whitespace.
+func WithWhitespaceBackground(c TerminalColor) WhitespaceOption {
+ return func(w *whitespace) {
+ w.style = w.style.Background(c.color(w.re))
+ }
+}
+
+// WithWhitespaceChars sets the characters to be rendered in the whitespace.
+func WithWhitespaceChars(s string) WhitespaceOption {
+ return func(w *whitespace) {
+ w.chars = s
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/LICENSE b/vendor/github.com/charmbracelet/x/ansi/LICENSE
new file mode 100644
index 00000000..65a5654e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Charmbracelet, Inc.
+
+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.
diff --git a/vendor/github.com/charmbracelet/x/ansi/ansi.go b/vendor/github.com/charmbracelet/x/ansi/ansi.go
new file mode 100644
index 00000000..48d873c3
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/ansi.go
@@ -0,0 +1,11 @@
+package ansi
+
+import "io"
+
+// Execute is a function that "execute" the given escape sequence by writing it
+// to the provided output writter.
+//
+// This is a syntactic sugar over [io.WriteString].
+func Execute(w io.Writer, s string) (int, error) {
+ return io.WriteString(w, s)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/ascii.go b/vendor/github.com/charmbracelet/x/ansi/ascii.go
new file mode 100644
index 00000000..188582f7
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/ascii.go
@@ -0,0 +1,8 @@
+package ansi
+
+const (
+ // SP is the space character (Char: \x20).
+ SP = 0x20
+ // DEL is the delete character (Caret: ^?, Char: \x7f).
+ DEL = 0x7F
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/background.go b/vendor/github.com/charmbracelet/x/ansi/background.go
new file mode 100644
index 00000000..2383cf09
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/background.go
@@ -0,0 +1,169 @@
+package ansi
+
+import (
+ "fmt"
+ "image/color"
+)
+
+// Colorizer is a [color.Color] interface that can be formatted as a string.
+type Colorizer interface {
+ color.Color
+ fmt.Stringer
+}
+
+// HexColorizer is a [color.Color] that can be formatted as a hex string.
+type HexColorizer struct{ color.Color }
+
+var _ Colorizer = HexColorizer{}
+
+// String returns the color as a hex string. If the color is nil, an empty
+// string is returned.
+func (h HexColorizer) String() string {
+ if h.Color == nil {
+ return ""
+ }
+ r, g, b, _ := h.RGBA()
+ // Get the lower 8 bits
+ r &= 0xff
+ g &= 0xff
+ b &= 0xff
+ return fmt.Sprintf("#%02x%02x%02x", uint8(r), uint8(g), uint8(b)) //nolint:gosec
+}
+
+// XRGBColorizer is a [color.Color] that can be formatted as an XParseColor
+// rgb: string.
+//
+// See: https://linux.die.net/man/3/xparsecolor
+type XRGBColorizer struct{ color.Color }
+
+var _ Colorizer = XRGBColorizer{}
+
+// String returns the color as an XParseColor rgb: string. If the color is nil,
+// an empty string is returned.
+func (x XRGBColorizer) String() string {
+ if x.Color == nil {
+ return ""
+ }
+ r, g, b, _ := x.RGBA()
+ // Get the lower 8 bits
+ return fmt.Sprintf("rgb:%04x/%04x/%04x", r, g, b)
+}
+
+// XRGBAColorizer is a [color.Color] that can be formatted as an XParseColor
+// rgba: string.
+//
+// See: https://linux.die.net/man/3/xparsecolor
+type XRGBAColorizer struct{ color.Color }
+
+var _ Colorizer = XRGBAColorizer{}
+
+// String returns the color as an XParseColor rgba: string. If the color is nil,
+// an empty string is returned.
+func (x XRGBAColorizer) String() string {
+ if x.Color == nil {
+ return ""
+ }
+ r, g, b, a := x.RGBA()
+ // Get the lower 8 bits
+ return fmt.Sprintf("rgba:%04x/%04x/%04x/%04x", r, g, b, a)
+}
+
+// SetForegroundColor returns a sequence that sets the default terminal
+// foreground color.
+//
+// OSC 10 ; color ST
+// OSC 10 ; color BEL
+//
+// Where color is the encoded color number.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func SetForegroundColor(c color.Color) string {
+ var s string
+ switch c := c.(type) {
+ case Colorizer:
+ s = c.String()
+ case fmt.Stringer:
+ s = c.String()
+ default:
+ s = HexColorizer{c}.String()
+ }
+ return "\x1b]10;" + s + "\x07"
+}
+
+// RequestForegroundColor is a sequence that requests the current default
+// terminal foreground color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const RequestForegroundColor = "\x1b]10;?\x07"
+
+// ResetForegroundColor is a sequence that resets the default terminal
+// foreground color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const ResetForegroundColor = "\x1b]110\x07"
+
+// SetBackgroundColor returns a sequence that sets the default terminal
+// background color.
+//
+// OSC 11 ; color ST
+// OSC 11 ; color BEL
+//
+// Where color is the encoded color number.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func SetBackgroundColor(c color.Color) string {
+ var s string
+ switch c := c.(type) {
+ case Colorizer:
+ s = c.String()
+ case fmt.Stringer:
+ s = c.String()
+ default:
+ s = HexColorizer{c}.String()
+ }
+ return "\x1b]11;" + s + "\x07"
+}
+
+// RequestBackgroundColor is a sequence that requests the current default
+// terminal background color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const RequestBackgroundColor = "\x1b]11;?\x07"
+
+// ResetBackgroundColor is a sequence that resets the default terminal
+// background color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const ResetBackgroundColor = "\x1b]111\x07"
+
+// SetCursorColor returns a sequence that sets the terminal cursor color.
+//
+// OSC 12 ; color ST
+// OSC 12 ; color BEL
+//
+// Where color is the encoded color number.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func SetCursorColor(c color.Color) string {
+ var s string
+ switch c := c.(type) {
+ case Colorizer:
+ s = c.String()
+ case fmt.Stringer:
+ s = c.String()
+ default:
+ s = HexColorizer{c}.String()
+ }
+ return "\x1b]12;" + s + "\x07"
+}
+
+// RequestCursorColor is a sequence that requests the current terminal cursor
+// color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const RequestCursorColor = "\x1b]12;?\x07"
+
+// ResetCursorColor is a sequence that resets the terminal cursor color.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+const ResetCursorColor = "\x1b]112\x07"
diff --git a/vendor/github.com/charmbracelet/x/ansi/c0.go b/vendor/github.com/charmbracelet/x/ansi/c0.go
new file mode 100644
index 00000000..28ff7c2a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/c0.go
@@ -0,0 +1,79 @@
+package ansi
+
+// C0 control characters.
+//
+// These range from (0x00-0x1F) as defined in ISO 646 (ASCII).
+// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes
+const (
+ // NUL is the null character (Caret: ^@, Char: \0).
+ NUL = 0x00
+ // SOH is the start of heading character (Caret: ^A).
+ SOH = 0x01
+ // STX is the start of text character (Caret: ^B).
+ STX = 0x02
+ // ETX is the end of text character (Caret: ^C).
+ ETX = 0x03
+ // EOT is the end of transmission character (Caret: ^D).
+ EOT = 0x04
+ // ENQ is the enquiry character (Caret: ^E).
+ ENQ = 0x05
+ // ACK is the acknowledge character (Caret: ^F).
+ ACK = 0x06
+ // BEL is the bell character (Caret: ^G, Char: \a).
+ BEL = 0x07
+ // BS is the backspace character (Caret: ^H, Char: \b).
+ BS = 0x08
+ // HT is the horizontal tab character (Caret: ^I, Char: \t).
+ HT = 0x09
+ // LF is the line feed character (Caret: ^J, Char: \n).
+ LF = 0x0A
+ // VT is the vertical tab character (Caret: ^K, Char: \v).
+ VT = 0x0B
+ // FF is the form feed character (Caret: ^L, Char: \f).
+ FF = 0x0C
+ // CR is the carriage return character (Caret: ^M, Char: \r).
+ CR = 0x0D
+ // SO is the shift out character (Caret: ^N).
+ SO = 0x0E
+ // SI is the shift in character (Caret: ^O).
+ SI = 0x0F
+ // DLE is the data link escape character (Caret: ^P).
+ DLE = 0x10
+ // DC1 is the device control 1 character (Caret: ^Q).
+ DC1 = 0x11
+ // DC2 is the device control 2 character (Caret: ^R).
+ DC2 = 0x12
+ // DC3 is the device control 3 character (Caret: ^S).
+ DC3 = 0x13
+ // DC4 is the device control 4 character (Caret: ^T).
+ DC4 = 0x14
+ // NAK is the negative acknowledge character (Caret: ^U).
+ NAK = 0x15
+ // SYN is the synchronous idle character (Caret: ^V).
+ SYN = 0x16
+ // ETB is the end of transmission block character (Caret: ^W).
+ ETB = 0x17
+ // CAN is the cancel character (Caret: ^X).
+ CAN = 0x18
+ // EM is the end of medium character (Caret: ^Y).
+ EM = 0x19
+ // SUB is the substitute character (Caret: ^Z).
+ SUB = 0x1A
+ // ESC is the escape character (Caret: ^[, Char: \e).
+ ESC = 0x1B
+ // FS is the file separator character (Caret: ^\).
+ FS = 0x1C
+ // GS is the group separator character (Caret: ^]).
+ GS = 0x1D
+ // RS is the record separator character (Caret: ^^).
+ RS = 0x1E
+ // US is the unit separator character (Caret: ^_).
+ US = 0x1F
+
+ // LS0 is the locking shift 0 character.
+ // This is an alias for [SI].
+ LS0 = SI
+ // LS1 is the locking shift 1 character.
+ // This is an alias for [SO].
+ LS1 = SO
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/c1.go b/vendor/github.com/charmbracelet/x/ansi/c1.go
new file mode 100644
index 00000000..71058f53
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/c1.go
@@ -0,0 +1,72 @@
+package ansi
+
+// C1 control characters.
+//
+// These range from (0x80-0x9F) as defined in ISO 6429 (ECMA-48).
+// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes
+const (
+ // PAD is the padding character.
+ PAD = 0x80
+ // HOP is the high octet preset character.
+ HOP = 0x81
+ // BPH is the break permitted here character.
+ BPH = 0x82
+ // NBH is the no break here character.
+ NBH = 0x83
+ // IND is the index character.
+ IND = 0x84
+ // NEL is the next line character.
+ NEL = 0x85
+ // SSA is the start of selected area character.
+ SSA = 0x86
+ // ESA is the end of selected area character.
+ ESA = 0x87
+ // HTS is the horizontal tab set character.
+ HTS = 0x88
+ // HTJ is the horizontal tab with justification character.
+ HTJ = 0x89
+ // VTS is the vertical tab set character.
+ VTS = 0x8A
+ // PLD is the partial line forward character.
+ PLD = 0x8B
+ // PLU is the partial line backward character.
+ PLU = 0x8C
+ // RI is the reverse index character.
+ RI = 0x8D
+ // SS2 is the single shift 2 character.
+ SS2 = 0x8E
+ // SS3 is the single shift 3 character.
+ SS3 = 0x8F
+ // DCS is the device control string character.
+ DCS = 0x90
+ // PU1 is the private use 1 character.
+ PU1 = 0x91
+ // PU2 is the private use 2 character.
+ PU2 = 0x92
+ // STS is the set transmit state character.
+ STS = 0x93
+ // CCH is the cancel character.
+ CCH = 0x94
+ // MW is the message waiting character.
+ MW = 0x95
+ // SPA is the start of guarded area character.
+ SPA = 0x96
+ // EPA is the end of guarded area character.
+ EPA = 0x97
+ // SOS is the start of string character.
+ SOS = 0x98
+ // SGCI is the single graphic character introducer character.
+ SGCI = 0x99
+ // SCI is the single character introducer character.
+ SCI = 0x9A
+ // CSI is the control sequence introducer character.
+ CSI = 0x9B
+ // ST is the string terminator character.
+ ST = 0x9C
+ // OSC is the operating system command character.
+ OSC = 0x9D
+ // PM is the privacy message character.
+ PM = 0x9E
+ // APC is the application program command character.
+ APC = 0x9F
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/charset.go b/vendor/github.com/charmbracelet/x/ansi/charset.go
new file mode 100644
index 00000000..50fff51f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/charset.go
@@ -0,0 +1,55 @@
+package ansi
+
+// SelectCharacterSet sets the G-set character designator to the specified
+// character set.
+//
+// ESC Ps Pd
+//
+// Where Ps is the G-set character designator, and Pd is the identifier.
+// For 94-character sets, the designator can be one of:
+// - ( G0
+// - ) G1
+// - * G2
+// - + G3
+//
+// For 96-character sets, the designator can be one of:
+// - - G1
+// - . G2
+// - / G3
+//
+// Some common 94-character sets are:
+// - 0 DEC Special Drawing Set
+// - A United Kingdom (UK)
+// - B United States (USASCII)
+//
+// Examples:
+//
+// ESC ( B Select character set G0 = United States (USASCII)
+// ESC ( 0 Select character set G0 = Special Character and Line Drawing Set
+// ESC ) 0 Select character set G1 = Special Character and Line Drawing Set
+// ESC * A Select character set G2 = United Kingdom (UK)
+//
+// See: https://vt100.net/docs/vt510-rm/SCS.html
+func SelectCharacterSet(gset byte, charset byte) string {
+ return "\x1b" + string(gset) + string(charset)
+}
+
+// SCS is an alias for SelectCharacterSet.
+func SCS(gset byte, charset byte) string {
+ return SelectCharacterSet(gset, charset)
+}
+
+// Locking Shift 1 Right (LS1R) shifts G1 into GR character set.
+const LS1R = "\x1b~"
+
+// Locking Shift 2 (LS2) shifts G2 into GL character set.
+const LS2 = "\x1bn"
+
+// Locking Shift 2 Right (LS2R) shifts G2 into GR character set.
+const LS2R = "\x1b}"
+
+// Locking Shift 3 (LS3) shifts G3 into GL character set.
+const LS3 = "\x1bo"
+
+// Locking Shift 3 Right (LS3R) shifts G3 into GR character set.
+const LS3R = "\x1b|"
diff --git a/vendor/github.com/charmbracelet/x/ansi/clipboard.go b/vendor/github.com/charmbracelet/x/ansi/clipboard.go
new file mode 100644
index 00000000..94d26c36
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/clipboard.go
@@ -0,0 +1,75 @@
+package ansi
+
+import "encoding/base64"
+
+// Clipboard names.
+const (
+ SystemClipboard = 'c'
+ PrimaryClipboard = 'p'
+)
+
+// SetClipboard returns a sequence for manipulating the clipboard.
+//
+// OSC 52 ; Pc ; Pd ST
+// OSC 52 ; Pc ; Pd BEL
+//
+// Where Pc is the clipboard name and Pd is the base64 encoded data.
+// Empty data or invalid base64 data will reset the clipboard.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func SetClipboard(c byte, d string) string {
+ if d != "" {
+ d = base64.StdEncoding.EncodeToString([]byte(d))
+ }
+ return "\x1b]52;" + string(c) + ";" + d + "\x07"
+}
+
+// SetSystemClipboard returns a sequence for setting the system clipboard.
+//
+// This is equivalent to SetClipboard(SystemClipboard, d).
+func SetSystemClipboard(d string) string {
+ return SetClipboard(SystemClipboard, d)
+}
+
+// SetPrimaryClipboard returns a sequence for setting the primary clipboard.
+//
+// This is equivalent to SetClipboard(PrimaryClipboard, d).
+func SetPrimaryClipboard(d string) string {
+ return SetClipboard(PrimaryClipboard, d)
+}
+
+// ResetClipboard returns a sequence for resetting the clipboard.
+//
+// This is equivalent to SetClipboard(c, "").
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func ResetClipboard(c byte) string {
+ return SetClipboard(c, "")
+}
+
+// ResetSystemClipboard is a sequence for resetting the system clipboard.
+//
+// This is equivalent to ResetClipboard(SystemClipboard).
+const ResetSystemClipboard = "\x1b]52;c;\x07"
+
+// ResetPrimaryClipboard is a sequence for resetting the primary clipboard.
+//
+// This is equivalent to ResetClipboard(PrimaryClipboard).
+const ResetPrimaryClipboard = "\x1b]52;p;\x07"
+
+// RequestClipboard returns a sequence for requesting the clipboard.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func RequestClipboard(c byte) string {
+ return "\x1b]52;" + string(c) + ";?\x07"
+}
+
+// RequestSystemClipboard is a sequence for requesting the system clipboard.
+//
+// This is equivalent to RequestClipboard(SystemClipboard).
+const RequestSystemClipboard = "\x1b]52;c;?\x07"
+
+// RequestPrimaryClipboard is a sequence for requesting the primary clipboard.
+//
+// This is equivalent to RequestClipboard(PrimaryClipboard).
+const RequestPrimaryClipboard = "\x1b]52;p;?\x07"
diff --git a/vendor/github.com/charmbracelet/x/ansi/color.go b/vendor/github.com/charmbracelet/x/ansi/color.go
new file mode 100644
index 00000000..77f8a08d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/color.go
@@ -0,0 +1,196 @@
+package ansi
+
+import (
+ "image/color"
+)
+
+// Technically speaking, the 16 basic ANSI colors are arbitrary and can be
+// customized at the terminal level. Given that, we're returning what we feel
+// are good defaults.
+//
+// This could also be a slice, but we use a map to make the mappings very
+// explicit.
+//
+// See: https://www.ditig.com/publications/256-colors-cheat-sheet
+var lowANSI = map[uint32]uint32{
+ 0: 0x000000, // black
+ 1: 0x800000, // red
+ 2: 0x008000, // green
+ 3: 0x808000, // yellow
+ 4: 0x000080, // blue
+ 5: 0x800080, // magenta
+ 6: 0x008080, // cyan
+ 7: 0xc0c0c0, // white
+ 8: 0x808080, // bright black
+ 9: 0xff0000, // bright red
+ 10: 0x00ff00, // bright green
+ 11: 0xffff00, // bright yellow
+ 12: 0x0000ff, // bright blue
+ 13: 0xff00ff, // bright magenta
+ 14: 0x00ffff, // bright cyan
+ 15: 0xffffff, // bright white
+}
+
+// Color is a color that can be used in a terminal. ANSI (including
+// ANSI256) and 24-bit "true colors" fall under this category.
+type Color interface {
+ color.Color
+}
+
+// BasicColor is an ANSI 3-bit or 4-bit color with a value from 0 to 15.
+type BasicColor uint8
+
+var _ Color = BasicColor(0)
+
+const (
+ // Black is the ANSI black color.
+ Black BasicColor = iota
+
+ // Red is the ANSI red color.
+ Red
+
+ // Green is the ANSI green color.
+ Green
+
+ // Yellow is the ANSI yellow color.
+ Yellow
+
+ // Blue is the ANSI blue color.
+ Blue
+
+ // Magenta is the ANSI magenta color.
+ Magenta
+
+ // Cyan is the ANSI cyan color.
+ Cyan
+
+ // White is the ANSI white color.
+ White
+
+ // BrightBlack is the ANSI bright black color.
+ BrightBlack
+
+ // BrightRed is the ANSI bright red color.
+ BrightRed
+
+ // BrightGreen is the ANSI bright green color.
+ BrightGreen
+
+ // BrightYellow is the ANSI bright yellow color.
+ BrightYellow
+
+ // BrightBlue is the ANSI bright blue color.
+ BrightBlue
+
+ // BrightMagenta is the ANSI bright magenta color.
+ BrightMagenta
+
+ // BrightCyan is the ANSI bright cyan color.
+ BrightCyan
+
+ // BrightWhite is the ANSI bright white color.
+ BrightWhite
+)
+
+// RGBA returns the red, green, blue and alpha components of the color. It
+// satisfies the color.Color interface.
+func (c BasicColor) RGBA() (uint32, uint32, uint32, uint32) {
+ ansi := uint32(c)
+ if ansi > 15 {
+ return 0, 0, 0, 0xffff
+ }
+
+ r, g, b := ansiToRGB(ansi)
+ return toRGBA(r, g, b)
+}
+
+// ExtendedColor is an ANSI 256 (8-bit) color with a value from 0 to 255.
+type ExtendedColor uint8
+
+var _ Color = ExtendedColor(0)
+
+// RGBA returns the red, green, blue and alpha components of the color. It
+// satisfies the color.Color interface.
+func (c ExtendedColor) RGBA() (uint32, uint32, uint32, uint32) {
+ r, g, b := ansiToRGB(uint32(c))
+ return toRGBA(r, g, b)
+}
+
+// TrueColor is a 24-bit color that can be used in the terminal.
+// This can be used to represent RGB colors.
+//
+// For example, the color red can be represented as:
+//
+// TrueColor(0xff0000)
+type TrueColor uint32
+
+var _ Color = TrueColor(0)
+
+// RGBA returns the red, green, blue and alpha components of the color. It
+// satisfies the color.Color interface.
+func (c TrueColor) RGBA() (uint32, uint32, uint32, uint32) {
+ r, g, b := hexToRGB(uint32(c))
+ return toRGBA(r, g, b)
+}
+
+// ansiToRGB converts an ANSI color to a 24-bit RGB color.
+//
+// r, g, b := ansiToRGB(57)
+func ansiToRGB(ansi uint32) (uint32, uint32, uint32) {
+ // For out-of-range values return black.
+ if ansi > 255 {
+ return 0, 0, 0
+ }
+
+ // Low ANSI.
+ if ansi < 16 {
+ h, ok := lowANSI[ansi]
+ if !ok {
+ return 0, 0, 0
+ }
+ r, g, b := hexToRGB(h)
+ return r, g, b
+ }
+
+ // Grays.
+ if ansi > 231 {
+ s := (ansi-232)*10 + 8
+ return s, s, s
+ }
+
+ // ANSI256.
+ n := ansi - 16
+ b := n % 6
+ g := (n - b) / 6 % 6
+ r := (n - b - g*6) / 36 % 6
+ for _, v := range []*uint32{&r, &g, &b} {
+ if *v > 0 {
+ c := *v*40 + 55
+ *v = c
+ }
+ }
+
+ return r, g, b
+}
+
+// hexToRGB converts a number in hexadecimal format to red, green, and blue
+// values.
+//
+// r, g, b := hexToRGB(0x0000FF)
+func hexToRGB(hex uint32) (uint32, uint32, uint32) {
+ return hex >> 16 & 0xff, hex >> 8 & 0xff, hex & 0xff
+}
+
+// toRGBA converts an RGB 8-bit color values to 32-bit color values suitable
+// for color.Color.
+//
+// color.Color requires 16-bit color values, so we duplicate the 8-bit values
+// to fill the 16-bit values.
+//
+// This always returns 0xffff (opaque) for the alpha channel.
+func toRGBA(r, g, b uint32) (uint32, uint32, uint32, uint32) {
+ r |= r << 8
+ g |= g << 8
+ b |= b << 8
+ return r, g, b, 0xffff
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/ctrl.go b/vendor/github.com/charmbracelet/x/ansi/ctrl.go
new file mode 100644
index 00000000..8ca744cf
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/ctrl.go
@@ -0,0 +1,137 @@
+package ansi
+
+import (
+ "strconv"
+ "strings"
+)
+
+// RequestNameVersion (XTVERSION) is a control sequence that requests the
+// terminal's name and version. It responds with a DSR sequence identifying the
+// terminal.
+//
+// CSI > 0 q
+// DCS > | text ST
+//
+// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-PC-Style-Function-Keys
+const (
+ RequestNameVersion = "\x1b[>q"
+ XTVERSION = RequestNameVersion
+)
+
+// RequestXTVersion is a control sequence that requests the terminal's XTVERSION. It responds with a DSR sequence identifying the version.
+//
+// CSI > Ps q
+// DCS > | text ST
+//
+// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-PC-Style-Function-Keys
+//
+// Deprecated: use [RequestNameVersion] instead.
+const RequestXTVersion = RequestNameVersion
+
+// PrimaryDeviceAttributes (DA1) is a control sequence that reports the
+// terminal's primary device attributes.
+//
+// CSI c
+// CSI 0 c
+// CSI ? Ps ; ... c
+//
+// If no attributes are given, or if the attribute is 0, this function returns
+// the request sequence. Otherwise, it returns the response sequence.
+//
+// See https://vt100.net/docs/vt510-rm/DA1.html
+func PrimaryDeviceAttributes(attrs ...int) string {
+ if len(attrs) == 0 {
+ return RequestPrimaryDeviceAttributes
+ } else if len(attrs) == 1 && attrs[0] == 0 {
+ return "\x1b[0c"
+ }
+
+ as := make([]string, len(attrs))
+ for i, a := range attrs {
+ as[i] = strconv.Itoa(a)
+ }
+ return "\x1b[?" + strings.Join(as, ";") + "c"
+}
+
+// DA1 is an alias for [PrimaryDeviceAttributes].
+func DA1(attrs ...int) string {
+ return PrimaryDeviceAttributes(attrs...)
+}
+
+// RequestPrimaryDeviceAttributes is a control sequence that requests the
+// terminal's primary device attributes (DA1).
+//
+// CSI c
+//
+// See https://vt100.net/docs/vt510-rm/DA1.html
+const RequestPrimaryDeviceAttributes = "\x1b[c"
+
+// SecondaryDeviceAttributes (DA2) is a control sequence that reports the
+// terminal's secondary device attributes.
+//
+// CSI > c
+// CSI > 0 c
+// CSI > Ps ; ... c
+//
+// See https://vt100.net/docs/vt510-rm/DA2.html
+func SecondaryDeviceAttributes(attrs ...int) string {
+ if len(attrs) == 0 {
+ return RequestSecondaryDeviceAttributes
+ }
+
+ as := make([]string, len(attrs))
+ for i, a := range attrs {
+ as[i] = strconv.Itoa(a)
+ }
+ return "\x1b[>" + strings.Join(as, ";") + "c"
+}
+
+// DA2 is an alias for [SecondaryDeviceAttributes].
+func DA2(attrs ...int) string {
+ return SecondaryDeviceAttributes(attrs...)
+}
+
+// RequestSecondaryDeviceAttributes is a control sequence that requests the
+// terminal's secondary device attributes (DA2).
+//
+// CSI > c
+//
+// See https://vt100.net/docs/vt510-rm/DA2.html
+const RequestSecondaryDeviceAttributes = "\x1b[>c"
+
+// TertiaryDeviceAttributes (DA3) is a control sequence that reports the
+// terminal's tertiary device attributes.
+//
+// CSI = c
+// CSI = 0 c
+// DCS ! | Text ST
+//
+// Where Text is the unit ID for the terminal.
+//
+// If no unit ID is given, or if the unit ID is 0, this function returns the
+// request sequence. Otherwise, it returns the response sequence.
+//
+// See https://vt100.net/docs/vt510-rm/DA3.html
+func TertiaryDeviceAttributes(unitID string) string {
+ switch unitID {
+ case "":
+ return RequestTertiaryDeviceAttributes
+ case "0":
+ return "\x1b[=0c"
+ }
+
+ return "\x1bP!|" + unitID + "\x1b\\"
+}
+
+// DA3 is an alias for [TertiaryDeviceAttributes].
+func DA3(unitID string) string {
+ return TertiaryDeviceAttributes(unitID)
+}
+
+// RequestTertiaryDeviceAttributes is a control sequence that requests the
+// terminal's tertiary device attributes (DA3).
+//
+// CSI = c
+//
+// See https://vt100.net/docs/vt510-rm/DA3.html
+const RequestTertiaryDeviceAttributes = "\x1b[=c"
diff --git a/vendor/github.com/charmbracelet/x/ansi/cursor.go b/vendor/github.com/charmbracelet/x/ansi/cursor.go
new file mode 100644
index 00000000..0c364d60
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/cursor.go
@@ -0,0 +1,633 @@
+package ansi
+
+import "strconv"
+
+// SaveCursor (DECSC) is an escape sequence that saves the current cursor
+// position.
+//
+// ESC 7
+//
+// See: https://vt100.net/docs/vt510-rm/DECSC.html
+const (
+ SaveCursor = "\x1b7"
+ DECSC = SaveCursor
+)
+
+// RestoreCursor (DECRC) is an escape sequence that restores the cursor
+// position.
+//
+// ESC 8
+//
+// See: https://vt100.net/docs/vt510-rm/DECRC.html
+const (
+ RestoreCursor = "\x1b8"
+ DECRC = RestoreCursor
+)
+
+// RequestCursorPosition is an escape sequence that requests the current cursor
+// position.
+//
+// CSI 6 n
+//
+// The terminal will report the cursor position as a CSI sequence in the
+// following format:
+//
+// CSI Pl ; Pc R
+//
+// Where Pl is the line number and Pc is the column number.
+// See: https://vt100.net/docs/vt510-rm/CPR.html
+//
+// Deprecated: use [RequestCursorPositionReport] instead.
+const RequestCursorPosition = "\x1b[6n"
+
+// RequestExtendedCursorPosition (DECXCPR) is a sequence for requesting the
+// cursor position report including the current page number.
+//
+// CSI ? 6 n
+//
+// The terminal will report the cursor position as a CSI sequence in the
+// following format:
+//
+// CSI ? Pl ; Pc ; Pp R
+//
+// Where Pl is the line number, Pc is the column number, and Pp is the page
+// number.
+// See: https://vt100.net/docs/vt510-rm/DECXCPR.html
+//
+// Deprecated: use [RequestExtendedCursorPositionReport] instead.
+const RequestExtendedCursorPosition = "\x1b[?6n"
+
+// CursorUp (CUU) returns a sequence for moving the cursor up n cells.
+//
+// CSI n A
+//
+// See: https://vt100.net/docs/vt510-rm/CUU.html
+func CursorUp(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "A"
+}
+
+// CUU is an alias for [CursorUp].
+func CUU(n int) string {
+ return CursorUp(n)
+}
+
+// CUU1 is a sequence for moving the cursor up one cell.
+const CUU1 = "\x1b[A"
+
+// CursorUp1 is a sequence for moving the cursor up one cell.
+//
+// This is equivalent to CursorUp(1).
+//
+// Deprecated: use [CUU1] instead.
+const CursorUp1 = "\x1b[A"
+
+// CursorDown (CUD) returns a sequence for moving the cursor down n cells.
+//
+// CSI n B
+//
+// See: https://vt100.net/docs/vt510-rm/CUD.html
+func CursorDown(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "B"
+}
+
+// CUD is an alias for [CursorDown].
+func CUD(n int) string {
+ return CursorDown(n)
+}
+
+// CUD1 is a sequence for moving the cursor down one cell.
+const CUD1 = "\x1b[B"
+
+// CursorDown1 is a sequence for moving the cursor down one cell.
+//
+// This is equivalent to CursorDown(1).
+//
+// Deprecated: use [CUD1] instead.
+const CursorDown1 = "\x1b[B"
+
+// CursorForward (CUF) returns a sequence for moving the cursor right n cells.
+//
+// # CSI n C
+//
+// See: https://vt100.net/docs/vt510-rm/CUF.html
+func CursorForward(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "C"
+}
+
+// CUF is an alias for [CursorForward].
+func CUF(n int) string {
+ return CursorForward(n)
+}
+
+// CUF1 is a sequence for moving the cursor right one cell.
+const CUF1 = "\x1b[C"
+
+// CursorRight (CUF) returns a sequence for moving the cursor right n cells.
+//
+// CSI n C
+//
+// See: https://vt100.net/docs/vt510-rm/CUF.html
+//
+// Deprecated: use [CursorForward] instead.
+func CursorRight(n int) string {
+ return CursorForward(n)
+}
+
+// CursorRight1 is a sequence for moving the cursor right one cell.
+//
+// This is equivalent to CursorRight(1).
+//
+// Deprecated: use [CUF1] instead.
+const CursorRight1 = CUF1
+
+// CursorBackward (CUB) returns a sequence for moving the cursor left n cells.
+//
+// # CSI n D
+//
+// See: https://vt100.net/docs/vt510-rm/CUB.html
+func CursorBackward(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "D"
+}
+
+// CUB is an alias for [CursorBackward].
+func CUB(n int) string {
+ return CursorBackward(n)
+}
+
+// CUB1 is a sequence for moving the cursor left one cell.
+const CUB1 = "\x1b[D"
+
+// CursorLeft (CUB) returns a sequence for moving the cursor left n cells.
+//
+// CSI n D
+//
+// See: https://vt100.net/docs/vt510-rm/CUB.html
+//
+// Deprecated: use [CursorBackward] instead.
+func CursorLeft(n int) string {
+ return CursorBackward(n)
+}
+
+// CursorLeft1 is a sequence for moving the cursor left one cell.
+//
+// This is equivalent to CursorLeft(1).
+//
+// Deprecated: use [CUB1] instead.
+const CursorLeft1 = CUB1
+
+// CursorNextLine (CNL) returns a sequence for moving the cursor to the
+// beginning of the next line n times.
+//
+// CSI n E
+//
+// See: https://vt100.net/docs/vt510-rm/CNL.html
+func CursorNextLine(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "E"
+}
+
+// CNL is an alias for [CursorNextLine].
+func CNL(n int) string {
+ return CursorNextLine(n)
+}
+
+// CursorPreviousLine (CPL) returns a sequence for moving the cursor to the
+// beginning of the previous line n times.
+//
+// CSI n F
+//
+// See: https://vt100.net/docs/vt510-rm/CPL.html
+func CursorPreviousLine(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "F"
+}
+
+// CPL is an alias for [CursorPreviousLine].
+func CPL(n int) string {
+ return CursorPreviousLine(n)
+}
+
+// CursorHorizontalAbsolute (CHA) returns a sequence for moving the cursor to
+// the given column.
+//
+// Default is 1.
+//
+// CSI n G
+//
+// See: https://vt100.net/docs/vt510-rm/CHA.html
+func CursorHorizontalAbsolute(col int) string {
+ var s string
+ if col > 0 {
+ s = strconv.Itoa(col)
+ }
+ return "\x1b[" + s + "G"
+}
+
+// CHA is an alias for [CursorHorizontalAbsolute].
+func CHA(col int) string {
+ return CursorHorizontalAbsolute(col)
+}
+
+// CursorPosition (CUP) returns a sequence for setting the cursor to the
+// given row and column.
+//
+// Default is 1,1.
+//
+// CSI n ; m H
+//
+// See: https://vt100.net/docs/vt510-rm/CUP.html
+func CursorPosition(col, row int) string {
+ if row <= 0 && col <= 0 {
+ return HomeCursorPosition
+ }
+
+ var r, c string
+ if row > 0 {
+ r = strconv.Itoa(row)
+ }
+ if col > 0 {
+ c = strconv.Itoa(col)
+ }
+ return "\x1b[" + r + ";" + c + "H"
+}
+
+// CUP is an alias for [CursorPosition].
+func CUP(col, row int) string {
+ return CursorPosition(col, row)
+}
+
+// CursorHomePosition is a sequence for moving the cursor to the upper left
+// corner of the scrolling region. This is equivalent to `CursorPosition(1, 1)`.
+const CursorHomePosition = "\x1b[H"
+
+// SetCursorPosition (CUP) returns a sequence for setting the cursor to the
+// given row and column.
+//
+// CSI n ; m H
+//
+// See: https://vt100.net/docs/vt510-rm/CUP.html
+//
+// Deprecated: use [CursorPosition] instead.
+func SetCursorPosition(col, row int) string {
+ if row <= 0 && col <= 0 {
+ return HomeCursorPosition
+ }
+
+ var r, c string
+ if row > 0 {
+ r = strconv.Itoa(row)
+ }
+ if col > 0 {
+ c = strconv.Itoa(col)
+ }
+ return "\x1b[" + r + ";" + c + "H"
+}
+
+// HomeCursorPosition is a sequence for moving the cursor to the upper left
+// corner of the scrolling region. This is equivalent to `SetCursorPosition(1, 1)`.
+//
+// Deprecated: use [CursorHomePosition] instead.
+const HomeCursorPosition = CursorHomePosition
+
+// MoveCursor (CUP) returns a sequence for setting the cursor to the
+// given row and column.
+//
+// CSI n ; m H
+//
+// See: https://vt100.net/docs/vt510-rm/CUP.html
+//
+// Deprecated: use [CursorPosition] instead.
+func MoveCursor(col, row int) string {
+ return SetCursorPosition(col, row)
+}
+
+// CursorOrigin is a sequence for moving the cursor to the upper left corner of
+// the display. This is equivalent to `SetCursorPosition(1, 1)`.
+//
+// Deprecated: use [CursorHomePosition] instead.
+const CursorOrigin = "\x1b[1;1H"
+
+// MoveCursorOrigin is a sequence for moving the cursor to the upper left
+// corner of the display. This is equivalent to `SetCursorPosition(1, 1)`.
+//
+// Deprecated: use [CursorHomePosition] instead.
+const MoveCursorOrigin = CursorOrigin
+
+// CursorHorizontalForwardTab (CHT) returns a sequence for moving the cursor to
+// the next tab stop n times.
+//
+// Default is 1.
+//
+// CSI n I
+//
+// See: https://vt100.net/docs/vt510-rm/CHT.html
+func CursorHorizontalForwardTab(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "I"
+}
+
+// CHT is an alias for [CursorHorizontalForwardTab].
+func CHT(n int) string {
+ return CursorHorizontalForwardTab(n)
+}
+
+// EraseCharacter (ECH) returns a sequence for erasing n characters and moving
+// the cursor to the right. This doesn't affect other cell attributes.
+//
+// Default is 1.
+//
+// CSI n X
+//
+// See: https://vt100.net/docs/vt510-rm/ECH.html
+func EraseCharacter(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "X"
+}
+
+// ECH is an alias for [EraseCharacter].
+func ECH(n int) string {
+ return EraseCharacter(n)
+}
+
+// CursorBackwardTab (CBT) returns a sequence for moving the cursor to the
+// previous tab stop n times.
+//
+// Default is 1.
+//
+// CSI n Z
+//
+// See: https://vt100.net/docs/vt510-rm/CBT.html
+func CursorBackwardTab(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "Z"
+}
+
+// CBT is an alias for [CursorBackwardTab].
+func CBT(n int) string {
+ return CursorBackwardTab(n)
+}
+
+// VerticalPositionAbsolute (VPA) returns a sequence for moving the cursor to
+// the given row.
+//
+// Default is 1.
+//
+// CSI n d
+//
+// See: https://vt100.net/docs/vt510-rm/VPA.html
+func VerticalPositionAbsolute(row int) string {
+ var s string
+ if row > 0 {
+ s = strconv.Itoa(row)
+ }
+ return "\x1b[" + s + "d"
+}
+
+// VPA is an alias for [VerticalPositionAbsolute].
+func VPA(row int) string {
+ return VerticalPositionAbsolute(row)
+}
+
+// VerticalPositionRelative (VPR) returns a sequence for moving the cursor down
+// n rows relative to the current position.
+//
+// Default is 1.
+//
+// CSI n e
+//
+// See: https://vt100.net/docs/vt510-rm/VPR.html
+func VerticalPositionRelative(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "e"
+}
+
+// VPR is an alias for [VerticalPositionRelative].
+func VPR(n int) string {
+ return VerticalPositionRelative(n)
+}
+
+// HorizontalVerticalPosition (HVP) returns a sequence for moving the cursor to
+// the given row and column.
+//
+// Default is 1,1.
+//
+// CSI n ; m f
+//
+// This has the same effect as [CursorPosition].
+//
+// See: https://vt100.net/docs/vt510-rm/HVP.html
+func HorizontalVerticalPosition(col, row int) string {
+ var r, c string
+ if row > 0 {
+ r = strconv.Itoa(row)
+ }
+ if col > 0 {
+ c = strconv.Itoa(col)
+ }
+ return "\x1b[" + r + ";" + c + "f"
+}
+
+// HVP is an alias for [HorizontalVerticalPosition].
+func HVP(col, row int) string {
+ return HorizontalVerticalPosition(col, row)
+}
+
+// HorizontalVerticalHomePosition is a sequence for moving the cursor to the
+// upper left corner of the scrolling region. This is equivalent to
+// `HorizontalVerticalPosition(1, 1)`.
+const HorizontalVerticalHomePosition = "\x1b[f"
+
+// SaveCurrentCursorPosition (SCOSC) is a sequence for saving the current cursor
+// position for SCO console mode.
+//
+// CSI s
+//
+// This acts like [DECSC], except the page number where the cursor is located
+// is not saved.
+//
+// See: https://vt100.net/docs/vt510-rm/SCOSC.html
+const (
+ SaveCurrentCursorPosition = "\x1b[s"
+ SCOSC = SaveCurrentCursorPosition
+)
+
+// SaveCursorPosition (SCP or SCOSC) is a sequence for saving the cursor
+// position.
+//
+// CSI s
+//
+// This acts like Save, except the page number where the cursor is located is
+// not saved.
+//
+// See: https://vt100.net/docs/vt510-rm/SCOSC.html
+//
+// Deprecated: use [SaveCurrentCursorPosition] instead.
+const SaveCursorPosition = "\x1b[s"
+
+// RestoreCurrentCursorPosition (SCORC) is a sequence for restoring the current
+// cursor position for SCO console mode.
+//
+// CSI u
+//
+// This acts like [DECRC], except the page number where the cursor was saved is
+// not restored.
+//
+// See: https://vt100.net/docs/vt510-rm/SCORC.html
+const (
+ RestoreCurrentCursorPosition = "\x1b[u"
+ SCORC = RestoreCurrentCursorPosition
+)
+
+// RestoreCursorPosition (RCP or SCORC) is a sequence for restoring the cursor
+// position.
+//
+// CSI u
+//
+// This acts like Restore, except the cursor stays on the same page where the
+// cursor was saved.
+//
+// See: https://vt100.net/docs/vt510-rm/SCORC.html
+//
+// Deprecated: use [RestoreCurrentCursorPosition] instead.
+const RestoreCursorPosition = "\x1b[u"
+
+// SetCursorStyle (DECSCUSR) returns a sequence for changing the cursor style.
+//
+// Default is 1.
+//
+// CSI Ps SP q
+//
+// Where Ps is the cursor style:
+//
+// 0: Blinking block
+// 1: Blinking block (default)
+// 2: Steady block
+// 3: Blinking underline
+// 4: Steady underline
+// 5: Blinking bar (xterm)
+// 6: Steady bar (xterm)
+//
+// See: https://vt100.net/docs/vt510-rm/DECSCUSR.html
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
+func SetCursorStyle(style int) string {
+ if style < 0 {
+ style = 0
+ }
+ return "\x1b[" + strconv.Itoa(style) + " q"
+}
+
+// DECSCUSR is an alias for [SetCursorStyle].
+func DECSCUSR(style int) string {
+ return SetCursorStyle(style)
+}
+
+// SetPointerShape returns a sequence for changing the mouse pointer cursor
+// shape. Use "default" for the default pointer shape.
+//
+// OSC 22 ; Pt ST
+// OSC 22 ; Pt BEL
+//
+// Where Pt is the pointer shape name. The name can be anything that the
+// operating system can understand. Some common names are:
+//
+// - copy
+// - crosshair
+// - default
+// - ew-resize
+// - n-resize
+// - text
+// - wait
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
+func SetPointerShape(shape string) string {
+ return "\x1b]22;" + shape + "\x07"
+}
+
+// ReverseIndex (RI) is an escape sequence for moving the cursor up one line in
+// the same column. If the cursor is at the top margin, the screen scrolls
+// down.
+//
+// This has the same effect as [RI].
+const ReverseIndex = "\x1bM"
+
+// HorizontalPositionAbsolute (HPA) returns a sequence for moving the cursor to
+// the given column. This has the same effect as [CUP].
+//
+// Default is 1.
+//
+// CSI n `
+//
+// See: https://vt100.net/docs/vt510-rm/HPA.html
+func HorizontalPositionAbsolute(col int) string {
+ var s string
+ if col > 0 {
+ s = strconv.Itoa(col)
+ }
+ return "\x1b[" + s + "`"
+}
+
+// HPA is an alias for [HorizontalPositionAbsolute].
+func HPA(col int) string {
+ return HorizontalPositionAbsolute(col)
+}
+
+// HorizontalPositionRelative (HPR) returns a sequence for moving the cursor
+// right n columns relative to the current position. This has the same effect
+// as [CUP].
+//
+// Default is 1.
+//
+// CSI n a
+//
+// See: https://vt100.net/docs/vt510-rm/HPR.html
+func HorizontalPositionRelative(n int) string {
+ var s string
+ if n > 0 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "a"
+}
+
+// HPR is an alias for [HorizontalPositionRelative].
+func HPR(n int) string {
+ return HorizontalPositionRelative(n)
+}
+
+// Index (IND) is an escape sequence for moving the cursor down one line in the
+// same column. If the cursor is at the bottom margin, the screen scrolls up.
+// This has the same effect as [IND].
+const Index = "\x1bD"
diff --git a/vendor/github.com/charmbracelet/x/ansi/cwd.go b/vendor/github.com/charmbracelet/x/ansi/cwd.go
new file mode 100644
index 00000000..b03ac1bb
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/cwd.go
@@ -0,0 +1,26 @@
+package ansi
+
+import (
+ "net/url"
+ "path"
+)
+
+// NotifyWorkingDirectory returns a sequence that notifies the terminal
+// of the current working directory.
+//
+// OSC 7 ; Pt BEL
+//
+// Where Pt is a URL in the format "file://[host]/[path]".
+// Set host to "localhost" if this is a path on the local computer.
+//
+// See: https://wezfurlong.org/wezterm/shell-integration.html#osc-7-escape-sequence-to-set-the-working-directory
+// See: https://iterm2.com/documentation-escape-codes.html#:~:text=RemoteHost%20and%20CurrentDir%3A-,OSC%207,-%3B%20%5BPs%5D%20ST
+func NotifyWorkingDirectory(host string, paths ...string) string {
+ path := path.Join(paths...)
+ u := &url.URL{
+ Scheme: "file",
+ Host: host,
+ Path: path,
+ }
+ return "\x1b]7;" + u.String() + "\x07"
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/doc.go b/vendor/github.com/charmbracelet/x/ansi/doc.go
new file mode 100644
index 00000000..e955e9f1
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/doc.go
@@ -0,0 +1,7 @@
+// Package ansi defines common ANSI escape sequences based on the ECMA-48
+// specs.
+//
+// All sequences use 7-bit C1 control codes, which are supported by most
+// terminal emulators. OSC sequences are terminated by a BEL for wider
+// compatibility with terminals.
+package ansi
diff --git a/vendor/github.com/charmbracelet/x/ansi/focus.go b/vendor/github.com/charmbracelet/x/ansi/focus.go
new file mode 100644
index 00000000..4e0207ce
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/focus.go
@@ -0,0 +1,9 @@
+package ansi
+
+// Focus is an escape sequence to notify the terminal that it has focus.
+// This is used with [FocusEventMode].
+const Focus = "\x1b[I"
+
+// Blur is an escape sequence to notify the terminal that it has lost focus.
+// This is used with [FocusEventMode].
+const Blur = "\x1b[O"
diff --git a/vendor/github.com/charmbracelet/x/ansi/graphics.go b/vendor/github.com/charmbracelet/x/ansi/graphics.go
new file mode 100644
index 00000000..604fef47
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/graphics.go
@@ -0,0 +1,199 @@
+package ansi
+
+import (
+ "bytes"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "image"
+ "io"
+ "os"
+ "strings"
+
+ "github.com/charmbracelet/x/ansi/kitty"
+)
+
+// KittyGraphics returns a sequence that encodes the given image in the Kitty
+// graphics protocol.
+//
+// APC G [comma separated options] ; [base64 encoded payload] ST
+//
+// See https://sw.kovidgoyal.net/kitty/graphics-protocol/
+func KittyGraphics(payload []byte, opts ...string) string {
+ var buf bytes.Buffer
+ buf.WriteString("\x1b_G")
+ buf.WriteString(strings.Join(opts, ","))
+ if len(payload) > 0 {
+ buf.WriteString(";")
+ buf.Write(payload)
+ }
+ buf.WriteString("\x1b\\")
+ return buf.String()
+}
+
+var (
+ // KittyGraphicsTempDir is the directory where temporary files are stored.
+ // This is used in [WriteKittyGraphics] along with [os.CreateTemp].
+ KittyGraphicsTempDir = ""
+
+ // KittyGraphicsTempPattern is the pattern used to create temporary files.
+ // This is used in [WriteKittyGraphics] along with [os.CreateTemp].
+ // The Kitty Graphics protocol requires the file path to contain the
+ // substring "tty-graphics-protocol".
+ KittyGraphicsTempPattern = "tty-graphics-protocol-*"
+)
+
+// WriteKittyGraphics writes an image using the Kitty Graphics protocol with
+// the given options to w. It chunks the written data if o.Chunk is true.
+//
+// You can omit m and use nil when rendering an image from a file. In this
+// case, you must provide a file path in o.File and use o.Transmission =
+// [kitty.File]. You can also use o.Transmission = [kitty.TempFile] to write
+// the image to a temporary file. In that case, the file path is ignored, and
+// the image is written to a temporary file that is automatically deleted by
+// the terminal.
+//
+// See https://sw.kovidgoyal.net/kitty/graphics-protocol/
+func WriteKittyGraphics(w io.Writer, m image.Image, o *kitty.Options) error {
+ if o == nil {
+ o = &kitty.Options{}
+ }
+
+ if o.Transmission == 0 && len(o.File) != 0 {
+ o.Transmission = kitty.File
+ }
+
+ var data bytes.Buffer // the data to be encoded into base64
+ e := &kitty.Encoder{
+ Compress: o.Compression == kitty.Zlib,
+ Format: o.Format,
+ }
+
+ switch o.Transmission {
+ case kitty.Direct:
+ if err := e.Encode(&data, m); err != nil {
+ return fmt.Errorf("failed to encode direct image: %w", err)
+ }
+
+ case kitty.SharedMemory:
+ // TODO: Implement shared memory
+ return fmt.Errorf("shared memory transmission is not yet implemented")
+
+ case kitty.File:
+ if len(o.File) == 0 {
+ return kitty.ErrMissingFile
+ }
+
+ f, err := os.Open(o.File)
+ if err != nil {
+ return fmt.Errorf("failed to open file: %w", err)
+ }
+
+ defer f.Close() //nolint:errcheck
+
+ stat, err := f.Stat()
+ if err != nil {
+ return fmt.Errorf("failed to get file info: %w", err)
+ }
+
+ mode := stat.Mode()
+ if !mode.IsRegular() {
+ return fmt.Errorf("file is not a regular file")
+ }
+
+ // Write the file path to the buffer
+ if _, err := data.WriteString(f.Name()); err != nil {
+ return fmt.Errorf("failed to write file path to buffer: %w", err)
+ }
+
+ case kitty.TempFile:
+ f, err := os.CreateTemp(KittyGraphicsTempDir, KittyGraphicsTempPattern)
+ if err != nil {
+ return fmt.Errorf("failed to create file: %w", err)
+ }
+
+ defer f.Close() //nolint:errcheck
+
+ if err := e.Encode(f, m); err != nil {
+ return fmt.Errorf("failed to encode image to file: %w", err)
+ }
+
+ // Write the file path to the buffer
+ if _, err := data.WriteString(f.Name()); err != nil {
+ return fmt.Errorf("failed to write file path to buffer: %w", err)
+ }
+ }
+
+ // Encode image to base64
+ var payload bytes.Buffer // the base64 encoded image to be written to w
+ b64 := base64.NewEncoder(base64.StdEncoding, &payload)
+ if _, err := data.WriteTo(b64); err != nil {
+ return fmt.Errorf("failed to write base64 encoded image to payload: %w", err)
+ }
+ if err := b64.Close(); err != nil {
+ return err
+ }
+
+ // If not chunking, write all at once
+ if !o.Chunk {
+ _, err := io.WriteString(w, KittyGraphics(payload.Bytes(), o.Options()...))
+ return err
+ }
+
+ // Write in chunks
+ var (
+ err error
+ n int
+ )
+ chunk := make([]byte, kitty.MaxChunkSize)
+ isFirstChunk := true
+
+ for {
+ // Stop if we read less than the chunk size [kitty.MaxChunkSize].
+ n, err = io.ReadFull(&payload, chunk)
+ if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) {
+ break
+ }
+ if err != nil {
+ return fmt.Errorf("failed to read chunk: %w", err)
+ }
+
+ opts := buildChunkOptions(o, isFirstChunk, false)
+ if _, err := io.WriteString(w, KittyGraphics(chunk[:n], opts...)); err != nil {
+ return err
+ }
+
+ isFirstChunk = false
+ }
+
+ // Write the last chunk
+ opts := buildChunkOptions(o, isFirstChunk, true)
+ _, err = io.WriteString(w, KittyGraphics(chunk[:n], opts...))
+ return err
+}
+
+// buildChunkOptions creates the options slice for a chunk
+func buildChunkOptions(o *kitty.Options, isFirstChunk, isLastChunk bool) []string {
+ var opts []string
+ if isFirstChunk {
+ opts = o.Options()
+ } else {
+ // These options are allowed in subsequent chunks
+ if o.Quite > 0 {
+ opts = append(opts, fmt.Sprintf("q=%d", o.Quite))
+ }
+ if o.Action == kitty.Frame {
+ opts = append(opts, "a=f")
+ }
+ }
+
+ if !isFirstChunk || !isLastChunk {
+ // We don't need to encode the (m=) option when we only have one chunk.
+ if isLastChunk {
+ opts = append(opts, "m=0")
+ } else {
+ opts = append(opts, "m=1")
+ }
+ }
+ return opts
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/hyperlink.go b/vendor/github.com/charmbracelet/x/ansi/hyperlink.go
new file mode 100644
index 00000000..323bfe93
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/hyperlink.go
@@ -0,0 +1,28 @@
+package ansi
+
+import "strings"
+
+// SetHyperlink returns a sequence for starting a hyperlink.
+//
+// OSC 8 ; Params ; Uri ST
+// OSC 8 ; Params ; Uri BEL
+//
+// To reset the hyperlink, omit the URI.
+//
+// See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
+func SetHyperlink(uri string, params ...string) string {
+ var p string
+ if len(params) > 0 {
+ p = strings.Join(params, ":")
+ }
+ return "\x1b]8;" + p + ";" + uri + "\x07"
+}
+
+// ResetHyperlink returns a sequence for resetting the hyperlink.
+//
+// This is equivalent to SetHyperlink("", params...).
+//
+// See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
+func ResetHyperlink(params ...string) string {
+ return SetHyperlink("", params...)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/iterm2.go b/vendor/github.com/charmbracelet/x/ansi/iterm2.go
new file mode 100644
index 00000000..0ecb336d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/iterm2.go
@@ -0,0 +1,18 @@
+package ansi
+
+import "fmt"
+
+// ITerm2 returns a sequence that uses the iTerm2 proprietary protocol. Use the
+// iterm2 package for a more convenient API.
+//
+// OSC 1337 ; key = value ST
+//
+// Example:
+//
+// ITerm2(iterm2.File{...})
+//
+// See https://iterm2.com/documentation-escape-codes.html
+// See https://iterm2.com/documentation-images.html
+func ITerm2(data any) string {
+ return "\x1b]1337;" + fmt.Sprint(data) + "\x07"
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/keypad.go b/vendor/github.com/charmbracelet/x/ansi/keypad.go
new file mode 100644
index 00000000..9183c6a7
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/keypad.go
@@ -0,0 +1,28 @@
+package ansi
+
+// Keypad Application Mode (DECKPAM) is a mode that determines whether the
+// keypad sends application sequences or ANSI sequences.
+//
+// This works like enabling [DECNKM].
+// Use [NumericKeypadMode] to set the numeric keypad mode.
+//
+// ESC =
+//
+// See: https://vt100.net/docs/vt510-rm/DECKPAM.html
+const (
+ KeypadApplicationMode = "\x1b="
+ DECKPAM = KeypadApplicationMode
+)
+
+// Keypad Numeric Mode (DECKPNM) is a mode that determines whether the keypad
+// sends application sequences or ANSI sequences.
+//
+// This works the same as disabling [DECNKM].
+//
+// ESC >
+//
+// See: https://vt100.net/docs/vt510-rm/DECKPNM.html
+const (
+ KeypadNumericMode = "\x1b>"
+ DECKPNM = KeypadNumericMode
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty.go b/vendor/github.com/charmbracelet/x/ansi/kitty.go
new file mode 100644
index 00000000..124ab839
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/kitty.go
@@ -0,0 +1,90 @@
+package ansi
+
+import "strconv"
+
+// Kitty keyboard protocol progressive enhancement flags.
+// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
+const (
+ KittyDisambiguateEscapeCodes = 1 << iota
+ KittyReportEventTypes
+ KittyReportAlternateKeys
+ KittyReportAllKeysAsEscapeCodes
+ KittyReportAssociatedKeys
+
+ KittyAllFlags = KittyDisambiguateEscapeCodes | KittyReportEventTypes |
+ KittyReportAlternateKeys | KittyReportAllKeysAsEscapeCodes | KittyReportAssociatedKeys
+)
+
+// RequestKittyKeyboard is a sequence to request the terminal Kitty keyboard
+// protocol enabled flags.
+//
+// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/
+const RequestKittyKeyboard = "\x1b[?u"
+
+// KittyKeyboard returns a sequence to request keyboard enhancements from the terminal.
+// The flags argument is a bitmask of the Kitty keyboard protocol flags. While
+// mode specifies how the flags should be interpreted.
+//
+// Possible values for flags mask:
+//
+// 1: Disambiguate escape codes
+// 2: Report event types
+// 4: Report alternate keys
+// 8: Report all keys as escape codes
+// 16: Report associated text
+//
+// Possible values for mode:
+//
+// 1: Set given flags and unset all others
+// 2: Set given flags and keep existing flags unchanged
+// 3: Unset given flags and keep existing flags unchanged
+//
+// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
+func KittyKeyboard(flags, mode int) string {
+ return "\x1b[=" + strconv.Itoa(flags) + ";" + strconv.Itoa(mode) + "u"
+}
+
+// PushKittyKeyboard returns a sequence to push the given flags to the terminal
+// Kitty Keyboard stack.
+//
+// Possible values for flags mask:
+//
+// 0: Disable all features
+// 1: Disambiguate escape codes
+// 2: Report event types
+// 4: Report alternate keys
+// 8: Report all keys as escape codes
+// 16: Report associated text
+//
+// CSI > flags u
+//
+// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
+func PushKittyKeyboard(flags int) string {
+ var f string
+ if flags > 0 {
+ f = strconv.Itoa(flags)
+ }
+
+ return "\x1b[>" + f + "u"
+}
+
+// DisableKittyKeyboard is a sequence to push zero into the terminal Kitty
+// Keyboard stack to disable the protocol.
+//
+// This is equivalent to PushKittyKeyboard(0).
+const DisableKittyKeyboard = "\x1b[>u"
+
+// PopKittyKeyboard returns a sequence to pop n number of flags from the
+// terminal Kitty Keyboard stack.
+//
+// CSI < flags u
+//
+// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
+func PopKittyKeyboard(n int) string {
+ var num string
+ if n > 0 {
+ num = strconv.Itoa(n)
+ }
+
+ return "\x1b[<" + num + "u"
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go b/vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go
new file mode 100644
index 00000000..fbd08441
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go
@@ -0,0 +1,85 @@
+package kitty
+
+import (
+ "compress/zlib"
+ "fmt"
+ "image"
+ "image/color"
+ "image/png"
+ "io"
+)
+
+// Decoder is a decoder for the Kitty graphics protocol. It supports decoding
+// images in the 24-bit [RGB], 32-bit [RGBA], and [PNG] formats. It can also
+// decompress data using zlib.
+// The default format is 32-bit [RGBA].
+type Decoder struct {
+ // Uses zlib decompression.
+ Decompress bool
+
+ // Can be one of [RGB], [RGBA], or [PNG].
+ Format int
+
+ // Width of the image in pixels. This can be omitted if the image is [PNG]
+ // formatted.
+ Width int
+
+ // Height of the image in pixels. This can be omitted if the image is [PNG]
+ // formatted.
+ Height int
+}
+
+// Decode decodes the image data from r in the specified format.
+func (d *Decoder) Decode(r io.Reader) (image.Image, error) {
+ if d.Decompress {
+ zr, err := zlib.NewReader(r)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create zlib reader: %w", err)
+ }
+
+ defer zr.Close() //nolint:errcheck
+ r = zr
+ }
+
+ if d.Format == 0 {
+ d.Format = RGBA
+ }
+
+ switch d.Format {
+ case RGBA, RGB:
+ return d.decodeRGBA(r, d.Format == RGBA)
+
+ case PNG:
+ return png.Decode(r)
+
+ default:
+ return nil, fmt.Errorf("unsupported format: %d", d.Format)
+ }
+}
+
+// decodeRGBA decodes the image data in 32-bit RGBA or 24-bit RGB formats.
+func (d *Decoder) decodeRGBA(r io.Reader, alpha bool) (image.Image, error) {
+ m := image.NewRGBA(image.Rect(0, 0, d.Width, d.Height))
+
+ var buf []byte
+ if alpha {
+ buf = make([]byte, 4)
+ } else {
+ buf = make([]byte, 3)
+ }
+
+ for y := 0; y < d.Height; y++ {
+ for x := 0; x < d.Width; x++ {
+ if _, err := io.ReadFull(r, buf[:]); err != nil {
+ return nil, fmt.Errorf("failed to read pixel data: %w", err)
+ }
+ if alpha {
+ m.SetRGBA(x, y, color.RGBA{buf[0], buf[1], buf[2], buf[3]})
+ } else {
+ m.SetRGBA(x, y, color.RGBA{buf[0], buf[1], buf[2], 0xff})
+ }
+ }
+ }
+
+ return m, nil
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go b/vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go
new file mode 100644
index 00000000..f668b9e3
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go
@@ -0,0 +1,64 @@
+package kitty
+
+import (
+ "compress/zlib"
+ "fmt"
+ "image"
+ "image/png"
+ "io"
+)
+
+// Encoder is an encoder for the Kitty graphics protocol. It supports encoding
+// images in the 24-bit [RGB], 32-bit [RGBA], and [PNG] formats, and
+// compressing the data using zlib.
+// The default format is 32-bit [RGBA].
+type Encoder struct {
+ // Uses zlib compression.
+ Compress bool
+
+ // Can be one of [RGBA], [RGB], or [PNG].
+ Format int
+}
+
+// Encode encodes the image data in the specified format and writes it to w.
+func (e *Encoder) Encode(w io.Writer, m image.Image) error {
+ if m == nil {
+ return nil
+ }
+
+ if e.Compress {
+ zw := zlib.NewWriter(w)
+ defer zw.Close() //nolint:errcheck
+ w = zw
+ }
+
+ if e.Format == 0 {
+ e.Format = RGBA
+ }
+
+ switch e.Format {
+ case RGBA, RGB:
+ bounds := m.Bounds()
+ for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
+ for x := bounds.Min.X; x < bounds.Max.X; x++ {
+ r, g, b, a := m.At(x, y).RGBA()
+ switch e.Format {
+ case RGBA:
+ w.Write([]byte{byte(r >> 8), byte(g >> 8), byte(b >> 8), byte(a >> 8)}) //nolint:errcheck
+ case RGB:
+ w.Write([]byte{byte(r >> 8), byte(g >> 8), byte(b >> 8)}) //nolint:errcheck
+ }
+ }
+ }
+
+ case PNG:
+ if err := png.Encode(w, m); err != nil {
+ return fmt.Errorf("failed to encode PNG: %w", err)
+ }
+
+ default:
+ return fmt.Errorf("unsupported format: %d", e.Format)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go b/vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go
new file mode 100644
index 00000000..490e7a8a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go
@@ -0,0 +1,414 @@
+package kitty
+
+import "errors"
+
+// ErrMissingFile is returned when the file path is missing.
+var ErrMissingFile = errors.New("missing file path")
+
+// MaxChunkSize is the maximum chunk size for the image data.
+const MaxChunkSize = 1024 * 4
+
+// Placeholder is a special Unicode character that can be used as a placeholder
+// for an image.
+const Placeholder = '\U0010EEEE'
+
+// Graphics image format.
+const (
+ // 32-bit RGBA format.
+ RGBA = 32
+
+ // 24-bit RGB format.
+ RGB = 24
+
+ // PNG format.
+ PNG = 100
+)
+
+// Compression types.
+const (
+ Zlib = 'z'
+)
+
+// Transmission types.
+const (
+ // The data transmitted directly in the escape sequence.
+ Direct = 'd'
+
+ // The data transmitted in a regular file.
+ File = 'f'
+
+ // A temporary file is used and deleted after transmission.
+ TempFile = 't'
+
+ // A shared memory object.
+ // For POSIX see https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_open.html
+ // For Windows see https://docs.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory
+ SharedMemory = 's'
+)
+
+// Action types.
+const (
+ // Transmit image data.
+ Transmit = 't'
+ // TransmitAndPut transmit image data and display (put) it.
+ TransmitAndPut = 'T'
+ // Query terminal for image info.
+ Query = 'q'
+ // Put (display) previously transmitted image.
+ Put = 'p'
+ // Delete image.
+ Delete = 'd'
+ // Frame transmits data for animation frames.
+ Frame = 'f'
+ // Animate controls animation.
+ Animate = 'a'
+ // Compose composes animation frames.
+ Compose = 'c'
+)
+
+// Delete types.
+const (
+ // Delete all placements visible on screen
+ DeleteAll = 'a'
+ // Delete all images with the specified id, specified using the i key. If
+ // you specify a p key for the placement id as well, then only the
+ // placement with the specified image id and placement id will be deleted.
+ DeleteID = 'i'
+ // Delete newest image with the specified number, specified using the I
+ // key. If you specify a p key for the placement id as well, then only the
+ // placement with the specified number and placement id will be deleted.
+ DeleteNumber = 'n'
+ // Delete all placements that intersect with the current cursor position.
+ DeleteCursor = 'c'
+ // Delete animation frames.
+ DeleteFrames = 'f'
+ // Delete all placements that intersect a specific cell, the cell is
+ // specified using the x and y keys
+ DeleteCell = 'p'
+ // Delete all placements that intersect a specific cell having a specific
+ // z-index. The cell and z-index is specified using the x, y and z keys.
+ DeleteCellZ = 'q'
+ // Delete all images whose id is greater than or equal to the value of the x
+ // key and less than or equal to the value of the y.
+ DeleteRange = 'r'
+ // Delete all placements that intersect the specified column, specified using
+ // the x key.
+ DeleteColumn = 'x'
+ // Delete all placements that intersect the specified row, specified using
+ // the y key.
+ DeleteRow = 'y'
+ // Delete all placements that have the specified z-index, specified using the
+ // z key.
+ DeleteZ = 'z'
+)
+
+// Diacritic returns the diacritic rune at the specified index. If the index is
+// out of bounds, the first diacritic rune is returned.
+func Diacritic(i int) rune {
+ if i < 0 || i >= len(diacritics) {
+ return diacritics[0]
+ }
+ return diacritics[i]
+}
+
+// From https://sw.kovidgoyal.net/kitty/_downloads/f0a0de9ec8d9ff4456206db8e0814937/rowcolumn-diacritics.txt
+// See https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders for further explanation.
+var diacritics = []rune{
+ '\u0305',
+ '\u030D',
+ '\u030E',
+ '\u0310',
+ '\u0312',
+ '\u033D',
+ '\u033E',
+ '\u033F',
+ '\u0346',
+ '\u034A',
+ '\u034B',
+ '\u034C',
+ '\u0350',
+ '\u0351',
+ '\u0352',
+ '\u0357',
+ '\u035B',
+ '\u0363',
+ '\u0364',
+ '\u0365',
+ '\u0366',
+ '\u0367',
+ '\u0368',
+ '\u0369',
+ '\u036A',
+ '\u036B',
+ '\u036C',
+ '\u036D',
+ '\u036E',
+ '\u036F',
+ '\u0483',
+ '\u0484',
+ '\u0485',
+ '\u0486',
+ '\u0487',
+ '\u0592',
+ '\u0593',
+ '\u0594',
+ '\u0595',
+ '\u0597',
+ '\u0598',
+ '\u0599',
+ '\u059C',
+ '\u059D',
+ '\u059E',
+ '\u059F',
+ '\u05A0',
+ '\u05A1',
+ '\u05A8',
+ '\u05A9',
+ '\u05AB',
+ '\u05AC',
+ '\u05AF',
+ '\u05C4',
+ '\u0610',
+ '\u0611',
+ '\u0612',
+ '\u0613',
+ '\u0614',
+ '\u0615',
+ '\u0616',
+ '\u0617',
+ '\u0657',
+ '\u0658',
+ '\u0659',
+ '\u065A',
+ '\u065B',
+ '\u065D',
+ '\u065E',
+ '\u06D6',
+ '\u06D7',
+ '\u06D8',
+ '\u06D9',
+ '\u06DA',
+ '\u06DB',
+ '\u06DC',
+ '\u06DF',
+ '\u06E0',
+ '\u06E1',
+ '\u06E2',
+ '\u06E4',
+ '\u06E7',
+ '\u06E8',
+ '\u06EB',
+ '\u06EC',
+ '\u0730',
+ '\u0732',
+ '\u0733',
+ '\u0735',
+ '\u0736',
+ '\u073A',
+ '\u073D',
+ '\u073F',
+ '\u0740',
+ '\u0741',
+ '\u0743',
+ '\u0745',
+ '\u0747',
+ '\u0749',
+ '\u074A',
+ '\u07EB',
+ '\u07EC',
+ '\u07ED',
+ '\u07EE',
+ '\u07EF',
+ '\u07F0',
+ '\u07F1',
+ '\u07F3',
+ '\u0816',
+ '\u0817',
+ '\u0818',
+ '\u0819',
+ '\u081B',
+ '\u081C',
+ '\u081D',
+ '\u081E',
+ '\u081F',
+ '\u0820',
+ '\u0821',
+ '\u0822',
+ '\u0823',
+ '\u0825',
+ '\u0826',
+ '\u0827',
+ '\u0829',
+ '\u082A',
+ '\u082B',
+ '\u082C',
+ '\u082D',
+ '\u0951',
+ '\u0953',
+ '\u0954',
+ '\u0F82',
+ '\u0F83',
+ '\u0F86',
+ '\u0F87',
+ '\u135D',
+ '\u135E',
+ '\u135F',
+ '\u17DD',
+ '\u193A',
+ '\u1A17',
+ '\u1A75',
+ '\u1A76',
+ '\u1A77',
+ '\u1A78',
+ '\u1A79',
+ '\u1A7A',
+ '\u1A7B',
+ '\u1A7C',
+ '\u1B6B',
+ '\u1B6D',
+ '\u1B6E',
+ '\u1B6F',
+ '\u1B70',
+ '\u1B71',
+ '\u1B72',
+ '\u1B73',
+ '\u1CD0',
+ '\u1CD1',
+ '\u1CD2',
+ '\u1CDA',
+ '\u1CDB',
+ '\u1CE0',
+ '\u1DC0',
+ '\u1DC1',
+ '\u1DC3',
+ '\u1DC4',
+ '\u1DC5',
+ '\u1DC6',
+ '\u1DC7',
+ '\u1DC8',
+ '\u1DC9',
+ '\u1DCB',
+ '\u1DCC',
+ '\u1DD1',
+ '\u1DD2',
+ '\u1DD3',
+ '\u1DD4',
+ '\u1DD5',
+ '\u1DD6',
+ '\u1DD7',
+ '\u1DD8',
+ '\u1DD9',
+ '\u1DDA',
+ '\u1DDB',
+ '\u1DDC',
+ '\u1DDD',
+ '\u1DDE',
+ '\u1DDF',
+ '\u1DE0',
+ '\u1DE1',
+ '\u1DE2',
+ '\u1DE3',
+ '\u1DE4',
+ '\u1DE5',
+ '\u1DE6',
+ '\u1DFE',
+ '\u20D0',
+ '\u20D1',
+ '\u20D4',
+ '\u20D5',
+ '\u20D6',
+ '\u20D7',
+ '\u20DB',
+ '\u20DC',
+ '\u20E1',
+ '\u20E7',
+ '\u20E9',
+ '\u20F0',
+ '\u2CEF',
+ '\u2CF0',
+ '\u2CF1',
+ '\u2DE0',
+ '\u2DE1',
+ '\u2DE2',
+ '\u2DE3',
+ '\u2DE4',
+ '\u2DE5',
+ '\u2DE6',
+ '\u2DE7',
+ '\u2DE8',
+ '\u2DE9',
+ '\u2DEA',
+ '\u2DEB',
+ '\u2DEC',
+ '\u2DED',
+ '\u2DEE',
+ '\u2DEF',
+ '\u2DF0',
+ '\u2DF1',
+ '\u2DF2',
+ '\u2DF3',
+ '\u2DF4',
+ '\u2DF5',
+ '\u2DF6',
+ '\u2DF7',
+ '\u2DF8',
+ '\u2DF9',
+ '\u2DFA',
+ '\u2DFB',
+ '\u2DFC',
+ '\u2DFD',
+ '\u2DFE',
+ '\u2DFF',
+ '\uA66F',
+ '\uA67C',
+ '\uA67D',
+ '\uA6F0',
+ '\uA6F1',
+ '\uA8E0',
+ '\uA8E1',
+ '\uA8E2',
+ '\uA8E3',
+ '\uA8E4',
+ '\uA8E5',
+ '\uA8E6',
+ '\uA8E7',
+ '\uA8E8',
+ '\uA8E9',
+ '\uA8EA',
+ '\uA8EB',
+ '\uA8EC',
+ '\uA8ED',
+ '\uA8EE',
+ '\uA8EF',
+ '\uA8F0',
+ '\uA8F1',
+ '\uAAB0',
+ '\uAAB2',
+ '\uAAB3',
+ '\uAAB7',
+ '\uAAB8',
+ '\uAABE',
+ '\uAABF',
+ '\uAAC1',
+ '\uFE20',
+ '\uFE21',
+ '\uFE22',
+ '\uFE23',
+ '\uFE24',
+ '\uFE25',
+ '\uFE26',
+ '\U00010A0F',
+ '\U00010A38',
+ '\U0001D185',
+ '\U0001D186',
+ '\U0001D187',
+ '\U0001D188',
+ '\U0001D189',
+ '\U0001D1AA',
+ '\U0001D1AB',
+ '\U0001D1AC',
+ '\U0001D1AD',
+ '\U0001D242',
+ '\U0001D243',
+ '\U0001D244',
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/options.go b/vendor/github.com/charmbracelet/x/ansi/kitty/options.go
new file mode 100644
index 00000000..a8d907bd
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/kitty/options.go
@@ -0,0 +1,367 @@
+package kitty
+
+import (
+ "encoding"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+var (
+ _ encoding.TextMarshaler = Options{}
+ _ encoding.TextUnmarshaler = &Options{}
+)
+
+// Options represents a Kitty Graphics Protocol options.
+type Options struct {
+ // Common options.
+
+ // Action (a=t) is the action to be performed on the image. Can be one of
+ // [Transmit], [TransmitDisplay], [Query], [Put], [Delete], [Frame],
+ // [Animate], [Compose].
+ Action byte
+
+ // Quite mode (q=0) is the quiet mode. Can be either zero, one, or two
+ // where zero is the default, 1 suppresses OK responses, and 2 suppresses
+ // both OK and error responses.
+ Quite byte
+
+ // Transmission options.
+
+ // ID (i=) is the image ID. The ID is a unique identifier for the image.
+ // Must be a positive integer up to [math.MaxUint32].
+ ID int
+
+ // PlacementID (p=) is the placement ID. The placement ID is a unique
+ // identifier for the placement of the image. Must be a positive integer up
+ // to [math.MaxUint32].
+ PlacementID int
+
+ // Number (I=0) is the number of images to be transmitted.
+ Number int
+
+ // Format (f=32) is the image format. One of [RGBA], [RGB], [PNG].
+ Format int
+
+ // ImageWidth (s=0) is the transmitted image width.
+ ImageWidth int
+
+ // ImageHeight (v=0) is the transmitted image height.
+ ImageHeight int
+
+ // Compression (o=) is the image compression type. Can be [Zlib] or zero.
+ Compression byte
+
+ // Transmission (t=d) is the image transmission type. Can be [Direct], [File],
+ // [TempFile], or[SharedMemory].
+ Transmission byte
+
+ // File is the file path to be used when the transmission type is [File].
+ // If [Options.Transmission] is omitted i.e. zero and this is non-empty,
+ // the transmission type is set to [File].
+ File string
+
+ // Size (S=0) is the size to be read from the transmission medium.
+ Size int
+
+ // Offset (O=0) is the offset byte to start reading from the transmission
+ // medium.
+ Offset int
+
+ // Chunk (m=) whether the image is transmitted in chunks. Can be either
+ // zero or one. When true, the image is transmitted in chunks. Each chunk
+ // must be a multiple of 4, and up to [MaxChunkSize] bytes. Each chunk must
+ // have the m=1 option except for the last chunk which must have m=0.
+ Chunk bool
+
+ // Display options.
+
+ // X (x=0) is the pixel X coordinate of the image to start displaying.
+ X int
+
+ // Y (y=0) is the pixel Y coordinate of the image to start displaying.
+ Y int
+
+ // Z (z=0) is the Z coordinate of the image to display.
+ Z int
+
+ // Width (w=0) is the width of the image to display.
+ Width int
+
+ // Height (h=0) is the height of the image to display.
+ Height int
+
+ // OffsetX (X=0) is the OffsetX coordinate of the cursor cell to start
+ // displaying the image. OffsetX=0 is the leftmost cell. This must be
+ // smaller than the terminal cell width.
+ OffsetX int
+
+ // OffsetY (Y=0) is the OffsetY coordinate of the cursor cell to start
+ // displaying the image. OffsetY=0 is the topmost cell. This must be
+ // smaller than the terminal cell height.
+ OffsetY int
+
+ // Columns (c=0) is the number of columns to display the image. The image
+ // will be scaled to fit the number of columns.
+ Columns int
+
+ // Rows (r=0) is the number of rows to display the image. The image will be
+ // scaled to fit the number of rows.
+ Rows int
+
+ // VirtualPlacement (U=0) whether to use virtual placement. This is used
+ // with Unicode [Placeholder] to display images.
+ VirtualPlacement bool
+
+ // DoNotMoveCursor (C=0) whether to move the cursor after displaying the
+ // image.
+ DoNotMoveCursor bool
+
+ // ParentID (P=0) is the parent image ID. The parent ID is the ID of the
+ // image that is the parent of the current image. This is used with Unicode
+ // [Placeholder] to display images relative to the parent image.
+ ParentID int
+
+ // ParentPlacementID (Q=0) is the parent placement ID. The parent placement
+ // ID is the ID of the placement of the parent image. This is used with
+ // Unicode [Placeholder] to display images relative to the parent image.
+ ParentPlacementID int
+
+ // Delete options.
+
+ // Delete (d=a) is the delete action. Can be one of [DeleteAll],
+ // [DeleteID], [DeleteNumber], [DeleteCursor], [DeleteFrames],
+ // [DeleteCell], [DeleteCellZ], [DeleteRange], [DeleteColumn], [DeleteRow],
+ // [DeleteZ].
+ Delete byte
+
+ // DeleteResources indicates whether to delete the resources associated
+ // with the image.
+ DeleteResources bool
+}
+
+// Options returns the options as a slice of a key-value pairs.
+func (o *Options) Options() (opts []string) {
+ opts = []string{}
+ if o.Format == 0 {
+ o.Format = RGBA
+ }
+
+ if o.Action == 0 {
+ o.Action = Transmit
+ }
+
+ if o.Delete == 0 {
+ o.Delete = DeleteAll
+ }
+
+ if o.Transmission == 0 {
+ if len(o.File) > 0 {
+ o.Transmission = File
+ } else {
+ o.Transmission = Direct
+ }
+ }
+
+ if o.Format != RGBA {
+ opts = append(opts, fmt.Sprintf("f=%d", o.Format))
+ }
+
+ if o.Quite > 0 {
+ opts = append(opts, fmt.Sprintf("q=%d", o.Quite))
+ }
+
+ if o.ID > 0 {
+ opts = append(opts, fmt.Sprintf("i=%d", o.ID))
+ }
+
+ if o.PlacementID > 0 {
+ opts = append(opts, fmt.Sprintf("p=%d", o.PlacementID))
+ }
+
+ if o.Number > 0 {
+ opts = append(opts, fmt.Sprintf("I=%d", o.Number))
+ }
+
+ if o.ImageWidth > 0 {
+ opts = append(opts, fmt.Sprintf("s=%d", o.ImageWidth))
+ }
+
+ if o.ImageHeight > 0 {
+ opts = append(opts, fmt.Sprintf("v=%d", o.ImageHeight))
+ }
+
+ if o.Transmission != Direct {
+ opts = append(opts, fmt.Sprintf("t=%c", o.Transmission))
+ }
+
+ if o.Size > 0 {
+ opts = append(opts, fmt.Sprintf("S=%d", o.Size))
+ }
+
+ if o.Offset > 0 {
+ opts = append(opts, fmt.Sprintf("O=%d", o.Offset))
+ }
+
+ if o.Compression == Zlib {
+ opts = append(opts, fmt.Sprintf("o=%c", o.Compression))
+ }
+
+ if o.VirtualPlacement {
+ opts = append(opts, "U=1")
+ }
+
+ if o.DoNotMoveCursor {
+ opts = append(opts, "C=1")
+ }
+
+ if o.ParentID > 0 {
+ opts = append(opts, fmt.Sprintf("P=%d", o.ParentID))
+ }
+
+ if o.ParentPlacementID > 0 {
+ opts = append(opts, fmt.Sprintf("Q=%d", o.ParentPlacementID))
+ }
+
+ if o.X > 0 {
+ opts = append(opts, fmt.Sprintf("x=%d", o.X))
+ }
+
+ if o.Y > 0 {
+ opts = append(opts, fmt.Sprintf("y=%d", o.Y))
+ }
+
+ if o.Z > 0 {
+ opts = append(opts, fmt.Sprintf("z=%d", o.Z))
+ }
+
+ if o.Width > 0 {
+ opts = append(opts, fmt.Sprintf("w=%d", o.Width))
+ }
+
+ if o.Height > 0 {
+ opts = append(opts, fmt.Sprintf("h=%d", o.Height))
+ }
+
+ if o.OffsetX > 0 {
+ opts = append(opts, fmt.Sprintf("X=%d", o.OffsetX))
+ }
+
+ if o.OffsetY > 0 {
+ opts = append(opts, fmt.Sprintf("Y=%d", o.OffsetY))
+ }
+
+ if o.Columns > 0 {
+ opts = append(opts, fmt.Sprintf("c=%d", o.Columns))
+ }
+
+ if o.Rows > 0 {
+ opts = append(opts, fmt.Sprintf("r=%d", o.Rows))
+ }
+
+ if o.Delete != DeleteAll || o.DeleteResources {
+ da := o.Delete
+ if o.DeleteResources {
+ da = da - ' ' // to uppercase
+ }
+
+ opts = append(opts, fmt.Sprintf("d=%c", da))
+ }
+
+ if o.Action != Transmit {
+ opts = append(opts, fmt.Sprintf("a=%c", o.Action))
+ }
+
+ return
+}
+
+// String returns the string representation of the options.
+func (o Options) String() string {
+ return strings.Join(o.Options(), ",")
+}
+
+// MarshalText returns the string representation of the options.
+func (o Options) MarshalText() ([]byte, error) {
+ return []byte(o.String()), nil
+}
+
+// UnmarshalText parses the options from the given string.
+func (o *Options) UnmarshalText(text []byte) error {
+ opts := strings.Split(string(text), ",")
+ for _, opt := range opts {
+ ps := strings.SplitN(opt, "=", 2)
+ if len(ps) != 2 || len(ps[1]) == 0 {
+ continue
+ }
+
+ switch ps[0] {
+ case "a":
+ o.Action = ps[1][0]
+ case "o":
+ o.Compression = ps[1][0]
+ case "t":
+ o.Transmission = ps[1][0]
+ case "d":
+ d := ps[1][0]
+ if d >= 'A' && d <= 'Z' {
+ o.DeleteResources = true
+ d = d + ' ' // to lowercase
+ }
+ o.Delete = d
+ case "i", "q", "p", "I", "f", "s", "v", "S", "O", "m", "x", "y", "z", "w", "h", "X", "Y", "c", "r", "U", "P", "Q":
+ v, err := strconv.Atoi(ps[1])
+ if err != nil {
+ continue
+ }
+
+ switch ps[0] {
+ case "i":
+ o.ID = v
+ case "q":
+ o.Quite = byte(v)
+ case "p":
+ o.PlacementID = v
+ case "I":
+ o.Number = v
+ case "f":
+ o.Format = v
+ case "s":
+ o.ImageWidth = v
+ case "v":
+ o.ImageHeight = v
+ case "S":
+ o.Size = v
+ case "O":
+ o.Offset = v
+ case "m":
+ o.Chunk = v == 0 || v == 1
+ case "x":
+ o.X = v
+ case "y":
+ o.Y = v
+ case "z":
+ o.Z = v
+ case "w":
+ o.Width = v
+ case "h":
+ o.Height = v
+ case "X":
+ o.OffsetX = v
+ case "Y":
+ o.OffsetY = v
+ case "c":
+ o.Columns = v
+ case "r":
+ o.Rows = v
+ case "U":
+ o.VirtualPlacement = v == 1
+ case "P":
+ o.ParentID = v
+ case "Q":
+ o.ParentPlacementID = v
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/method.go b/vendor/github.com/charmbracelet/x/ansi/method.go
new file mode 100644
index 00000000..0218809c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/method.go
@@ -0,0 +1,172 @@
+package ansi
+
+// Method is a type that represents the how the renderer should calculate the
+// display width of cells.
+type Method uint8
+
+// Display width modes.
+const (
+ WcWidth Method = iota
+ GraphemeWidth
+)
+
+// StringWidth returns the width of a string in cells. This is the number of
+// cells that the string will occupy when printed in a terminal. ANSI escape
+// codes are ignored and wide characters (such as East Asians and emojis) are
+// accounted for.
+func (m Method) StringWidth(s string) int {
+ return stringWidth(m, s)
+}
+
+// Truncate truncates a string to a given length, adding a tail to the end if
+// the string is longer than the given length. This function is aware of ANSI
+// escape codes and will not break them, and accounts for wide-characters (such
+// as East-Asian characters and emojis).
+func (m Method) Truncate(s string, length int, tail string) string {
+ return truncate(m, s, length, tail)
+}
+
+// TruncateLeft truncates a string to a given length, adding a prefix to the
+// beginning if the string is longer than the given length. This function is
+// aware of ANSI escape codes and will not break them, and accounts for
+// wide-characters (such as East-Asian characters and emojis).
+func (m Method) TruncateLeft(s string, length int, prefix string) string {
+ return truncateLeft(m, s, length, prefix)
+}
+
+// Cut the string, without adding any prefix or tail strings. This function is
+// aware of ANSI escape codes and will not break them, and accounts for
+// wide-characters (such as East-Asian characters and emojis). Note that the
+// [left] parameter is inclusive, while [right] isn't.
+func (m Method) Cut(s string, left, right int) string {
+ return cut(m, s, left, right)
+}
+
+// Hardwrap wraps a string or a block of text to a given line length, breaking
+// word boundaries. This will preserve ANSI escape codes and will account for
+// wide-characters in the string.
+// When preserveSpace is true, spaces at the beginning of a line will be
+// preserved.
+// This treats the text as a sequence of graphemes.
+func (m Method) Hardwrap(s string, length int, preserveSpace bool) string {
+ return hardwrap(m, s, length, preserveSpace)
+}
+
+// Wordwrap wraps a string or a block of text to a given line length, not
+// breaking word boundaries. This will preserve ANSI escape codes and will
+// account for wide-characters in the string.
+// The breakpoints string is a list of characters that are considered
+// breakpoints for word wrapping. A hyphen (-) is always considered a
+// breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+func (m Method) Wordwrap(s string, length int, breakpoints string) string {
+ return wordwrap(m, s, length, breakpoints)
+}
+
+// Wrap wraps a string or a block of text to a given line length, breaking word
+// boundaries if necessary. This will preserve ANSI escape codes and will
+// account for wide-characters in the string. The breakpoints string is a list
+// of characters that are considered breakpoints for word wrapping. A hyphen
+// (-) is always considered a breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+func (m Method) Wrap(s string, length int, breakpoints string) string {
+ return wrap(m, s, length, breakpoints)
+}
+
+// DecodeSequence decodes the first ANSI escape sequence or a printable
+// grapheme from the given data. It returns the sequence slice, the number of
+// bytes read, the cell width for each sequence, and the new state.
+//
+// The cell width will always be 0 for control and escape sequences, 1 for
+// ASCII printable characters, and the number of cells other Unicode characters
+// occupy. It uses the uniseg package to calculate the width of Unicode
+// graphemes and characters. This means it will always do grapheme clustering
+// (mode 2027).
+//
+// Passing a non-nil [*Parser] as the last argument will allow the decoder to
+// collect sequence parameters, data, and commands. The parser cmd will have
+// the packed command value that contains intermediate and prefix characters.
+// In the case of a OSC sequence, the cmd will be the OSC command number. Use
+// [Cmd] and [Param] types to unpack command intermediates and prefixes as well
+// as parameters.
+//
+// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
+// validity of other data sequences, OSC, DCS, etc, will require checking for
+// the returned sequence terminator bytes such as ST (ESC \\) and BEL).
+//
+// We store the command byte in [Cmd] in the most significant byte, the
+// prefix byte in the next byte, and the intermediate byte in the least
+// significant byte. This is done to avoid using a struct to store the command
+// and its intermediates and prefixes. The command byte is always the least
+// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the
+// command, intermediate, and prefix bytes. Note that we only collect the last
+// prefix character and intermediate byte.
+//
+// The [p.Params] slice will contain the parameters of the sequence. Any
+// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type
+// to unpack the parameters.
+//
+// Example:
+//
+// var state byte // the initial state is always zero [NormalState]
+// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional)
+// input := []byte("\x1b[31mHello, World!\x1b[0m")
+// for len(input) > 0 {
+// seq, width, n, newState := DecodeSequence(input, state, p)
+// log.Printf("seq: %q, width: %d", seq, width)
+// state = newState
+// input = input[n:]
+// }
+func (m Method) DecodeSequence(data []byte, state byte, p *Parser) (seq []byte, width, n int, newState byte) {
+ return decodeSequence(m, data, state, p)
+}
+
+// DecodeSequenceInString decodes the first ANSI escape sequence or a printable
+// grapheme from the given data. It returns the sequence slice, the number of
+// bytes read, the cell width for each sequence, and the new state.
+//
+// The cell width will always be 0 for control and escape sequences, 1 for
+// ASCII printable characters, and the number of cells other Unicode characters
+// occupy. It uses the uniseg package to calculate the width of Unicode
+// graphemes and characters. This means it will always do grapheme clustering
+// (mode 2027).
+//
+// Passing a non-nil [*Parser] as the last argument will allow the decoder to
+// collect sequence parameters, data, and commands. The parser cmd will have
+// the packed command value that contains intermediate and prefix characters.
+// In the case of a OSC sequence, the cmd will be the OSC command number. Use
+// [Cmd] and [Param] types to unpack command intermediates and prefixes as well
+// as parameters.
+//
+// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
+// validity of other data sequences, OSC, DCS, etc, will require checking for
+// the returned sequence terminator bytes such as ST (ESC \\) and BEL).
+//
+// We store the command byte in [Cmd] in the most significant byte, the
+// prefix byte in the next byte, and the intermediate byte in the least
+// significant byte. This is done to avoid using a struct to store the command
+// and its intermediates and prefixes. The command byte is always the least
+// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the
+// command, intermediate, and prefix bytes. Note that we only collect the last
+// prefix character and intermediate byte.
+//
+// The [p.Params] slice will contain the parameters of the sequence. Any
+// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type
+// to unpack the parameters.
+//
+// Example:
+//
+// var state byte // the initial state is always zero [NormalState]
+// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional)
+// input := []byte("\x1b[31mHello, World!\x1b[0m")
+// for len(input) > 0 {
+// seq, width, n, newState := DecodeSequenceInString(input, state, p)
+// log.Printf("seq: %q, width: %d", seq, width)
+// state = newState
+// input = input[n:]
+// }
+func (m Method) DecodeSequenceInString(data string, state byte, p *Parser) (seq string, width, n int, newState byte) {
+ return decodeSequence(m, data, state, p)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/mode.go b/vendor/github.com/charmbracelet/x/ansi/mode.go
new file mode 100644
index 00000000..57f3f0a8
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/mode.go
@@ -0,0 +1,763 @@
+package ansi
+
+import (
+ "strconv"
+ "strings"
+)
+
+// ModeSetting represents a mode setting.
+type ModeSetting byte
+
+// ModeSetting constants.
+const (
+ ModeNotRecognized ModeSetting = iota
+ ModeSet
+ ModeReset
+ ModePermanentlySet
+ ModePermanentlyReset
+)
+
+// IsNotRecognized returns true if the mode is not recognized.
+func (m ModeSetting) IsNotRecognized() bool {
+ return m == ModeNotRecognized
+}
+
+// IsSet returns true if the mode is set or permanently set.
+func (m ModeSetting) IsSet() bool {
+ return m == ModeSet || m == ModePermanentlySet
+}
+
+// IsReset returns true if the mode is reset or permanently reset.
+func (m ModeSetting) IsReset() bool {
+ return m == ModeReset || m == ModePermanentlyReset
+}
+
+// IsPermanentlySet returns true if the mode is permanently set.
+func (m ModeSetting) IsPermanentlySet() bool {
+ return m == ModePermanentlySet
+}
+
+// IsPermanentlyReset returns true if the mode is permanently reset.
+func (m ModeSetting) IsPermanentlyReset() bool {
+ return m == ModePermanentlyReset
+}
+
+// Mode represents an interface for terminal modes.
+// Modes can be set, reset, and requested.
+type Mode interface {
+ Mode() int
+}
+
+// SetMode (SM) returns a sequence to set a mode.
+// The mode arguments are a list of modes to set.
+//
+// If one of the modes is a [DECMode], the function will returns two escape
+// sequences.
+//
+// ANSI format:
+//
+// CSI Pd ; ... ; Pd h
+//
+// DEC format:
+//
+// CSI ? Pd ; ... ; Pd h
+//
+// See: https://vt100.net/docs/vt510-rm/SM.html
+func SetMode(modes ...Mode) string {
+ return setMode(false, modes...)
+}
+
+// SM is an alias for [SetMode].
+func SM(modes ...Mode) string {
+ return SetMode(modes...)
+}
+
+// ResetMode (RM) returns a sequence to reset a mode.
+// The mode arguments are a list of modes to reset.
+//
+// If one of the modes is a [DECMode], the function will returns two escape
+// sequences.
+//
+// ANSI format:
+//
+// CSI Pd ; ... ; Pd l
+//
+// DEC format:
+//
+// CSI ? Pd ; ... ; Pd l
+//
+// See: https://vt100.net/docs/vt510-rm/RM.html
+func ResetMode(modes ...Mode) string {
+ return setMode(true, modes...)
+}
+
+// RM is an alias for [ResetMode].
+func RM(modes ...Mode) string {
+ return ResetMode(modes...)
+}
+
+func setMode(reset bool, modes ...Mode) (s string) {
+ if len(modes) == 0 {
+ return
+ }
+
+ cmd := "h"
+ if reset {
+ cmd = "l"
+ }
+
+ seq := "\x1b["
+ if len(modes) == 1 {
+ switch modes[0].(type) {
+ case DECMode:
+ seq += "?"
+ }
+ return seq + strconv.Itoa(modes[0].Mode()) + cmd
+ }
+
+ dec := make([]string, 0, len(modes)/2)
+ ansi := make([]string, 0, len(modes)/2)
+ for _, m := range modes {
+ switch m.(type) {
+ case DECMode:
+ dec = append(dec, strconv.Itoa(m.Mode()))
+ case ANSIMode:
+ ansi = append(ansi, strconv.Itoa(m.Mode()))
+ }
+ }
+
+ if len(ansi) > 0 {
+ s += seq + strings.Join(ansi, ";") + cmd
+ }
+ if len(dec) > 0 {
+ s += seq + "?" + strings.Join(dec, ";") + cmd
+ }
+ return
+}
+
+// RequestMode (DECRQM) returns a sequence to request a mode from the terminal.
+// The terminal responds with a report mode function [DECRPM].
+//
+// ANSI format:
+//
+// CSI Pa $ p
+//
+// DEC format:
+//
+// CSI ? Pa $ p
+//
+// See: https://vt100.net/docs/vt510-rm/DECRQM.html
+func RequestMode(m Mode) string {
+ seq := "\x1b["
+ switch m.(type) {
+ case DECMode:
+ seq += "?"
+ }
+ return seq + strconv.Itoa(m.Mode()) + "$p"
+}
+
+// DECRQM is an alias for [RequestMode].
+func DECRQM(m Mode) string {
+ return RequestMode(m)
+}
+
+// ReportMode (DECRPM) returns a sequence that the terminal sends to the host
+// in response to a mode request [DECRQM].
+//
+// ANSI format:
+//
+// CSI Pa ; Ps ; $ y
+//
+// DEC format:
+//
+// CSI ? Pa ; Ps $ y
+//
+// Where Pa is the mode number, and Ps is the mode value.
+//
+// 0: Not recognized
+// 1: Set
+// 2: Reset
+// 3: Permanent set
+// 4: Permanent reset
+//
+// See: https://vt100.net/docs/vt510-rm/DECRPM.html
+func ReportMode(mode Mode, value ModeSetting) string {
+ if value > 4 {
+ value = 0
+ }
+ switch mode.(type) {
+ case DECMode:
+ return "\x1b[?" + strconv.Itoa(mode.Mode()) + ";" + strconv.Itoa(int(value)) + "$y"
+ }
+ return "\x1b[" + strconv.Itoa(mode.Mode()) + ";" + strconv.Itoa(int(value)) + "$y"
+}
+
+// DECRPM is an alias for [ReportMode].
+func DECRPM(mode Mode, value ModeSetting) string {
+ return ReportMode(mode, value)
+}
+
+// ANSIMode represents an ANSI terminal mode.
+type ANSIMode int //nolint:revive
+
+// Mode returns the ANSI mode as an integer.
+func (m ANSIMode) Mode() int {
+ return int(m)
+}
+
+// DECMode represents a private DEC terminal mode.
+type DECMode int
+
+// Mode returns the DEC mode as an integer.
+func (m DECMode) Mode() int {
+ return int(m)
+}
+
+// Keyboard Action Mode (KAM) is a mode that controls locking of the keyboard.
+// When the keyboard is locked, it cannot send data to the terminal.
+//
+// See: https://vt100.net/docs/vt510-rm/KAM.html
+const (
+ KeyboardActionMode = ANSIMode(2)
+ KAM = KeyboardActionMode
+
+ SetKeyboardActionMode = "\x1b[2h"
+ ResetKeyboardActionMode = "\x1b[2l"
+ RequestKeyboardActionMode = "\x1b[2$p"
+)
+
+// Insert/Replace Mode (IRM) is a mode that determines whether characters are
+// inserted or replaced when typed.
+//
+// When enabled, characters are inserted at the cursor position pushing the
+// characters to the right. When disabled, characters replace the character at
+// the cursor position.
+//
+// See: https://vt100.net/docs/vt510-rm/IRM.html
+const (
+ InsertReplaceMode = ANSIMode(4)
+ IRM = InsertReplaceMode
+
+ SetInsertReplaceMode = "\x1b[4h"
+ ResetInsertReplaceMode = "\x1b[4l"
+ RequestInsertReplaceMode = "\x1b[4$p"
+)
+
+// Send Receive Mode (SRM) or Local Echo Mode is a mode that determines whether
+// the terminal echoes characters back to the host. When enabled, the terminal
+// sends characters to the host as they are typed.
+//
+// See: https://vt100.net/docs/vt510-rm/SRM.html
+const (
+ SendReceiveMode = ANSIMode(12)
+ LocalEchoMode = SendReceiveMode
+ SRM = SendReceiveMode
+
+ SetSendReceiveMode = "\x1b[12h"
+ ResetSendReceiveMode = "\x1b[12l"
+ RequestSendReceiveMode = "\x1b[12$p"
+
+ SetLocalEchoMode = "\x1b[12h"
+ ResetLocalEchoMode = "\x1b[12l"
+ RequestLocalEchoMode = "\x1b[12$p"
+)
+
+// Line Feed/New Line Mode (LNM) is a mode that determines whether the terminal
+// interprets the line feed character as a new line.
+//
+// When enabled, the terminal interprets the line feed character as a new line.
+// When disabled, the terminal interprets the line feed character as a line feed.
+//
+// A new line moves the cursor to the first position of the next line.
+// A line feed moves the cursor down one line without changing the column
+// scrolling the screen if necessary.
+//
+// See: https://vt100.net/docs/vt510-rm/LNM.html
+const (
+ LineFeedNewLineMode = ANSIMode(20)
+ LNM = LineFeedNewLineMode
+
+ SetLineFeedNewLineMode = "\x1b[20h"
+ ResetLineFeedNewLineMode = "\x1b[20l"
+ RequestLineFeedNewLineMode = "\x1b[20$p"
+)
+
+// Cursor Keys Mode (DECCKM) is a mode that determines whether the cursor keys
+// send ANSI cursor sequences or application sequences.
+//
+// See: https://vt100.net/docs/vt510-rm/DECCKM.html
+const (
+ CursorKeysMode = DECMode(1)
+ DECCKM = CursorKeysMode
+
+ SetCursorKeysMode = "\x1b[?1h"
+ ResetCursorKeysMode = "\x1b[?1l"
+ RequestCursorKeysMode = "\x1b[?1$p"
+)
+
+// Deprecated: use [SetCursorKeysMode] and [ResetCursorKeysMode] instead.
+const (
+ EnableCursorKeys = "\x1b[?1h"
+ DisableCursorKeys = "\x1b[?1l"
+)
+
+// Origin Mode (DECOM) is a mode that determines whether the cursor moves to the
+// home position or the margin position.
+//
+// See: https://vt100.net/docs/vt510-rm/DECOM.html
+const (
+ OriginMode = DECMode(6)
+ DECOM = OriginMode
+
+ SetOriginMode = "\x1b[?6h"
+ ResetOriginMode = "\x1b[?6l"
+ RequestOriginMode = "\x1b[?6$p"
+)
+
+// Auto Wrap Mode (DECAWM) is a mode that determines whether the cursor wraps
+// to the next line when it reaches the right margin.
+//
+// See: https://vt100.net/docs/vt510-rm/DECAWM.html
+const (
+ AutoWrapMode = DECMode(7)
+ DECAWM = AutoWrapMode
+
+ SetAutoWrapMode = "\x1b[?7h"
+ ResetAutoWrapMode = "\x1b[?7l"
+ RequestAutoWrapMode = "\x1b[?7$p"
+)
+
+// X10 Mouse Mode is a mode that determines whether the mouse reports on button
+// presses.
+//
+// The terminal responds with the following encoding:
+//
+// CSI M CbCxCy
+//
+// Where Cb is the button-1, where it can be 1, 2, or 3.
+// Cx and Cy are the x and y coordinates of the mouse event.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ X10MouseMode = DECMode(9)
+
+ SetX10MouseMode = "\x1b[?9h"
+ ResetX10MouseMode = "\x1b[?9l"
+ RequestX10MouseMode = "\x1b[?9$p"
+)
+
+// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor.
+//
+// See: https://vt100.net/docs/vt510-rm/DECTCEM.html
+const (
+ TextCursorEnableMode = DECMode(25)
+ DECTCEM = TextCursorEnableMode
+
+ SetTextCursorEnableMode = "\x1b[?25h"
+ ResetTextCursorEnableMode = "\x1b[?25l"
+ RequestTextCursorEnableMode = "\x1b[?25$p"
+)
+
+// These are aliases for [SetTextCursorEnableMode] and [ResetTextCursorEnableMode].
+const (
+ ShowCursor = SetTextCursorEnableMode
+ HideCursor = ResetTextCursorEnableMode
+)
+
+// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor.
+//
+// See: https://vt100.net/docs/vt510-rm/DECTCEM.html
+//
+// Deprecated: use [SetTextCursorEnableMode] and [ResetTextCursorEnableMode] instead.
+const (
+ CursorEnableMode = DECMode(25)
+ RequestCursorVisibility = "\x1b[?25$p"
+)
+
+// Numeric Keypad Mode (DECNKM) is a mode that determines whether the keypad
+// sends application sequences or numeric sequences.
+//
+// This works like [DECKPAM] and [DECKPNM], but uses different sequences.
+//
+// See: https://vt100.net/docs/vt510-rm/DECNKM.html
+const (
+ NumericKeypadMode = DECMode(66)
+ DECNKM = NumericKeypadMode
+
+ SetNumericKeypadMode = "\x1b[?66h"
+ ResetNumericKeypadMode = "\x1b[?66l"
+ RequestNumericKeypadMode = "\x1b[?66$p"
+)
+
+// Backarrow Key Mode (DECBKM) is a mode that determines whether the backspace
+// key sends a backspace or delete character. Disabled by default.
+//
+// See: https://vt100.net/docs/vt510-rm/DECBKM.html
+const (
+ BackarrowKeyMode = DECMode(67)
+ DECBKM = BackarrowKeyMode
+
+ SetBackarrowKeyMode = "\x1b[?67h"
+ ResetBackarrowKeyMode = "\x1b[?67l"
+ RequestBackarrowKeyMode = "\x1b[?67$p"
+)
+
+// Left Right Margin Mode (DECLRMM) is a mode that determines whether the left
+// and right margins can be set with [DECSLRM].
+//
+// See: https://vt100.net/docs/vt510-rm/DECLRMM.html
+const (
+ LeftRightMarginMode = DECMode(69)
+ DECLRMM = LeftRightMarginMode
+
+ SetLeftRightMarginMode = "\x1b[?69h"
+ ResetLeftRightMarginMode = "\x1b[?69l"
+ RequestLeftRightMarginMode = "\x1b[?69$p"
+)
+
+// Normal Mouse Mode is a mode that determines whether the mouse reports on
+// button presses and releases. It will also report modifier keys, wheel
+// events, and extra buttons.
+//
+// It uses the same encoding as [X10MouseMode] with a few differences:
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ NormalMouseMode = DECMode(1000)
+
+ SetNormalMouseMode = "\x1b[?1000h"
+ ResetNormalMouseMode = "\x1b[?1000l"
+ RequestNormalMouseMode = "\x1b[?1000$p"
+)
+
+// VT Mouse Tracking is a mode that determines whether the mouse reports on
+// button press and release.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+//
+// Deprecated: use [NormalMouseMode] instead.
+const (
+ MouseMode = DECMode(1000)
+
+ EnableMouse = "\x1b[?1000h"
+ DisableMouse = "\x1b[?1000l"
+ RequestMouse = "\x1b[?1000$p"
+)
+
+// Highlight Mouse Tracking is a mode that determines whether the mouse reports
+// on button presses, releases, and highlighted cells.
+//
+// It uses the same encoding as [NormalMouseMode] with a few differences:
+//
+// On highlight events, the terminal responds with the following encoding:
+//
+// CSI t CxCy
+// CSI T CxCyCxCyCxCy
+//
+// Where the parameters are startx, starty, endx, endy, mousex, and mousey.
+const (
+ HighlightMouseMode = DECMode(1001)
+
+ SetHighlightMouseMode = "\x1b[?1001h"
+ ResetHighlightMouseMode = "\x1b[?1001l"
+ RequestHighlightMouseMode = "\x1b[?1001$p"
+)
+
+// VT Hilite Mouse Tracking is a mode that determines whether the mouse reports on
+// button presses, releases, and highlighted cells.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+//
+// Deprecated: use [HighlightMouseMode] instead.
+const (
+ MouseHiliteMode = DECMode(1001)
+
+ EnableMouseHilite = "\x1b[?1001h"
+ DisableMouseHilite = "\x1b[?1001l"
+ RequestMouseHilite = "\x1b[?1001$p"
+)
+
+// Button Event Mouse Tracking is essentially the same as [NormalMouseMode],
+// but it also reports button-motion events when a button is pressed.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ ButtonEventMouseMode = DECMode(1002)
+
+ SetButtonEventMouseMode = "\x1b[?1002h"
+ ResetButtonEventMouseMode = "\x1b[?1002l"
+ RequestButtonEventMouseMode = "\x1b[?1002$p"
+)
+
+// Cell Motion Mouse Tracking is a mode that determines whether the mouse
+// reports on button press, release, and motion events.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+//
+// Deprecated: use [ButtonEventMouseMode] instead.
+const (
+ MouseCellMotionMode = DECMode(1002)
+
+ EnableMouseCellMotion = "\x1b[?1002h"
+ DisableMouseCellMotion = "\x1b[?1002l"
+ RequestMouseCellMotion = "\x1b[?1002$p"
+)
+
+// Any Event Mouse Tracking is the same as [ButtonEventMouseMode], except that
+// all motion events are reported even if no mouse buttons are pressed.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ AnyEventMouseMode = DECMode(1003)
+
+ SetAnyEventMouseMode = "\x1b[?1003h"
+ ResetAnyEventMouseMode = "\x1b[?1003l"
+ RequestAnyEventMouseMode = "\x1b[?1003$p"
+)
+
+// All Mouse Tracking is a mode that determines whether the mouse reports on
+// button press, release, motion, and highlight events.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+//
+// Deprecated: use [AnyEventMouseMode] instead.
+const (
+ MouseAllMotionMode = DECMode(1003)
+
+ EnableMouseAllMotion = "\x1b[?1003h"
+ DisableMouseAllMotion = "\x1b[?1003l"
+ RequestMouseAllMotion = "\x1b[?1003$p"
+)
+
+// Focus Event Mode is a mode that determines whether the terminal reports focus
+// and blur events.
+//
+// The terminal sends the following encoding:
+//
+// CSI I // Focus In
+// CSI O // Focus Out
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Focus-Tracking
+const (
+ FocusEventMode = DECMode(1004)
+
+ SetFocusEventMode = "\x1b[?1004h"
+ ResetFocusEventMode = "\x1b[?1004l"
+ RequestFocusEventMode = "\x1b[?1004$p"
+)
+
+// Deprecated: use [SetFocusEventMode], [ResetFocusEventMode], and
+// [RequestFocusEventMode] instead.
+const (
+ ReportFocusMode = DECMode(1004)
+
+ EnableReportFocus = "\x1b[?1004h"
+ DisableReportFocus = "\x1b[?1004l"
+ RequestReportFocus = "\x1b[?1004$p"
+)
+
+// SGR Extended Mouse Mode is a mode that changes the mouse tracking encoding
+// to use SGR parameters.
+//
+// The terminal responds with the following encoding:
+//
+// CSI < Cb ; Cx ; Cy M
+//
+// Where Cb is the same as [NormalMouseMode], and Cx and Cy are the x and y.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ SgrExtMouseMode = DECMode(1006)
+
+ SetSgrExtMouseMode = "\x1b[?1006h"
+ ResetSgrExtMouseMode = "\x1b[?1006l"
+ RequestSgrExtMouseMode = "\x1b[?1006$p"
+)
+
+// Deprecated: use [SgrExtMouseMode] [SetSgrExtMouseMode],
+// [ResetSgrExtMouseMode], and [RequestSgrExtMouseMode] instead.
+const (
+ MouseSgrExtMode = DECMode(1006)
+ EnableMouseSgrExt = "\x1b[?1006h"
+ DisableMouseSgrExt = "\x1b[?1006l"
+ RequestMouseSgrExt = "\x1b[?1006$p"
+)
+
+// UTF-8 Extended Mouse Mode is a mode that changes the mouse tracking encoding
+// to use UTF-8 parameters.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ Utf8ExtMouseMode = DECMode(1005)
+
+ SetUtf8ExtMouseMode = "\x1b[?1005h"
+ ResetUtf8ExtMouseMode = "\x1b[?1005l"
+ RequestUtf8ExtMouseMode = "\x1b[?1005$p"
+)
+
+// URXVT Extended Mouse Mode is a mode that changes the mouse tracking encoding
+// to use an alternate encoding.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ UrxvtExtMouseMode = DECMode(1015)
+
+ SetUrxvtExtMouseMode = "\x1b[?1015h"
+ ResetUrxvtExtMouseMode = "\x1b[?1015l"
+ RequestUrxvtExtMouseMode = "\x1b[?1015$p"
+)
+
+// SGR Pixel Extended Mouse Mode is a mode that changes the mouse tracking
+// encoding to use SGR parameters with pixel coordinates.
+//
+// This is similar to [SgrExtMouseMode], but also reports pixel coordinates.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ SgrPixelExtMouseMode = DECMode(1016)
+
+ SetSgrPixelExtMouseMode = "\x1b[?1016h"
+ ResetSgrPixelExtMouseMode = "\x1b[?1016l"
+ RequestSgrPixelExtMouseMode = "\x1b[?1016$p"
+)
+
+// Alternate Screen Mode is a mode that determines whether the alternate screen
+// buffer is active. When this mode is enabled, the alternate screen buffer is
+// cleared.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
+const (
+ AltScreenMode = DECMode(1047)
+
+ SetAltScreenMode = "\x1b[?1047h"
+ ResetAltScreenMode = "\x1b[?1047l"
+ RequestAltScreenMode = "\x1b[?1047$p"
+)
+
+// Save Cursor Mode is a mode that saves the cursor position.
+// This is equivalent to [SaveCursor] and [RestoreCursor].
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
+const (
+ SaveCursorMode = DECMode(1048)
+
+ SetSaveCursorMode = "\x1b[?1048h"
+ ResetSaveCursorMode = "\x1b[?1048l"
+ RequestSaveCursorMode = "\x1b[?1048$p"
+)
+
+// Alternate Screen Save Cursor Mode is a mode that saves the cursor position as in
+// [SaveCursorMode], switches to the alternate screen buffer as in [AltScreenMode],
+// and clears the screen on switch.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
+const (
+ AltScreenSaveCursorMode = DECMode(1049)
+
+ SetAltScreenSaveCursorMode = "\x1b[?1049h"
+ ResetAltScreenSaveCursorMode = "\x1b[?1049l"
+ RequestAltScreenSaveCursorMode = "\x1b[?1049$p"
+)
+
+// Alternate Screen Buffer is a mode that determines whether the alternate screen
+// buffer is active.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
+//
+// Deprecated: use [AltScreenSaveCursorMode] instead.
+const (
+ AltScreenBufferMode = DECMode(1049)
+
+ SetAltScreenBufferMode = "\x1b[?1049h"
+ ResetAltScreenBufferMode = "\x1b[?1049l"
+ RequestAltScreenBufferMode = "\x1b[?1049$p"
+
+ EnableAltScreenBuffer = "\x1b[?1049h"
+ DisableAltScreenBuffer = "\x1b[?1049l"
+ RequestAltScreenBuffer = "\x1b[?1049$p"
+)
+
+// Bracketed Paste Mode is a mode that determines whether pasted text is
+// bracketed with escape sequences.
+//
+// See: https://cirw.in/blog/bracketed-paste
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Bracketed-Paste-Mode
+const (
+ BracketedPasteMode = DECMode(2004)
+
+ SetBracketedPasteMode = "\x1b[?2004h"
+ ResetBracketedPasteMode = "\x1b[?2004l"
+ RequestBracketedPasteMode = "\x1b[?2004$p"
+)
+
+// Deprecated: use [SetBracketedPasteMode], [ResetBracketedPasteMode], and
+// [RequestBracketedPasteMode] instead.
+const (
+ EnableBracketedPaste = "\x1b[?2004h"
+ DisableBracketedPaste = "\x1b[?2004l"
+ RequestBracketedPaste = "\x1b[?2004$p"
+)
+
+// Synchronized Output Mode is a mode that determines whether output is
+// synchronized with the terminal.
+//
+// See: https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036
+const (
+ SynchronizedOutputMode = DECMode(2026)
+
+ SetSynchronizedOutputMode = "\x1b[?2026h"
+ ResetSynchronizedOutputMode = "\x1b[?2026l"
+ RequestSynchronizedOutputMode = "\x1b[?2026$p"
+)
+
+// Deprecated: use [SynchronizedOutputMode], [SetSynchronizedOutputMode], and
+// [ResetSynchronizedOutputMode], and [RequestSynchronizedOutputMode] instead.
+const (
+ SyncdOutputMode = DECMode(2026)
+
+ EnableSyncdOutput = "\x1b[?2026h"
+ DisableSyncdOutput = "\x1b[?2026l"
+ RequestSyncdOutput = "\x1b[?2026$p"
+)
+
+// Grapheme Clustering Mode is a mode that determines whether the terminal
+// should look for grapheme clusters instead of single runes in the rendered
+// text. This makes the terminal properly render combining characters such as
+// emojis.
+//
+// See: https://github.com/contour-terminal/terminal-unicode-core
+const (
+ GraphemeClusteringMode = DECMode(2027)
+
+ SetGraphemeClusteringMode = "\x1b[?2027h"
+ ResetGraphemeClusteringMode = "\x1b[?2027l"
+ RequestGraphemeClusteringMode = "\x1b[?2027$p"
+)
+
+// Deprecated: use [SetGraphemeClusteringMode], [ResetGraphemeClusteringMode], and
+// [RequestGraphemeClusteringMode] instead.
+const (
+ EnableGraphemeClustering = "\x1b[?2027h"
+ DisableGraphemeClustering = "\x1b[?2027l"
+ RequestGraphemeClustering = "\x1b[?2027$p"
+)
+
+// Win32Input is a mode that determines whether input is processed by the
+// Win32 console and Conpty.
+//
+// See: https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md
+const (
+ Win32InputMode = DECMode(9001)
+
+ SetWin32InputMode = "\x1b[?9001h"
+ ResetWin32InputMode = "\x1b[?9001l"
+ RequestWin32InputMode = "\x1b[?9001$p"
+)
+
+// Deprecated: use [SetWin32InputMode], [ResetWin32InputMode], and
+// [RequestWin32InputMode] instead.
+const (
+ EnableWin32Input = "\x1b[?9001h"
+ DisableWin32Input = "\x1b[?9001l"
+ RequestWin32Input = "\x1b[?9001$p"
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/modes.go b/vendor/github.com/charmbracelet/x/ansi/modes.go
new file mode 100644
index 00000000..1bec5bc8
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/modes.go
@@ -0,0 +1,71 @@
+package ansi
+
+// Modes represents the terminal modes that can be set or reset. By default,
+// all modes are [ModeNotRecognized].
+type Modes map[Mode]ModeSetting
+
+// NewModes creates a new Modes map. By default, all modes are
+// [ModeNotRecognized].
+func NewModes() Modes {
+ return make(Modes)
+}
+
+// Get returns the setting of a terminal mode. If the mode is not set, it
+// returns [ModeNotRecognized].
+func (m Modes) Get(mode Mode) ModeSetting {
+ return m[mode]
+}
+
+// Delete deletes a terminal mode. This has the same effect as setting the mode
+// to [ModeNotRecognized].
+func (m Modes) Delete(mode Mode) {
+ delete(m, mode)
+}
+
+// Set sets a terminal mode to [ModeSet].
+func (m Modes) Set(modes ...Mode) {
+ for _, mode := range modes {
+ m[mode] = ModeSet
+ }
+}
+
+// PermanentlySet sets a terminal mode to [ModePermanentlySet].
+func (m Modes) PermanentlySet(modes ...Mode) {
+ for _, mode := range modes {
+ m[mode] = ModePermanentlySet
+ }
+}
+
+// Reset sets a terminal mode to [ModeReset].
+func (m Modes) Reset(modes ...Mode) {
+ for _, mode := range modes {
+ m[mode] = ModeReset
+ }
+}
+
+// PermanentlyReset sets a terminal mode to [ModePermanentlyReset].
+func (m Modes) PermanentlyReset(modes ...Mode) {
+ for _, mode := range modes {
+ m[mode] = ModePermanentlyReset
+ }
+}
+
+// IsSet returns true if the mode is set to [ModeSet] or [ModePermanentlySet].
+func (m Modes) IsSet(mode Mode) bool {
+ return m[mode].IsSet()
+}
+
+// IsPermanentlySet returns true if the mode is set to [ModePermanentlySet].
+func (m Modes) IsPermanentlySet(mode Mode) bool {
+ return m[mode].IsPermanentlySet()
+}
+
+// IsReset returns true if the mode is set to [ModeReset] or [ModePermanentlyReset].
+func (m Modes) IsReset(mode Mode) bool {
+ return m[mode].IsReset()
+}
+
+// IsPermanentlyReset returns true if the mode is set to [ModePermanentlyReset].
+func (m Modes) IsPermanentlyReset(mode Mode) bool {
+ return m[mode].IsPermanentlyReset()
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/mouse.go b/vendor/github.com/charmbracelet/x/ansi/mouse.go
new file mode 100644
index 00000000..95b0127f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/mouse.go
@@ -0,0 +1,172 @@
+package ansi
+
+import (
+ "fmt"
+)
+
+// MouseButton represents the button that was pressed during a mouse message.
+type MouseButton byte
+
+// Mouse event buttons
+//
+// This is based on X11 mouse button codes.
+//
+// 1 = left button
+// 2 = middle button (pressing the scroll wheel)
+// 3 = right button
+// 4 = turn scroll wheel up
+// 5 = turn scroll wheel down
+// 6 = push scroll wheel left
+// 7 = push scroll wheel right
+// 8 = 4th button (aka browser backward button)
+// 9 = 5th button (aka browser forward button)
+// 10
+// 11
+//
+// Other buttons are not supported.
+const (
+ MouseNone MouseButton = iota
+ MouseButton1
+ MouseButton2
+ MouseButton3
+ MouseButton4
+ MouseButton5
+ MouseButton6
+ MouseButton7
+ MouseButton8
+ MouseButton9
+ MouseButton10
+ MouseButton11
+
+ MouseLeft = MouseButton1
+ MouseMiddle = MouseButton2
+ MouseRight = MouseButton3
+ MouseWheelUp = MouseButton4
+ MouseWheelDown = MouseButton5
+ MouseWheelLeft = MouseButton6
+ MouseWheelRight = MouseButton7
+ MouseBackward = MouseButton8
+ MouseForward = MouseButton9
+ MouseRelease = MouseNone
+)
+
+var mouseButtons = map[MouseButton]string{
+ MouseNone: "none",
+ MouseLeft: "left",
+ MouseMiddle: "middle",
+ MouseRight: "right",
+ MouseWheelUp: "wheelup",
+ MouseWheelDown: "wheeldown",
+ MouseWheelLeft: "wheelleft",
+ MouseWheelRight: "wheelright",
+ MouseBackward: "backward",
+ MouseForward: "forward",
+ MouseButton10: "button10",
+ MouseButton11: "button11",
+}
+
+// String returns a string representation of the mouse button.
+func (b MouseButton) String() string {
+ return mouseButtons[b]
+}
+
+// EncodeMouseButton returns a byte representing a mouse button.
+// The button is a bitmask of the following leftmost values:
+//
+// - The first two bits are the button number:
+// 0 = left button, wheel up, or button no. 8 aka (backwards)
+// 1 = middle button, wheel down, or button no. 9 aka (forwards)
+// 2 = right button, wheel left, or button no. 10
+// 3 = release event, wheel right, or button no. 11
+//
+// - The third bit indicates whether the shift key was pressed.
+//
+// - The fourth bit indicates the alt key was pressed.
+//
+// - The fifth bit indicates the control key was pressed.
+//
+// - The sixth bit indicates motion events. Combined with button number 3, i.e.
+// release event, it represents a drag event.
+//
+// - The seventh bit indicates a wheel event.
+//
+// - The eighth bit indicates additional buttons.
+//
+// If button is [MouseNone], and motion is false, this returns a release event.
+// If button is undefined, this function returns 0xff.
+func EncodeMouseButton(b MouseButton, motion, shift, alt, ctrl bool) (m byte) {
+ // mouse bit shifts
+ const (
+ bitShift = 0b0000_0100
+ bitAlt = 0b0000_1000
+ bitCtrl = 0b0001_0000
+ bitMotion = 0b0010_0000
+ bitWheel = 0b0100_0000
+ bitAdd = 0b1000_0000 // additional buttons 8-11
+
+ bitsMask = 0b0000_0011
+ )
+
+ if b == MouseNone {
+ m = bitsMask
+ } else if b >= MouseLeft && b <= MouseRight {
+ m = byte(b - MouseLeft)
+ } else if b >= MouseWheelUp && b <= MouseWheelRight {
+ m = byte(b - MouseWheelUp)
+ m |= bitWheel
+ } else if b >= MouseBackward && b <= MouseButton11 {
+ m = byte(b - MouseBackward)
+ m |= bitAdd
+ } else {
+ m = 0xff // invalid button
+ }
+
+ if shift {
+ m |= bitShift
+ }
+ if alt {
+ m |= bitAlt
+ }
+ if ctrl {
+ m |= bitCtrl
+ }
+ if motion {
+ m |= bitMotion
+ }
+
+ return
+}
+
+// x10Offset is the offset for X10 mouse events.
+// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
+const x10Offset = 32
+
+// MouseX10 returns an escape sequence representing a mouse event in X10 mode.
+// Note that this requires the terminal support X10 mouse modes.
+//
+// CSI M Cb Cx Cy
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
+func MouseX10(b byte, x, y int) string {
+ return "\x1b[M" + string(b+x10Offset) + string(byte(x)+x10Offset+1) + string(byte(y)+x10Offset+1)
+}
+
+// MouseSgr returns an escape sequence representing a mouse event in SGR mode.
+//
+// CSI < Cb ; Cx ; Cy M
+// CSI < Cb ; Cx ; Cy m (release)
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
+func MouseSgr(b byte, x, y int, release bool) string {
+ s := 'M'
+ if release {
+ s = 'm'
+ }
+ if x < 0 {
+ x = -x
+ }
+ if y < 0 {
+ y = -y
+ }
+ return fmt.Sprintf("\x1b[<%d;%d;%d%c", b, x+1, y+1, s)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/notification.go b/vendor/github.com/charmbracelet/x/ansi/notification.go
new file mode 100644
index 00000000..c712f340
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/notification.go
@@ -0,0 +1,13 @@
+package ansi
+
+// Notify sends a desktop notification using iTerm's OSC 9.
+//
+// OSC 9 ; Mc ST
+// OSC 9 ; Mc BEL
+//
+// Where Mc is the notification body.
+//
+// See: https://iterm2.com/documentation-escape-codes.html
+func Notify(s string) string {
+ return "\x1b]9;" + s + "\x07"
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser.go b/vendor/github.com/charmbracelet/x/ansi/parser.go
new file mode 100644
index 00000000..882e1ed7
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser.go
@@ -0,0 +1,417 @@
+package ansi
+
+import (
+ "unicode/utf8"
+ "unsafe"
+
+ "github.com/charmbracelet/x/ansi/parser"
+)
+
+// Parser represents a DEC ANSI compatible sequence parser.
+//
+// It uses a state machine to parse ANSI escape sequences and control
+// characters. The parser is designed to be used with a terminal emulator or
+// similar application that needs to parse ANSI escape sequences and control
+// characters.
+// See package [parser] for more information.
+//
+//go:generate go run ./gen.go
+type Parser struct {
+ handler Handler
+
+ // params contains the raw parameters of the sequence.
+ // These parameters used when constructing CSI and DCS sequences.
+ params []int
+
+ // data contains the raw data of the sequence.
+ // These data used when constructing OSC, DCS, SOS, PM, and APC sequences.
+ data []byte
+
+ // dataLen keeps track of the length of the data buffer.
+ // If dataLen is -1, the data buffer is unlimited and will grow as needed.
+ // Otherwise, dataLen is limited by the size of the data buffer.
+ dataLen int
+
+ // paramsLen keeps track of the number of parameters.
+ // This is limited by the size of the params buffer.
+ //
+ // This is also used when collecting UTF-8 runes to keep track of the
+ // number of rune bytes collected.
+ paramsLen int
+
+ // cmd contains the raw command along with the private prefix and
+ // intermediate bytes of the sequence.
+ // The first lower byte contains the command byte, the next byte contains
+ // the private prefix, and the next byte contains the intermediate byte.
+ //
+ // This is also used when collecting UTF-8 runes treating it as a slice of
+ // 4 bytes.
+ cmd int
+
+ // state is the current state of the parser.
+ state byte
+}
+
+// NewParser returns a new parser with the default settings.
+// The [Parser] uses a default size of 32 for the parameters and 64KB for the
+// data buffer. Use [Parser.SetParamsSize] and [Parser.SetDataSize] to set the
+// size of the parameters and data buffer respectively.
+func NewParser() *Parser {
+ p := new(Parser)
+ p.SetParamsSize(parser.MaxParamsSize)
+ p.SetDataSize(1024 * 64) // 64KB data buffer
+ return p
+}
+
+// SetParamsSize sets the size of the parameters buffer.
+// This is used when constructing CSI and DCS sequences.
+func (p *Parser) SetParamsSize(size int) {
+ p.params = make([]int, size)
+}
+
+// SetDataSize sets the size of the data buffer.
+// This is used when constructing OSC, DCS, SOS, PM, and APC sequences.
+// If size is less than or equal to 0, the data buffer is unlimited and will
+// grow as needed.
+func (p *Parser) SetDataSize(size int) {
+ if size <= 0 {
+ size = 0
+ p.dataLen = -1
+ }
+ p.data = make([]byte, size)
+}
+
+// Params returns the list of parsed packed parameters.
+func (p *Parser) Params() Params {
+ return unsafe.Slice((*Param)(unsafe.Pointer(&p.params[0])), p.paramsLen)
+}
+
+// Param returns the parameter at the given index and falls back to the default
+// value if the parameter is missing. If the index is out of bounds, it returns
+// the default value and false.
+func (p *Parser) Param(i, def int) (int, bool) {
+ if i < 0 || i >= p.paramsLen {
+ return def, false
+ }
+ return Param(p.params[i]).Param(def), true
+}
+
+// Command returns the packed command of the last dispatched sequence. Use
+// [Cmd] to unpack the command.
+func (p *Parser) Command() int {
+ return p.cmd
+}
+
+// Rune returns the last dispatched sequence as a rune.
+func (p *Parser) Rune() rune {
+ rw := utf8ByteLen(byte(p.cmd & 0xff))
+ if rw == -1 {
+ return utf8.RuneError
+ }
+ r, _ := utf8.DecodeRune((*[utf8.UTFMax]byte)(unsafe.Pointer(&p.cmd))[:rw])
+ return r
+}
+
+// Control returns the last dispatched sequence as a control code.
+func (p *Parser) Control() byte {
+ return byte(p.cmd & 0xff)
+}
+
+// Data returns the raw data of the last dispatched sequence.
+func (p *Parser) Data() []byte {
+ return p.data[:p.dataLen]
+}
+
+// Reset resets the parser to its initial state.
+func (p *Parser) Reset() {
+ p.clear()
+ p.state = parser.GroundState
+}
+
+// clear clears the parser parameters and command.
+func (p *Parser) clear() {
+ if len(p.params) > 0 {
+ p.params[0] = parser.MissingParam
+ }
+ p.paramsLen = 0
+ p.cmd = 0
+}
+
+// State returns the current state of the parser.
+func (p *Parser) State() parser.State {
+ return p.state
+}
+
+// StateName returns the name of the current state.
+func (p *Parser) StateName() string {
+ return parser.StateNames[p.state]
+}
+
+// Parse parses the given dispatcher and byte buffer.
+// Deprecated: Loop over the buffer and call [Parser.Advance] instead.
+func (p *Parser) Parse(b []byte) {
+ for i := 0; i < len(b); i++ {
+ p.Advance(b[i])
+ }
+}
+
+// Advance advances the parser using the given byte. It returns the action
+// performed by the parser.
+func (p *Parser) Advance(b byte) parser.Action {
+ switch p.state {
+ case parser.Utf8State:
+ // We handle UTF-8 here.
+ return p.advanceUtf8(b)
+ default:
+ return p.advance(b)
+ }
+}
+
+func (p *Parser) collectRune(b byte) {
+ if p.paramsLen >= utf8.UTFMax {
+ return
+ }
+
+ shift := p.paramsLen * 8
+ p.cmd &^= 0xff << shift
+ p.cmd |= int(b) << shift
+ p.paramsLen++
+}
+
+func (p *Parser) advanceUtf8(b byte) parser.Action {
+ // Collect UTF-8 rune bytes.
+ p.collectRune(b)
+ rw := utf8ByteLen(byte(p.cmd & 0xff))
+ if rw == -1 {
+ // We panic here because the first byte comes from the state machine,
+ // if this panics, it means there is a bug in the state machine!
+ panic("invalid rune") // unreachable
+ }
+
+ if p.paramsLen < rw {
+ return parser.CollectAction
+ }
+
+ // We have enough bytes to decode the rune using unsafe
+ if p.handler.Print != nil {
+ p.handler.Print(p.Rune())
+ }
+
+ p.state = parser.GroundState
+ p.paramsLen = 0
+
+ return parser.PrintAction
+}
+
+func (p *Parser) advance(b byte) parser.Action {
+ state, action := parser.Table.Transition(p.state, b)
+
+ // We need to clear the parser state if the state changes from EscapeState.
+ // This is because when we enter the EscapeState, we don't get a chance to
+ // clear the parser state. For example, when a sequence terminates with a
+ // ST (\x1b\\ or \x9c), we dispatch the current sequence and transition to
+ // EscapeState. However, the parser state is not cleared in this case and
+ // we need to clear it here before dispatching the esc sequence.
+ if p.state != state {
+ if p.state == parser.EscapeState {
+ p.performAction(parser.ClearAction, state, b)
+ }
+ if action == parser.PutAction &&
+ p.state == parser.DcsEntryState && state == parser.DcsStringState {
+ // XXX: This is a special case where we need to start collecting
+ // non-string parameterized data i.e. doesn't follow the ECMA-48 §
+ // 5.4.1 string parameters format.
+ p.performAction(parser.StartAction, state, 0)
+ }
+ }
+
+ // Handle special cases
+ switch {
+ case b == ESC && p.state == parser.EscapeState:
+ // Two ESCs in a row
+ p.performAction(parser.ExecuteAction, state, b)
+ default:
+ p.performAction(action, state, b)
+ }
+
+ p.state = state
+
+ return action
+}
+
+func (p *Parser) parseStringCmd() {
+ // Try to parse the command
+ datalen := len(p.data)
+ if p.dataLen >= 0 {
+ datalen = p.dataLen
+ }
+ for i := 0; i < datalen; i++ {
+ d := p.data[i]
+ if d < '0' || d > '9' {
+ break
+ }
+ if p.cmd == parser.MissingCommand {
+ p.cmd = 0
+ }
+ p.cmd *= 10
+ p.cmd += int(d - '0')
+ }
+}
+
+func (p *Parser) performAction(action parser.Action, state parser.State, b byte) {
+ switch action {
+ case parser.IgnoreAction:
+ break
+
+ case parser.ClearAction:
+ p.clear()
+
+ case parser.PrintAction:
+ p.cmd = int(b)
+ if p.handler.Print != nil {
+ p.handler.Print(rune(b))
+ }
+
+ case parser.ExecuteAction:
+ p.cmd = int(b)
+ if p.handler.Execute != nil {
+ p.handler.Execute(b)
+ }
+
+ case parser.PrefixAction:
+ // Collect private prefix
+ // we only store the last prefix
+ p.cmd &^= 0xff << parser.PrefixShift
+ p.cmd |= int(b) << parser.PrefixShift
+
+ case parser.CollectAction:
+ if state == parser.Utf8State {
+ // Reset the UTF-8 counter
+ p.paramsLen = 0
+ p.collectRune(b)
+ } else {
+ // Collect intermediate bytes
+ // we only store the last intermediate byte
+ p.cmd &^= 0xff << parser.IntermedShift
+ p.cmd |= int(b) << parser.IntermedShift
+ }
+
+ case parser.ParamAction:
+ // Collect parameters
+ if p.paramsLen >= len(p.params) {
+ break
+ }
+
+ if b >= '0' && b <= '9' {
+ if p.params[p.paramsLen] == parser.MissingParam {
+ p.params[p.paramsLen] = 0
+ }
+
+ p.params[p.paramsLen] *= 10
+ p.params[p.paramsLen] += int(b - '0')
+ }
+
+ if b == ':' {
+ p.params[p.paramsLen] |= parser.HasMoreFlag
+ }
+
+ if b == ';' || b == ':' {
+ p.paramsLen++
+ if p.paramsLen < len(p.params) {
+ p.params[p.paramsLen] = parser.MissingParam
+ }
+ }
+
+ case parser.StartAction:
+ if p.dataLen < 0 && p.data != nil {
+ p.data = p.data[:0]
+ } else {
+ p.dataLen = 0
+ }
+ if p.state >= parser.DcsEntryState && p.state <= parser.DcsStringState {
+ // Collect the command byte for DCS
+ p.cmd |= int(b)
+ } else {
+ p.cmd = parser.MissingCommand
+ }
+
+ case parser.PutAction:
+ switch p.state {
+ case parser.OscStringState:
+ if b == ';' && p.cmd == parser.MissingCommand {
+ p.parseStringCmd()
+ }
+ }
+
+ if p.dataLen < 0 {
+ p.data = append(p.data, b)
+ } else {
+ if p.dataLen < len(p.data) {
+ p.data[p.dataLen] = b
+ p.dataLen++
+ }
+ }
+
+ case parser.DispatchAction:
+ // Increment the last parameter
+ if p.paramsLen > 0 && p.paramsLen < len(p.params)-1 ||
+ p.paramsLen == 0 && len(p.params) > 0 && p.params[0] != parser.MissingParam {
+ p.paramsLen++
+ }
+
+ if p.state == parser.OscStringState && p.cmd == parser.MissingCommand {
+ // Ensure we have a command for OSC
+ p.parseStringCmd()
+ }
+
+ data := p.data
+ if p.dataLen >= 0 {
+ data = data[:p.dataLen]
+ }
+ switch p.state {
+ case parser.CsiEntryState, parser.CsiParamState, parser.CsiIntermediateState:
+ p.cmd |= int(b)
+ if p.handler.HandleCsi != nil {
+ p.handler.HandleCsi(Cmd(p.cmd), p.Params())
+ }
+ case parser.EscapeState, parser.EscapeIntermediateState:
+ p.cmd |= int(b)
+ if p.handler.HandleEsc != nil {
+ p.handler.HandleEsc(Cmd(p.cmd))
+ }
+ case parser.DcsEntryState, parser.DcsParamState, parser.DcsIntermediateState, parser.DcsStringState:
+ if p.handler.HandleDcs != nil {
+ p.handler.HandleDcs(Cmd(p.cmd), p.Params(), data)
+ }
+ case parser.OscStringState:
+ if p.handler.HandleOsc != nil {
+ p.handler.HandleOsc(p.cmd, data)
+ }
+ case parser.SosStringState:
+ if p.handler.HandleSos != nil {
+ p.handler.HandleSos(data)
+ }
+ case parser.PmStringState:
+ if p.handler.HandlePm != nil {
+ p.handler.HandlePm(data)
+ }
+ case parser.ApcStringState:
+ if p.handler.HandleApc != nil {
+ p.handler.HandleApc(data)
+ }
+ }
+ }
+}
+
+func utf8ByteLen(b byte) int {
+ if b <= 0b0111_1111 { // 0x00-0x7F
+ return 1
+ } else if b >= 0b1100_0000 && b <= 0b1101_1111 { // 0xC0-0xDF
+ return 2
+ } else if b >= 0b1110_0000 && b <= 0b1110_1111 { // 0xE0-0xEF
+ return 3
+ } else if b >= 0b1111_0000 && b <= 0b1111_0111 { // 0xF0-0xF7
+ return 4
+ }
+ return -1
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/const.go b/vendor/github.com/charmbracelet/x/ansi/parser/const.go
new file mode 100644
index 00000000..d62dbf37
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser/const.go
@@ -0,0 +1,78 @@
+package parser
+
+// Action is a DEC ANSI parser action.
+type Action = byte
+
+// These are the actions that the parser can take.
+const (
+ NoneAction Action = iota
+ ClearAction
+ CollectAction
+ PrefixAction
+ DispatchAction
+ ExecuteAction
+ StartAction // Start of a data string
+ PutAction // Put into the data string
+ ParamAction
+ PrintAction
+
+ IgnoreAction = NoneAction
+)
+
+// nolint: unused
+var ActionNames = []string{
+ "NoneAction",
+ "ClearAction",
+ "CollectAction",
+ "PrefixAction",
+ "DispatchAction",
+ "ExecuteAction",
+ "StartAction",
+ "PutAction",
+ "ParamAction",
+ "PrintAction",
+}
+
+// State is a DEC ANSI parser state.
+type State = byte
+
+// These are the states that the parser can be in.
+const (
+ GroundState State = iota
+ CsiEntryState
+ CsiIntermediateState
+ CsiParamState
+ DcsEntryState
+ DcsIntermediateState
+ DcsParamState
+ DcsStringState
+ EscapeState
+ EscapeIntermediateState
+ OscStringState
+ SosStringState
+ PmStringState
+ ApcStringState
+
+ // Utf8State is not part of the DEC ANSI standard. It is used to handle
+ // UTF-8 sequences.
+ Utf8State
+)
+
+// nolint: unused
+var StateNames = []string{
+ "GroundState",
+ "CsiEntryState",
+ "CsiIntermediateState",
+ "CsiParamState",
+ "DcsEntryState",
+ "DcsIntermediateState",
+ "DcsParamState",
+ "DcsStringState",
+ "EscapeState",
+ "EscapeIntermediateState",
+ "OscStringState",
+ "SosStringState",
+ "PmStringState",
+ "ApcStringState",
+ "Utf8State",
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/seq.go b/vendor/github.com/charmbracelet/x/ansi/parser/seq.go
new file mode 100644
index 00000000..29f491d1
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser/seq.go
@@ -0,0 +1,136 @@
+package parser
+
+import "math"
+
+// Shift and masks for sequence parameters and intermediates.
+const (
+ PrefixShift = 8
+ IntermedShift = 16
+ FinalMask = 0xff
+ HasMoreFlag = math.MinInt32
+ ParamMask = ^HasMoreFlag
+ MissingParam = ParamMask
+ MissingCommand = MissingParam
+ MaxParam = math.MaxUint16 // the maximum value a parameter can have
+)
+
+const (
+ // MaxParamsSize is the maximum number of parameters a sequence can have.
+ MaxParamsSize = 32
+
+ // DefaultParamValue is the default value used for missing parameters.
+ DefaultParamValue = 0
+)
+
+// Prefix returns the prefix byte of the sequence.
+// This is always gonna be one of the following '<' '=' '>' '?' and in the
+// range of 0x3C-0x3F.
+// Zero is returned if the sequence does not have a prefix.
+func Prefix(cmd int) int {
+ return (cmd >> PrefixShift) & FinalMask
+}
+
+// Intermediate returns the intermediate byte of the sequence.
+// An intermediate byte is in the range of 0x20-0x2F. This includes these
+// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+',
+// ',', '-', '.', '/'.
+// Zero is returned if the sequence does not have an intermediate byte.
+func Intermediate(cmd int) int {
+ return (cmd >> IntermedShift) & FinalMask
+}
+
+// Command returns the command byte of the CSI sequence.
+func Command(cmd int) int {
+ return cmd & FinalMask
+}
+
+// Param returns the parameter at the given index.
+// It returns -1 if the parameter does not exist.
+func Param(params []int, i int) int {
+ if len(params) == 0 || i < 0 || i >= len(params) {
+ return -1
+ }
+
+ p := params[i] & ParamMask
+ if p == MissingParam {
+ return -1
+ }
+
+ return p
+}
+
+// HasMore returns true if the parameter has more sub-parameters.
+func HasMore(params []int, i int) bool {
+ if len(params) == 0 || i >= len(params) {
+ return false
+ }
+
+ return params[i]&HasMoreFlag != 0
+}
+
+// Subparams returns the sub-parameters of the given parameter.
+// It returns nil if the parameter does not exist.
+func Subparams(params []int, i int) []int {
+ if len(params) == 0 || i < 0 || i >= len(params) {
+ return nil
+ }
+
+ // Count the number of parameters before the given parameter index.
+ var count int
+ var j int
+ for j = 0; j < len(params); j++ {
+ if count == i {
+ break
+ }
+ if !HasMore(params, j) {
+ count++
+ }
+ }
+
+ if count > i || j >= len(params) {
+ return nil
+ }
+
+ var subs []int
+ for ; j < len(params); j++ {
+ if !HasMore(params, j) {
+ break
+ }
+ p := Param(params, j)
+ if p == -1 {
+ p = DefaultParamValue
+ }
+ subs = append(subs, p)
+ }
+
+ p := Param(params, j)
+ if p == -1 {
+ p = DefaultParamValue
+ }
+
+ return append(subs, p)
+}
+
+// Len returns the number of parameters in the sequence.
+// This will return the number of parameters in the sequence, excluding any
+// sub-parameters.
+func Len(params []int) int {
+ var n int
+ for i := 0; i < len(params); i++ {
+ if !HasMore(params, i) {
+ n++
+ }
+ }
+ return n
+}
+
+// Range iterates over the parameters of the sequence and calls the given
+// function for each parameter.
+// The function should return false to stop the iteration.
+func Range(params []int, fn func(i int, param int, hasMore bool) bool) {
+ for i := 0; i < len(params); i++ {
+ if !fn(i, Param(params, i), HasMore(params, i)) {
+ break
+ }
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go b/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go
new file mode 100644
index 00000000..558a5eac
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go
@@ -0,0 +1,273 @@
+package parser
+
+// Table values are generated like this:
+//
+// index: currentState << IndexStateShift | charCode
+// value: action << TransitionActionShift | nextState
+const (
+ TransitionActionShift = 4
+ TransitionStateMask = 15
+ IndexStateShift = 8
+
+ // DefaultTableSize is the default size of the transition table.
+ DefaultTableSize = 4096
+)
+
+// Table is a DEC ANSI transition table.
+var Table = GenerateTransitionTable()
+
+// TransitionTable is a DEC ANSI transition table.
+// https://vt100.net/emu/dec_ansi_parser
+type TransitionTable []byte
+
+// NewTransitionTable returns a new DEC ANSI transition table.
+func NewTransitionTable(size int) TransitionTable {
+ if size <= 0 {
+ size = DefaultTableSize
+ }
+ return TransitionTable(make([]byte, size))
+}
+
+// SetDefault sets default transition.
+func (t TransitionTable) SetDefault(action Action, state State) {
+ for i := 0; i < len(t); i++ {
+ t[i] = action<> TransitionActionShift
+}
+
+// byte range macro
+func r(start, end byte) []byte {
+ var a []byte
+ for i := int(start); i <= int(end); i++ {
+ a = append(a, byte(i))
+ }
+ return a
+}
+
+// GenerateTransitionTable generates a DEC ANSI transition table compatible
+// with the VT500-series of terminals. This implementation includes a few
+// modifications that include:
+// - A new Utf8State is introduced to handle UTF8 sequences.
+// - Osc and Dcs data accept UTF8 sequences by extending the printable range
+// to 0xFF and 0xFE respectively.
+// - We don't ignore 0x3A (':') when building Csi and Dcs parameters and
+// instead use it to denote sub-parameters.
+// - Support dispatching SosPmApc sequences.
+// - The DEL (0x7F) character is executed in the Ground state.
+// - The DEL (0x7F) character is collected in the DcsPassthrough string state.
+// - The ST C1 control character (0x9C) is executed and not ignored.
+func GenerateTransitionTable() TransitionTable {
+ table := NewTransitionTable(DefaultTableSize)
+ table.SetDefault(NoneAction, GroundState)
+
+ // Anywhere
+ for _, state := range r(GroundState, Utf8State) {
+ // Anywhere -> Ground
+ table.AddMany([]byte{0x18, 0x1a, 0x99, 0x9a}, state, ExecuteAction, GroundState)
+ table.AddRange(0x80, 0x8F, state, ExecuteAction, GroundState)
+ table.AddRange(0x90, 0x97, state, ExecuteAction, GroundState)
+ table.AddOne(0x9C, state, ExecuteAction, GroundState)
+ // Anywhere -> Escape
+ table.AddOne(0x1B, state, ClearAction, EscapeState)
+ // Anywhere -> SosStringState
+ table.AddOne(0x98, state, StartAction, SosStringState)
+ // Anywhere -> PmStringState
+ table.AddOne(0x9E, state, StartAction, PmStringState)
+ // Anywhere -> ApcStringState
+ table.AddOne(0x9F, state, StartAction, ApcStringState)
+ // Anywhere -> CsiEntry
+ table.AddOne(0x9B, state, ClearAction, CsiEntryState)
+ // Anywhere -> DcsEntry
+ table.AddOne(0x90, state, ClearAction, DcsEntryState)
+ // Anywhere -> OscString
+ table.AddOne(0x9D, state, StartAction, OscStringState)
+ // Anywhere -> Utf8
+ table.AddRange(0xC2, 0xDF, state, CollectAction, Utf8State) // UTF8 2 byte sequence
+ table.AddRange(0xE0, 0xEF, state, CollectAction, Utf8State) // UTF8 3 byte sequence
+ table.AddRange(0xF0, 0xF4, state, CollectAction, Utf8State) // UTF8 4 byte sequence
+ }
+
+ // Ground
+ table.AddRange(0x00, 0x17, GroundState, ExecuteAction, GroundState)
+ table.AddOne(0x19, GroundState, ExecuteAction, GroundState)
+ table.AddRange(0x1C, 0x1F, GroundState, ExecuteAction, GroundState)
+ table.AddRange(0x20, 0x7E, GroundState, PrintAction, GroundState)
+ table.AddOne(0x7F, GroundState, ExecuteAction, GroundState)
+
+ // EscapeIntermediate
+ table.AddRange(0x00, 0x17, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState)
+ table.AddOne(0x19, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState)
+ table.AddRange(0x1C, 0x1F, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState)
+ table.AddRange(0x20, 0x2F, EscapeIntermediateState, CollectAction, EscapeIntermediateState)
+ table.AddOne(0x7F, EscapeIntermediateState, IgnoreAction, EscapeIntermediateState)
+ // EscapeIntermediate -> Ground
+ table.AddRange(0x30, 0x7E, EscapeIntermediateState, DispatchAction, GroundState)
+
+ // Escape
+ table.AddRange(0x00, 0x17, EscapeState, ExecuteAction, EscapeState)
+ table.AddOne(0x19, EscapeState, ExecuteAction, EscapeState)
+ table.AddRange(0x1C, 0x1F, EscapeState, ExecuteAction, EscapeState)
+ table.AddOne(0x7F, EscapeState, IgnoreAction, EscapeState)
+ // Escape -> Ground
+ table.AddRange(0x30, 0x4F, EscapeState, DispatchAction, GroundState)
+ table.AddRange(0x51, 0x57, EscapeState, DispatchAction, GroundState)
+ table.AddOne(0x59, EscapeState, DispatchAction, GroundState)
+ table.AddOne(0x5A, EscapeState, DispatchAction, GroundState)
+ table.AddOne(0x5C, EscapeState, DispatchAction, GroundState)
+ table.AddRange(0x60, 0x7E, EscapeState, DispatchAction, GroundState)
+ // Escape -> Escape_intermediate
+ table.AddRange(0x20, 0x2F, EscapeState, CollectAction, EscapeIntermediateState)
+ // Escape -> Sos_pm_apc_string
+ table.AddOne('X', EscapeState, StartAction, SosStringState) // SOS
+ table.AddOne('^', EscapeState, StartAction, PmStringState) // PM
+ table.AddOne('_', EscapeState, StartAction, ApcStringState) // APC
+ // Escape -> Dcs_entry
+ table.AddOne('P', EscapeState, ClearAction, DcsEntryState)
+ // Escape -> Csi_entry
+ table.AddOne('[', EscapeState, ClearAction, CsiEntryState)
+ // Escape -> Osc_string
+ table.AddOne(']', EscapeState, StartAction, OscStringState)
+
+ // Sos_pm_apc_string
+ for _, state := range r(SosStringState, ApcStringState) {
+ table.AddRange(0x00, 0x17, state, PutAction, state)
+ table.AddOne(0x19, state, PutAction, state)
+ table.AddRange(0x1C, 0x1F, state, PutAction, state)
+ table.AddRange(0x20, 0x7F, state, PutAction, state)
+ // ESC, ST, CAN, and SUB terminate the sequence
+ table.AddOne(0x1B, state, DispatchAction, EscapeState)
+ table.AddOne(0x9C, state, DispatchAction, GroundState)
+ table.AddMany([]byte{0x18, 0x1A}, state, IgnoreAction, GroundState)
+ }
+
+ // Dcs_entry
+ table.AddRange(0x00, 0x07, DcsEntryState, IgnoreAction, DcsEntryState)
+ table.AddRange(0x0E, 0x17, DcsEntryState, IgnoreAction, DcsEntryState)
+ table.AddOne(0x19, DcsEntryState, IgnoreAction, DcsEntryState)
+ table.AddRange(0x1C, 0x1F, DcsEntryState, IgnoreAction, DcsEntryState)
+ table.AddOne(0x7F, DcsEntryState, IgnoreAction, DcsEntryState)
+ // Dcs_entry -> Dcs_intermediate
+ table.AddRange(0x20, 0x2F, DcsEntryState, CollectAction, DcsIntermediateState)
+ // Dcs_entry -> Dcs_param
+ table.AddRange(0x30, 0x3B, DcsEntryState, ParamAction, DcsParamState)
+ table.AddRange(0x3C, 0x3F, DcsEntryState, PrefixAction, DcsParamState)
+ // Dcs_entry -> Dcs_passthrough
+ table.AddRange(0x08, 0x0D, DcsEntryState, PutAction, DcsStringState) // Follows ECMA-48 § 8.3.27
+ // XXX: allows passing ESC (not a ECMA-48 standard) this to allow for
+ // passthrough of ANSI sequences like in Screen or Tmux passthrough mode.
+ table.AddOne(0x1B, DcsEntryState, PutAction, DcsStringState)
+ table.AddRange(0x40, 0x7E, DcsEntryState, StartAction, DcsStringState)
+
+ // Dcs_intermediate
+ table.AddRange(0x00, 0x17, DcsIntermediateState, IgnoreAction, DcsIntermediateState)
+ table.AddOne(0x19, DcsIntermediateState, IgnoreAction, DcsIntermediateState)
+ table.AddRange(0x1C, 0x1F, DcsIntermediateState, IgnoreAction, DcsIntermediateState)
+ table.AddRange(0x20, 0x2F, DcsIntermediateState, CollectAction, DcsIntermediateState)
+ table.AddOne(0x7F, DcsIntermediateState, IgnoreAction, DcsIntermediateState)
+ // Dcs_intermediate -> Dcs_passthrough
+ table.AddRange(0x30, 0x3F, DcsIntermediateState, StartAction, DcsStringState)
+ table.AddRange(0x40, 0x7E, DcsIntermediateState, StartAction, DcsStringState)
+
+ // Dcs_param
+ table.AddRange(0x00, 0x17, DcsParamState, IgnoreAction, DcsParamState)
+ table.AddOne(0x19, DcsParamState, IgnoreAction, DcsParamState)
+ table.AddRange(0x1C, 0x1F, DcsParamState, IgnoreAction, DcsParamState)
+ table.AddRange(0x30, 0x3B, DcsParamState, ParamAction, DcsParamState)
+ table.AddOne(0x7F, DcsParamState, IgnoreAction, DcsParamState)
+ table.AddRange(0x3C, 0x3F, DcsParamState, IgnoreAction, DcsParamState)
+ // Dcs_param -> Dcs_intermediate
+ table.AddRange(0x20, 0x2F, DcsParamState, CollectAction, DcsIntermediateState)
+ // Dcs_param -> Dcs_passthrough
+ table.AddRange(0x40, 0x7E, DcsParamState, StartAction, DcsStringState)
+
+ // Dcs_passthrough
+ table.AddRange(0x00, 0x17, DcsStringState, PutAction, DcsStringState)
+ table.AddOne(0x19, DcsStringState, PutAction, DcsStringState)
+ table.AddRange(0x1C, 0x1F, DcsStringState, PutAction, DcsStringState)
+ table.AddRange(0x20, 0x7E, DcsStringState, PutAction, DcsStringState)
+ table.AddOne(0x7F, DcsStringState, PutAction, DcsStringState)
+ table.AddRange(0x80, 0xFF, DcsStringState, PutAction, DcsStringState) // Allow Utf8 characters by extending the printable range from 0x7F to 0xFF
+ // ST, CAN, SUB, and ESC terminate the sequence
+ table.AddOne(0x1B, DcsStringState, DispatchAction, EscapeState)
+ table.AddOne(0x9C, DcsStringState, DispatchAction, GroundState)
+ table.AddMany([]byte{0x18, 0x1A}, DcsStringState, IgnoreAction, GroundState)
+
+ // Csi_param
+ table.AddRange(0x00, 0x17, CsiParamState, ExecuteAction, CsiParamState)
+ table.AddOne(0x19, CsiParamState, ExecuteAction, CsiParamState)
+ table.AddRange(0x1C, 0x1F, CsiParamState, ExecuteAction, CsiParamState)
+ table.AddRange(0x30, 0x3B, CsiParamState, ParamAction, CsiParamState)
+ table.AddOne(0x7F, CsiParamState, IgnoreAction, CsiParamState)
+ table.AddRange(0x3C, 0x3F, CsiParamState, IgnoreAction, CsiParamState)
+ // Csi_param -> Ground
+ table.AddRange(0x40, 0x7E, CsiParamState, DispatchAction, GroundState)
+ // Csi_param -> Csi_intermediate
+ table.AddRange(0x20, 0x2F, CsiParamState, CollectAction, CsiIntermediateState)
+
+ // Csi_intermediate
+ table.AddRange(0x00, 0x17, CsiIntermediateState, ExecuteAction, CsiIntermediateState)
+ table.AddOne(0x19, CsiIntermediateState, ExecuteAction, CsiIntermediateState)
+ table.AddRange(0x1C, 0x1F, CsiIntermediateState, ExecuteAction, CsiIntermediateState)
+ table.AddRange(0x20, 0x2F, CsiIntermediateState, CollectAction, CsiIntermediateState)
+ table.AddOne(0x7F, CsiIntermediateState, IgnoreAction, CsiIntermediateState)
+ // Csi_intermediate -> Ground
+ table.AddRange(0x40, 0x7E, CsiIntermediateState, DispatchAction, GroundState)
+ // Csi_intermediate -> Csi_ignore
+ table.AddRange(0x30, 0x3F, CsiIntermediateState, IgnoreAction, GroundState)
+
+ // Csi_entry
+ table.AddRange(0x00, 0x17, CsiEntryState, ExecuteAction, CsiEntryState)
+ table.AddOne(0x19, CsiEntryState, ExecuteAction, CsiEntryState)
+ table.AddRange(0x1C, 0x1F, CsiEntryState, ExecuteAction, CsiEntryState)
+ table.AddOne(0x7F, CsiEntryState, IgnoreAction, CsiEntryState)
+ // Csi_entry -> Ground
+ table.AddRange(0x40, 0x7E, CsiEntryState, DispatchAction, GroundState)
+ // Csi_entry -> Csi_intermediate
+ table.AddRange(0x20, 0x2F, CsiEntryState, CollectAction, CsiIntermediateState)
+ // Csi_entry -> Csi_param
+ table.AddRange(0x30, 0x3B, CsiEntryState, ParamAction, CsiParamState)
+ table.AddRange(0x3C, 0x3F, CsiEntryState, PrefixAction, CsiParamState)
+
+ // Osc_string
+ table.AddRange(0x00, 0x06, OscStringState, IgnoreAction, OscStringState)
+ table.AddRange(0x08, 0x17, OscStringState, IgnoreAction, OscStringState)
+ table.AddOne(0x19, OscStringState, IgnoreAction, OscStringState)
+ table.AddRange(0x1C, 0x1F, OscStringState, IgnoreAction, OscStringState)
+ table.AddRange(0x20, 0xFF, OscStringState, PutAction, OscStringState) // Allow Utf8 characters by extending the printable range from 0x7F to 0xFF
+
+ // ST, CAN, SUB, ESC, and BEL terminate the sequence
+ table.AddOne(0x1B, OscStringState, DispatchAction, EscapeState)
+ table.AddOne(0x07, OscStringState, DispatchAction, GroundState)
+ table.AddOne(0x9C, OscStringState, DispatchAction, GroundState)
+ table.AddMany([]byte{0x18, 0x1A}, OscStringState, IgnoreAction, GroundState)
+
+ return table
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser_decode.go b/vendor/github.com/charmbracelet/x/ansi/parser_decode.go
new file mode 100644
index 00000000..3e504739
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser_decode.go
@@ -0,0 +1,524 @@
+package ansi
+
+import (
+ "unicode/utf8"
+
+ "github.com/charmbracelet/x/ansi/parser"
+ "github.com/mattn/go-runewidth"
+ "github.com/rivo/uniseg"
+)
+
+// State represents the state of the ANSI escape sequence parser used by
+// [DecodeSequence].
+type State = byte
+
+// ANSI escape sequence states used by [DecodeSequence].
+const (
+ NormalState State = iota
+ PrefixState
+ ParamsState
+ IntermedState
+ EscapeState
+ StringState
+)
+
+// DecodeSequence decodes the first ANSI escape sequence or a printable
+// grapheme from the given data. It returns the sequence slice, the number of
+// bytes read, the cell width for each sequence, and the new state.
+//
+// The cell width will always be 0 for control and escape sequences, 1 for
+// ASCII printable characters, and the number of cells other Unicode characters
+// occupy. It uses the uniseg package to calculate the width of Unicode
+// graphemes and characters. This means it will always do grapheme clustering
+// (mode 2027).
+//
+// Passing a non-nil [*Parser] as the last argument will allow the decoder to
+// collect sequence parameters, data, and commands. The parser cmd will have
+// the packed command value that contains intermediate and prefix characters.
+// In the case of a OSC sequence, the cmd will be the OSC command number. Use
+// [Cmd] and [Param] types to unpack command intermediates and prefixes as well
+// as parameters.
+//
+// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
+// validity of other data sequences, OSC, DCS, etc, will require checking for
+// the returned sequence terminator bytes such as ST (ESC \\) and BEL).
+//
+// We store the command byte in [Cmd] in the most significant byte, the
+// prefix byte in the next byte, and the intermediate byte in the least
+// significant byte. This is done to avoid using a struct to store the command
+// and its intermediates and prefixes. The command byte is always the least
+// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the
+// command, intermediate, and prefix bytes. Note that we only collect the last
+// prefix character and intermediate byte.
+//
+// The [p.Params] slice will contain the parameters of the sequence. Any
+// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type
+// to unpack the parameters.
+//
+// Example:
+//
+// var state byte // the initial state is always zero [NormalState]
+// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional)
+// input := []byte("\x1b[31mHello, World!\x1b[0m")
+// for len(input) > 0 {
+// seq, width, n, newState := DecodeSequence(input, state, p)
+// log.Printf("seq: %q, width: %d", seq, width)
+// state = newState
+// input = input[n:]
+// }
+//
+// This function treats the text as a sequence of grapheme clusters.
+func DecodeSequence[T string | []byte](b T, state byte, p *Parser) (seq T, width int, n int, newState byte) {
+ return decodeSequence(GraphemeWidth, b, state, p)
+}
+
+// DecodeSequenceWc decodes the first ANSI escape sequence or a printable
+// grapheme from the given data. It returns the sequence slice, the number of
+// bytes read, the cell width for each sequence, and the new state.
+//
+// The cell width will always be 0 for control and escape sequences, 1 for
+// ASCII printable characters, and the number of cells other Unicode characters
+// occupy. It uses the uniseg package to calculate the width of Unicode
+// graphemes and characters. This means it will always do grapheme clustering
+// (mode 2027).
+//
+// Passing a non-nil [*Parser] as the last argument will allow the decoder to
+// collect sequence parameters, data, and commands. The parser cmd will have
+// the packed command value that contains intermediate and prefix characters.
+// In the case of a OSC sequence, the cmd will be the OSC command number. Use
+// [Cmd] and [Param] types to unpack command intermediates and prefixes as well
+// as parameters.
+//
+// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
+// validity of other data sequences, OSC, DCS, etc, will require checking for
+// the returned sequence terminator bytes such as ST (ESC \\) and BEL).
+//
+// We store the command byte in [Cmd] in the most significant byte, the
+// prefix byte in the next byte, and the intermediate byte in the least
+// significant byte. This is done to avoid using a struct to store the command
+// and its intermediates and prefixes. The command byte is always the least
+// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the
+// command, intermediate, and prefix bytes. Note that we only collect the last
+// prefix character and intermediate byte.
+//
+// The [p.Params] slice will contain the parameters of the sequence. Any
+// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type
+// to unpack the parameters.
+//
+// Example:
+//
+// var state byte // the initial state is always zero [NormalState]
+// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional)
+// input := []byte("\x1b[31mHello, World!\x1b[0m")
+// for len(input) > 0 {
+// seq, width, n, newState := DecodeSequenceWc(input, state, p)
+// log.Printf("seq: %q, width: %d", seq, width)
+// state = newState
+// input = input[n:]
+// }
+//
+// This function treats the text as a sequence of wide characters and runes.
+func DecodeSequenceWc[T string | []byte](b T, state byte, p *Parser) (seq T, width int, n int, newState byte) {
+ return decodeSequence(WcWidth, b, state, p)
+}
+
+func decodeSequence[T string | []byte](m Method, b T, state State, p *Parser) (seq T, width int, n int, newState byte) {
+ for i := 0; i < len(b); i++ {
+ c := b[i]
+
+ switch state {
+ case NormalState:
+ switch c {
+ case ESC:
+ if p != nil {
+ if len(p.params) > 0 {
+ p.params[0] = parser.MissingParam
+ }
+ p.cmd = 0
+ p.paramsLen = 0
+ p.dataLen = 0
+ }
+ state = EscapeState
+ continue
+ case CSI, DCS:
+ if p != nil {
+ if len(p.params) > 0 {
+ p.params[0] = parser.MissingParam
+ }
+ p.cmd = 0
+ p.paramsLen = 0
+ p.dataLen = 0
+ }
+ state = PrefixState
+ continue
+ case OSC, APC, SOS, PM:
+ if p != nil {
+ p.cmd = parser.MissingCommand
+ p.dataLen = 0
+ }
+ state = StringState
+ continue
+ }
+
+ if p != nil {
+ p.dataLen = 0
+ p.paramsLen = 0
+ p.cmd = 0
+ }
+ if c > US && c < DEL {
+ // ASCII printable characters
+ return b[i : i+1], 1, 1, NormalState
+ }
+
+ if c <= US || c == DEL || c < 0xC0 {
+ // C0 & C1 control characters & DEL
+ return b[i : i+1], 0, 1, NormalState
+ }
+
+ if utf8.RuneStart(c) {
+ seq, _, width, _ = FirstGraphemeCluster(b, -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(seq))
+ }
+ i += len(seq)
+ return b[:i], width, i, NormalState
+ }
+
+ // Invalid UTF-8 sequence
+ return b[:i], 0, i, NormalState
+ case PrefixState:
+ if c >= '<' && c <= '?' {
+ if p != nil {
+ // We only collect the last prefix character.
+ p.cmd &^= 0xff << parser.PrefixShift
+ p.cmd |= int(c) << parser.PrefixShift
+ }
+ break
+ }
+
+ state = ParamsState
+ fallthrough
+ case ParamsState:
+ if c >= '0' && c <= '9' {
+ if p != nil {
+ if p.params[p.paramsLen] == parser.MissingParam {
+ p.params[p.paramsLen] = 0
+ }
+
+ p.params[p.paramsLen] *= 10
+ p.params[p.paramsLen] += int(c - '0')
+ }
+ break
+ }
+
+ if c == ':' {
+ if p != nil {
+ p.params[p.paramsLen] |= parser.HasMoreFlag
+ }
+ }
+
+ if c == ';' || c == ':' {
+ if p != nil {
+ p.paramsLen++
+ if p.paramsLen < len(p.params) {
+ p.params[p.paramsLen] = parser.MissingParam
+ }
+ }
+ break
+ }
+
+ state = IntermedState
+ fallthrough
+ case IntermedState:
+ if c >= ' ' && c <= '/' {
+ if p != nil {
+ p.cmd &^= 0xff << parser.IntermedShift
+ p.cmd |= int(c) << parser.IntermedShift
+ }
+ break
+ }
+
+ if p != nil {
+ // Increment the last parameter
+ if p.paramsLen > 0 && p.paramsLen < len(p.params)-1 ||
+ p.paramsLen == 0 && len(p.params) > 0 && p.params[0] != parser.MissingParam {
+ p.paramsLen++
+ }
+ }
+
+ if c >= '@' && c <= '~' {
+ if p != nil {
+ p.cmd &^= 0xff
+ p.cmd |= int(c)
+ }
+
+ if HasDcsPrefix(b) {
+ // Continue to collect DCS data
+ if p != nil {
+ p.dataLen = 0
+ }
+ state = StringState
+ continue
+ }
+
+ return b[:i+1], 0, i + 1, NormalState
+ }
+
+ // Invalid CSI/DCS sequence
+ return b[:i], 0, i, NormalState
+ case EscapeState:
+ switch c {
+ case '[', 'P':
+ if p != nil {
+ if len(p.params) > 0 {
+ p.params[0] = parser.MissingParam
+ }
+ p.paramsLen = 0
+ p.cmd = 0
+ }
+ state = PrefixState
+ continue
+ case ']', 'X', '^', '_':
+ if p != nil {
+ p.cmd = parser.MissingCommand
+ p.dataLen = 0
+ }
+ state = StringState
+ continue
+ }
+
+ if c >= ' ' && c <= '/' {
+ if p != nil {
+ p.cmd &^= 0xff << parser.IntermedShift
+ p.cmd |= int(c) << parser.IntermedShift
+ }
+ continue
+ } else if c >= '0' && c <= '~' {
+ if p != nil {
+ p.cmd &^= 0xff
+ p.cmd |= int(c)
+ }
+ return b[:i+1], 0, i + 1, NormalState
+ }
+
+ // Invalid escape sequence
+ return b[:i], 0, i, NormalState
+ case StringState:
+ switch c {
+ case BEL:
+ if HasOscPrefix(b) {
+ parseOscCmd(p)
+ return b[:i+1], 0, i + 1, NormalState
+ }
+ case CAN, SUB:
+ if HasOscPrefix(b) {
+ // Ensure we parse the OSC command number
+ parseOscCmd(p)
+ }
+
+ // Cancel the sequence
+ return b[:i], 0, i, NormalState
+ case ST:
+ if HasOscPrefix(b) {
+ // Ensure we parse the OSC command number
+ parseOscCmd(p)
+ }
+
+ return b[:i+1], 0, i + 1, NormalState
+ case ESC:
+ if HasStPrefix(b[i:]) {
+ if HasOscPrefix(b) {
+ // Ensure we parse the OSC command number
+ parseOscCmd(p)
+ }
+
+ // End of string 7-bit (ST)
+ return b[:i+2], 0, i + 2, NormalState
+ }
+
+ // Otherwise, cancel the sequence
+ return b[:i], 0, i, NormalState
+ }
+
+ if p != nil && p.dataLen < len(p.data) {
+ p.data[p.dataLen] = c
+ p.dataLen++
+
+ // Parse the OSC command number
+ if c == ';' && HasOscPrefix(b) {
+ parseOscCmd(p)
+ }
+ }
+ }
+ }
+
+ return b, 0, len(b), state
+}
+
+func parseOscCmd(p *Parser) {
+ if p == nil || p.cmd != parser.MissingCommand {
+ return
+ }
+ for j := 0; j < p.dataLen; j++ {
+ d := p.data[j]
+ if d < '0' || d > '9' {
+ break
+ }
+ if p.cmd == parser.MissingCommand {
+ p.cmd = 0
+ }
+ p.cmd *= 10
+ p.cmd += int(d - '0')
+ }
+}
+
+// Equal returns true if the given byte slices are equal.
+func Equal[T string | []byte](a, b T) bool {
+ return string(a) == string(b)
+}
+
+// HasPrefix returns true if the given byte slice has prefix.
+func HasPrefix[T string | []byte](b, prefix T) bool {
+ return len(b) >= len(prefix) && Equal(b[0:len(prefix)], prefix)
+}
+
+// HasSuffix returns true if the given byte slice has suffix.
+func HasSuffix[T string | []byte](b, suffix T) bool {
+ return len(b) >= len(suffix) && Equal(b[len(b)-len(suffix):], suffix)
+}
+
+// HasCsiPrefix returns true if the given byte slice has a CSI prefix.
+func HasCsiPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == CSI) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == '[')
+}
+
+// HasOscPrefix returns true if the given byte slice has an OSC prefix.
+func HasOscPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == OSC) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == ']')
+}
+
+// HasApcPrefix returns true if the given byte slice has an APC prefix.
+func HasApcPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == APC) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == '_')
+}
+
+// HasDcsPrefix returns true if the given byte slice has a DCS prefix.
+func HasDcsPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == DCS) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == 'P')
+}
+
+// HasSosPrefix returns true if the given byte slice has a SOS prefix.
+func HasSosPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == SOS) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == 'X')
+}
+
+// HasPmPrefix returns true if the given byte slice has a PM prefix.
+func HasPmPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == PM) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == '^')
+}
+
+// HasStPrefix returns true if the given byte slice has a ST prefix.
+func HasStPrefix[T string | []byte](b T) bool {
+ return (len(b) > 0 && b[0] == ST) ||
+ (len(b) > 1 && b[0] == ESC && b[1] == '\\')
+}
+
+// HasEscPrefix returns true if the given byte slice has an ESC prefix.
+func HasEscPrefix[T string | []byte](b T) bool {
+ return len(b) > 0 && b[0] == ESC
+}
+
+// FirstGraphemeCluster returns the first grapheme cluster in the given string or byte slice.
+// This is a syntactic sugar function that wraps
+// uniseg.FirstGraphemeClusterInString and uniseg.FirstGraphemeCluster.
+func FirstGraphemeCluster[T string | []byte](b T, state int) (T, T, int, int) {
+ switch b := any(b).(type) {
+ case string:
+ cluster, rest, width, newState := uniseg.FirstGraphemeClusterInString(b, state)
+ return T(cluster), T(rest), width, newState
+ case []byte:
+ cluster, rest, width, newState := uniseg.FirstGraphemeCluster(b, state)
+ return T(cluster), T(rest), width, newState
+ }
+ panic("unreachable")
+}
+
+// Cmd represents a sequence command. This is used to pack/unpack a sequence
+// command with its intermediate and prefix characters. Those are commonly
+// found in CSI and DCS sequences.
+type Cmd int
+
+// Prefix returns the unpacked prefix byte of the CSI sequence.
+// This is always gonna be one of the following '<' '=' '>' '?' and in the
+// range of 0x3C-0x3F.
+// Zero is returned if the sequence does not have a prefix.
+func (c Cmd) Prefix() byte {
+ return byte(parser.Prefix(int(c)))
+}
+
+// Intermediate returns the unpacked intermediate byte of the CSI sequence.
+// An intermediate byte is in the range of 0x20-0x2F. This includes these
+// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+',
+// ',', '-', '.', '/'.
+// Zero is returned if the sequence does not have an intermediate byte.
+func (c Cmd) Intermediate() byte {
+ return byte(parser.Intermediate(int(c)))
+}
+
+// Final returns the unpacked command byte of the CSI sequence.
+func (c Cmd) Final() byte {
+ return byte(parser.Command(int(c)))
+}
+
+// Command packs a command with the given prefix, intermediate, and final. A
+// zero byte means the sequence does not have a prefix or intermediate.
+//
+// Prefixes are in the range of 0x3C-0x3F that is one of `<=>?`.
+//
+// Intermediates are in the range of 0x20-0x2F that is anything in
+// `!"#$%&'()*+,-./`.
+//
+// Final bytes are in the range of 0x40-0x7E that is anything in the range
+// `@A–Z[\]^_`a–z{|}~`.
+func Command(prefix, inter, final byte) (c int) {
+ c = int(final)
+ c |= int(prefix) << parser.PrefixShift
+ c |= int(inter) << parser.IntermedShift
+ return
+}
+
+// Param represents a sequence parameter. Sequence parameters with
+// sub-parameters are packed with the HasMoreFlag set. This is used to unpack
+// the parameters from a CSI and DCS sequences.
+type Param int
+
+// Param returns the unpacked parameter at the given index.
+// It returns the default value if the parameter is missing.
+func (s Param) Param(def int) int {
+ p := int(s) & parser.ParamMask
+ if p == parser.MissingParam {
+ return def
+ }
+ return p
+}
+
+// HasMore unpacks the HasMoreFlag from the parameter.
+func (s Param) HasMore() bool {
+ return s&parser.HasMoreFlag != 0
+}
+
+// Parameter packs an escape code parameter with the given parameter and
+// whether this parameter has following sub-parameters.
+func Parameter(p int, hasMore bool) (s int) {
+ s = p & parser.ParamMask
+ if hasMore {
+ s |= parser.HasMoreFlag
+ }
+ return
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser_handler.go b/vendor/github.com/charmbracelet/x/ansi/parser_handler.go
new file mode 100644
index 00000000..03f9ed4c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser_handler.go
@@ -0,0 +1,60 @@
+package ansi
+
+import "unsafe"
+
+// Params represents a list of packed parameters.
+type Params []Param
+
+// Param returns the parameter at the given index and if it is part of a
+// sub-parameters. It falls back to the default value if the parameter is
+// missing. If the index is out of bounds, it returns the default value and
+// false.
+func (p Params) Param(i, def int) (int, bool, bool) {
+ if i < 0 || i >= len(p) {
+ return def, false, false
+ }
+ return p[i].Param(def), p[i].HasMore(), true
+}
+
+// ForEach iterates over the parameters and calls the given function for each
+// parameter. If a parameter is part of a sub-parameter, it will be called with
+// hasMore set to true.
+// Use def to set a default value for missing parameters.
+func (p Params) ForEach(def int, f func(i, param int, hasMore bool)) {
+ for i := range p {
+ f(i, p[i].Param(def), p[i].HasMore())
+ }
+}
+
+// ToParams converts a list of integers to a list of parameters.
+func ToParams(params []int) Params {
+ return unsafe.Slice((*Param)(unsafe.Pointer(¶ms[0])), len(params))
+}
+
+// Handler handles actions performed by the parser.
+// It is used to handle ANSI escape sequences, control characters, and runes.
+type Handler struct {
+ // Print is called when a printable rune is encountered.
+ Print func(r rune)
+ // Execute is called when a control character is encountered.
+ Execute func(b byte)
+ // HandleCsi is called when a CSI sequence is encountered.
+ HandleCsi func(cmd Cmd, params Params)
+ // HandleEsc is called when an ESC sequence is encountered.
+ HandleEsc func(cmd Cmd)
+ // HandleDcs is called when a DCS sequence is encountered.
+ HandleDcs func(cmd Cmd, params Params, data []byte)
+ // HandleOsc is called when an OSC sequence is encountered.
+ HandleOsc func(cmd int, data []byte)
+ // HandlePm is called when a PM sequence is encountered.
+ HandlePm func(data []byte)
+ // HandleApc is called when an APC sequence is encountered.
+ HandleApc func(data []byte)
+ // HandleSos is called when a SOS sequence is encountered.
+ HandleSos func(data []byte)
+}
+
+// SetHandler sets the handler for the parser.
+func (p *Parser) SetHandler(h Handler) {
+ p.handler = h
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/parser_sync.go b/vendor/github.com/charmbracelet/x/ansi/parser_sync.go
new file mode 100644
index 00000000..65d25a9a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/parser_sync.go
@@ -0,0 +1,29 @@
+package ansi
+
+import (
+ "sync"
+
+ "github.com/charmbracelet/x/ansi/parser"
+)
+
+var parserPool = sync.Pool{
+ New: func() any {
+ p := NewParser()
+ p.SetParamsSize(parser.MaxParamsSize)
+ p.SetDataSize(1024 * 1024 * 4) // 4MB of data buffer
+ return p
+ },
+}
+
+// GetParser returns a parser from a sync pool.
+func GetParser() *Parser {
+ return parserPool.Get().(*Parser)
+}
+
+// PutParser returns a parser to a sync pool. The parser is reset
+// automatically.
+func PutParser(p *Parser) {
+ p.Reset()
+ p.dataLen = 0
+ parserPool.Put(p)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/passthrough.go b/vendor/github.com/charmbracelet/x/ansi/passthrough.go
new file mode 100644
index 00000000..14a74522
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/passthrough.go
@@ -0,0 +1,63 @@
+package ansi
+
+import (
+ "bytes"
+)
+
+// ScreenPassthrough wraps the given ANSI sequence in a DCS passthrough
+// sequence to be sent to the outer terminal. This is used to send raw escape
+// sequences to the outer terminal when running inside GNU Screen.
+//
+// DCS ST
+//
+// Note: Screen limits the length of string sequences to 768 bytes (since 2014).
+// Use zero to indicate no limit, otherwise, this will chunk the returned
+// string into limit sized chunks.
+//
+// See: https://www.gnu.org/software/screen/manual/screen.html#String-Escapes
+// See: https://git.savannah.gnu.org/cgit/screen.git/tree/src/screen.h?id=c184c6ec27683ff1a860c45be5cf520d896fd2ef#n44
+func ScreenPassthrough(seq string, limit int) string {
+ var b bytes.Buffer
+ b.WriteString("\x1bP")
+ if limit > 0 {
+ for i := 0; i < len(seq); i += limit {
+ end := i + limit
+ if end > len(seq) {
+ end = len(seq)
+ }
+ b.WriteString(seq[i:end])
+ if end < len(seq) {
+ b.WriteString("\x1b\\\x1bP")
+ }
+ }
+ } else {
+ b.WriteString(seq)
+ }
+ b.WriteString("\x1b\\")
+ return b.String()
+}
+
+// TmuxPassthrough wraps the given ANSI sequence in a special DCS passthrough
+// sequence to be sent to the outer terminal. This is used to send raw escape
+// sequences to the outer terminal when running inside Tmux.
+//
+// DCS tmux ; ST
+//
+// Where is the given sequence in which all occurrences of ESC
+// (0x1b) are doubled i.e. replaced with ESC ESC (0x1b 0x1b).
+//
+// Note: this needs the `allow-passthrough` option to be set to `on`.
+//
+// See: https://github.com/tmux/tmux/wiki/FAQ#what-is-the-passthrough-escape-sequence-and-how-do-i-use-it
+func TmuxPassthrough(seq string) string {
+ var b bytes.Buffer
+ b.WriteString("\x1bPtmux;")
+ for i := 0; i < len(seq); i++ {
+ if seq[i] == ESC {
+ b.WriteByte(ESC)
+ }
+ b.WriteByte(seq[i])
+ }
+ b.WriteString("\x1b\\")
+ return b.String()
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/paste.go b/vendor/github.com/charmbracelet/x/ansi/paste.go
new file mode 100644
index 00000000..2f9ea6f7
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/paste.go
@@ -0,0 +1,7 @@
+package ansi
+
+// BracketedPasteStart is the control sequence to enable bracketed paste mode.
+const BracketedPasteStart = "\x1b[200~"
+
+// BracketedPasteEnd is the control sequence to disable bracketed paste mode.
+const BracketedPasteEnd = "\x1b[201~"
diff --git a/vendor/github.com/charmbracelet/x/ansi/reset.go b/vendor/github.com/charmbracelet/x/ansi/reset.go
new file mode 100644
index 00000000..c1b89ea4
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/reset.go
@@ -0,0 +1,11 @@
+package ansi
+
+// ResetInitialState (RIS) resets the terminal to its initial state.
+//
+// ESC c
+//
+// See: https://vt100.net/docs/vt510-rm/RIS.html
+const (
+ ResetInitialState = "\x1bc"
+ RIS = ResetInitialState
+)
diff --git a/vendor/github.com/charmbracelet/x/ansi/screen.go b/vendor/github.com/charmbracelet/x/ansi/screen.go
new file mode 100644
index 00000000..c76e4f0d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/screen.go
@@ -0,0 +1,410 @@
+package ansi
+
+import (
+ "strconv"
+ "strings"
+)
+
+// EraseDisplay (ED) clears the display or parts of the display. A screen is
+// the shown part of the terminal display excluding the scrollback buffer.
+// Possible values:
+//
+// Default is 0.
+//
+// 0: Clear from cursor to end of screen.
+// 1: Clear from cursor to beginning of the screen.
+// 2: Clear entire screen (and moves cursor to upper left on DOS).
+// 3: Clear entire display which delete all lines saved in the scrollback buffer (xterm).
+//
+// CSI J
+//
+// See: https://vt100.net/docs/vt510-rm/ED.html
+func EraseDisplay(n int) string {
+ var s string
+ if n > 0 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "J"
+}
+
+// ED is an alias for [EraseDisplay].
+func ED(n int) string {
+ return EraseDisplay(n)
+}
+
+// EraseDisplay constants.
+// These are the possible values for the EraseDisplay function.
+const (
+ EraseScreenBelow = "\x1b[J"
+ EraseScreenAbove = "\x1b[1J"
+ EraseEntireScreen = "\x1b[2J"
+ EraseEntireDisplay = "\x1b[3J"
+)
+
+// EraseLine (EL) clears the current line or parts of the line. Possible values:
+//
+// 0: Clear from cursor to end of line.
+// 1: Clear from cursor to beginning of the line.
+// 2: Clear entire line.
+//
+// The cursor position is not affected.
+//
+// CSI K
+//
+// See: https://vt100.net/docs/vt510-rm/EL.html
+func EraseLine(n int) string {
+ var s string
+ if n > 0 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "K"
+}
+
+// EL is an alias for [EraseLine].
+func EL(n int) string {
+ return EraseLine(n)
+}
+
+// EraseLine constants.
+// These are the possible values for the EraseLine function.
+const (
+ EraseLineRight = "\x1b[K"
+ EraseLineLeft = "\x1b[1K"
+ EraseEntireLine = "\x1b[2K"
+)
+
+// ScrollUp (SU) scrolls the screen up n lines. New lines are added at the
+// bottom of the screen.
+//
+// CSI Pn S
+//
+// See: https://vt100.net/docs/vt510-rm/SU.html
+func ScrollUp(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "S"
+}
+
+// PanDown is an alias for [ScrollUp].
+func PanDown(n int) string {
+ return ScrollUp(n)
+}
+
+// SU is an alias for [ScrollUp].
+func SU(n int) string {
+ return ScrollUp(n)
+}
+
+// ScrollDown (SD) scrolls the screen down n lines. New lines are added at the
+// top of the screen.
+//
+// CSI Pn T
+//
+// See: https://vt100.net/docs/vt510-rm/SD.html
+func ScrollDown(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "T"
+}
+
+// PanUp is an alias for [ScrollDown].
+func PanUp(n int) string {
+ return ScrollDown(n)
+}
+
+// SD is an alias for [ScrollDown].
+func SD(n int) string {
+ return ScrollDown(n)
+}
+
+// InsertLine (IL) inserts n blank lines at the current cursor position.
+// Existing lines are moved down.
+//
+// CSI Pn L
+//
+// See: https://vt100.net/docs/vt510-rm/IL.html
+func InsertLine(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "L"
+}
+
+// IL is an alias for [InsertLine].
+func IL(n int) string {
+ return InsertLine(n)
+}
+
+// DeleteLine (DL) deletes n lines at the current cursor position. Existing
+// lines are moved up.
+//
+// CSI Pn M
+//
+// See: https://vt100.net/docs/vt510-rm/DL.html
+func DeleteLine(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "M"
+}
+
+// DL is an alias for [DeleteLine].
+func DL(n int) string {
+ return DeleteLine(n)
+}
+
+// SetTopBottomMargins (DECSTBM) sets the top and bottom margins for the scrolling
+// region. The default is the entire screen.
+//
+// Default is 1 and the bottom of the screen.
+//
+// CSI Pt ; Pb r
+//
+// See: https://vt100.net/docs/vt510-rm/DECSTBM.html
+func SetTopBottomMargins(top, bot int) string {
+ var t, b string
+ if top > 0 {
+ t = strconv.Itoa(top)
+ }
+ if bot > 0 {
+ b = strconv.Itoa(bot)
+ }
+ return "\x1b[" + t + ";" + b + "r"
+}
+
+// DECSTBM is an alias for [SetTopBottomMargins].
+func DECSTBM(top, bot int) string {
+ return SetTopBottomMargins(top, bot)
+}
+
+// SetLeftRightMargins (DECSLRM) sets the left and right margins for the scrolling
+// region.
+//
+// Default is 1 and the right of the screen.
+//
+// CSI Pl ; Pr s
+//
+// See: https://vt100.net/docs/vt510-rm/DECSLRM.html
+func SetLeftRightMargins(left, right int) string {
+ var l, r string
+ if left > 0 {
+ l = strconv.Itoa(left)
+ }
+ if right > 0 {
+ r = strconv.Itoa(right)
+ }
+ return "\x1b[" + l + ";" + r + "s"
+}
+
+// DECSLRM is an alias for [SetLeftRightMargins].
+func DECSLRM(left, right int) string {
+ return SetLeftRightMargins(left, right)
+}
+
+// SetScrollingRegion (DECSTBM) sets the top and bottom margins for the scrolling
+// region. The default is the entire screen.
+//
+// CSI ; r
+//
+// See: https://vt100.net/docs/vt510-rm/DECSTBM.html
+//
+// Deprecated: use [SetTopBottomMargins] instead.
+func SetScrollingRegion(t, b int) string {
+ if t < 0 {
+ t = 0
+ }
+ if b < 0 {
+ b = 0
+ }
+ return "\x1b[" + strconv.Itoa(t) + ";" + strconv.Itoa(b) + "r"
+}
+
+// InsertCharacter (ICH) inserts n blank characters at the current cursor
+// position. Existing characters move to the right. Characters moved past the
+// right margin are lost. ICH has no effect outside the scrolling margins.
+//
+// Default is 1.
+//
+// CSI Pn @
+//
+// See: https://vt100.net/docs/vt510-rm/ICH.html
+func InsertCharacter(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "@"
+}
+
+// ICH is an alias for [InsertCharacter].
+func ICH(n int) string {
+ return InsertCharacter(n)
+}
+
+// DeleteCharacter (DCH) deletes n characters at the current cursor position.
+// As the characters are deleted, the remaining characters move to the left and
+// the cursor remains at the same position.
+//
+// Default is 1.
+//
+// CSI Pn P
+//
+// See: https://vt100.net/docs/vt510-rm/DCH.html
+func DeleteCharacter(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "P"
+}
+
+// DCH is an alias for [DeleteCharacter].
+func DCH(n int) string {
+ return DeleteCharacter(n)
+}
+
+// SetTabEvery8Columns (DECST8C) sets the tab stops at every 8 columns.
+//
+// CSI ? 5 W
+//
+// See: https://vt100.net/docs/vt510-rm/DECST8C.html
+const (
+ SetTabEvery8Columns = "\x1b[?5W"
+ DECST8C = SetTabEvery8Columns
+)
+
+// HorizontalTabSet (HTS) sets a horizontal tab stop at the current cursor
+// column.
+//
+// This is equivalent to [HTS].
+//
+// ESC H
+//
+// See: https://vt100.net/docs/vt510-rm/HTS.html
+const HorizontalTabSet = "\x1bH"
+
+// TabClear (TBC) clears tab stops.
+//
+// Default is 0.
+//
+// Possible values:
+// 0: Clear tab stop at the current column. (default)
+// 3: Clear all tab stops.
+//
+// CSI Pn g
+//
+// See: https://vt100.net/docs/vt510-rm/TBC.html
+func TabClear(n int) string {
+ var s string
+ if n > 0 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "g"
+}
+
+// TBC is an alias for [TabClear].
+func TBC(n int) string {
+ return TabClear(n)
+}
+
+// RequestPresentationStateReport (DECRQPSR) requests the terminal to send a
+// report of the presentation state. This includes the cursor information [DECCIR],
+// and tab stop [DECTABSR] reports.
+//
+// Default is 0.
+//
+// Possible values:
+// 0: Error, request ignored.
+// 1: Cursor information report [DECCIR].
+// 2: Tab stop report [DECTABSR].
+//
+// CSI Ps $ w
+//
+// See: https://vt100.net/docs/vt510-rm/DECRQPSR.html
+func RequestPresentationStateReport(n int) string {
+ var s string
+ if n > 0 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "$w"
+}
+
+// DECRQPSR is an alias for [RequestPresentationStateReport].
+func DECRQPSR(n int) string {
+ return RequestPresentationStateReport(n)
+}
+
+// TabStopReport (DECTABSR) is the response to a tab stop report request.
+// It reports the tab stops set in the terminal.
+//
+// The response is a list of tab stops separated by a slash (/) character.
+//
+// DCS 2 $ u D ... D ST
+//
+// Where D is a decimal number representing a tab stop.
+//
+// See: https://vt100.net/docs/vt510-rm/DECTABSR.html
+func TabStopReport(stops ...int) string {
+ var s []string
+ for _, v := range stops {
+ s = append(s, strconv.Itoa(v))
+ }
+ return "\x1bP2$u" + strings.Join(s, "/") + "\x1b\\"
+}
+
+// DECTABSR is an alias for [TabStopReport].
+func DECTABSR(stops ...int) string {
+ return TabStopReport(stops...)
+}
+
+// CursorInformationReport (DECCIR) is the response to a cursor information
+// report request. It reports the cursor position, visual attributes, and
+// character protection attributes. It also reports the status of origin mode
+// [DECOM] and the current active character set.
+//
+// The response is a list of values separated by a semicolon (;) character.
+//
+// DCS 1 $ u D ... D ST
+//
+// Where D is a decimal number representing a value.
+//
+// See: https://vt100.net/docs/vt510-rm/DECCIR.html
+func CursorInformationReport(values ...int) string {
+ var s []string
+ for _, v := range values {
+ s = append(s, strconv.Itoa(v))
+ }
+ return "\x1bP1$u" + strings.Join(s, ";") + "\x1b\\"
+}
+
+// DECCIR is an alias for [CursorInformationReport].
+func DECCIR(values ...int) string {
+ return CursorInformationReport(values...)
+}
+
+// RepeatPreviousCharacter (REP) repeats the previous character n times.
+// This is identical to typing the same character n times.
+//
+// Default is 1.
+//
+// CSI Pn b
+//
+// See: ECMA-48 § 8.3.103
+func RepeatPreviousCharacter(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "b"
+}
+
+// REP is an alias for [RepeatPreviousCharacter].
+func REP(n int) string {
+ return RepeatPreviousCharacter(n)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/sgr.go b/vendor/github.com/charmbracelet/x/ansi/sgr.go
new file mode 100644
index 00000000..1a18c98e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/sgr.go
@@ -0,0 +1,95 @@
+package ansi
+
+import "strconv"
+
+// Select Graphic Rendition (SGR) is a command that sets display attributes.
+//
+// Default is 0.
+//
+// CSI Ps ; Ps ... m
+//
+// See: https://vt100.net/docs/vt510-rm/SGR.html
+func SelectGraphicRendition(ps ...Attr) string {
+ if len(ps) == 0 {
+ return ResetStyle
+ }
+
+ var s Style
+ for _, p := range ps {
+ attr, ok := attrStrings[p]
+ if ok {
+ s = append(s, attr)
+ } else {
+ if p < 0 {
+ p = 0
+ }
+ s = append(s, strconv.Itoa(p))
+ }
+ }
+
+ return s.String()
+}
+
+// SGR is an alias for [SelectGraphicRendition].
+func SGR(ps ...Attr) string {
+ return SelectGraphicRendition(ps...)
+}
+
+var attrStrings = map[int]string{
+ ResetAttr: "0",
+ BoldAttr: "1",
+ FaintAttr: "2",
+ ItalicAttr: "3",
+ UnderlineAttr: "4",
+ SlowBlinkAttr: "5",
+ RapidBlinkAttr: "6",
+ ReverseAttr: "7",
+ ConcealAttr: "8",
+ StrikethroughAttr: "9",
+ NoBoldAttr: "21",
+ NormalIntensityAttr: "22",
+ NoItalicAttr: "23",
+ NoUnderlineAttr: "24",
+ NoBlinkAttr: "25",
+ NoReverseAttr: "27",
+ NoConcealAttr: "28",
+ NoStrikethroughAttr: "29",
+ BlackForegroundColorAttr: "30",
+ RedForegroundColorAttr: "31",
+ GreenForegroundColorAttr: "32",
+ YellowForegroundColorAttr: "33",
+ BlueForegroundColorAttr: "34",
+ MagentaForegroundColorAttr: "35",
+ CyanForegroundColorAttr: "36",
+ WhiteForegroundColorAttr: "37",
+ ExtendedForegroundColorAttr: "38",
+ DefaultForegroundColorAttr: "39",
+ BlackBackgroundColorAttr: "40",
+ RedBackgroundColorAttr: "41",
+ GreenBackgroundColorAttr: "42",
+ YellowBackgroundColorAttr: "43",
+ BlueBackgroundColorAttr: "44",
+ MagentaBackgroundColorAttr: "45",
+ CyanBackgroundColorAttr: "46",
+ WhiteBackgroundColorAttr: "47",
+ ExtendedBackgroundColorAttr: "48",
+ DefaultBackgroundColorAttr: "49",
+ ExtendedUnderlineColorAttr: "58",
+ DefaultUnderlineColorAttr: "59",
+ BrightBlackForegroundColorAttr: "90",
+ BrightRedForegroundColorAttr: "91",
+ BrightGreenForegroundColorAttr: "92",
+ BrightYellowForegroundColorAttr: "93",
+ BrightBlueForegroundColorAttr: "94",
+ BrightMagentaForegroundColorAttr: "95",
+ BrightCyanForegroundColorAttr: "96",
+ BrightWhiteForegroundColorAttr: "97",
+ BrightBlackBackgroundColorAttr: "100",
+ BrightRedBackgroundColorAttr: "101",
+ BrightGreenBackgroundColorAttr: "102",
+ BrightYellowBackgroundColorAttr: "103",
+ BrightBlueBackgroundColorAttr: "104",
+ BrightMagentaBackgroundColorAttr: "105",
+ BrightCyanBackgroundColorAttr: "106",
+ BrightWhiteBackgroundColorAttr: "107",
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/status.go b/vendor/github.com/charmbracelet/x/ansi/status.go
new file mode 100644
index 00000000..4337e189
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/status.go
@@ -0,0 +1,144 @@
+package ansi
+
+import (
+ "strconv"
+ "strings"
+)
+
+// StatusReport represents a terminal status report.
+type StatusReport interface {
+ // StatusReport returns the status report identifier.
+ StatusReport() int
+}
+
+// ANSIReport represents an ANSI terminal status report.
+type ANSIStatusReport int //nolint:revive
+
+// Report returns the status report identifier.
+func (s ANSIStatusReport) StatusReport() int {
+ return int(s)
+}
+
+// DECStatusReport represents a DEC terminal status report.
+type DECStatusReport int
+
+// Status returns the status report identifier.
+func (s DECStatusReport) StatusReport() int {
+ return int(s)
+}
+
+// DeviceStatusReport (DSR) is a control sequence that reports the terminal's
+// status.
+// The terminal responds with a DSR sequence.
+//
+// CSI Ps n
+// CSI ? Ps n
+//
+// If one of the statuses is a [DECStatus], the sequence will use the DEC
+// format.
+//
+// See also https://vt100.net/docs/vt510-rm/DSR.html
+func DeviceStatusReport(statues ...StatusReport) string {
+ var dec bool
+ list := make([]string, len(statues))
+ seq := "\x1b["
+ for i, status := range statues {
+ list[i] = strconv.Itoa(status.StatusReport())
+ switch status.(type) {
+ case DECStatusReport:
+ dec = true
+ }
+ }
+ if dec {
+ seq += "?"
+ }
+ return seq + strings.Join(list, ";") + "n"
+}
+
+// DSR is an alias for [DeviceStatusReport].
+func DSR(status StatusReport) string {
+ return DeviceStatusReport(status)
+}
+
+// RequestCursorPositionReport is an escape sequence that requests the current
+// cursor position.
+//
+// CSI 6 n
+//
+// The terminal will report the cursor position as a CSI sequence in the
+// following format:
+//
+// CSI Pl ; Pc R
+//
+// Where Pl is the line number and Pc is the column number.
+// See: https://vt100.net/docs/vt510-rm/CPR.html
+const RequestCursorPositionReport = "\x1b[6n"
+
+// RequestExtendedCursorPositionReport (DECXCPR) is a sequence for requesting
+// the cursor position report including the current page number.
+//
+// CSI ? 6 n
+//
+// The terminal will report the cursor position as a CSI sequence in the
+// following format:
+//
+// CSI ? Pl ; Pc ; Pp R
+//
+// Where Pl is the line number, Pc is the column number, and Pp is the page
+// number.
+// See: https://vt100.net/docs/vt510-rm/DECXCPR.html
+const RequestExtendedCursorPositionReport = "\x1b[?6n"
+
+// CursorPositionReport (CPR) is a control sequence that reports the cursor's
+// position.
+//
+// CSI Pl ; Pc R
+//
+// Where Pl is the line number and Pc is the column number.
+//
+// See also https://vt100.net/docs/vt510-rm/CPR.html
+func CursorPositionReport(line, column int) string {
+ if line < 1 {
+ line = 1
+ }
+ if column < 1 {
+ column = 1
+ }
+ return "\x1b[" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + "R"
+}
+
+// CPR is an alias for [CursorPositionReport].
+func CPR(line, column int) string {
+ return CursorPositionReport(line, column)
+}
+
+// ExtendedCursorPositionReport (DECXCPR) is a control sequence that reports the
+// cursor's position along with the page number (optional).
+//
+// CSI ? Pl ; Pc R
+// CSI ? Pl ; Pc ; Pv R
+//
+// Where Pl is the line number, Pc is the column number, and Pv is the page
+// number.
+//
+// If the page number is zero or negative, the returned sequence won't include
+// the page number.
+//
+// See also https://vt100.net/docs/vt510-rm/DECXCPR.html
+func ExtendedCursorPositionReport(line, column, page int) string {
+ if line < 1 {
+ line = 1
+ }
+ if column < 1 {
+ column = 1
+ }
+ if page < 1 {
+ return "\x1b[?" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + "R"
+ }
+ return "\x1b[?" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + ";" + strconv.Itoa(page) + "R"
+}
+
+// DECXCPR is an alias for [ExtendedCursorPositionReport].
+func DECXCPR(line, column, page int) string {
+ return ExtendedCursorPositionReport(line, column, page)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/style.go b/vendor/github.com/charmbracelet/x/ansi/style.go
new file mode 100644
index 00000000..46ddcaa9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/style.go
@@ -0,0 +1,660 @@
+package ansi
+
+import (
+ "image/color"
+ "strconv"
+ "strings"
+)
+
+// ResetStyle is a SGR (Select Graphic Rendition) style sequence that resets
+// all attributes.
+// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
+const ResetStyle = "\x1b[m"
+
+// Attr is a SGR (Select Graphic Rendition) style attribute.
+type Attr = int
+
+// Style represents an ANSI SGR (Select Graphic Rendition) style.
+type Style []string
+
+// String returns the ANSI SGR (Select Graphic Rendition) style sequence for
+// the given style.
+func (s Style) String() string {
+ if len(s) == 0 {
+ return ResetStyle
+ }
+ return "\x1b[" + strings.Join(s, ";") + "m"
+}
+
+// Styled returns a styled string with the given style applied.
+func (s Style) Styled(str string) string {
+ if len(s) == 0 {
+ return str
+ }
+ return s.String() + str + ResetStyle
+}
+
+// Reset appends the reset style attribute to the style.
+func (s Style) Reset() Style {
+ return append(s, resetAttr)
+}
+
+// Bold appends the bold style attribute to the style.
+func (s Style) Bold() Style {
+ return append(s, boldAttr)
+}
+
+// Faint appends the faint style attribute to the style.
+func (s Style) Faint() Style {
+ return append(s, faintAttr)
+}
+
+// Italic appends the italic style attribute to the style.
+func (s Style) Italic() Style {
+ return append(s, italicAttr)
+}
+
+// Underline appends the underline style attribute to the style.
+func (s Style) Underline() Style {
+ return append(s, underlineAttr)
+}
+
+// UnderlineStyle appends the underline style attribute to the style.
+func (s Style) UnderlineStyle(u UnderlineStyle) Style {
+ switch u {
+ case NoUnderlineStyle:
+ return s.NoUnderline()
+ case SingleUnderlineStyle:
+ return s.Underline()
+ case DoubleUnderlineStyle:
+ return append(s, doubleUnderlineStyle)
+ case CurlyUnderlineStyle:
+ return append(s, curlyUnderlineStyle)
+ case DottedUnderlineStyle:
+ return append(s, dottedUnderlineStyle)
+ case DashedUnderlineStyle:
+ return append(s, dashedUnderlineStyle)
+ }
+ return s
+}
+
+// DoubleUnderline appends the double underline style attribute to the style.
+// This is a convenience method for UnderlineStyle(DoubleUnderlineStyle).
+func (s Style) DoubleUnderline() Style {
+ return s.UnderlineStyle(DoubleUnderlineStyle)
+}
+
+// CurlyUnderline appends the curly underline style attribute to the style.
+// This is a convenience method for UnderlineStyle(CurlyUnderlineStyle).
+func (s Style) CurlyUnderline() Style {
+ return s.UnderlineStyle(CurlyUnderlineStyle)
+}
+
+// DottedUnderline appends the dotted underline style attribute to the style.
+// This is a convenience method for UnderlineStyle(DottedUnderlineStyle).
+func (s Style) DottedUnderline() Style {
+ return s.UnderlineStyle(DottedUnderlineStyle)
+}
+
+// DashedUnderline appends the dashed underline style attribute to the style.
+// This is a convenience method for UnderlineStyle(DashedUnderlineStyle).
+func (s Style) DashedUnderline() Style {
+ return s.UnderlineStyle(DashedUnderlineStyle)
+}
+
+// SlowBlink appends the slow blink style attribute to the style.
+func (s Style) SlowBlink() Style {
+ return append(s, slowBlinkAttr)
+}
+
+// RapidBlink appends the rapid blink style attribute to the style.
+func (s Style) RapidBlink() Style {
+ return append(s, rapidBlinkAttr)
+}
+
+// Reverse appends the reverse style attribute to the style.
+func (s Style) Reverse() Style {
+ return append(s, reverseAttr)
+}
+
+// Conceal appends the conceal style attribute to the style.
+func (s Style) Conceal() Style {
+ return append(s, concealAttr)
+}
+
+// Strikethrough appends the strikethrough style attribute to the style.
+func (s Style) Strikethrough() Style {
+ return append(s, strikethroughAttr)
+}
+
+// NoBold appends the no bold style attribute to the style.
+func (s Style) NoBold() Style {
+ return append(s, noBoldAttr)
+}
+
+// NormalIntensity appends the normal intensity style attribute to the style.
+func (s Style) NormalIntensity() Style {
+ return append(s, normalIntensityAttr)
+}
+
+// NoItalic appends the no italic style attribute to the style.
+func (s Style) NoItalic() Style {
+ return append(s, noItalicAttr)
+}
+
+// NoUnderline appends the no underline style attribute to the style.
+func (s Style) NoUnderline() Style {
+ return append(s, noUnderlineAttr)
+}
+
+// NoBlink appends the no blink style attribute to the style.
+func (s Style) NoBlink() Style {
+ return append(s, noBlinkAttr)
+}
+
+// NoReverse appends the no reverse style attribute to the style.
+func (s Style) NoReverse() Style {
+ return append(s, noReverseAttr)
+}
+
+// NoConceal appends the no conceal style attribute to the style.
+func (s Style) NoConceal() Style {
+ return append(s, noConcealAttr)
+}
+
+// NoStrikethrough appends the no strikethrough style attribute to the style.
+func (s Style) NoStrikethrough() Style {
+ return append(s, noStrikethroughAttr)
+}
+
+// DefaultForegroundColor appends the default foreground color style attribute to the style.
+func (s Style) DefaultForegroundColor() Style {
+ return append(s, defaultForegroundColorAttr)
+}
+
+// DefaultBackgroundColor appends the default background color style attribute to the style.
+func (s Style) DefaultBackgroundColor() Style {
+ return append(s, defaultBackgroundColorAttr)
+}
+
+// DefaultUnderlineColor appends the default underline color style attribute to the style.
+func (s Style) DefaultUnderlineColor() Style {
+ return append(s, defaultUnderlineColorAttr)
+}
+
+// ForegroundColor appends the foreground color style attribute to the style.
+func (s Style) ForegroundColor(c Color) Style {
+ return append(s, foregroundColorString(c))
+}
+
+// BackgroundColor appends the background color style attribute to the style.
+func (s Style) BackgroundColor(c Color) Style {
+ return append(s, backgroundColorString(c))
+}
+
+// UnderlineColor appends the underline color style attribute to the style.
+func (s Style) UnderlineColor(c Color) Style {
+ return append(s, underlineColorString(c))
+}
+
+// UnderlineStyle represents an ANSI SGR (Select Graphic Rendition) underline
+// style.
+type UnderlineStyle = byte
+
+const (
+ doubleUnderlineStyle = "4:2"
+ curlyUnderlineStyle = "4:3"
+ dottedUnderlineStyle = "4:4"
+ dashedUnderlineStyle = "4:5"
+)
+
+const (
+ // NoUnderlineStyle is the default underline style.
+ NoUnderlineStyle UnderlineStyle = iota
+ // SingleUnderlineStyle is a single underline style.
+ SingleUnderlineStyle
+ // DoubleUnderlineStyle is a double underline style.
+ DoubleUnderlineStyle
+ // CurlyUnderlineStyle is a curly underline style.
+ CurlyUnderlineStyle
+ // DottedUnderlineStyle is a dotted underline style.
+ DottedUnderlineStyle
+ // DashedUnderlineStyle is a dashed underline style.
+ DashedUnderlineStyle
+)
+
+// SGR (Select Graphic Rendition) style attributes.
+// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
+const (
+ ResetAttr Attr = 0
+ BoldAttr Attr = 1
+ FaintAttr Attr = 2
+ ItalicAttr Attr = 3
+ UnderlineAttr Attr = 4
+ SlowBlinkAttr Attr = 5
+ RapidBlinkAttr Attr = 6
+ ReverseAttr Attr = 7
+ ConcealAttr Attr = 8
+ StrikethroughAttr Attr = 9
+ NoBoldAttr Attr = 21 // Some terminals treat this as double underline.
+ NormalIntensityAttr Attr = 22
+ NoItalicAttr Attr = 23
+ NoUnderlineAttr Attr = 24
+ NoBlinkAttr Attr = 25
+ NoReverseAttr Attr = 27
+ NoConcealAttr Attr = 28
+ NoStrikethroughAttr Attr = 29
+ BlackForegroundColorAttr Attr = 30
+ RedForegroundColorAttr Attr = 31
+ GreenForegroundColorAttr Attr = 32
+ YellowForegroundColorAttr Attr = 33
+ BlueForegroundColorAttr Attr = 34
+ MagentaForegroundColorAttr Attr = 35
+ CyanForegroundColorAttr Attr = 36
+ WhiteForegroundColorAttr Attr = 37
+ ExtendedForegroundColorAttr Attr = 38
+ DefaultForegroundColorAttr Attr = 39
+ BlackBackgroundColorAttr Attr = 40
+ RedBackgroundColorAttr Attr = 41
+ GreenBackgroundColorAttr Attr = 42
+ YellowBackgroundColorAttr Attr = 43
+ BlueBackgroundColorAttr Attr = 44
+ MagentaBackgroundColorAttr Attr = 45
+ CyanBackgroundColorAttr Attr = 46
+ WhiteBackgroundColorAttr Attr = 47
+ ExtendedBackgroundColorAttr Attr = 48
+ DefaultBackgroundColorAttr Attr = 49
+ ExtendedUnderlineColorAttr Attr = 58
+ DefaultUnderlineColorAttr Attr = 59
+ BrightBlackForegroundColorAttr Attr = 90
+ BrightRedForegroundColorAttr Attr = 91
+ BrightGreenForegroundColorAttr Attr = 92
+ BrightYellowForegroundColorAttr Attr = 93
+ BrightBlueForegroundColorAttr Attr = 94
+ BrightMagentaForegroundColorAttr Attr = 95
+ BrightCyanForegroundColorAttr Attr = 96
+ BrightWhiteForegroundColorAttr Attr = 97
+ BrightBlackBackgroundColorAttr Attr = 100
+ BrightRedBackgroundColorAttr Attr = 101
+ BrightGreenBackgroundColorAttr Attr = 102
+ BrightYellowBackgroundColorAttr Attr = 103
+ BrightBlueBackgroundColorAttr Attr = 104
+ BrightMagentaBackgroundColorAttr Attr = 105
+ BrightCyanBackgroundColorAttr Attr = 106
+ BrightWhiteBackgroundColorAttr Attr = 107
+
+ RGBColorIntroducerAttr Attr = 2
+ ExtendedColorIntroducerAttr Attr = 5
+)
+
+const (
+ resetAttr = "0"
+ boldAttr = "1"
+ faintAttr = "2"
+ italicAttr = "3"
+ underlineAttr = "4"
+ slowBlinkAttr = "5"
+ rapidBlinkAttr = "6"
+ reverseAttr = "7"
+ concealAttr = "8"
+ strikethroughAttr = "9"
+ noBoldAttr = "21"
+ normalIntensityAttr = "22"
+ noItalicAttr = "23"
+ noUnderlineAttr = "24"
+ noBlinkAttr = "25"
+ noReverseAttr = "27"
+ noConcealAttr = "28"
+ noStrikethroughAttr = "29"
+ blackForegroundColorAttr = "30"
+ redForegroundColorAttr = "31"
+ greenForegroundColorAttr = "32"
+ yellowForegroundColorAttr = "33"
+ blueForegroundColorAttr = "34"
+ magentaForegroundColorAttr = "35"
+ cyanForegroundColorAttr = "36"
+ whiteForegroundColorAttr = "37"
+ extendedForegroundColorAttr = "38"
+ defaultForegroundColorAttr = "39"
+ blackBackgroundColorAttr = "40"
+ redBackgroundColorAttr = "41"
+ greenBackgroundColorAttr = "42"
+ yellowBackgroundColorAttr = "43"
+ blueBackgroundColorAttr = "44"
+ magentaBackgroundColorAttr = "45"
+ cyanBackgroundColorAttr = "46"
+ whiteBackgroundColorAttr = "47"
+ extendedBackgroundColorAttr = "48"
+ defaultBackgroundColorAttr = "49"
+ extendedUnderlineColorAttr = "58"
+ defaultUnderlineColorAttr = "59"
+ brightBlackForegroundColorAttr = "90"
+ brightRedForegroundColorAttr = "91"
+ brightGreenForegroundColorAttr = "92"
+ brightYellowForegroundColorAttr = "93"
+ brightBlueForegroundColorAttr = "94"
+ brightMagentaForegroundColorAttr = "95"
+ brightCyanForegroundColorAttr = "96"
+ brightWhiteForegroundColorAttr = "97"
+ brightBlackBackgroundColorAttr = "100"
+ brightRedBackgroundColorAttr = "101"
+ brightGreenBackgroundColorAttr = "102"
+ brightYellowBackgroundColorAttr = "103"
+ brightBlueBackgroundColorAttr = "104"
+ brightMagentaBackgroundColorAttr = "105"
+ brightCyanBackgroundColorAttr = "106"
+ brightWhiteBackgroundColorAttr = "107"
+)
+
+// foregroundColorString returns the style SGR attribute for the given
+// foreground color.
+// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
+func foregroundColorString(c Color) string {
+ switch c := c.(type) {
+ case BasicColor:
+ // 3-bit or 4-bit ANSI foreground
+ // "3" or "9" where n is the color number from 0 to 7
+ switch c {
+ case Black:
+ return blackForegroundColorAttr
+ case Red:
+ return redForegroundColorAttr
+ case Green:
+ return greenForegroundColorAttr
+ case Yellow:
+ return yellowForegroundColorAttr
+ case Blue:
+ return blueForegroundColorAttr
+ case Magenta:
+ return magentaForegroundColorAttr
+ case Cyan:
+ return cyanForegroundColorAttr
+ case White:
+ return whiteForegroundColorAttr
+ case BrightBlack:
+ return brightBlackForegroundColorAttr
+ case BrightRed:
+ return brightRedForegroundColorAttr
+ case BrightGreen:
+ return brightGreenForegroundColorAttr
+ case BrightYellow:
+ return brightYellowForegroundColorAttr
+ case BrightBlue:
+ return brightBlueForegroundColorAttr
+ case BrightMagenta:
+ return brightMagentaForegroundColorAttr
+ case BrightCyan:
+ return brightCyanForegroundColorAttr
+ case BrightWhite:
+ return brightWhiteForegroundColorAttr
+ }
+ case ExtendedColor:
+ // 256-color ANSI foreground
+ // "38;5;"
+ return "38;5;" + strconv.FormatUint(uint64(c), 10)
+ case TrueColor, color.Color:
+ // 24-bit "true color" foreground
+ // "38;2;;;"
+ r, g, b, _ := c.RGBA()
+ return "38;2;" +
+ strconv.FormatUint(uint64(shift(r)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(g)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(b)), 10)
+ }
+ return defaultForegroundColorAttr
+}
+
+// backgroundColorString returns the style SGR attribute for the given
+// background color.
+// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
+func backgroundColorString(c Color) string {
+ switch c := c.(type) {
+ case BasicColor:
+ // 3-bit or 4-bit ANSI foreground
+ // "4" or "10" where n is the color number from 0 to 7
+ switch c {
+ case Black:
+ return blackBackgroundColorAttr
+ case Red:
+ return redBackgroundColorAttr
+ case Green:
+ return greenBackgroundColorAttr
+ case Yellow:
+ return yellowBackgroundColorAttr
+ case Blue:
+ return blueBackgroundColorAttr
+ case Magenta:
+ return magentaBackgroundColorAttr
+ case Cyan:
+ return cyanBackgroundColorAttr
+ case White:
+ return whiteBackgroundColorAttr
+ case BrightBlack:
+ return brightBlackBackgroundColorAttr
+ case BrightRed:
+ return brightRedBackgroundColorAttr
+ case BrightGreen:
+ return brightGreenBackgroundColorAttr
+ case BrightYellow:
+ return brightYellowBackgroundColorAttr
+ case BrightBlue:
+ return brightBlueBackgroundColorAttr
+ case BrightMagenta:
+ return brightMagentaBackgroundColorAttr
+ case BrightCyan:
+ return brightCyanBackgroundColorAttr
+ case BrightWhite:
+ return brightWhiteBackgroundColorAttr
+ }
+ case ExtendedColor:
+ // 256-color ANSI foreground
+ // "48;5;"
+ return "48;5;" + strconv.FormatUint(uint64(c), 10)
+ case TrueColor, color.Color:
+ // 24-bit "true color" foreground
+ // "38;2;;;"
+ r, g, b, _ := c.RGBA()
+ return "48;2;" +
+ strconv.FormatUint(uint64(shift(r)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(g)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(b)), 10)
+ }
+ return defaultBackgroundColorAttr
+}
+
+// underlineColorString returns the style SGR attribute for the given underline
+// color.
+// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
+func underlineColorString(c Color) string {
+ switch c := c.(type) {
+ // NOTE: we can't use 3-bit and 4-bit ANSI color codes with underline
+ // color, use 256-color instead.
+ //
+ // 256-color ANSI underline color
+ // "58;5;"
+ case BasicColor:
+ return "58;5;" + strconv.FormatUint(uint64(c), 10)
+ case ExtendedColor:
+ return "58;5;" + strconv.FormatUint(uint64(c), 10)
+ case TrueColor, color.Color:
+ // 24-bit "true color" foreground
+ // "38;2;;;"
+ r, g, b, _ := c.RGBA()
+ return "58;2;" +
+ strconv.FormatUint(uint64(shift(r)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(g)), 10) + ";" +
+ strconv.FormatUint(uint64(shift(b)), 10)
+ }
+ return defaultUnderlineColorAttr
+}
+
+// ReadStyleColor decodes a color from a slice of parameters. It returns the
+// number of parameters read and the color. This function is used to read SGR
+// color parameters following the ITU T.416 standard.
+//
+// It supports reading the following color types:
+// - 0: implementation defined
+// - 1: transparent
+// - 2: RGB direct color
+// - 3: CMY direct color
+// - 4: CMYK direct color
+// - 5: indexed color
+// - 6: RGBA direct color (WezTerm extension)
+//
+// The parameters can be separated by semicolons (;) or colons (:). Mixing
+// separators is not allowed.
+//
+// The specs supports defining a color space id, a color tolerance value, and a
+// tolerance color space id. However, these values have no effect on the
+// returned color and will be ignored.
+//
+// This implementation includes a few modifications to the specs:
+// 1. Support for legacy color values separated by semicolons (;) with respect to RGB, and indexed colors
+// 2. Support ignoring and omitting the color space id (second parameter) with respect to RGB colors
+// 3. Support ignoring and omitting the 6th parameter with respect to RGB and CMY colors
+// 4. Support reading RGBA colors
+func ReadStyleColor(params Params, co *color.Color) (n int) {
+ if len(params) < 2 { // Need at least SGR type and color type
+ return 0
+ }
+
+ // First parameter indicates one of 38, 48, or 58 (foreground, background, or underline)
+ s := params[0]
+ p := params[1]
+ colorType := p.Param(0)
+ n = 2
+
+ paramsfn := func() (p1, p2, p3, p4 int) {
+ // Where should we start reading the color?
+ switch {
+ case s.HasMore() && p.HasMore() && len(params) > 8 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore() && params[6].HasMore() && params[7].HasMore():
+ // We have color space id, a 6th parameter, a tolerance value, and a tolerance color space
+ n += 7
+ return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0)
+ case s.HasMore() && p.HasMore() && len(params) > 7 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore() && params[6].HasMore():
+ // We have color space id, a 6th parameter, and a tolerance value
+ n += 6
+ return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0)
+ case s.HasMore() && p.HasMore() && len(params) > 6 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore():
+ // We have color space id and a 6th parameter
+ // 48 : 4 : : 1 : 2 : 3 :4
+ n += 5
+ return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0)
+ case s.HasMore() && p.HasMore() && len(params) > 5 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && !params[5].HasMore():
+ // We have color space
+ // 48 : 3 : : 1 : 2 : 3
+ n += 4
+ return params[3].Param(0), params[4].Param(0), params[5].Param(0), -1
+ case s.HasMore() && p.HasMore() && p.Param(0) == 2 && params[2].HasMore() && params[3].HasMore() && !params[4].HasMore():
+ // We have color values separated by colons (:)
+ // 48 : 2 : 1 : 2 : 3
+ fallthrough
+ case !s.HasMore() && !p.HasMore() && p.Param(0) == 2 && !params[2].HasMore() && !params[3].HasMore() && !params[4].HasMore():
+ // Support legacy color values separated by semicolons (;)
+ // 48 ; 2 ; 1 ; 2 ; 3
+ n += 3
+ return params[2].Param(0), params[3].Param(0), params[4].Param(0), -1
+ }
+ // Ambiguous SGR color
+ return -1, -1, -1, -1
+ }
+
+ switch colorType {
+ case 0: // implementation defined
+ return 2
+ case 1: // transparent
+ *co = color.Transparent
+ return 2
+ case 2: // RGB direct color
+ if len(params) < 5 {
+ return 0
+ }
+
+ r, g, b, _ := paramsfn()
+ if r == -1 || g == -1 || b == -1 {
+ return 0
+ }
+
+ *co = color.RGBA{
+ R: uint8(r), //nolint:gosec
+ G: uint8(g), //nolint:gosec
+ B: uint8(b), //nolint:gosec
+ A: 0xff,
+ }
+ return
+
+ case 3: // CMY direct color
+ if len(params) < 5 {
+ return 0
+ }
+
+ c, m, y, _ := paramsfn()
+ if c == -1 || m == -1 || y == -1 {
+ return 0
+ }
+
+ *co = color.CMYK{
+ C: uint8(c), //nolint:gosec
+ M: uint8(m), //nolint:gosec
+ Y: uint8(y), //nolint:gosec
+ K: 0,
+ }
+ return
+
+ case 4: // CMYK direct color
+ if len(params) < 6 {
+ return 0
+ }
+
+ c, m, y, k := paramsfn()
+ if c == -1 || m == -1 || y == -1 || k == -1 {
+ return 0
+ }
+
+ *co = color.CMYK{
+ C: uint8(c), //nolint:gosec
+ M: uint8(m), //nolint:gosec
+ Y: uint8(y), //nolint:gosec
+ K: uint8(k), //nolint:gosec
+ }
+ return
+
+ case 5: // indexed color
+ if len(params) < 3 {
+ return 0
+ }
+ switch {
+ case s.HasMore() && p.HasMore() && !params[2].HasMore():
+ // Colon separated indexed color
+ // 38 : 5 : 234
+ case !s.HasMore() && !p.HasMore() && !params[2].HasMore():
+ // Legacy semicolon indexed color
+ // 38 ; 5 ; 234
+ default:
+ return 0
+ }
+ *co = ExtendedColor(params[2].Param(0)) //nolint:gosec
+ return 3
+
+ case 6: // RGBA direct color
+ if len(params) < 6 {
+ return 0
+ }
+
+ r, g, b, a := paramsfn()
+ if r == -1 || g == -1 || b == -1 || a == -1 {
+ return 0
+ }
+
+ *co = color.RGBA{
+ R: uint8(r), //nolint:gosec
+ G: uint8(g), //nolint:gosec
+ B: uint8(b), //nolint:gosec
+ A: uint8(a), //nolint:gosec
+ }
+ return
+
+ default:
+ return 0
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/termcap.go b/vendor/github.com/charmbracelet/x/ansi/termcap.go
new file mode 100644
index 00000000..3c5c7da9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/termcap.go
@@ -0,0 +1,41 @@
+package ansi
+
+import (
+ "encoding/hex"
+ "strings"
+)
+
+// RequestTermcap (XTGETTCAP) requests Termcap/Terminfo strings.
+//
+// DCS + q ST
+//
+// Where is a list of Termcap/Terminfo capabilities, encoded in 2-digit
+// hexadecimals, separated by semicolons.
+//
+// See: https://man7.org/linux/man-pages/man5/terminfo.5.html
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+func XTGETTCAP(caps ...string) string {
+ if len(caps) == 0 {
+ return ""
+ }
+
+ s := "\x1bP+q"
+ for i, c := range caps {
+ if i > 0 {
+ s += ";"
+ }
+ s += strings.ToUpper(hex.EncodeToString([]byte(c)))
+ }
+
+ return s + "\x1b\\"
+}
+
+// RequestTermcap is an alias for [XTGETTCAP].
+func RequestTermcap(caps ...string) string {
+ return XTGETTCAP(caps...)
+}
+
+// RequestTerminfo is an alias for [XTGETTCAP].
+func RequestTerminfo(caps ...string) string {
+ return XTGETTCAP(caps...)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/title.go b/vendor/github.com/charmbracelet/x/ansi/title.go
new file mode 100644
index 00000000..8fd8bf98
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/title.go
@@ -0,0 +1,32 @@
+package ansi
+
+// SetIconNameWindowTitle returns a sequence for setting the icon name and
+// window title.
+//
+// OSC 0 ; title ST
+// OSC 0 ; title BEL
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
+func SetIconNameWindowTitle(s string) string {
+ return "\x1b]0;" + s + "\x07"
+}
+
+// SetIconName returns a sequence for setting the icon name.
+//
+// OSC 1 ; title ST
+// OSC 1 ; title BEL
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
+func SetIconName(s string) string {
+ return "\x1b]1;" + s + "\x07"
+}
+
+// SetWindowTitle returns a sequence for setting the window title.
+//
+// OSC 2 ; title ST
+// OSC 2 ; title BEL
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
+func SetWindowTitle(s string) string {
+ return "\x1b]2;" + s + "\x07"
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/truncate.go b/vendor/github.com/charmbracelet/x/ansi/truncate.go
new file mode 100644
index 00000000..1fa3efef
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/truncate.go
@@ -0,0 +1,282 @@
+package ansi
+
+import (
+ "bytes"
+
+ "github.com/charmbracelet/x/ansi/parser"
+ "github.com/mattn/go-runewidth"
+ "github.com/rivo/uniseg"
+)
+
+// Cut the string, without adding any prefix or tail strings. This function is
+// aware of ANSI escape codes and will not break them, and accounts for
+// wide-characters (such as East-Asian characters and emojis). Note that the
+// [left] parameter is inclusive, while [right] isn't.
+// This treats the text as a sequence of graphemes.
+func Cut(s string, left, right int) string {
+ return cut(GraphemeWidth, s, left, right)
+}
+
+// CutWc the string, without adding any prefix or tail strings. This function is
+// aware of ANSI escape codes and will not break them, and accounts for
+// wide-characters (such as East-Asian characters and emojis). Note that the
+// [left] parameter is inclusive, while [right] isn't.
+// This treats the text as a sequence of wide characters and runes.
+func CutWc(s string, left, right int) string {
+ return cut(WcWidth, s, left, right)
+}
+
+func cut(m Method, s string, left, right int) string {
+ if right <= left {
+ return ""
+ }
+
+ truncate := Truncate
+ truncateLeft := TruncateLeft
+ if m == WcWidth {
+ truncate = TruncateWc
+ truncateLeft = TruncateWc
+ }
+
+ if left == 0 {
+ return truncate(s, right, "")
+ }
+ return truncateLeft(Truncate(s, right, ""), left, "")
+}
+
+// Truncate truncates a string to a given length, adding a tail to the end if
+// the string is longer than the given length. This function is aware of ANSI
+// escape codes and will not break them, and accounts for wide-characters (such
+// as East-Asian characters and emojis).
+// This treats the text as a sequence of graphemes.
+func Truncate(s string, length int, tail string) string {
+ return truncate(GraphemeWidth, s, length, tail)
+}
+
+// TruncateWc truncates a string to a given length, adding a tail to the end if
+// the string is longer than the given length. This function is aware of ANSI
+// escape codes and will not break them, and accounts for wide-characters (such
+// as East-Asian characters and emojis).
+// This treats the text as a sequence of wide characters and runes.
+func TruncateWc(s string, length int, tail string) string {
+ return truncate(WcWidth, s, length, tail)
+}
+
+func truncate(m Method, s string, length int, tail string) string {
+ if sw := StringWidth(s); sw <= length {
+ return s
+ }
+
+ tw := StringWidth(tail)
+ length -= tw
+ if length < 0 {
+ return ""
+ }
+
+ var cluster []byte
+ var buf bytes.Buffer
+ curWidth := 0
+ ignoring := false
+ pstate := parser.GroundState // initial state
+ b := []byte(s)
+ i := 0
+
+ // Here we iterate over the bytes of the string and collect printable
+ // characters and runes. We also keep track of the width of the string
+ // in cells.
+ //
+ // Once we reach the given length, we start ignoring characters and only
+ // collect ANSI escape codes until we reach the end of string.
+ for i < len(b) {
+ state, action := parser.Table.Transition(pstate, b[i])
+ if state == parser.Utf8State {
+ // This action happens when we transition to the Utf8State.
+ var width int
+ cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(cluster))
+ }
+
+ // increment the index by the length of the cluster
+ i += len(cluster)
+
+ // Are we ignoring? Skip to the next byte
+ if ignoring {
+ continue
+ }
+
+ // Is this gonna be too wide?
+ // If so write the tail and stop collecting.
+ if curWidth+width > length && !ignoring {
+ ignoring = true
+ buf.WriteString(tail)
+ }
+
+ if curWidth+width > length {
+ continue
+ }
+
+ curWidth += width
+ buf.Write(cluster)
+
+ // Done collecting, now we're back in the ground state.
+ pstate = parser.GroundState
+ continue
+ }
+
+ switch action {
+ case parser.PrintAction:
+ // Is this gonna be too wide?
+ // If so write the tail and stop collecting.
+ if curWidth >= length && !ignoring {
+ ignoring = true
+ buf.WriteString(tail)
+ }
+
+ // Skip to the next byte if we're ignoring
+ if ignoring {
+ i++
+ continue
+ }
+
+ // collects printable ASCII
+ curWidth++
+ fallthrough
+ default:
+ buf.WriteByte(b[i])
+ i++
+ }
+
+ // Transition to the next state.
+ pstate = state
+
+ // Once we reach the given length, we start ignoring runes and write
+ // the tail to the buffer.
+ if curWidth > length && !ignoring {
+ ignoring = true
+ buf.WriteString(tail)
+ }
+ }
+
+ return buf.String()
+}
+
+// TruncateLeft truncates a string from the left side by removing n characters,
+// adding a prefix to the beginning if the string is longer than n.
+// This function is aware of ANSI escape codes and will not break them, and
+// accounts for wide-characters (such as East-Asian characters and emojis).
+// This treats the text as a sequence of graphemes.
+func TruncateLeft(s string, n int, prefix string) string {
+ return truncateLeft(GraphemeWidth, s, n, prefix)
+}
+
+// TruncateLeftWc truncates a string from the left side by removing n characters,
+// adding a prefix to the beginning if the string is longer than n.
+// This function is aware of ANSI escape codes and will not break them, and
+// accounts for wide-characters (such as East-Asian characters and emojis).
+// This treats the text as a sequence of wide characters and runes.
+func TruncateLeftWc(s string, n int, prefix string) string {
+ return truncateLeft(WcWidth, s, n, prefix)
+}
+
+func truncateLeft(m Method, s string, n int, prefix string) string {
+ if n <= 0 {
+ return s
+ }
+
+ var cluster []byte
+ var buf bytes.Buffer
+ curWidth := 0
+ ignoring := true
+ pstate := parser.GroundState
+ b := []byte(s)
+ i := 0
+
+ for i < len(b) {
+ if !ignoring {
+ buf.Write(b[i:])
+ break
+ }
+
+ state, action := parser.Table.Transition(pstate, b[i])
+ if state == parser.Utf8State {
+ var width int
+ cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(cluster))
+ }
+
+ i += len(cluster)
+ curWidth += width
+
+ if curWidth > n && ignoring {
+ ignoring = false
+ buf.WriteString(prefix)
+ }
+
+ if ignoring {
+ continue
+ }
+
+ if curWidth > n {
+ buf.Write(cluster)
+ }
+
+ pstate = parser.GroundState
+ continue
+ }
+
+ switch action {
+ case parser.PrintAction:
+ curWidth++
+
+ if curWidth > n && ignoring {
+ ignoring = false
+ buf.WriteString(prefix)
+ }
+
+ if ignoring {
+ i++
+ continue
+ }
+
+ fallthrough
+ default:
+ buf.WriteByte(b[i])
+ i++
+ }
+
+ pstate = state
+ if curWidth > n && ignoring {
+ ignoring = false
+ buf.WriteString(prefix)
+ }
+ }
+
+ return buf.String()
+}
+
+// ByteToGraphemeRange takes start and stop byte positions and converts them to
+// grapheme-aware char positions.
+// You can use this with [Truncate], [TruncateLeft], and [Cut].
+func ByteToGraphemeRange(str string, byteStart, byteStop int) (charStart, charStop int) {
+ bytePos, charPos := 0, 0
+ gr := uniseg.NewGraphemes(str)
+ for byteStart > bytePos {
+ if !gr.Next() {
+ break
+ }
+ bytePos += len(gr.Str())
+ charPos += max(1, gr.Width())
+ }
+ charStart = charPos
+ for byteStop > bytePos {
+ if !gr.Next() {
+ break
+ }
+ bytePos += len(gr.Str())
+ charPos += max(1, gr.Width())
+ }
+ charStop = charPos
+ return
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/util.go b/vendor/github.com/charmbracelet/x/ansi/util.go
new file mode 100644
index 00000000..301ef15f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/util.go
@@ -0,0 +1,106 @@
+package ansi
+
+import (
+ "fmt"
+ "image/color"
+ "strconv"
+ "strings"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+// colorToHexString returns a hex string representation of a color.
+func colorToHexString(c color.Color) string {
+ if c == nil {
+ return ""
+ }
+ shift := func(v uint32) uint32 {
+ if v > 0xff {
+ return v >> 8
+ }
+ return v
+ }
+ r, g, b, _ := c.RGBA()
+ r, g, b = shift(r), shift(g), shift(b)
+ return fmt.Sprintf("#%02x%02x%02x", r, g, b)
+}
+
+// rgbToHex converts red, green, and blue values to a hexadecimal value.
+//
+// hex := rgbToHex(0, 0, 255) // 0x0000FF
+func rgbToHex(r, g, b uint32) uint32 {
+ return r<<16 + g<<8 + b
+}
+
+type shiftable interface {
+ ~uint | ~uint16 | ~uint32 | ~uint64
+}
+
+func shift[T shiftable](x T) T {
+ if x > 0xff {
+ x >>= 8
+ }
+ return x
+}
+
+// XParseColor is a helper function that parses a string into a color.Color. It
+// provides a similar interface to the XParseColor function in Xlib. It
+// supports the following formats:
+//
+// - #RGB
+// - #RRGGBB
+// - rgb:RRRR/GGGG/BBBB
+// - rgba:RRRR/GGGG/BBBB/AAAA
+//
+// If the string is not a valid color, nil is returned.
+//
+// See: https://linux.die.net/man/3/xparsecolor
+func XParseColor(s string) color.Color {
+ switch {
+ case strings.HasPrefix(s, "#"):
+ c, err := colorful.Hex(s)
+ if err != nil {
+ return nil
+ }
+
+ return c
+ case strings.HasPrefix(s, "rgb:"):
+ parts := strings.Split(s[4:], "/")
+ if len(parts) != 3 {
+ return nil
+ }
+
+ r, _ := strconv.ParseUint(parts[0], 16, 32)
+ g, _ := strconv.ParseUint(parts[1], 16, 32)
+ b, _ := strconv.ParseUint(parts[2], 16, 32)
+
+ return color.RGBA{uint8(shift(r)), uint8(shift(g)), uint8(shift(b)), 255} //nolint:gosec
+ case strings.HasPrefix(s, "rgba:"):
+ parts := strings.Split(s[5:], "/")
+ if len(parts) != 4 {
+ return nil
+ }
+
+ r, _ := strconv.ParseUint(parts[0], 16, 32)
+ g, _ := strconv.ParseUint(parts[1], 16, 32)
+ b, _ := strconv.ParseUint(parts[2], 16, 32)
+ a, _ := strconv.ParseUint(parts[3], 16, 32)
+
+ return color.RGBA{uint8(shift(r)), uint8(shift(g)), uint8(shift(b)), uint8(shift(a))} //nolint:gosec
+ }
+ return nil
+}
+
+type ordered interface {
+ ~int | ~int8 | ~int16 | ~int32 | ~int64 |
+ ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
+ ~float32 | ~float64 |
+ ~string
+}
+
+func max[T ordered](a, b T) T { //nolint:predeclared
+ if a > b {
+ return a
+ }
+ return b
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/width.go b/vendor/github.com/charmbracelet/x/ansi/width.go
new file mode 100644
index 00000000..d0487d35
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/width.go
@@ -0,0 +1,113 @@
+package ansi
+
+import (
+ "bytes"
+
+ "github.com/charmbracelet/x/ansi/parser"
+ "github.com/mattn/go-runewidth"
+ "github.com/rivo/uniseg"
+)
+
+// Strip removes ANSI escape codes from a string.
+func Strip(s string) string {
+ var (
+ buf bytes.Buffer // buffer for collecting printable characters
+ ri int // rune index
+ rw int // rune width
+ pstate = parser.GroundState // initial state
+ )
+
+ // This implements a subset of the Parser to only collect runes and
+ // printable characters.
+ for i := 0; i < len(s); i++ {
+ if pstate == parser.Utf8State {
+ // During this state, collect rw bytes to form a valid rune in the
+ // buffer. After getting all the rune bytes into the buffer,
+ // transition to GroundState and reset the counters.
+ buf.WriteByte(s[i])
+ ri++
+ if ri < rw {
+ continue
+ }
+ pstate = parser.GroundState
+ ri = 0
+ rw = 0
+ continue
+ }
+
+ state, action := parser.Table.Transition(pstate, s[i])
+ switch action {
+ case parser.CollectAction:
+ if state == parser.Utf8State {
+ // This action happens when we transition to the Utf8State.
+ rw = utf8ByteLen(s[i])
+ buf.WriteByte(s[i])
+ ri++
+ }
+ case parser.PrintAction, parser.ExecuteAction:
+ // collects printable ASCII and non-printable characters
+ buf.WriteByte(s[i])
+ }
+
+ // Transition to the next state.
+ // The Utf8State is managed separately above.
+ if pstate != parser.Utf8State {
+ pstate = state
+ }
+ }
+
+ return buf.String()
+}
+
+// StringWidth returns the width of a string in cells. This is the number of
+// cells that the string will occupy when printed in a terminal. ANSI escape
+// codes are ignored and wide characters (such as East Asians and emojis) are
+// accounted for.
+// This treats the text as a sequence of grapheme clusters.
+func StringWidth(s string) int {
+ return stringWidth(GraphemeWidth, s)
+}
+
+// StringWidthWc returns the width of a string in cells. This is the number of
+// cells that the string will occupy when printed in a terminal. ANSI escape
+// codes are ignored and wide characters (such as East Asians and emojis) are
+// accounted for.
+// This treats the text as a sequence of wide characters and runes.
+func StringWidthWc(s string) int {
+ return stringWidth(WcWidth, s)
+}
+
+func stringWidth(m Method, s string) int {
+ if s == "" {
+ return 0
+ }
+
+ var (
+ pstate = parser.GroundState // initial state
+ cluster string
+ width int
+ )
+
+ for i := 0; i < len(s); i++ {
+ state, action := parser.Table.Transition(pstate, s[i])
+ if state == parser.Utf8State {
+ var w int
+ cluster, _, w, _ = uniseg.FirstGraphemeClusterInString(s[i:], -1)
+ if m == WcWidth {
+ w = runewidth.StringWidth(cluster)
+ }
+ width += w
+ i += len(cluster) - 1
+ pstate = parser.GroundState
+ continue
+ }
+
+ if action == parser.PrintAction {
+ width++
+ }
+
+ pstate = state
+ }
+
+ return width
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/winop.go b/vendor/github.com/charmbracelet/x/ansi/winop.go
new file mode 100644
index 00000000..0238780d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/winop.go
@@ -0,0 +1,53 @@
+package ansi
+
+import (
+ "strconv"
+ "strings"
+)
+
+const (
+ // ResizeWindowWinOp is a window operation that resizes the terminal
+ // window.
+ ResizeWindowWinOp = 4
+
+ // RequestWindowSizeWinOp is a window operation that requests a report of
+ // the size of the terminal window in pixels. The response is in the form:
+ // CSI 4 ; height ; width t
+ RequestWindowSizeWinOp = 14
+
+ // RequestCellSizeWinOp is a window operation that requests a report of
+ // the size of the terminal cell size in pixels. The response is in the form:
+ // CSI 6 ; height ; width t
+ RequestCellSizeWinOp = 16
+)
+
+// WindowOp (XTWINOPS) is a sequence that manipulates the terminal window.
+//
+// CSI Ps ; Ps ; Ps t
+//
+// Ps is a semicolon-separated list of parameters.
+// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps;Ps;Ps-t.1EB0
+func WindowOp(p int, ps ...int) string {
+ if p <= 0 {
+ return ""
+ }
+
+ if len(ps) == 0 {
+ return "\x1b[" + strconv.Itoa(p) + "t"
+ }
+
+ params := make([]string, 0, len(ps)+1)
+ params = append(params, strconv.Itoa(p))
+ for _, p := range ps {
+ if p >= 0 {
+ params = append(params, strconv.Itoa(p))
+ }
+ }
+
+ return "\x1b[" + strings.Join(params, ";") + "t"
+}
+
+// XTWINOPS is an alias for [WindowOp].
+func XTWINOPS(p int, ps ...int) string {
+ return WindowOp(p, ps...)
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/wrap.go b/vendor/github.com/charmbracelet/x/ansi/wrap.go
new file mode 100644
index 00000000..6b995800
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/wrap.go
@@ -0,0 +1,467 @@
+package ansi
+
+import (
+ "bytes"
+ "unicode"
+ "unicode/utf8"
+
+ "github.com/charmbracelet/x/ansi/parser"
+ "github.com/mattn/go-runewidth"
+ "github.com/rivo/uniseg"
+)
+
+// nbsp is a non-breaking space
+const nbsp = 0xA0
+
+// Hardwrap wraps a string or a block of text to a given line length, breaking
+// word boundaries. This will preserve ANSI escape codes and will account for
+// wide-characters in the string.
+// When preserveSpace is true, spaces at the beginning of a line will be
+// preserved.
+// This treats the text as a sequence of graphemes.
+func Hardwrap(s string, limit int, preserveSpace bool) string {
+ return hardwrap(GraphemeWidth, s, limit, preserveSpace)
+}
+
+// HardwrapWc wraps a string or a block of text to a given line length, breaking
+// word boundaries. This will preserve ANSI escape codes and will account for
+// wide-characters in the string.
+// When preserveSpace is true, spaces at the beginning of a line will be
+// preserved.
+// This treats the text as a sequence of wide characters and runes.
+func HardwrapWc(s string, limit int, preserveSpace bool) string {
+ return hardwrap(WcWidth, s, limit, preserveSpace)
+}
+
+func hardwrap(m Method, s string, limit int, preserveSpace bool) string {
+ if limit < 1 {
+ return s
+ }
+
+ var (
+ cluster []byte
+ buf bytes.Buffer
+ curWidth int
+ forceNewline bool
+ pstate = parser.GroundState // initial state
+ b = []byte(s)
+ )
+
+ addNewline := func() {
+ buf.WriteByte('\n')
+ curWidth = 0
+ }
+
+ i := 0
+ for i < len(b) {
+ state, action := parser.Table.Transition(pstate, b[i])
+ if state == parser.Utf8State {
+ var width int
+ cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(cluster))
+ }
+ i += len(cluster)
+
+ if curWidth+width > limit {
+ addNewline()
+ }
+ if !preserveSpace && curWidth == 0 && len(cluster) <= 4 {
+ // Skip spaces at the beginning of a line
+ if r, _ := utf8.DecodeRune(cluster); r != utf8.RuneError && unicode.IsSpace(r) {
+ pstate = parser.GroundState
+ continue
+ }
+ }
+
+ buf.Write(cluster)
+ curWidth += width
+ pstate = parser.GroundState
+ continue
+ }
+
+ switch action {
+ case parser.PrintAction, parser.ExecuteAction:
+ if b[i] == '\n' {
+ addNewline()
+ forceNewline = false
+ break
+ }
+
+ if curWidth+1 > limit {
+ addNewline()
+ forceNewline = true
+ }
+
+ // Skip spaces at the beginning of a line
+ if curWidth == 0 {
+ if !preserveSpace && forceNewline && unicode.IsSpace(rune(b[i])) {
+ break
+ }
+ forceNewline = false
+ }
+
+ buf.WriteByte(b[i])
+ if action == parser.PrintAction {
+ curWidth++
+ }
+ default:
+ buf.WriteByte(b[i])
+ }
+
+ // We manage the UTF8 state separately manually above.
+ if pstate != parser.Utf8State {
+ pstate = state
+ }
+ i++
+ }
+
+ return buf.String()
+}
+
+// Wordwrap wraps a string or a block of text to a given line length, not
+// breaking word boundaries. This will preserve ANSI escape codes and will
+// account for wide-characters in the string.
+// The breakpoints string is a list of characters that are considered
+// breakpoints for word wrapping. A hyphen (-) is always considered a
+// breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+//
+// This treats the text as a sequence of graphemes.
+func Wordwrap(s string, limit int, breakpoints string) string {
+ return wordwrap(GraphemeWidth, s, limit, breakpoints)
+}
+
+// WordwrapWc wraps a string or a block of text to a given line length, not
+// breaking word boundaries. This will preserve ANSI escape codes and will
+// account for wide-characters in the string.
+// The breakpoints string is a list of characters that are considered
+// breakpoints for word wrapping. A hyphen (-) is always considered a
+// breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+//
+// This treats the text as a sequence of wide characters and runes.
+func WordwrapWc(s string, limit int, breakpoints string) string {
+ return wordwrap(WcWidth, s, limit, breakpoints)
+}
+
+func wordwrap(m Method, s string, limit int, breakpoints string) string {
+ if limit < 1 {
+ return s
+ }
+
+ var (
+ cluster []byte
+ buf bytes.Buffer
+ word bytes.Buffer
+ space bytes.Buffer
+ curWidth int
+ wordLen int
+ pstate = parser.GroundState // initial state
+ b = []byte(s)
+ )
+
+ addSpace := func() {
+ curWidth += space.Len()
+ buf.Write(space.Bytes())
+ space.Reset()
+ }
+
+ addWord := func() {
+ if word.Len() == 0 {
+ return
+ }
+
+ addSpace()
+ curWidth += wordLen
+ buf.Write(word.Bytes())
+ word.Reset()
+ wordLen = 0
+ }
+
+ addNewline := func() {
+ buf.WriteByte('\n')
+ curWidth = 0
+ space.Reset()
+ }
+
+ i := 0
+ for i < len(b) {
+ state, action := parser.Table.Transition(pstate, b[i])
+ if state == parser.Utf8State {
+ var width int
+ cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(cluster))
+ }
+ i += len(cluster)
+
+ r, _ := utf8.DecodeRune(cluster)
+ if r != utf8.RuneError && unicode.IsSpace(r) && r != nbsp {
+ addWord()
+ space.WriteRune(r)
+ } else if bytes.ContainsAny(cluster, breakpoints) {
+ addSpace()
+ addWord()
+ buf.Write(cluster)
+ curWidth++
+ } else {
+ word.Write(cluster)
+ wordLen += width
+ if curWidth+space.Len()+wordLen > limit &&
+ wordLen < limit {
+ addNewline()
+ }
+ }
+
+ pstate = parser.GroundState
+ continue
+ }
+
+ switch action {
+ case parser.PrintAction, parser.ExecuteAction:
+ r := rune(b[i])
+ switch {
+ case r == '\n':
+ if wordLen == 0 {
+ if curWidth+space.Len() > limit {
+ curWidth = 0
+ } else {
+ buf.Write(space.Bytes())
+ }
+ space.Reset()
+ }
+
+ addWord()
+ addNewline()
+ case unicode.IsSpace(r):
+ addWord()
+ space.WriteByte(b[i])
+ case r == '-':
+ fallthrough
+ case runeContainsAny(r, breakpoints):
+ addSpace()
+ addWord()
+ buf.WriteByte(b[i])
+ curWidth++
+ default:
+ word.WriteByte(b[i])
+ wordLen++
+ if curWidth+space.Len()+wordLen > limit &&
+ wordLen < limit {
+ addNewline()
+ }
+ }
+
+ default:
+ word.WriteByte(b[i])
+ }
+
+ // We manage the UTF8 state separately manually above.
+ if pstate != parser.Utf8State {
+ pstate = state
+ }
+ i++
+ }
+
+ addWord()
+
+ return buf.String()
+}
+
+// Wrap wraps a string or a block of text to a given line length, breaking word
+// boundaries if necessary. This will preserve ANSI escape codes and will
+// account for wide-characters in the string. The breakpoints string is a list
+// of characters that are considered breakpoints for word wrapping. A hyphen
+// (-) is always considered a breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+//
+// This treats the text as a sequence of graphemes.
+func Wrap(s string, limit int, breakpoints string) string {
+ return wrap(GraphemeWidth, s, limit, breakpoints)
+}
+
+// WrapWc wraps a string or a block of text to a given line length, breaking word
+// boundaries if necessary. This will preserve ANSI escape codes and will
+// account for wide-characters in the string. The breakpoints string is a list
+// of characters that are considered breakpoints for word wrapping. A hyphen
+// (-) is always considered a breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+//
+// This treats the text as a sequence of wide characters and runes.
+func WrapWc(s string, limit int, breakpoints string) string {
+ return wrap(WcWidth, s, limit, breakpoints)
+}
+
+func wrap(m Method, s string, limit int, breakpoints string) string {
+ if limit < 1 {
+ return s
+ }
+
+ var (
+ cluster []byte
+ buf bytes.Buffer
+ word bytes.Buffer
+ space bytes.Buffer
+ curWidth int // written width of the line
+ wordLen int // word buffer len without ANSI escape codes
+ pstate = parser.GroundState // initial state
+ b = []byte(s)
+ )
+
+ addSpace := func() {
+ curWidth += space.Len()
+ buf.Write(space.Bytes())
+ space.Reset()
+ }
+
+ addWord := func() {
+ if word.Len() == 0 {
+ return
+ }
+
+ addSpace()
+ curWidth += wordLen
+ buf.Write(word.Bytes())
+ word.Reset()
+ wordLen = 0
+ }
+
+ addNewline := func() {
+ buf.WriteByte('\n')
+ curWidth = 0
+ space.Reset()
+ }
+
+ i := 0
+ for i < len(b) {
+ state, action := parser.Table.Transition(pstate, b[i])
+ if state == parser.Utf8State {
+ var width int
+ cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1)
+ if m == WcWidth {
+ width = runewidth.StringWidth(string(cluster))
+ }
+ i += len(cluster)
+
+ r, _ := utf8.DecodeRune(cluster)
+ switch {
+ case r != utf8.RuneError && unicode.IsSpace(r) && r != nbsp: // nbsp is a non-breaking space
+ addWord()
+ space.WriteRune(r)
+ case bytes.ContainsAny(cluster, breakpoints):
+ addSpace()
+ if curWidth+wordLen+width > limit {
+ word.Write(cluster)
+ wordLen += width
+ } else {
+ addWord()
+ buf.Write(cluster)
+ curWidth += width
+ }
+ default:
+ if wordLen+width > limit {
+ // Hardwrap the word if it's too long
+ addWord()
+ }
+
+ word.Write(cluster)
+ wordLen += width
+
+ if curWidth+wordLen+space.Len() > limit {
+ addNewline()
+ }
+ }
+
+ pstate = parser.GroundState
+ continue
+ }
+
+ switch action {
+ case parser.PrintAction, parser.ExecuteAction:
+ switch r := rune(b[i]); {
+ case r == '\n':
+ if wordLen == 0 {
+ if curWidth+space.Len() > limit {
+ curWidth = 0
+ } else {
+ // preserve whitespaces
+ buf.Write(space.Bytes())
+ }
+ space.Reset()
+ }
+
+ addWord()
+ addNewline()
+ case unicode.IsSpace(r):
+ addWord()
+ space.WriteRune(r)
+ case r == '-':
+ fallthrough
+ case runeContainsAny(r, breakpoints):
+ addSpace()
+ if curWidth+wordLen >= limit {
+ // We can't fit the breakpoint in the current line, treat
+ // it as part of the word.
+ word.WriteRune(r)
+ wordLen++
+ } else {
+ addWord()
+ buf.WriteRune(r)
+ curWidth++
+ }
+ default:
+ if curWidth == limit {
+ addNewline()
+ }
+ word.WriteRune(r)
+ wordLen++
+
+ if wordLen == limit {
+ // Hardwrap the word if it's too long
+ addWord()
+ }
+
+ if curWidth+wordLen+space.Len() > limit {
+ addNewline()
+ }
+ }
+
+ default:
+ word.WriteByte(b[i])
+ }
+
+ // We manage the UTF8 state separately manually above.
+ if pstate != parser.Utf8State {
+ pstate = state
+ }
+ i++
+ }
+
+ if wordLen == 0 {
+ if curWidth+space.Len() > limit {
+ curWidth = 0
+ } else {
+ // preserve whitespaces
+ buf.Write(space.Bytes())
+ }
+ space.Reset()
+ }
+
+ addWord()
+
+ return buf.String()
+}
+
+func runeContainsAny(r rune, s string) bool {
+ for _, c := range s {
+ if c == r {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/charmbracelet/x/ansi/xterm.go b/vendor/github.com/charmbracelet/x/ansi/xterm.go
new file mode 100644
index 00000000..83fd4bdc
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/ansi/xterm.go
@@ -0,0 +1,138 @@
+package ansi
+
+import "strconv"
+
+// KeyModifierOptions (XTMODKEYS) sets/resets xterm key modifier options.
+//
+// Default is 0.
+//
+// CSI > Pp m
+// CSI > Pp ; Pv m
+//
+// If Pv is omitted, the resource is reset to its initial value.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+func KeyModifierOptions(p int, vs ...int) string {
+ var pp, pv string
+ if p > 0 {
+ pp = strconv.Itoa(p)
+ }
+
+ if len(vs) == 0 {
+ return "\x1b[>" + strconv.Itoa(p) + "m"
+ }
+
+ v := vs[0]
+ if v > 0 {
+ pv = strconv.Itoa(v)
+ return "\x1b[>" + pp + ";" + pv + "m"
+ }
+
+ return "\x1b[>" + pp + "m"
+}
+
+// XTMODKEYS is an alias for [KeyModifierOptions].
+func XTMODKEYS(p int, vs ...int) string {
+ return KeyModifierOptions(p, vs...)
+}
+
+// SetKeyModifierOptions sets xterm key modifier options.
+// This is an alias for [KeyModifierOptions].
+func SetKeyModifierOptions(pp int, pv int) string {
+ return KeyModifierOptions(pp, pv)
+}
+
+// ResetKeyModifierOptions resets xterm key modifier options.
+// This is an alias for [KeyModifierOptions].
+func ResetKeyModifierOptions(pp int) string {
+ return KeyModifierOptions(pp)
+}
+
+// QueryKeyModifierOptions (XTQMODKEYS) requests xterm key modifier options.
+//
+// Default is 0.
+//
+// CSI ? Pp m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+func QueryKeyModifierOptions(pp int) string {
+ var p string
+ if pp > 0 {
+ p = strconv.Itoa(pp)
+ }
+ return "\x1b[?" + p + "m"
+}
+
+// XTQMODKEYS is an alias for [QueryKeyModifierOptions].
+func XTQMODKEYS(pp int) string {
+ return QueryKeyModifierOptions(pp)
+}
+
+// Modify Other Keys (modifyOtherKeys) is an xterm feature that allows the
+// terminal to modify the behavior of certain keys to send different escape
+// sequences when pressed.
+//
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+const (
+ SetModifyOtherKeys1 = "\x1b[>4;1m"
+ SetModifyOtherKeys2 = "\x1b[>4;2m"
+ ResetModifyOtherKeys = "\x1b[>4m"
+ QueryModifyOtherKeys = "\x1b[?4m"
+)
+
+// ModifyOtherKeys returns a sequence that sets XTerm modifyOtherKeys mode.
+// The mode argument specifies the mode to set.
+//
+// 0: Disable modifyOtherKeys mode.
+// 1: Enable modifyOtherKeys mode 1.
+// 2: Enable modifyOtherKeys mode 2.
+//
+// CSI > 4 ; mode m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+//
+// Deprecated: use [SetModifyOtherKeys1] or [SetModifyOtherKeys2] instead.
+func ModifyOtherKeys(mode int) string {
+ return "\x1b[>4;" + strconv.Itoa(mode) + "m"
+}
+
+// DisableModifyOtherKeys disables the modifyOtherKeys mode.
+//
+// CSI > 4 ; 0 m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+//
+// Deprecated: use [ResetModifyOtherKeys] instead.
+const DisableModifyOtherKeys = "\x1b[>4;0m"
+
+// EnableModifyOtherKeys1 enables the modifyOtherKeys mode 1.
+//
+// CSI > 4 ; 1 m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+//
+// Deprecated: use [SetModifyOtherKeys1] instead.
+const EnableModifyOtherKeys1 = "\x1b[>4;1m"
+
+// EnableModifyOtherKeys2 enables the modifyOtherKeys mode 2.
+//
+// CSI > 4 ; 2 m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+//
+// Deprecated: use [SetModifyOtherKeys2] instead.
+const EnableModifyOtherKeys2 = "\x1b[>4;2m"
+
+// RequestModifyOtherKeys requests the modifyOtherKeys mode.
+//
+// CSI ? 4 m
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+//
+// Deprecated: use [QueryModifyOtherKeys] instead.
+const RequestModifyOtherKeys = "\x1b[?4m"
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/LICENSE b/vendor/github.com/charmbracelet/x/cellbuf/LICENSE
new file mode 100644
index 00000000..65a5654e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Charmbracelet, Inc.
+
+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.
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/buffer.go b/vendor/github.com/charmbracelet/x/cellbuf/buffer.go
new file mode 100644
index 00000000..790d1f7c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/buffer.go
@@ -0,0 +1,473 @@
+package cellbuf
+
+import (
+ "strings"
+
+ "github.com/mattn/go-runewidth"
+ "github.com/rivo/uniseg"
+)
+
+// NewCell returns a new cell. This is a convenience function that initializes a
+// new cell with the given content. The cell's width is determined by the
+// content using [runewidth.RuneWidth].
+// This will only account for the first combined rune in the content. If the
+// content is empty, it will return an empty cell with a width of 0.
+func NewCell(r rune, comb ...rune) (c *Cell) {
+ c = new(Cell)
+ c.Rune = r
+ c.Width = runewidth.RuneWidth(r)
+ for _, r := range comb {
+ if runewidth.RuneWidth(r) > 0 {
+ break
+ }
+ c.Comb = append(c.Comb, r)
+ }
+ c.Comb = comb
+ c.Width = runewidth.StringWidth(string(append([]rune{r}, comb...)))
+ return
+}
+
+// NewCellString returns a new cell with the given string content. This is a
+// convenience function that initializes a new cell with the given content. The
+// cell's width is determined by the content using [runewidth.StringWidth].
+// This will only use the first combined rune in the string. If the string is
+// empty, it will return an empty cell with a width of 0.
+func NewCellString(s string) (c *Cell) {
+ c = new(Cell)
+ for i, r := range s {
+ if i == 0 {
+ c.Rune = r
+ // We only care about the first rune's width
+ c.Width = runewidth.RuneWidth(r)
+ } else {
+ if runewidth.RuneWidth(r) > 0 {
+ break
+ }
+ c.Comb = append(c.Comb, r)
+ }
+ }
+ return
+}
+
+// NewGraphemeCell returns a new cell. This is a convenience function that
+// initializes a new cell with the given content. The cell's width is determined
+// by the content using [uniseg.FirstGraphemeClusterInString].
+// This is used when the content is a grapheme cluster i.e. a sequence of runes
+// that form a single visual unit.
+// This will only return the first grapheme cluster in the string. If the
+// string is empty, it will return an empty cell with a width of 0.
+func NewGraphemeCell(s string) (c *Cell) {
+ g, _, w, _ := uniseg.FirstGraphemeClusterInString(s, -1)
+ return newGraphemeCell(g, w)
+}
+
+func newGraphemeCell(s string, w int) (c *Cell) {
+ c = new(Cell)
+ c.Width = w
+ for i, r := range s {
+ if i == 0 {
+ c.Rune = r
+ } else {
+ c.Comb = append(c.Comb, r)
+ }
+ }
+ return
+}
+
+// Line represents a line in the terminal.
+// A nil cell represents an blank cell, a cell with a space character and a
+// width of 1.
+// If a cell has no content and a width of 0, it is a placeholder for a wide
+// cell.
+type Line []*Cell
+
+// Width returns the width of the line.
+func (l Line) Width() int {
+ return len(l)
+}
+
+// Len returns the length of the line.
+func (l Line) Len() int {
+ return len(l)
+}
+
+// String returns the string representation of the line. Any trailing spaces
+// are removed.
+func (l Line) String() (s string) {
+ for _, c := range l {
+ if c == nil {
+ s += " "
+ } else if c.Empty() {
+ continue
+ } else {
+ s += c.String()
+ }
+ }
+ s = strings.TrimRight(s, " ")
+ return
+}
+
+// At returns the cell at the given x position.
+// If the cell does not exist, it returns nil.
+func (l Line) At(x int) *Cell {
+ if x < 0 || x >= len(l) {
+ return nil
+ }
+
+ c := l[x]
+ if c == nil {
+ newCell := BlankCell
+ return &newCell
+ }
+
+ return c
+}
+
+// Set sets the cell at the given x position. If a wide cell is given, it will
+// set the cell and the following cells to [EmptyCell]. It returns true if the
+// cell was set.
+func (l Line) Set(x int, c *Cell) bool {
+ return l.set(x, c, true)
+}
+
+func (l Line) set(x int, c *Cell, clone bool) bool {
+ width := l.Width()
+ if x < 0 || x >= width {
+ return false
+ }
+
+ // When a wide cell is partially overwritten, we need
+ // to fill the rest of the cell with space cells to
+ // avoid rendering issues.
+ prev := l.At(x)
+ if prev != nil && prev.Width > 1 {
+ // Writing to the first wide cell
+ for j := 0; j < prev.Width && x+j < l.Width(); j++ {
+ l[x+j] = prev.Clone().Blank()
+ }
+ } else if prev != nil && prev.Width == 0 {
+ // Writing to wide cell placeholders
+ for j := 1; j < maxCellWidth && x-j >= 0; j++ {
+ wide := l.At(x - j)
+ if wide != nil && wide.Width > 1 && j < wide.Width {
+ for k := 0; k < wide.Width; k++ {
+ l[x-j+k] = wide.Clone().Blank()
+ }
+ break
+ }
+ }
+ }
+
+ if clone && c != nil {
+ // Clone the cell if not nil.
+ c = c.Clone()
+ }
+
+ if c != nil && x+c.Width > width {
+ // If the cell is too wide, we write blanks with the same style.
+ for i := 0; i < c.Width && x+i < width; i++ {
+ l[x+i] = c.Clone().Blank()
+ }
+ } else {
+ l[x] = c
+
+ // Mark wide cells with an empty cell zero width
+ // We set the wide cell down below
+ if c != nil && c.Width > 1 {
+ for j := 1; j < c.Width && x+j < l.Width(); j++ {
+ var wide Cell
+ l[x+j] = &wide
+ }
+ }
+ }
+
+ return true
+}
+
+// Buffer is a 2D grid of cells representing a screen or terminal.
+type Buffer struct {
+ // Lines holds the lines of the buffer.
+ Lines []Line
+}
+
+// NewBuffer creates a new buffer with the given width and height.
+// This is a convenience function that initializes a new buffer and resizes it.
+func NewBuffer(width int, height int) *Buffer {
+ b := new(Buffer)
+ b.Resize(width, height)
+ return b
+}
+
+// String returns the string representation of the buffer.
+func (b *Buffer) String() (s string) {
+ for i, l := range b.Lines {
+ s += l.String()
+ if i < len(b.Lines)-1 {
+ s += "\r\n"
+ }
+ }
+ return
+}
+
+// Line returns a pointer to the line at the given y position.
+// If the line does not exist, it returns nil.
+func (b *Buffer) Line(y int) Line {
+ if y < 0 || y >= len(b.Lines) {
+ return nil
+ }
+ return b.Lines[y]
+}
+
+// Cell implements Screen.
+func (b *Buffer) Cell(x int, y int) *Cell {
+ if y < 0 || y >= len(b.Lines) {
+ return nil
+ }
+ return b.Lines[y].At(x)
+}
+
+// maxCellWidth is the maximum width a terminal cell can get.
+const maxCellWidth = 4
+
+// SetCell sets the cell at the given x, y position.
+func (b *Buffer) SetCell(x, y int, c *Cell) bool {
+ return b.setCell(x, y, c, true)
+}
+
+// setCell sets the cell at the given x, y position. This will always clone and
+// allocates a new cell if c is not nil.
+func (b *Buffer) setCell(x, y int, c *Cell, clone bool) bool {
+ if y < 0 || y >= len(b.Lines) {
+ return false
+ }
+ return b.Lines[y].set(x, c, clone)
+}
+
+// Height implements Screen.
+func (b *Buffer) Height() int {
+ return len(b.Lines)
+}
+
+// Width implements Screen.
+func (b *Buffer) Width() int {
+ if len(b.Lines) == 0 {
+ return 0
+ }
+ return b.Lines[0].Width()
+}
+
+// Bounds returns the bounds of the buffer.
+func (b *Buffer) Bounds() Rectangle {
+ return Rect(0, 0, b.Width(), b.Height())
+}
+
+// Resize resizes the buffer to the given width and height.
+func (b *Buffer) Resize(width int, height int) {
+ if width == 0 || height == 0 {
+ b.Lines = nil
+ return
+ }
+
+ if width > b.Width() {
+ line := make(Line, width-b.Width())
+ for i := range b.Lines {
+ b.Lines[i] = append(b.Lines[i], line...)
+ }
+ } else if width < b.Width() {
+ for i := range b.Lines {
+ b.Lines[i] = b.Lines[i][:width]
+ }
+ }
+
+ if height > len(b.Lines) {
+ for i := len(b.Lines); i < height; i++ {
+ b.Lines = append(b.Lines, make(Line, width))
+ }
+ } else if height < len(b.Lines) {
+ b.Lines = b.Lines[:height]
+ }
+}
+
+// FillRect fills the buffer with the given cell and rectangle.
+func (b *Buffer) FillRect(c *Cell, rect Rectangle) {
+ cellWidth := 1
+ if c != nil && c.Width > 1 {
+ cellWidth = c.Width
+ }
+ for y := rect.Min.Y; y < rect.Max.Y; y++ {
+ for x := rect.Min.X; x < rect.Max.X; x += cellWidth {
+ b.setCell(x, y, c, false) //nolint:errcheck
+ }
+ }
+}
+
+// Fill fills the buffer with the given cell and rectangle.
+func (b *Buffer) Fill(c *Cell) {
+ b.FillRect(c, b.Bounds())
+}
+
+// Clear clears the buffer with space cells and rectangle.
+func (b *Buffer) Clear() {
+ b.ClearRect(b.Bounds())
+}
+
+// ClearRect clears the buffer with space cells within the specified
+// rectangles. Only cells within the rectangle's bounds are affected.
+func (b *Buffer) ClearRect(rect Rectangle) {
+ b.FillRect(nil, rect)
+}
+
+// InsertLine inserts n lines at the given line position, with the given
+// optional cell, within the specified rectangles. If no rectangles are
+// specified, it inserts lines in the entire buffer. Only cells within the
+// rectangle's horizontal bounds are affected. Lines are pushed out of the
+// rectangle bounds and lost. This follows terminal [ansi.IL] behavior.
+// It returns the pushed out lines.
+func (b *Buffer) InsertLine(y, n int, c *Cell) {
+ b.InsertLineRect(y, n, c, b.Bounds())
+}
+
+// InsertLineRect inserts new lines at the given line position, with the
+// given optional cell, within the rectangle bounds. Only cells within the
+// rectangle's horizontal bounds are affected. Lines are pushed out of the
+// rectangle bounds and lost. This follows terminal [ansi.IL] behavior.
+func (b *Buffer) InsertLineRect(y, n int, c *Cell, rect Rectangle) {
+ if n <= 0 || y < rect.Min.Y || y >= rect.Max.Y || y >= b.Height() {
+ return
+ }
+
+ // Limit number of lines to insert to available space
+ if y+n > rect.Max.Y {
+ n = rect.Max.Y - y
+ }
+
+ // Move existing lines down within the bounds
+ for i := rect.Max.Y - 1; i >= y+n; i-- {
+ for x := rect.Min.X; x < rect.Max.X; x++ {
+ // We don't need to clone c here because we're just moving lines down.
+ b.setCell(x, i, b.Lines[i-n][x], false)
+ }
+ }
+
+ // Clear the newly inserted lines within bounds
+ for i := y; i < y+n; i++ {
+ for x := rect.Min.X; x < rect.Max.X; x++ {
+ b.setCell(x, i, c, true)
+ }
+ }
+}
+
+// DeleteLineRect deletes lines at the given line position, with the given
+// optional cell, within the rectangle bounds. Only cells within the
+// rectangle's bounds are affected. Lines are shifted up within the bounds and
+// new blank lines are created at the bottom. This follows terminal [ansi.DL]
+// behavior.
+func (b *Buffer) DeleteLineRect(y, n int, c *Cell, rect Rectangle) {
+ if n <= 0 || y < rect.Min.Y || y >= rect.Max.Y || y >= b.Height() {
+ return
+ }
+
+ // Limit deletion count to available space in scroll region
+ if n > rect.Max.Y-y {
+ n = rect.Max.Y - y
+ }
+
+ // Shift cells up within the bounds
+ for dst := y; dst < rect.Max.Y-n; dst++ {
+ src := dst + n
+ for x := rect.Min.X; x < rect.Max.X; x++ {
+ // We don't need to clone c here because we're just moving cells up.
+ // b.lines[dst][x] = b.lines[src][x]
+ b.setCell(x, dst, b.Lines[src][x], false)
+ }
+ }
+
+ // Fill the bottom n lines with blank cells
+ for i := rect.Max.Y - n; i < rect.Max.Y; i++ {
+ for x := rect.Min.X; x < rect.Max.X; x++ {
+ b.setCell(x, i, c, true)
+ }
+ }
+}
+
+// DeleteLine deletes n lines at the given line position, with the given
+// optional cell, within the specified rectangles. If no rectangles are
+// specified, it deletes lines in the entire buffer.
+func (b *Buffer) DeleteLine(y, n int, c *Cell) {
+ b.DeleteLineRect(y, n, c, b.Bounds())
+}
+
+// InsertCell inserts new cells at the given position, with the given optional
+// cell, within the specified rectangles. If no rectangles are specified, it
+// inserts cells in the entire buffer. This follows terminal [ansi.ICH]
+// behavior.
+func (b *Buffer) InsertCell(x, y, n int, c *Cell) {
+ b.InsertCellRect(x, y, n, c, b.Bounds())
+}
+
+// InsertCellRect inserts new cells at the given position, with the given
+// optional cell, within the rectangle bounds. Only cells within the
+// rectangle's bounds are affected, following terminal [ansi.ICH] behavior.
+func (b *Buffer) InsertCellRect(x, y, n int, c *Cell, rect Rectangle) {
+ if n <= 0 || y < rect.Min.Y || y >= rect.Max.Y || y >= b.Height() ||
+ x < rect.Min.X || x >= rect.Max.X || x >= b.Width() {
+ return
+ }
+
+ // Limit number of cells to insert to available space
+ if x+n > rect.Max.X {
+ n = rect.Max.X - x
+ }
+
+ // Move existing cells within rectangle bounds to the right
+ for i := rect.Max.X - 1; i >= x+n && i-n >= rect.Min.X; i-- {
+ // We don't need to clone c here because we're just moving cells to the
+ // right.
+ // b.lines[y][i] = b.lines[y][i-n]
+ b.setCell(i, y, b.Lines[y][i-n], false)
+ }
+
+ // Clear the newly inserted cells within rectangle bounds
+ for i := x; i < x+n && i < rect.Max.X; i++ {
+ b.setCell(i, y, c, true)
+ }
+}
+
+// DeleteCell deletes cells at the given position, with the given optional
+// cell, within the specified rectangles. If no rectangles are specified, it
+// deletes cells in the entire buffer. This follows terminal [ansi.DCH]
+// behavior.
+func (b *Buffer) DeleteCell(x, y, n int, c *Cell) {
+ b.DeleteCellRect(x, y, n, c, b.Bounds())
+}
+
+// DeleteCellRect deletes cells at the given position, with the given
+// optional cell, within the rectangle bounds. Only cells within the
+// rectangle's bounds are affected, following terminal [ansi.DCH] behavior.
+func (b *Buffer) DeleteCellRect(x, y, n int, c *Cell, rect Rectangle) {
+ if n <= 0 || y < rect.Min.Y || y >= rect.Max.Y || y >= b.Height() ||
+ x < rect.Min.X || x >= rect.Max.X || x >= b.Width() {
+ return
+ }
+
+ // Calculate how many positions we can actually delete
+ remainingCells := rect.Max.X - x
+ if n > remainingCells {
+ n = remainingCells
+ }
+
+ // Shift the remaining cells to the left
+ for i := x; i < rect.Max.X-n; i++ {
+ if i+n < rect.Max.X {
+ // We don't need to clone c here because we're just moving cells to
+ // the left.
+ // b.lines[y][i] = b.lines[y][i+n]
+ b.setCell(i, y, b.Lines[y][i+n], false)
+ }
+ }
+
+ // Fill the vacated positions with the given cell
+ for i := rect.Max.X - n; i < rect.Max.X; i++ {
+ b.setCell(i, y, c, true)
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/cell.go b/vendor/github.com/charmbracelet/x/cellbuf/cell.go
new file mode 100644
index 00000000..991c919e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/cell.go
@@ -0,0 +1,503 @@
+package cellbuf
+
+import (
+ "github.com/charmbracelet/x/ansi"
+)
+
+var (
+ // BlankCell is a cell with a single space, width of 1, and no style or link.
+ BlankCell = Cell{Rune: ' ', Width: 1}
+
+ // EmptyCell is just an empty cell used for comparisons and as a placeholder
+ // for wide cells.
+ EmptyCell = Cell{}
+)
+
+// Cell represents a single cell in the terminal screen.
+type Cell struct {
+ // The style of the cell. Nil style means no style. Zero value prints a
+ // reset sequence.
+ Style Style
+
+ // Link is the hyperlink of the cell.
+ Link Link
+
+ // Comb is the combining runes of the cell. This is nil if the cell is a
+ // single rune or if it's a zero width cell that is part of a wider cell.
+ Comb []rune
+
+ // Width is the mono-space width of the grapheme cluster.
+ Width int
+
+ // Rune is the main rune of the cell. This is zero if the cell is part of a
+ // wider cell.
+ Rune rune
+}
+
+// Append appends runes to the cell without changing the width. This is useful
+// when we want to use the cell to store escape sequences or other runes that
+// don't affect the width of the cell.
+func (c *Cell) Append(r ...rune) {
+ for i, r := range r {
+ if i == 0 && c.Rune == 0 {
+ c.Rune = r
+ continue
+ }
+ c.Comb = append(c.Comb, r)
+ }
+}
+
+// String returns the string content of the cell excluding any styles, links,
+// and escape sequences.
+func (c Cell) String() string {
+ if c.Rune == 0 {
+ return ""
+ }
+ if len(c.Comb) == 0 {
+ return string(c.Rune)
+ }
+ return string(append([]rune{c.Rune}, c.Comb...))
+}
+
+// Equal returns whether the cell is equal to the other cell.
+func (c *Cell) Equal(o *Cell) bool {
+ return o != nil &&
+ c.Width == o.Width &&
+ c.Rune == o.Rune &&
+ runesEqual(c.Comb, o.Comb) &&
+ c.Style.Equal(&o.Style) &&
+ c.Link.Equal(&o.Link)
+}
+
+// Empty returns whether the cell is an empty cell. An empty cell is a cell
+// with a width of 0, a rune of 0, and no combining runes.
+func (c Cell) Empty() bool {
+ return c.Width == 0 &&
+ c.Rune == 0 &&
+ len(c.Comb) == 0
+}
+
+// Reset resets the cell to the default state zero value.
+func (c *Cell) Reset() {
+ c.Rune = 0
+ c.Comb = nil
+ c.Width = 0
+ c.Style.Reset()
+ c.Link.Reset()
+}
+
+// Clear returns whether the cell consists of only attributes that don't
+// affect appearance of a space character.
+func (c *Cell) Clear() bool {
+ return c.Rune == ' ' && len(c.Comb) == 0 && c.Width == 1 && c.Style.Clear() && c.Link.Empty()
+}
+
+// Clone returns a copy of the cell.
+func (c *Cell) Clone() (n *Cell) {
+ n = new(Cell)
+ *n = *c
+ return
+}
+
+// Blank makes the cell a blank cell by setting the rune to a space, comb to
+// nil, and the width to 1.
+func (c *Cell) Blank() *Cell {
+ c.Rune = ' '
+ c.Comb = nil
+ c.Width = 1
+ return c
+}
+
+// Link represents a hyperlink in the terminal screen.
+type Link struct {
+ URL string
+ Params string
+}
+
+// String returns a string representation of the hyperlink.
+func (h Link) String() string {
+ return h.URL
+}
+
+// Reset resets the hyperlink to the default state zero value.
+func (h *Link) Reset() {
+ h.URL = ""
+ h.Params = ""
+}
+
+// Equal returns whether the hyperlink is equal to the other hyperlink.
+func (h *Link) Equal(o *Link) bool {
+ return o != nil && h.URL == o.URL && h.Params == o.Params
+}
+
+// Empty returns whether the hyperlink is empty.
+func (h Link) Empty() bool {
+ return h.URL == "" && h.Params == ""
+}
+
+// AttrMask is a bitmask for text attributes that can change the look of text.
+// These attributes can be combined to create different styles.
+type AttrMask uint8
+
+// These are the available text attributes that can be combined to create
+// different styles.
+const (
+ BoldAttr AttrMask = 1 << iota
+ FaintAttr
+ ItalicAttr
+ SlowBlinkAttr
+ RapidBlinkAttr
+ ReverseAttr
+ ConcealAttr
+ StrikethroughAttr
+
+ ResetAttr AttrMask = 0
+)
+
+// UnderlineStyle is the style of underline to use for text.
+type UnderlineStyle = ansi.UnderlineStyle
+
+// These are the available underline styles.
+const (
+ NoUnderline = ansi.NoUnderlineStyle
+ SingleUnderline = ansi.SingleUnderlineStyle
+ DoubleUnderline = ansi.DoubleUnderlineStyle
+ CurlyUnderline = ansi.CurlyUnderlineStyle
+ DottedUnderline = ansi.DottedUnderlineStyle
+ DashedUnderline = ansi.DashedUnderlineStyle
+)
+
+// Style represents the Style of a cell.
+type Style struct {
+ Fg ansi.Color
+ Bg ansi.Color
+ Ul ansi.Color
+ Attrs AttrMask
+ UlStyle UnderlineStyle
+}
+
+// Sequence returns the ANSI sequence that sets the style.
+func (s Style) Sequence() string {
+ if s.Empty() {
+ return ansi.ResetStyle
+ }
+
+ var b ansi.Style
+
+ if s.Attrs != 0 {
+ if s.Attrs&BoldAttr != 0 {
+ b = b.Bold()
+ }
+ if s.Attrs&FaintAttr != 0 {
+ b = b.Faint()
+ }
+ if s.Attrs&ItalicAttr != 0 {
+ b = b.Italic()
+ }
+ if s.Attrs&SlowBlinkAttr != 0 {
+ b = b.SlowBlink()
+ }
+ if s.Attrs&RapidBlinkAttr != 0 {
+ b = b.RapidBlink()
+ }
+ if s.Attrs&ReverseAttr != 0 {
+ b = b.Reverse()
+ }
+ if s.Attrs&ConcealAttr != 0 {
+ b = b.Conceal()
+ }
+ if s.Attrs&StrikethroughAttr != 0 {
+ b = b.Strikethrough()
+ }
+ }
+ if s.UlStyle != NoUnderline {
+ switch s.UlStyle {
+ case SingleUnderline:
+ b = b.Underline()
+ case DoubleUnderline:
+ b = b.DoubleUnderline()
+ case CurlyUnderline:
+ b = b.CurlyUnderline()
+ case DottedUnderline:
+ b = b.DottedUnderline()
+ case DashedUnderline:
+ b = b.DashedUnderline()
+ }
+ }
+ if s.Fg != nil {
+ b = b.ForegroundColor(s.Fg)
+ }
+ if s.Bg != nil {
+ b = b.BackgroundColor(s.Bg)
+ }
+ if s.Ul != nil {
+ b = b.UnderlineColor(s.Ul)
+ }
+
+ return b.String()
+}
+
+// DiffSequence returns the ANSI sequence that sets the style as a diff from
+// another style.
+func (s Style) DiffSequence(o Style) string {
+ if o.Empty() {
+ return s.Sequence()
+ }
+
+ var b ansi.Style
+
+ if !colorEqual(s.Fg, o.Fg) {
+ b = b.ForegroundColor(s.Fg)
+ }
+
+ if !colorEqual(s.Bg, o.Bg) {
+ b = b.BackgroundColor(s.Bg)
+ }
+
+ if !colorEqual(s.Ul, o.Ul) {
+ b = b.UnderlineColor(s.Ul)
+ }
+
+ var (
+ noBlink bool
+ isNormal bool
+ )
+
+ if s.Attrs != o.Attrs {
+ if s.Attrs&BoldAttr != o.Attrs&BoldAttr {
+ if s.Attrs&BoldAttr != 0 {
+ b = b.Bold()
+ } else if !isNormal {
+ isNormal = true
+ b = b.NormalIntensity()
+ }
+ }
+ if s.Attrs&FaintAttr != o.Attrs&FaintAttr {
+ if s.Attrs&FaintAttr != 0 {
+ b = b.Faint()
+ } else if !isNormal {
+ b = b.NormalIntensity()
+ }
+ }
+ if s.Attrs&ItalicAttr != o.Attrs&ItalicAttr {
+ if s.Attrs&ItalicAttr != 0 {
+ b = b.Italic()
+ } else {
+ b = b.NoItalic()
+ }
+ }
+ if s.Attrs&SlowBlinkAttr != o.Attrs&SlowBlinkAttr {
+ if s.Attrs&SlowBlinkAttr != 0 {
+ b = b.SlowBlink()
+ } else if !noBlink {
+ noBlink = true
+ b = b.NoBlink()
+ }
+ }
+ if s.Attrs&RapidBlinkAttr != o.Attrs&RapidBlinkAttr {
+ if s.Attrs&RapidBlinkAttr != 0 {
+ b = b.RapidBlink()
+ } else if !noBlink {
+ b = b.NoBlink()
+ }
+ }
+ if s.Attrs&ReverseAttr != o.Attrs&ReverseAttr {
+ if s.Attrs&ReverseAttr != 0 {
+ b = b.Reverse()
+ } else {
+ b = b.NoReverse()
+ }
+ }
+ if s.Attrs&ConcealAttr != o.Attrs&ConcealAttr {
+ if s.Attrs&ConcealAttr != 0 {
+ b = b.Conceal()
+ } else {
+ b = b.NoConceal()
+ }
+ }
+ if s.Attrs&StrikethroughAttr != o.Attrs&StrikethroughAttr {
+ if s.Attrs&StrikethroughAttr != 0 {
+ b = b.Strikethrough()
+ } else {
+ b = b.NoStrikethrough()
+ }
+ }
+ }
+
+ if s.UlStyle != o.UlStyle {
+ b = b.UnderlineStyle(s.UlStyle)
+ }
+
+ return b.String()
+}
+
+// Equal returns true if the style is equal to the other style.
+func (s *Style) Equal(o *Style) bool {
+ return s.Attrs == o.Attrs &&
+ s.UlStyle == o.UlStyle &&
+ colorEqual(s.Fg, o.Fg) &&
+ colorEqual(s.Bg, o.Bg) &&
+ colorEqual(s.Ul, o.Ul)
+}
+
+func colorEqual(c, o ansi.Color) bool {
+ if c == nil && o == nil {
+ return true
+ }
+ if c == nil || o == nil {
+ return false
+ }
+ cr, cg, cb, ca := c.RGBA()
+ or, og, ob, oa := o.RGBA()
+ return cr == or && cg == og && cb == ob && ca == oa
+}
+
+// Bold sets the bold attribute.
+func (s *Style) Bold(v bool) *Style {
+ if v {
+ s.Attrs |= BoldAttr
+ } else {
+ s.Attrs &^= BoldAttr
+ }
+ return s
+}
+
+// Faint sets the faint attribute.
+func (s *Style) Faint(v bool) *Style {
+ if v {
+ s.Attrs |= FaintAttr
+ } else {
+ s.Attrs &^= FaintAttr
+ }
+ return s
+}
+
+// Italic sets the italic attribute.
+func (s *Style) Italic(v bool) *Style {
+ if v {
+ s.Attrs |= ItalicAttr
+ } else {
+ s.Attrs &^= ItalicAttr
+ }
+ return s
+}
+
+// SlowBlink sets the slow blink attribute.
+func (s *Style) SlowBlink(v bool) *Style {
+ if v {
+ s.Attrs |= SlowBlinkAttr
+ } else {
+ s.Attrs &^= SlowBlinkAttr
+ }
+ return s
+}
+
+// RapidBlink sets the rapid blink attribute.
+func (s *Style) RapidBlink(v bool) *Style {
+ if v {
+ s.Attrs |= RapidBlinkAttr
+ } else {
+ s.Attrs &^= RapidBlinkAttr
+ }
+ return s
+}
+
+// Reverse sets the reverse attribute.
+func (s *Style) Reverse(v bool) *Style {
+ if v {
+ s.Attrs |= ReverseAttr
+ } else {
+ s.Attrs &^= ReverseAttr
+ }
+ return s
+}
+
+// Conceal sets the conceal attribute.
+func (s *Style) Conceal(v bool) *Style {
+ if v {
+ s.Attrs |= ConcealAttr
+ } else {
+ s.Attrs &^= ConcealAttr
+ }
+ return s
+}
+
+// Strikethrough sets the strikethrough attribute.
+func (s *Style) Strikethrough(v bool) *Style {
+ if v {
+ s.Attrs |= StrikethroughAttr
+ } else {
+ s.Attrs &^= StrikethroughAttr
+ }
+ return s
+}
+
+// UnderlineStyle sets the underline style.
+func (s *Style) UnderlineStyle(style UnderlineStyle) *Style {
+ s.UlStyle = style
+ return s
+}
+
+// Underline sets the underline attribute.
+// This is a syntactic sugar for [UnderlineStyle].
+func (s *Style) Underline(v bool) *Style {
+ if v {
+ return s.UnderlineStyle(SingleUnderline)
+ }
+ return s.UnderlineStyle(NoUnderline)
+}
+
+// Foreground sets the foreground color.
+func (s *Style) Foreground(c ansi.Color) *Style {
+ s.Fg = c
+ return s
+}
+
+// Background sets the background color.
+func (s *Style) Background(c ansi.Color) *Style {
+ s.Bg = c
+ return s
+}
+
+// UnderlineColor sets the underline color.
+func (s *Style) UnderlineColor(c ansi.Color) *Style {
+ s.Ul = c
+ return s
+}
+
+// Reset resets the style to default.
+func (s *Style) Reset() *Style {
+ s.Fg = nil
+ s.Bg = nil
+ s.Ul = nil
+ s.Attrs = ResetAttr
+ s.UlStyle = NoUnderline
+ return s
+}
+
+// Empty returns true if the style is empty.
+func (s *Style) Empty() bool {
+ return s.Fg == nil && s.Bg == nil && s.Ul == nil && s.Attrs == ResetAttr && s.UlStyle == NoUnderline
+}
+
+// Clear returns whether the style consists of only attributes that don't
+// affect appearance of a space character.
+func (s *Style) Clear() bool {
+ return s.UlStyle == NoUnderline &&
+ s.Attrs&^(BoldAttr|FaintAttr|ItalicAttr|SlowBlinkAttr|RapidBlinkAttr) == 0 &&
+ s.Fg == nil &&
+ s.Bg == nil &&
+ s.Ul == nil
+}
+
+func runesEqual(a, b []rune) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for i, r := range a {
+ if r != b[i] {
+ return false
+ }
+ }
+ return true
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/errors.go b/vendor/github.com/charmbracelet/x/cellbuf/errors.go
new file mode 100644
index 00000000..64258fe3
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/errors.go
@@ -0,0 +1,6 @@
+package cellbuf
+
+import "errors"
+
+// ErrOutOfBounds is returned when the given x, y position is out of bounds.
+var ErrOutOfBounds = errors.New("out of bounds")
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/geom.go b/vendor/github.com/charmbracelet/x/cellbuf/geom.go
new file mode 100644
index 00000000..c12e6fb1
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/geom.go
@@ -0,0 +1,21 @@
+package cellbuf
+
+import (
+ "image"
+)
+
+// Position represents an x, y position.
+type Position = image.Point
+
+// Pos is a shorthand for Position{X: x, Y: y}.
+func Pos(x, y int) Position {
+ return image.Pt(x, y)
+}
+
+// Rectange represents a rectangle.
+type Rectangle = image.Rectangle
+
+// Rect is a shorthand for Rectangle.
+func Rect(x, y, w, h int) Rectangle {
+ return image.Rect(x, y, x+w, y+h)
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/hardscroll.go b/vendor/github.com/charmbracelet/x/cellbuf/hardscroll.go
new file mode 100644
index 00000000..402ac06a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/hardscroll.go
@@ -0,0 +1,272 @@
+package cellbuf
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// scrollOptimize optimizes the screen to transform the old buffer into the new
+// buffer.
+func (s *Screen) scrollOptimize() {
+ height := s.newbuf.Height()
+ if s.oldnum == nil || len(s.oldnum) < height {
+ s.oldnum = make([]int, height)
+ }
+
+ // Calculate the indices
+ s.updateHashmap()
+ if len(s.hashtab) < height {
+ return
+ }
+
+ // Pass 1 - from top to bottom scrolling up
+ for i := 0; i < height; {
+ for i < height && (s.oldnum[i] == newIndex || s.oldnum[i] <= i) {
+ i++
+ }
+ if i >= height {
+ break
+ }
+
+ shift := s.oldnum[i] - i // shift > 0
+ start := i
+
+ i++
+ for i < height && s.oldnum[i] != newIndex && s.oldnum[i]-i == shift {
+ i++
+ }
+ end := i - 1 + shift
+
+ if !s.scrolln(shift, start, end, height-1) {
+ continue
+ }
+ }
+
+ // Pass 2 - from bottom to top scrolling down
+ for i := height - 1; i >= 0; {
+ for i >= 0 && (s.oldnum[i] == newIndex || s.oldnum[i] >= i) {
+ i--
+ }
+ if i < 0 {
+ break
+ }
+
+ shift := s.oldnum[i] - i // shift < 0
+ end := i
+
+ i--
+ for i >= 0 && s.oldnum[i] != newIndex && s.oldnum[i]-i == shift {
+ i--
+ }
+
+ start := i + 1 - (-shift)
+ if !s.scrolln(shift, start, end, height-1) {
+ continue
+ }
+ }
+}
+
+// scrolln scrolls the screen up by n lines.
+func (s *Screen) scrolln(n, top, bot, maxY int) (v bool) { //nolint:unparam
+ const (
+ nonDestScrollRegion = false
+ memoryBelow = false
+ )
+
+ blank := s.clearBlank()
+ if n > 0 {
+ // Scroll up (forward)
+ v = s.scrollUp(n, top, bot, 0, maxY, blank)
+ if !v {
+ s.buf.WriteString(ansi.SetTopBottomMargins(top+1, bot+1))
+
+ // XXX: How should we handle this in inline mode when not using alternate screen?
+ s.cur.X, s.cur.Y = -1, -1
+ v = s.scrollUp(n, top, bot, top, bot, blank)
+ s.buf.WriteString(ansi.SetTopBottomMargins(1, maxY+1))
+ s.cur.X, s.cur.Y = -1, -1
+ }
+
+ if !v {
+ v = s.scrollIdl(n, top, bot-n+1, blank)
+ }
+
+ // Clear newly shifted-in lines.
+ if v &&
+ (nonDestScrollRegion || (memoryBelow && bot == maxY)) {
+ if bot == maxY {
+ s.move(0, bot-n+1)
+ s.clearToBottom(nil)
+ } else {
+ for i := 0; i < n; i++ {
+ s.move(0, bot-i)
+ s.clearToEnd(nil, false)
+ }
+ }
+ }
+ } else if n < 0 {
+ // Scroll down (backward)
+ v = s.scrollDown(-n, top, bot, 0, maxY, blank)
+ if !v {
+ s.buf.WriteString(ansi.SetTopBottomMargins(top+1, bot+1))
+
+ // XXX: How should we handle this in inline mode when not using alternate screen?
+ s.cur.X, s.cur.Y = -1, -1
+ v = s.scrollDown(-n, top, bot, top, bot, blank)
+ s.buf.WriteString(ansi.SetTopBottomMargins(1, maxY+1))
+ s.cur.X, s.cur.Y = -1, -1
+
+ if !v {
+ v = s.scrollIdl(-n, bot+n+1, top, blank)
+ }
+
+ // Clear newly shifted-in lines.
+ if v &&
+ (nonDestScrollRegion || (memoryBelow && top == 0)) {
+ for i := 0; i < -n; i++ {
+ s.move(0, top+i)
+ s.clearToEnd(nil, false)
+ }
+ }
+ }
+ }
+
+ if !v {
+ return
+ }
+
+ s.scrollBuffer(s.curbuf, n, top, bot, blank)
+
+ // shift hash values too, they can be reused
+ s.scrollOldhash(n, top, bot)
+
+ return true
+}
+
+// scrollBuffer scrolls the buffer by n lines.
+func (s *Screen) scrollBuffer(b *Buffer, n, top, bot int, blank *Cell) {
+ if top < 0 || bot < top || bot >= b.Height() {
+ // Nothing to scroll
+ return
+ }
+
+ if n < 0 {
+ // shift n lines downwards
+ limit := top - n
+ for line := bot; line >= limit && line >= 0 && line >= top; line-- {
+ copy(b.Lines[line], b.Lines[line+n])
+ }
+ for line := top; line < limit && line <= b.Height()-1 && line <= bot; line++ {
+ b.FillRect(blank, Rect(0, line, b.Width(), 1))
+ }
+ }
+
+ if n > 0 {
+ // shift n lines upwards
+ limit := bot - n
+ for line := top; line <= limit && line <= b.Height()-1 && line <= bot; line++ {
+ copy(b.Lines[line], b.Lines[line+n])
+ }
+ for line := bot; line > limit && line >= 0 && line >= top; line-- {
+ b.FillRect(blank, Rect(0, line, b.Width(), 1))
+ }
+ }
+
+ s.touchLine(b.Width(), b.Height(), top, bot-top+1, true)
+}
+
+// touchLine marks the line as touched.
+func (s *Screen) touchLine(width, height, y, n int, changed bool) {
+ if n < 0 || y < 0 || y >= height {
+ return // Nothing to touch
+ }
+
+ for i := y; i < y+n && i < height; i++ {
+ if changed {
+ s.touch[i] = lineData{firstCell: 0, lastCell: width - 1}
+ } else {
+ delete(s.touch, i)
+ }
+ }
+}
+
+// scrollUp scrolls the screen up by n lines.
+func (s *Screen) scrollUp(n, top, bot, minY, maxY int, blank *Cell) bool {
+ if n == 1 && top == minY && bot == maxY {
+ s.move(0, bot)
+ s.updatePen(blank)
+ s.buf.WriteByte('\n')
+ } else if n == 1 && bot == maxY {
+ s.move(0, top)
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.DeleteLine(1))
+ } else if top == minY && bot == maxY {
+ if s.xtermLike {
+ s.move(0, bot)
+ } else {
+ s.move(0, top)
+ }
+ s.updatePen(blank)
+ if s.xtermLike {
+ s.buf.WriteString(ansi.ScrollUp(n))
+ } else {
+ s.buf.WriteString(strings.Repeat("\n", n))
+ }
+ } else if bot == maxY {
+ s.move(0, top)
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.DeleteLine(n))
+ } else {
+ return false
+ }
+ return true
+}
+
+// scrollDown scrolls the screen down by n lines.
+func (s *Screen) scrollDown(n, top, bot, minY, maxY int, blank *Cell) bool {
+ if n == 1 && top == minY && bot == maxY {
+ s.move(0, top)
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.ReverseIndex)
+ } else if n == 1 && bot == maxY {
+ s.move(0, top)
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.InsertLine(1))
+ } else if top == minY && bot == maxY {
+ s.move(0, top)
+ s.updatePen(blank)
+ if s.xtermLike {
+ s.buf.WriteString(ansi.ScrollDown(n))
+ } else {
+ s.buf.WriteString(strings.Repeat(ansi.ReverseIndex, n))
+ }
+ } else if bot == maxY {
+ s.move(0, top)
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.InsertLine(n))
+ } else {
+ return false
+ }
+ return true
+}
+
+// scrollIdl scrolls the screen n lines by using [ansi.DL] at del and using
+// [ansi.IL] at ins.
+func (s *Screen) scrollIdl(n, del, ins int, blank *Cell) bool {
+ if n < 0 {
+ return false
+ }
+
+ // Delete lines
+ s.move(0, del)
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.DeleteLine(n))
+
+ // Insert lines
+ s.move(0, ins)
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.InsertLine(n))
+
+ return true
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/hashmap.go b/vendor/github.com/charmbracelet/x/cellbuf/hashmap.go
new file mode 100644
index 00000000..0d25b549
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/hashmap.go
@@ -0,0 +1,301 @@
+package cellbuf
+
+import (
+ "github.com/charmbracelet/x/ansi"
+)
+
+// hash returns the hash value of a [Line].
+func hash(l Line) (h uint64) {
+ for _, c := range l {
+ var r rune
+ if c == nil {
+ r = ansi.SP
+ } else {
+ r = c.Rune
+ }
+ h += (h << 5) + uint64(r)
+ }
+ return
+}
+
+// hashmap represents a single [Line] hash.
+type hashmap struct {
+ value uint64
+ oldcount, newcount int
+ oldindex, newindex int
+}
+
+// The value used to indicate lines created by insertions and scrolls.
+const newIndex = -1
+
+// updateHashmap updates the hashmap with the new hash value.
+func (s *Screen) updateHashmap() {
+ height := s.newbuf.Height()
+ if len(s.oldhash) >= height && len(s.newhash) >= height {
+ // rehash changed lines
+ for i := 0; i < height; i++ {
+ _, ok := s.touch[i]
+ if ok {
+ s.oldhash[i] = hash(s.curbuf.Line(i))
+ s.newhash[i] = hash(s.newbuf.Line(i))
+ }
+ }
+ } else {
+ // rehash all
+ if len(s.oldhash) != height {
+ s.oldhash = make([]uint64, height)
+ }
+ if len(s.newhash) != height {
+ s.newhash = make([]uint64, height)
+ }
+ for i := 0; i < height; i++ {
+ s.oldhash[i] = hash(s.curbuf.Line(i))
+ s.newhash[i] = hash(s.newbuf.Line(i))
+ }
+ }
+
+ s.hashtab = make([]hashmap, height*2)
+ for i := 0; i < height; i++ {
+ hashval := s.oldhash[i]
+
+ // Find matching hash or empty slot
+ idx := 0
+ for idx < len(s.hashtab) && s.hashtab[idx].value != 0 {
+ if s.hashtab[idx].value == hashval {
+ break
+ }
+ idx++
+ }
+
+ s.hashtab[idx].value = hashval // in case this is a new hash
+ s.hashtab[idx].oldcount++
+ s.hashtab[idx].oldindex = i
+ }
+ for i := 0; i < height; i++ {
+ hashval := s.newhash[i]
+
+ // Find matching hash or empty slot
+ idx := 0
+ for idx < len(s.hashtab) && s.hashtab[idx].value != 0 {
+ if s.hashtab[idx].value == hashval {
+ break
+ }
+ idx++
+ }
+
+ s.hashtab[idx].value = hashval // in case this is a new hash
+ s.hashtab[idx].newcount++
+ s.hashtab[idx].newindex = i
+
+ s.oldnum[i] = newIndex // init old indices slice
+ }
+
+ // Mark line pair corresponding to unique hash pairs.
+ for i := 0; i < len(s.hashtab) && s.hashtab[i].value != 0; i++ {
+ hsp := &s.hashtab[i]
+ if hsp.oldcount == 1 && hsp.newcount == 1 && hsp.oldindex != hsp.newindex {
+ s.oldnum[hsp.newindex] = hsp.oldindex
+ }
+ }
+
+ s.growHunks()
+
+ // Eliminate bad or impossible shifts. This includes removing those hunks
+ // which could not grow because of conflicts, as well those which are to be
+ // moved too far, they are likely to destroy more than carry.
+ for i := 0; i < height; {
+ var start, shift, size int
+ for i < height && s.oldnum[i] == newIndex {
+ i++
+ }
+ if i >= height {
+ break
+ }
+ start = i
+ shift = s.oldnum[i] - i
+ i++
+ for i < height && s.oldnum[i] != newIndex && s.oldnum[i]-i == shift {
+ i++
+ }
+ size = i - start
+ if size < 3 || size+min(size/8, 2) < abs(shift) {
+ for start < i {
+ s.oldnum[start] = newIndex
+ start++
+ }
+ }
+ }
+
+ // After clearing invalid hunks, try grow the rest.
+ s.growHunks()
+}
+
+// scrollOldhash
+func (s *Screen) scrollOldhash(n, top, bot int) {
+ if len(s.oldhash) == 0 {
+ return
+ }
+
+ size := bot - top + 1 - abs(n)
+ if n > 0 {
+ // Move existing hashes up
+ copy(s.oldhash[top:], s.oldhash[top+n:top+n+size])
+ // Recalculate hashes for newly shifted-in lines
+ for i := bot; i > bot-n; i-- {
+ s.oldhash[i] = hash(s.curbuf.Line(i))
+ }
+ } else {
+ // Move existing hashes down
+ copy(s.oldhash[top-n:], s.oldhash[top:top+size])
+ // Recalculate hashes for newly shifted-in lines
+ for i := top; i < top-n; i++ {
+ s.oldhash[i] = hash(s.curbuf.Line(i))
+ }
+ }
+}
+
+func (s *Screen) growHunks() {
+ var (
+ backLimit int // limits for cells to fill
+ backRefLimit int // limit for references
+ i int
+ nextHunk int
+ )
+
+ height := s.newbuf.Height()
+ for i < height && s.oldnum[i] == newIndex {
+ i++
+ }
+ for ; i < height; i = nextHunk {
+ var (
+ forwardLimit int
+ forwardRefLimit int
+ end int
+ start = i
+ shift = s.oldnum[i] - i
+ )
+
+ // get forward limit
+ i = start + 1
+ for i < height &&
+ s.oldnum[i] != newIndex &&
+ s.oldnum[i]-i == shift {
+ i++
+ }
+
+ end = i
+ for i < height && s.oldnum[i] == newIndex {
+ i++
+ }
+
+ nextHunk = i
+ forwardLimit = i
+ if i >= height || s.oldnum[i] >= i {
+ forwardRefLimit = i
+ } else {
+ forwardRefLimit = s.oldnum[i]
+ }
+
+ i = start - 1
+
+ // grow back
+ if shift < 0 {
+ backLimit = backRefLimit + (-shift)
+ }
+ for i >= backLimit {
+ if s.newhash[i] == s.oldhash[i+shift] ||
+ s.costEffective(i+shift, i, shift < 0) {
+ s.oldnum[i] = i + shift
+ } else {
+ break
+ }
+ i--
+ }
+
+ i = end
+ // grow forward
+ if shift > 0 {
+ forwardLimit = forwardRefLimit - shift
+ }
+ for i < forwardLimit {
+ if s.newhash[i] == s.oldhash[i+shift] ||
+ s.costEffective(i+shift, i, shift > 0) {
+ s.oldnum[i] = i + shift
+ } else {
+ break
+ }
+ i++
+ }
+
+ backLimit = i
+ backRefLimit = backLimit
+ if shift > 0 {
+ backRefLimit += shift
+ }
+ }
+}
+
+// costEffective returns true if the cost of moving line 'from' to line 'to' seems to be
+// cost effective. 'blank' indicates whether the line 'to' would become blank.
+func (s *Screen) costEffective(from, to int, blank bool) bool {
+ if from == to {
+ return false
+ }
+
+ newFrom := s.oldnum[from]
+ if newFrom == newIndex {
+ newFrom = from
+ }
+
+ // On the left side of >= is the cost before moving. On the right side --
+ // cost after moving.
+
+ // Calculate costs before moving.
+ var costBeforeMove int
+ if blank {
+ // Cost of updating blank line at destination.
+ costBeforeMove = s.updateCostBlank(s.newbuf.Line(to))
+ } else {
+ // Cost of updating exiting line at destination.
+ costBeforeMove = s.updateCost(s.curbuf.Line(to), s.newbuf.Line(to))
+ }
+
+ // Add cost of updating source line
+ costBeforeMove += s.updateCost(s.curbuf.Line(newFrom), s.newbuf.Line(from))
+
+ // Calculate costs after moving.
+ var costAfterMove int
+ if newFrom == from {
+ // Source becomes blank after move
+ costAfterMove = s.updateCostBlank(s.newbuf.Line(from))
+ } else {
+ // Source gets updated from another line
+ costAfterMove = s.updateCost(s.curbuf.Line(newFrom), s.newbuf.Line(from))
+ }
+
+ // Add cost of moving source line to destination
+ costAfterMove += s.updateCost(s.curbuf.Line(from), s.newbuf.Line(to))
+
+ // Return true if moving is cost effective (costs less or equal)
+ return costBeforeMove >= costAfterMove
+}
+
+func (s *Screen) updateCost(from, to Line) (cost int) {
+ var fidx, tidx int
+ for i := s.newbuf.Width() - 1; i > 0; i, fidx, tidx = i-1, fidx+1, tidx+1 {
+ if !cellEqual(from.At(fidx), to.At(tidx)) {
+ cost++
+ }
+ }
+ return
+}
+
+func (s *Screen) updateCostBlank(to Line) (cost int) {
+ var tidx int
+ for i := s.newbuf.Width() - 1; i > 0; i, tidx = i-1, tidx+1 {
+ if !cellEqual(nil, to.At(tidx)) {
+ cost++
+ }
+ }
+ return
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/link.go b/vendor/github.com/charmbracelet/x/cellbuf/link.go
new file mode 100644
index 00000000..112f8e8a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/link.go
@@ -0,0 +1,14 @@
+package cellbuf
+
+import (
+ "github.com/charmbracelet/colorprofile"
+)
+
+// Convert converts a hyperlink to respect the given color profile.
+func ConvertLink(h Link, p colorprofile.Profile) Link {
+ if p == colorprofile.NoTTY {
+ return Link{}
+ }
+
+ return h
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/screen.go b/vendor/github.com/charmbracelet/x/cellbuf/screen.go
new file mode 100644
index 00000000..963b9cac
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/screen.go
@@ -0,0 +1,1457 @@
+package cellbuf
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "os"
+ "strings"
+ "sync"
+
+ "github.com/charmbracelet/colorprofile"
+ "github.com/charmbracelet/x/ansi"
+ "github.com/charmbracelet/x/term"
+)
+
+// ErrInvalidDimensions is returned when the dimensions of a window are invalid
+// for the operation.
+var ErrInvalidDimensions = errors.New("invalid dimensions")
+
+// notLocal returns whether the coordinates are not considered local movement
+// using the defined thresholds.
+// This takes the number of columns, and the coordinates of the current and
+// target positions.
+func notLocal(cols, fx, fy, tx, ty int) bool {
+ // The typical distance for a [ansi.CUP] sequence. Anything less than this
+ // is considered local movement.
+ const longDist = 8 - 1
+ return (tx > longDist) &&
+ (tx < cols-1-longDist) &&
+ (abs(ty-fy)+abs(tx-fx) > longDist)
+}
+
+// relativeCursorMove returns the relative cursor movement sequence using one or two
+// of the following sequences [ansi.CUU], [ansi.CUD], [ansi.CUF], [ansi.CUB],
+// [ansi.VPA], [ansi.HPA].
+// When overwrite is true, this will try to optimize the sequence by using the
+// screen cells values to move the cursor instead of using escape sequences.
+func relativeCursorMove(s *Screen, fx, fy, tx, ty int, overwrite, useTabs, useBackspace bool) string {
+ var seq strings.Builder
+
+ width, height := s.newbuf.Width(), s.newbuf.Height()
+ if ty != fy {
+ var yseq string
+ if s.xtermLike && !s.opts.RelativeCursor {
+ yseq = ansi.VerticalPositionAbsolute(ty + 1)
+ }
+
+ // OPTIM: Use [ansi.LF] and [ansi.ReverseIndex] as optimizations.
+
+ if ty > fy {
+ n := ty - fy
+ if cud := ansi.CursorDown(n); yseq == "" || len(cud) < len(yseq) {
+ yseq = cud
+ }
+ shouldScroll := !s.opts.AltScreen && fy+n >= s.scrollHeight
+ if lf := strings.Repeat("\n", n); shouldScroll || (fy+n < height && len(lf) < len(yseq)) {
+ // TODO: Ensure we're not unintentionally scrolling the screen down.
+ yseq = lf
+ s.scrollHeight = max(s.scrollHeight, fy+n)
+ }
+ } else if ty < fy {
+ n := fy - ty
+ if cuu := ansi.CursorUp(n); yseq == "" || len(cuu) < len(yseq) {
+ yseq = cuu
+ }
+ if n == 1 && fy-1 > 0 {
+ // TODO: Ensure we're not unintentionally scrolling the screen up.
+ yseq = ansi.ReverseIndex
+ }
+ }
+
+ seq.WriteString(yseq)
+ }
+
+ if tx != fx {
+ var xseq string
+ if s.xtermLike && !s.opts.RelativeCursor {
+ xseq = ansi.HorizontalPositionAbsolute(tx + 1)
+ }
+
+ if tx > fx {
+ n := tx - fx
+ if useTabs {
+ var tabs int
+ var col int
+ for col = fx; s.tabs.Next(col) <= tx; col = s.tabs.Next(col) {
+ tabs++
+ if col == s.tabs.Next(col) || col >= width-1 {
+ break
+ }
+ }
+
+ if tabs > 0 {
+ cht := ansi.CursorHorizontalForwardTab(tabs)
+ tab := strings.Repeat("\t", tabs)
+ if false && s.xtermLike && len(cht) < len(tab) {
+ // TODO: The linux console and some terminals such as
+ // Alacritty don't support [ansi.CHT]. Enable this when
+ // we have a way to detect this, or after 5 years when
+ // we're sure everyone has updated their terminals :P
+ seq.WriteString(cht)
+ } else {
+ seq.WriteString(tab)
+ }
+
+ n = tx - col
+ fx = col
+ }
+ }
+
+ if cuf := ansi.CursorForward(n); xseq == "" || len(cuf) < len(xseq) {
+ xseq = cuf
+ }
+
+ // If we have no attribute and style changes, overwrite is cheaper.
+ var ovw string
+ if overwrite && ty >= 0 {
+ for i := 0; i < n; i++ {
+ cell := s.newbuf.Cell(fx+i, ty)
+ if cell != nil && cell.Width > 0 {
+ i += cell.Width - 1
+ if !cell.Style.Equal(&s.cur.Style) || !cell.Link.Equal(&s.cur.Link) {
+ overwrite = false
+ break
+ }
+ }
+ }
+ }
+
+ if overwrite && ty >= 0 {
+ for i := 0; i < n; i++ {
+ cell := s.newbuf.Cell(fx+i, ty)
+ if cell != nil && cell.Width > 0 {
+ ovw += cell.String()
+ i += cell.Width - 1
+ } else {
+ ovw += " "
+ }
+ }
+ }
+
+ if overwrite && len(ovw) < len(xseq) {
+ xseq = ovw
+ }
+ } else if tx < fx {
+ n := fx - tx
+ if useTabs && s.xtermLike {
+ // VT100 does not support backward tabs [ansi.CBT].
+
+ col := fx
+
+ var cbt int // cursor backward tabs count
+ for s.tabs.Prev(col) >= tx {
+ col = s.tabs.Prev(col)
+ cbt++
+ if col == s.tabs.Prev(col) || col <= 0 {
+ break
+ }
+ }
+
+ if cbt > 0 {
+ seq.WriteString(ansi.CursorBackwardTab(cbt))
+ n = col - tx
+ }
+ }
+
+ if cub := ansi.CursorBackward(n); xseq == "" || len(cub) < len(xseq) {
+ xseq = cub
+ }
+
+ if useBackspace && n < len(xseq) {
+ xseq = strings.Repeat("\b", n)
+ }
+ }
+
+ seq.WriteString(xseq)
+ }
+
+ return seq.String()
+}
+
+// moveCursor moves and returns the cursor movement sequence to move the cursor
+// to the specified position.
+// When overwrite is true, this will try to optimize the sequence by using the
+// screen cells values to move the cursor instead of using escape sequences.
+func moveCursor(s *Screen, x, y int, overwrite bool) (seq string) {
+ fx, fy := s.cur.X, s.cur.Y
+
+ if !s.opts.RelativeCursor {
+ // Method #0: Use [ansi.CUP] if the distance is long.
+ seq = ansi.CursorPosition(x+1, y+1)
+ if fx == -1 || fy == -1 || notLocal(s.newbuf.Width(), fx, fy, x, y) {
+ return
+ }
+ }
+
+ // Optimize based on options.
+ trials := 0
+ if s.opts.HardTabs {
+ trials |= 2 // 0b10 in binary
+ }
+ if s.opts.Backspace {
+ trials |= 1 // 0b01 in binary
+ }
+
+ // Try all possible combinations of hard tabs and backspace optimizations.
+ for i := 0; i <= trials; i++ {
+ // Skip combinations that are not enabled.
+ if i & ^trials != 0 {
+ continue
+ }
+
+ useHardTabs := i&2 != 0
+ useBackspace := i&1 != 0
+
+ // Method #1: Use local movement sequences.
+ nseq := relativeCursorMove(s, fx, fy, x, y, overwrite, useHardTabs, useBackspace)
+ if (i == 0 && len(seq) == 0) || len(nseq) < len(seq) {
+ seq = nseq
+ }
+
+ // Method #2: Use [ansi.CR] and local movement sequences.
+ nseq = "\r" + relativeCursorMove(s, 0, fy, x, y, overwrite, useHardTabs, useBackspace)
+ if len(nseq) < len(seq) {
+ seq = nseq
+ }
+
+ if !s.opts.RelativeCursor {
+ // Method #3: Use [ansi.CursorHomePosition] and local movement sequences.
+ nseq = ansi.CursorHomePosition + relativeCursorMove(s, 0, 0, x, y, overwrite, useHardTabs, useBackspace)
+ if len(nseq) < len(seq) {
+ seq = nseq
+ }
+ }
+ }
+
+ return
+}
+
+// moveCursor moves the cursor to the specified position.
+func (s *Screen) moveCursor(x, y int, overwrite bool) {
+ if !s.opts.AltScreen && s.cur.X == -1 && s.cur.Y == -1 {
+ // First cursor movement in inline mode, move the cursor to the first
+ // column before moving to the target position.
+ s.buf.WriteByte('\r') //nolint:errcheck
+ s.cur.X, s.cur.Y = 0, 0
+ }
+ s.buf.WriteString(moveCursor(s, x, y, overwrite)) //nolint:errcheck
+ s.cur.X, s.cur.Y = x, y
+}
+
+func (s *Screen) move(x, y int) {
+ // XXX: Make sure we use the max height and width of the buffer in case
+ // we're in the middle of a resize operation.
+ width := max(s.newbuf.Width(), s.curbuf.Width())
+ height := max(s.newbuf.Height(), s.curbuf.Height())
+
+ if width > 0 && x >= width {
+ // Handle autowrap
+ y += (x / width)
+ x %= width
+ }
+
+ // XXX: Disable styles if there's any
+ // Some move operations such as [ansi.LF] can apply styles to the new
+ // cursor position, thus, we need to reset the styles before moving the
+ // cursor.
+ blank := s.clearBlank()
+ resetPen := y != s.cur.Y && !blank.Equal(&BlankCell)
+ if resetPen {
+ s.updatePen(nil)
+ }
+
+ // Reset wrap around (phantom cursor) state
+ if s.atPhantom {
+ s.cur.X = 0
+ s.buf.WriteByte('\r') //nolint:errcheck
+ s.atPhantom = false // reset phantom cell state
+ }
+
+ // TODO: Investigate if we need to handle this case and/or if we need the
+ // following code.
+ //
+ // if width > 0 && s.cur.X >= width {
+ // l := (s.cur.X + 1) / width
+ //
+ // s.cur.Y += l
+ // if height > 0 && s.cur.Y >= height {
+ // l -= s.cur.Y - height - 1
+ // }
+ //
+ // if l > 0 {
+ // s.cur.X = 0
+ // s.buf.WriteString("\r" + strings.Repeat("\n", l)) //nolint:errcheck
+ // }
+ // }
+
+ if height > 0 {
+ if s.cur.Y > height-1 {
+ s.cur.Y = height - 1
+ }
+ if y > height-1 {
+ y = height - 1
+ }
+ }
+
+ if x == s.cur.X && y == s.cur.Y {
+ // We give up later because we need to run checks for the phantom cell
+ // and others before we can determine if we can give up.
+ return
+ }
+
+ // We set the new cursor in [Screen.moveCursor].
+ s.moveCursor(x, y, true) // Overwrite cells if possible
+}
+
+// Cursor represents a terminal Cursor.
+type Cursor struct {
+ Style
+ Link
+ Position
+}
+
+// ScreenOptions are options for the screen.
+type ScreenOptions struct {
+ // Term is the terminal type to use when writing to the screen. When empty,
+ // `$TERM` is used from [os.Getenv].
+ Term string
+ // Profile is the color profile to use when writing to the screen.
+ Profile colorprofile.Profile
+ // RelativeCursor is whether to use relative cursor movements. This is
+ // useful when alt-screen is not used or when using inline mode.
+ RelativeCursor bool
+ // AltScreen is whether to use the alternate screen buffer.
+ AltScreen bool
+ // ShowCursor is whether to show the cursor.
+ ShowCursor bool
+ // HardTabs is whether to use hard tabs to optimize cursor movements.
+ HardTabs bool
+ // Backspace is whether to use backspace characters to move the cursor.
+ Backspace bool
+}
+
+// lineData represents the metadata for a line.
+type lineData struct {
+ // first and last changed cell indices
+ firstCell, lastCell int
+ // old index used for scrolling
+ oldIndex int //nolint:unused
+}
+
+// Screen represents the terminal screen.
+type Screen struct {
+ w io.Writer
+ buf *bytes.Buffer // buffer for writing to the screen
+ curbuf *Buffer // the current buffer
+ newbuf *Buffer // the new buffer
+ tabs *TabStops
+ touch map[int]lineData
+ queueAbove []string // the queue of strings to write above the screen
+ oldhash, newhash []uint64 // the old and new hash values for each line
+ hashtab []hashmap // the hashmap table
+ oldnum []int // old indices from previous hash
+ cur, saved Cursor // the current and saved cursors
+ opts ScreenOptions
+ mu sync.Mutex
+ method ansi.Method
+ scrollHeight int // keeps track of how many lines we've scrolled down (inline mode)
+ altScreenMode bool // whether alternate screen mode is enabled
+ cursorHidden bool // whether text cursor mode is enabled
+ clear bool // whether to force clear the screen
+ xtermLike bool // whether to use xterm-like optimizations, otherwise, it uses vt100 only
+ queuedText bool // whether we have queued non-zero width text queued up
+ atPhantom bool // whether the cursor is out of bounds and at a phantom cell
+}
+
+// SetMethod sets the method used to calculate the width of cells.
+func (s *Screen) SetMethod(method ansi.Method) {
+ s.method = method
+}
+
+// UseBackspaces sets whether to use backspace characters to move the cursor.
+func (s *Screen) UseBackspaces(v bool) {
+ s.opts.Backspace = v
+}
+
+// UseHardTabs sets whether to use hard tabs to optimize cursor movements.
+func (s *Screen) UseHardTabs(v bool) {
+ s.opts.HardTabs = v
+}
+
+// SetColorProfile sets the color profile to use when writing to the screen.
+func (s *Screen) SetColorProfile(p colorprofile.Profile) {
+ s.opts.Profile = p
+}
+
+// SetRelativeCursor sets whether to use relative cursor movements.
+func (s *Screen) SetRelativeCursor(v bool) {
+ s.opts.RelativeCursor = v
+}
+
+// EnterAltScreen enters the alternate screen buffer.
+func (s *Screen) EnterAltScreen() {
+ s.opts.AltScreen = true
+ s.clear = true
+ s.saved = s.cur
+}
+
+// ExitAltScreen exits the alternate screen buffer.
+func (s *Screen) ExitAltScreen() {
+ s.opts.AltScreen = false
+ s.clear = true
+ s.cur = s.saved
+}
+
+// ShowCursor shows the cursor.
+func (s *Screen) ShowCursor() {
+ s.opts.ShowCursor = true
+}
+
+// HideCursor hides the cursor.
+func (s *Screen) HideCursor() {
+ s.opts.ShowCursor = false
+}
+
+// Bounds implements Window.
+func (s *Screen) Bounds() Rectangle {
+ // Always return the new buffer bounds.
+ return s.newbuf.Bounds()
+}
+
+// Cell implements Window.
+func (s *Screen) Cell(x int, y int) *Cell {
+ return s.newbuf.Cell(x, y)
+}
+
+// Redraw forces a full redraw of the screen.
+func (s *Screen) Redraw() {
+ s.mu.Lock()
+ s.clear = true
+ s.mu.Unlock()
+}
+
+// Clear clears the screen with blank cells. This is a convenience method for
+// [Screen.Fill] with a nil cell.
+func (s *Screen) Clear() bool {
+ return s.ClearRect(s.newbuf.Bounds())
+}
+
+// ClearRect clears the given rectangle with blank cells. This is a convenience
+// method for [Screen.FillRect] with a nil cell.
+func (s *Screen) ClearRect(r Rectangle) bool {
+ return s.FillRect(nil, r)
+}
+
+// SetCell implements Window.
+func (s *Screen) SetCell(x int, y int, cell *Cell) (v bool) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ cellWidth := 1
+ if cell != nil {
+ cellWidth = cell.Width
+ }
+ if prev := s.curbuf.Cell(x, y); !cellEqual(prev, cell) {
+ chg, ok := s.touch[y]
+ if !ok {
+ chg = lineData{firstCell: x, lastCell: x + cellWidth}
+ } else {
+ chg.firstCell = min(chg.firstCell, x)
+ chg.lastCell = max(chg.lastCell, x+cellWidth)
+ }
+ s.touch[y] = chg
+ }
+
+ return s.newbuf.SetCell(x, y, cell)
+}
+
+// Fill implements Window.
+func (s *Screen) Fill(cell *Cell) bool {
+ return s.FillRect(cell, s.newbuf.Bounds())
+}
+
+// FillRect implements Window.
+func (s *Screen) FillRect(cell *Cell, r Rectangle) bool {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ s.newbuf.FillRect(cell, r)
+ for i := r.Min.Y; i < r.Max.Y; i++ {
+ s.touch[i] = lineData{firstCell: r.Min.X, lastCell: r.Max.X}
+ }
+ return true
+}
+
+// isXtermLike returns whether the terminal is xterm-like. This means that the
+// terminal supports ECMA-48 and ANSI X3.64 escape sequences.
+// TODO: Should this be a lookup table into each $TERM terminfo database? Like
+// we could keep a map of ANSI escape sequence to terminfo capability name and
+// check if the database supports the escape sequence. Instead of keeping a
+// list of terminal names here.
+func isXtermLike(termtype string) (v bool) {
+ parts := strings.Split(termtype, "-")
+ if len(parts) == 0 {
+ return
+ }
+
+ switch parts[0] {
+ case
+ "alacritty",
+ "contour",
+ "foot",
+ "ghostty",
+ "kitty",
+ "linux",
+ "rio",
+ "screen",
+ "st",
+ "tmux",
+ "wezterm",
+ "xterm":
+ v = true
+ }
+
+ return
+}
+
+// NewScreen creates a new Screen.
+func NewScreen(w io.Writer, width, height int, opts *ScreenOptions) (s *Screen) {
+ s = new(Screen)
+ s.w = w
+ if opts != nil {
+ s.opts = *opts
+ }
+
+ if s.opts.Term == "" {
+ s.opts.Term = os.Getenv("TERM")
+ }
+
+ if width <= 0 || height <= 0 {
+ if f, ok := w.(term.File); ok {
+ width, height, _ = term.GetSize(f.Fd())
+ }
+ }
+ if width < 0 {
+ width = 0
+ }
+ if height < 0 {
+ height = 0
+ }
+
+ s.buf = new(bytes.Buffer)
+ s.xtermLike = isXtermLike(s.opts.Term)
+ s.curbuf = NewBuffer(width, height)
+ s.newbuf = NewBuffer(width, height)
+ s.cur = Cursor{Position: Pos(-1, -1)} // start at -1 to force a move
+ s.saved = s.cur
+ s.reset()
+
+ return
+}
+
+// Width returns the width of the screen.
+func (s *Screen) Width() int {
+ return s.newbuf.Width()
+}
+
+// Height returns the height of the screen.
+func (s *Screen) Height() int {
+ return s.newbuf.Height()
+}
+
+// cellEqual returns whether the two cells are equal. A nil cell is considered
+// a [BlankCell].
+func cellEqual(a, b *Cell) bool {
+ if a == b {
+ return true
+ }
+ if a == nil {
+ a = &BlankCell
+ }
+ if b == nil {
+ b = &BlankCell
+ }
+ return a.Equal(b)
+}
+
+// putCell draws a cell at the current cursor position.
+func (s *Screen) putCell(cell *Cell) {
+ width, height := s.newbuf.Width(), s.newbuf.Height()
+ if s.opts.AltScreen && s.cur.X == width-1 && s.cur.Y == height-1 {
+ s.putCellLR(cell)
+ } else {
+ s.putAttrCell(cell)
+ }
+}
+
+// wrapCursor wraps the cursor to the next line.
+//
+//nolint:unused
+func (s *Screen) wrapCursor() {
+ const autoRightMargin = true
+ if autoRightMargin {
+ // Assume we have auto wrap mode enabled.
+ s.cur.X = 0
+ s.cur.Y++
+ } else {
+ s.cur.X--
+ }
+}
+
+func (s *Screen) putAttrCell(cell *Cell) {
+ if cell != nil && cell.Empty() {
+ // XXX: Zero width cells are special and should not be written to the
+ // screen no matter what other attributes they have.
+ // Zero width cells are used for wide characters that are split into
+ // multiple cells.
+ return
+ }
+
+ if cell == nil {
+ cell = s.clearBlank()
+ }
+
+ // We're at pending wrap state (phantom cell), incoming cell should
+ // wrap.
+ if s.atPhantom {
+ s.wrapCursor()
+ s.atPhantom = false
+ }
+
+ s.updatePen(cell)
+ s.buf.WriteRune(cell.Rune) //nolint:errcheck
+ for _, c := range cell.Comb {
+ s.buf.WriteRune(c) //nolint:errcheck
+ }
+
+ s.cur.X += cell.Width
+
+ if cell.Width > 0 {
+ s.queuedText = true
+ }
+
+ if s.cur.X >= s.newbuf.Width() {
+ s.atPhantom = true
+ }
+}
+
+// putCellLR draws a cell at the lower right corner of the screen.
+func (s *Screen) putCellLR(cell *Cell) {
+ // Optimize for the lower right corner cell.
+ curX := s.cur.X
+ if cell == nil || !cell.Empty() {
+ s.buf.WriteString(ansi.ResetAutoWrapMode) //nolint:errcheck
+ s.putAttrCell(cell)
+ // Writing to lower-right corner cell should not wrap.
+ s.atPhantom = false
+ s.cur.X = curX
+ s.buf.WriteString(ansi.SetAutoWrapMode) //nolint:errcheck
+ }
+}
+
+// updatePen updates the cursor pen styles.
+func (s *Screen) updatePen(cell *Cell) {
+ if cell == nil {
+ cell = &BlankCell
+ }
+
+ if s.opts.Profile != 0 {
+ // Downsample colors to the given color profile.
+ cell.Style = ConvertStyle(cell.Style, s.opts.Profile)
+ cell.Link = ConvertLink(cell.Link, s.opts.Profile)
+ }
+
+ if !cell.Style.Equal(&s.cur.Style) {
+ seq := cell.Style.DiffSequence(s.cur.Style)
+ if cell.Style.Empty() && len(seq) > len(ansi.ResetStyle) {
+ seq = ansi.ResetStyle
+ }
+ s.buf.WriteString(seq) //nolint:errcheck
+ s.cur.Style = cell.Style
+ }
+ if !cell.Link.Equal(&s.cur.Link) {
+ s.buf.WriteString(ansi.SetHyperlink(cell.Link.URL, cell.Link.Params)) //nolint:errcheck
+ s.cur.Link = cell.Link
+ }
+}
+
+// emitRange emits a range of cells to the buffer. It it equivalent to calling
+// [Screen.putCell] for each cell in the range. This is optimized to use
+// [ansi.ECH] and [ansi.REP].
+// Returns whether the cursor is at the end of interval or somewhere in the
+// middle.
+func (s *Screen) emitRange(line Line, n int) (eoi bool) {
+ for n > 0 {
+ var count int
+ for n > 1 && !cellEqual(line.At(0), line.At(1)) {
+ s.putCell(line.At(0))
+ line = line[1:]
+ n--
+ }
+
+ cell0 := line[0]
+ if n == 1 {
+ s.putCell(cell0)
+ return false
+ }
+
+ count = 2
+ for count < n && cellEqual(line.At(count), cell0) {
+ count++
+ }
+
+ ech := ansi.EraseCharacter(count)
+ cup := ansi.CursorPosition(s.cur.X+count, s.cur.Y)
+ rep := ansi.RepeatPreviousCharacter(count)
+ if s.xtermLike && count > len(ech)+len(cup) && cell0 != nil && cell0.Clear() {
+ s.updatePen(cell0)
+ s.buf.WriteString(ech) //nolint:errcheck
+
+ // If this is the last cell, we don't need to move the cursor.
+ if count < n {
+ s.move(s.cur.X+count, s.cur.Y)
+ } else {
+ return true // cursor in the middle
+ }
+ } else if s.xtermLike && count > len(rep) &&
+ (cell0 == nil || (len(cell0.Comb) == 0 && cell0.Rune < 256)) {
+ // We only support ASCII characters. Most terminals will handle
+ // non-ASCII characters correctly, but some might not, ahem xterm.
+ //
+ // NOTE: [ansi.REP] only repeats the last rune and won't work
+ // if the last cell contains multiple runes.
+
+ wrapPossible := s.cur.X+count >= s.newbuf.Width()
+ repCount := count
+ if wrapPossible {
+ repCount--
+ }
+
+ s.updatePen(cell0)
+ s.putCell(cell0)
+ repCount-- // cell0 is a single width cell ASCII character
+
+ s.buf.WriteString(ansi.RepeatPreviousCharacter(repCount)) //nolint:errcheck
+ s.cur.X += repCount
+ if wrapPossible {
+ s.putCell(cell0)
+ }
+ } else {
+ for i := 0; i < count; i++ {
+ s.putCell(line.At(i))
+ }
+ }
+
+ line = line[clamp(count, 0, len(line)):]
+ n -= count
+ }
+
+ return
+}
+
+// putRange puts a range of cells from the old line to the new line.
+// Returns whether the cursor is at the end of interval or somewhere in the
+// middle.
+func (s *Screen) putRange(oldLine, newLine Line, y, start, end int) (eoi bool) {
+ inline := min(len(ansi.CursorPosition(start+1, y+1)),
+ min(len(ansi.HorizontalPositionAbsolute(start+1)),
+ len(ansi.CursorForward(start+1))))
+ if (end - start + 1) > inline {
+ var j, same int
+ for j, same = start, 0; j <= end; j++ {
+ oldCell, newCell := oldLine.At(j), newLine.At(j)
+ if same == 0 && oldCell != nil && oldCell.Empty() {
+ continue
+ }
+ if cellEqual(oldCell, newCell) {
+ same++
+ } else {
+ if same > end-start {
+ s.emitRange(newLine[start:], j-same-start)
+ s.move(j, y)
+ start = j
+ }
+ same = 0
+ }
+ }
+
+ i := s.emitRange(newLine[start:], j-same-start)
+
+ // Always return 1 for the next [Screen.move] after a [Screen.putRange] if
+ // we found identical characters at end of interval.
+ if same == 0 {
+ return i
+ }
+ return true
+ }
+
+ return s.emitRange(newLine[start:], end-start+1)
+}
+
+// clearToEnd clears the screen from the current cursor position to the end of
+// line.
+func (s *Screen) clearToEnd(blank *Cell, force bool) { //nolint:unparam
+ if s.cur.Y >= 0 {
+ curline := s.curbuf.Line(s.cur.Y)
+ for j := s.cur.X; j < s.curbuf.Width(); j++ {
+ if j >= 0 {
+ c := curline.At(j)
+ if !cellEqual(c, blank) {
+ curline.Set(j, blank)
+ force = true
+ }
+ }
+ }
+ }
+
+ if force {
+ s.updatePen(blank)
+ count := s.newbuf.Width() - s.cur.X
+ if s.el0Cost() <= count {
+ s.buf.WriteString(ansi.EraseLineRight) //nolint:errcheck
+ } else {
+ for i := 0; i < count; i++ {
+ s.putCell(blank)
+ }
+ }
+ }
+}
+
+// clearBlank returns a blank cell based on the current cursor background color.
+func (s *Screen) clearBlank() *Cell {
+ c := BlankCell
+ if !s.cur.Style.Empty() || !s.cur.Link.Empty() {
+ c.Style = s.cur.Style
+ c.Link = s.cur.Link
+ }
+ return &c
+}
+
+// insertCells inserts the count cells pointed by the given line at the current
+// cursor position.
+func (s *Screen) insertCells(line Line, count int) {
+ if s.xtermLike {
+ // Use [ansi.ICH] as an optimization.
+ s.buf.WriteString(ansi.InsertCharacter(count)) //nolint:errcheck
+ } else {
+ // Otherwise, use [ansi.IRM] mode.
+ s.buf.WriteString(ansi.SetInsertReplaceMode) //nolint:errcheck
+ }
+
+ for i := 0; count > 0; i++ {
+ s.putAttrCell(line[i])
+ count--
+ }
+
+ if !s.xtermLike {
+ s.buf.WriteString(ansi.ResetInsertReplaceMode) //nolint:errcheck
+ }
+}
+
+// el0Cost returns the cost of using [ansi.EL] 0 i.e. [ansi.EraseLineRight]. If
+// this terminal supports background color erase, it can be cheaper to use
+// [ansi.EL] 0 i.e. [ansi.EraseLineRight] to clear
+// trailing spaces.
+func (s *Screen) el0Cost() int {
+ if s.xtermLike {
+ return 0
+ }
+ return len(ansi.EraseLineRight)
+}
+
+// transformLine transforms the given line in the current window to the
+// corresponding line in the new window. It uses [ansi.ICH] and [ansi.DCH] to
+// insert or delete characters.
+func (s *Screen) transformLine(y int) {
+ var firstCell, oLastCell, nLastCell int // first, old last, new last index
+ oldLine := s.curbuf.Line(y)
+ newLine := s.newbuf.Line(y)
+
+ // Find the first changed cell in the line
+ var lineChanged bool
+ for i := 0; i < s.newbuf.Width(); i++ {
+ if !cellEqual(newLine.At(i), oldLine.At(i)) {
+ lineChanged = true
+ break
+ }
+ }
+
+ const ceolStandoutGlitch = false
+ if ceolStandoutGlitch && lineChanged {
+ s.move(0, y)
+ s.clearToEnd(nil, false)
+ s.putRange(oldLine, newLine, y, 0, s.newbuf.Width()-1)
+ } else {
+ blank := newLine.At(0)
+
+ // It might be cheaper to clear leading spaces with [ansi.EL] 1 i.e.
+ // [ansi.EraseLineLeft].
+ if blank == nil || blank.Clear() {
+ var oFirstCell, nFirstCell int
+ for oFirstCell = 0; oFirstCell < s.curbuf.Width(); oFirstCell++ {
+ if !cellEqual(oldLine.At(oFirstCell), blank) {
+ break
+ }
+ }
+ for nFirstCell = 0; nFirstCell < s.newbuf.Width(); nFirstCell++ {
+ if !cellEqual(newLine.At(nFirstCell), blank) {
+ break
+ }
+ }
+
+ if nFirstCell == oFirstCell {
+ firstCell = nFirstCell
+
+ // Find the first differing cell
+ for firstCell < s.newbuf.Width() &&
+ cellEqual(oldLine.At(firstCell), newLine.At(firstCell)) {
+ firstCell++
+ }
+ } else if oFirstCell > nFirstCell {
+ firstCell = nFirstCell
+ } else if oFirstCell < nFirstCell {
+ firstCell = oFirstCell
+ el1Cost := len(ansi.EraseLineLeft)
+ if el1Cost < nFirstCell-oFirstCell {
+ if nFirstCell >= s.newbuf.Width() {
+ s.move(0, y)
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.EraseLineRight) //nolint:errcheck
+ } else {
+ s.move(nFirstCell-1, y)
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.EraseLineLeft) //nolint:errcheck
+ }
+
+ for firstCell < nFirstCell {
+ oldLine.Set(firstCell, blank)
+ firstCell++
+ }
+ }
+ }
+ } else {
+ // Find the first differing cell
+ for firstCell < s.newbuf.Width() && cellEqual(newLine.At(firstCell), oldLine.At(firstCell)) {
+ firstCell++
+ }
+ }
+
+ // If we didn't find one, we're done
+ if firstCell >= s.newbuf.Width() {
+ return
+ }
+
+ blank = newLine.At(s.newbuf.Width() - 1)
+ if blank != nil && !blank.Clear() {
+ // Find the last differing cell
+ nLastCell = s.newbuf.Width() - 1
+ for nLastCell > firstCell && cellEqual(newLine.At(nLastCell), oldLine.At(nLastCell)) {
+ nLastCell--
+ }
+
+ if nLastCell >= firstCell {
+ s.move(firstCell, y)
+ s.putRange(oldLine, newLine, y, firstCell, nLastCell)
+ if firstCell < len(oldLine) && firstCell < len(newLine) {
+ copy(oldLine[firstCell:], newLine[firstCell:])
+ } else {
+ copy(oldLine, newLine)
+ }
+ }
+
+ return
+ }
+
+ // Find last non-blank cell in the old line.
+ oLastCell = s.curbuf.Width() - 1
+ for oLastCell > firstCell && cellEqual(oldLine.At(oLastCell), blank) {
+ oLastCell--
+ }
+
+ // Find last non-blank cell in the new line.
+ nLastCell = s.newbuf.Width() - 1
+ for nLastCell > firstCell && cellEqual(newLine.At(nLastCell), blank) {
+ nLastCell--
+ }
+
+ if nLastCell == firstCell && s.el0Cost() < oLastCell-nLastCell {
+ s.move(firstCell, y)
+ if !cellEqual(newLine.At(firstCell), blank) {
+ s.putCell(newLine.At(firstCell))
+ }
+ s.clearToEnd(blank, false)
+ } else if nLastCell != oLastCell &&
+ !cellEqual(newLine.At(nLastCell), oldLine.At(oLastCell)) {
+ s.move(firstCell, y)
+ if oLastCell-nLastCell > s.el0Cost() {
+ if s.putRange(oldLine, newLine, y, firstCell, nLastCell) {
+ s.move(nLastCell+1, y)
+ }
+ s.clearToEnd(blank, false)
+ } else {
+ n := max(nLastCell, oLastCell)
+ s.putRange(oldLine, newLine, y, firstCell, n)
+ }
+ } else {
+ nLastNonBlank := nLastCell
+ oLastNonBlank := oLastCell
+
+ // Find the last cells that really differ.
+ // Can be -1 if no cells differ.
+ for cellEqual(newLine.At(nLastCell), oldLine.At(oLastCell)) {
+ if !cellEqual(newLine.At(nLastCell-1), oldLine.At(oLastCell-1)) {
+ break
+ }
+ nLastCell--
+ oLastCell--
+ if nLastCell == -1 || oLastCell == -1 {
+ break
+ }
+ }
+
+ n := min(oLastCell, nLastCell)
+ if n >= firstCell {
+ s.move(firstCell, y)
+ s.putRange(oldLine, newLine, y, firstCell, n)
+ }
+
+ if oLastCell < nLastCell {
+ m := max(nLastNonBlank, oLastNonBlank)
+ if n != 0 {
+ for n > 0 {
+ wide := newLine.At(n + 1)
+ if wide == nil || !wide.Empty() {
+ break
+ }
+ n--
+ oLastCell--
+ }
+ } else if n >= firstCell && newLine.At(n) != nil && newLine.At(n).Width > 1 {
+ next := newLine.At(n + 1)
+ for next != nil && next.Empty() {
+ n++
+ oLastCell++
+ }
+ }
+
+ s.move(n+1, y)
+ ichCost := 3 + nLastCell - oLastCell
+ if s.xtermLike && (nLastCell < nLastNonBlank || ichCost > (m-n)) {
+ s.putRange(oldLine, newLine, y, n+1, m)
+ } else {
+ s.insertCells(newLine[n+1:], nLastCell-oLastCell)
+ }
+ } else if oLastCell > nLastCell {
+ s.move(n+1, y)
+ dchCost := 3 + oLastCell - nLastCell
+ if dchCost > len(ansi.EraseLineRight)+nLastNonBlank-(n+1) {
+ if s.putRange(oldLine, newLine, y, n+1, nLastNonBlank) {
+ s.move(nLastNonBlank+1, y)
+ }
+ s.clearToEnd(blank, false)
+ } else {
+ s.updatePen(blank)
+ s.deleteCells(oLastCell - nLastCell)
+ }
+ }
+ }
+ }
+
+ // Update the old line with the new line
+ if firstCell < len(oldLine) && firstCell < len(newLine) {
+ copy(oldLine[firstCell:], newLine[firstCell:])
+ } else {
+ copy(oldLine, newLine)
+ }
+}
+
+// deleteCells deletes the count cells at the current cursor position and moves
+// the rest of the line to the left. This is equivalent to [ansi.DCH].
+func (s *Screen) deleteCells(count int) {
+ // [ansi.DCH] will shift in cells from the right margin so we need to
+ // ensure that they are the right style.
+ s.buf.WriteString(ansi.DeleteCharacter(count)) //nolint:errcheck
+}
+
+// clearToBottom clears the screen from the current cursor position to the end
+// of the screen.
+func (s *Screen) clearToBottom(blank *Cell) {
+ row, col := s.cur.Y, s.cur.X
+ if row < 0 {
+ row = 0
+ }
+
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.EraseScreenBelow) //nolint:errcheck
+ // Clear the rest of the current line
+ s.curbuf.ClearRect(Rect(col, row, s.curbuf.Width()-col, 1))
+ // Clear everything below the current line
+ s.curbuf.ClearRect(Rect(0, row+1, s.curbuf.Width(), s.curbuf.Height()-row-1))
+}
+
+// clearBottom tests if clearing the end of the screen would satisfy part of
+// the screen update. Scan backwards through lines in the screen checking if
+// each is blank and one or more are changed.
+// It returns the top line.
+func (s *Screen) clearBottom(total int) (top int) {
+ if total <= 0 {
+ return
+ }
+
+ top = total
+ last := s.newbuf.Width()
+ blank := s.clearBlank()
+ canClearWithBlank := blank == nil || blank.Clear()
+
+ if canClearWithBlank {
+ var row int
+ for row = total - 1; row >= 0; row-- {
+ oldLine := s.curbuf.Line(row)
+ newLine := s.newbuf.Line(row)
+
+ var col int
+ ok := true
+ for col = 0; ok && col < last; col++ {
+ ok = cellEqual(newLine.At(col), blank)
+ }
+ if !ok {
+ break
+ }
+
+ for col = 0; ok && col < last; col++ {
+ ok = len(oldLine) == last && cellEqual(oldLine.At(col), blank)
+ }
+ if !ok {
+ top = row
+ }
+ }
+
+ if top < total {
+ s.move(0, top-1) // top is 1-based
+ s.clearToBottom(blank)
+ if s.oldhash != nil && s.newhash != nil &&
+ row < len(s.oldhash) && row < len(s.newhash) {
+ for row := top; row < s.newbuf.Height(); row++ {
+ s.oldhash[row] = s.newhash[row]
+ }
+ }
+ }
+ }
+
+ return
+}
+
+// clearScreen clears the screen and put cursor at home.
+func (s *Screen) clearScreen(blank *Cell) {
+ s.updatePen(blank)
+ s.buf.WriteString(ansi.CursorHomePosition) //nolint:errcheck
+ s.buf.WriteString(ansi.EraseEntireScreen) //nolint:errcheck
+ s.cur.X, s.cur.Y = 0, 0
+ s.curbuf.Fill(blank)
+}
+
+// clearBelow clears everything below and including the row.
+func (s *Screen) clearBelow(blank *Cell, row int) {
+ s.move(0, row)
+ s.clearToBottom(blank)
+}
+
+// clearUpdate forces a screen redraw.
+func (s *Screen) clearUpdate() {
+ blank := s.clearBlank()
+ var nonEmpty int
+ if s.opts.AltScreen {
+ // XXX: We're using the maximum height of the two buffers to ensure
+ // we write newly added lines to the screen in [Screen.transformLine].
+ nonEmpty = max(s.curbuf.Height(), s.newbuf.Height())
+ s.clearScreen(blank)
+ } else {
+ nonEmpty = s.newbuf.Height()
+ s.clearBelow(blank, 0)
+ }
+ nonEmpty = s.clearBottom(nonEmpty)
+ for i := 0; i < nonEmpty; i++ {
+ s.transformLine(i)
+ }
+}
+
+// Flush flushes the buffer to the screen.
+func (s *Screen) Flush() (err error) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ return s.flush()
+}
+
+func (s *Screen) flush() (err error) {
+ // Write the buffer
+ if s.buf.Len() > 0 {
+ _, err = s.w.Write(s.buf.Bytes()) //nolint:errcheck
+ if err == nil {
+ s.buf.Reset()
+ }
+ }
+
+ return
+}
+
+// Render renders changes of the screen to the internal buffer. Call
+// [Screen.Flush] to flush pending changes to the screen.
+func (s *Screen) Render() {
+ s.mu.Lock()
+ s.render()
+ s.mu.Unlock()
+}
+
+func (s *Screen) render() {
+ // Do we need to render anything?
+ if s.opts.AltScreen == s.altScreenMode &&
+ !s.opts.ShowCursor == s.cursorHidden &&
+ !s.clear &&
+ len(s.touch) == 0 &&
+ len(s.queueAbove) == 0 {
+ return
+ }
+
+ // TODO: Investigate whether this is necessary. Theoretically, terminals
+ // can add/remove tab stops and we should be able to handle that. We could
+ // use [ansi.DECTABSR] to read the tab stops, but that's not implemented in
+ // most terminals :/
+ // // Are we using hard tabs? If so, ensure tabs are using the
+ // // default interval using [ansi.DECST8C].
+ // if s.opts.HardTabs && !s.initTabs {
+ // s.buf.WriteString(ansi.SetTabEvery8Columns)
+ // s.initTabs = true
+ // }
+
+ // Do we need alt-screen mode?
+ if s.opts.AltScreen != s.altScreenMode {
+ if s.opts.AltScreen {
+ s.buf.WriteString(ansi.SetAltScreenSaveCursorMode)
+ } else {
+ s.buf.WriteString(ansi.ResetAltScreenSaveCursorMode)
+ }
+ s.altScreenMode = s.opts.AltScreen
+ }
+
+ // Do we need text cursor mode?
+ if !s.opts.ShowCursor != s.cursorHidden {
+ s.cursorHidden = !s.opts.ShowCursor
+ if s.cursorHidden {
+ s.buf.WriteString(ansi.HideCursor)
+ }
+ }
+
+ // Do we have queued strings to write above the screen?
+ if len(s.queueAbove) > 0 {
+ // TODO: Use scrolling region if available.
+ // TODO: Use [Screen.Write] [io.Writer] interface.
+
+ // We need to scroll the screen up by the number of lines in the queue.
+ // We can't use [ansi.SU] because we want the cursor to move down until
+ // it reaches the bottom of the screen.
+ s.move(0, s.newbuf.Height()-1)
+ s.buf.WriteString(strings.Repeat("\n", len(s.queueAbove)))
+ s.cur.Y += len(s.queueAbove)
+ // XXX: Now go to the top of the screen, insert new lines, and write
+ // the queued strings. It is important to use [Screen.moveCursor]
+ // instead of [Screen.move] because we don't want to perform any checks
+ // on the cursor position.
+ s.moveCursor(0, 0, false)
+ s.buf.WriteString(ansi.InsertLine(len(s.queueAbove)))
+ for _, line := range s.queueAbove {
+ s.buf.WriteString(line + "\r\n")
+ }
+
+ // Clear the queue
+ s.queueAbove = s.queueAbove[:0]
+ }
+
+ var nonEmpty int
+
+ // XXX: In inline mode, after a screen resize, we need to clear the extra
+ // lines at the bottom of the screen. This is because in inline mode, we
+ // don't use the full screen height and the current buffer size might be
+ // larger than the new buffer size.
+ partialClear := !s.opts.AltScreen && s.cur.X != -1 && s.cur.Y != -1 &&
+ s.curbuf.Width() == s.newbuf.Width() &&
+ s.curbuf.Height() > 0 &&
+ s.curbuf.Height() > s.newbuf.Height()
+
+ if !s.clear && partialClear {
+ s.clearBelow(nil, s.newbuf.Height()-1)
+ }
+
+ if s.clear {
+ s.clearUpdate()
+ s.clear = false
+ } else if len(s.touch) > 0 {
+ if s.opts.AltScreen {
+ // Optimize scrolling for the alternate screen buffer.
+ // TODO: Should we optimize for inline mode as well? If so, we need
+ // to know the actual cursor position to use [ansi.DECSTBM].
+ s.scrollOptimize()
+ }
+
+ var changedLines int
+ var i int
+
+ if s.opts.AltScreen {
+ nonEmpty = min(s.curbuf.Height(), s.newbuf.Height())
+ } else {
+ nonEmpty = s.newbuf.Height()
+ }
+
+ nonEmpty = s.clearBottom(nonEmpty)
+ for i = 0; i < nonEmpty; i++ {
+ _, ok := s.touch[i]
+ if ok {
+ s.transformLine(i)
+ changedLines++
+ }
+ }
+ }
+
+ // Sync windows and screen
+ s.touch = make(map[int]lineData, s.newbuf.Height())
+
+ if s.curbuf.Width() != s.newbuf.Width() || s.curbuf.Height() != s.newbuf.Height() {
+ // Resize the old buffer to match the new buffer.
+ _, oldh := s.curbuf.Width(), s.curbuf.Height()
+ s.curbuf.Resize(s.newbuf.Width(), s.newbuf.Height())
+ // Sync new lines to old lines
+ for i := oldh - 1; i < s.newbuf.Height(); i++ {
+ copy(s.curbuf.Line(i), s.newbuf.Line(i))
+ }
+ }
+
+ s.updatePen(nil) // nil indicates a blank cell with no styles
+
+ // Do we have enough changes to justify toggling the cursor?
+ if s.buf.Len() > 1 && s.opts.ShowCursor && !s.cursorHidden && s.queuedText {
+ nb := new(bytes.Buffer)
+ nb.Grow(s.buf.Len() + len(ansi.HideCursor) + len(ansi.ShowCursor))
+ nb.WriteString(ansi.HideCursor)
+ nb.Write(s.buf.Bytes())
+ nb.WriteString(ansi.ShowCursor)
+ *s.buf = *nb
+ }
+
+ s.queuedText = false
+}
+
+// Close writes the final screen update and resets the screen.
+func (s *Screen) Close() (err error) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ s.render()
+ s.updatePen(nil)
+ // Go to the bottom of the screen
+ s.move(0, s.newbuf.Height()-1)
+
+ if s.altScreenMode {
+ s.buf.WriteString(ansi.ResetAltScreenSaveCursorMode)
+ s.altScreenMode = false
+ }
+
+ if s.cursorHidden {
+ s.buf.WriteString(ansi.ShowCursor)
+ s.cursorHidden = false
+ }
+
+ // Write the buffer
+ err = s.flush()
+ if err != nil {
+ return
+ }
+
+ s.reset()
+ return
+}
+
+// reset resets the screen to its initial state.
+func (s *Screen) reset() {
+ s.scrollHeight = 0
+ s.cursorHidden = false
+ s.altScreenMode = false
+ s.touch = make(map[int]lineData, s.newbuf.Height())
+ if s.curbuf != nil {
+ s.curbuf.Clear()
+ }
+ if s.newbuf != nil {
+ s.newbuf.Clear()
+ }
+ s.buf.Reset()
+ s.tabs = DefaultTabStops(s.newbuf.Width())
+ s.oldhash, s.newhash = nil, nil
+
+ // We always disable HardTabs when termtype is "linux".
+ if strings.HasPrefix(s.opts.Term, "linux") {
+ s.opts.HardTabs = false
+ }
+}
+
+// Resize resizes the screen.
+func (s *Screen) Resize(width, height int) bool {
+ oldw := s.newbuf.Width()
+ oldh := s.newbuf.Height()
+
+ if s.opts.AltScreen || width != oldw {
+ // We only clear the whole screen if the width changes. Adding/removing
+ // rows is handled by the [Screen.render] and [Screen.transformLine]
+ // methods.
+ s.clear = true
+ }
+
+ // Clear new columns and lines
+ if width > oldh {
+ s.ClearRect(Rect(max(oldw-1, 0), 0, width-oldw, height))
+ } else if width < oldw {
+ s.ClearRect(Rect(max(width-1, 0), 0, oldw-width, height))
+ }
+
+ if height > oldh {
+ s.ClearRect(Rect(0, max(oldh-1, 0), width, height-oldh))
+ } else if height < oldh {
+ s.ClearRect(Rect(0, max(height-1, 0), width, oldh-height))
+ }
+
+ s.mu.Lock()
+ s.newbuf.Resize(width, height)
+ s.tabs.Resize(width)
+ s.oldhash, s.newhash = nil, nil
+ s.scrollHeight = 0 // reset scroll lines
+ s.mu.Unlock()
+
+ return true
+}
+
+// MoveTo moves the cursor to the given position.
+func (s *Screen) MoveTo(x, y int) {
+ s.mu.Lock()
+ s.move(x, y)
+ s.mu.Unlock()
+}
+
+// InsertAbove inserts string above the screen. The inserted string is not
+// managed by the screen. This does nothing when alternate screen mode is
+// enabled.
+func (s *Screen) InsertAbove(str string) {
+ if s.opts.AltScreen {
+ return
+ }
+ s.mu.Lock()
+ for _, line := range strings.Split(str, "\n") {
+ s.queueAbove = append(s.queueAbove, s.method.Truncate(line, s.Width(), ""))
+ }
+ s.mu.Unlock()
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/sequence.go b/vendor/github.com/charmbracelet/x/cellbuf/sequence.go
new file mode 100644
index 00000000..613eefef
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/sequence.go
@@ -0,0 +1,131 @@
+package cellbuf
+
+import (
+ "bytes"
+ "image/color"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// ReadStyle reads a Select Graphic Rendition (SGR) escape sequences from a
+// list of parameters.
+func ReadStyle(params ansi.Params, pen *Style) {
+ if len(params) == 0 {
+ pen.Reset()
+ return
+ }
+
+ for i := 0; i < len(params); i++ {
+ param, hasMore, _ := params.Param(i, 0)
+ switch param {
+ case 0: // Reset
+ pen.Reset()
+ case 1: // Bold
+ pen.Bold(true)
+ case 2: // Dim/Faint
+ pen.Faint(true)
+ case 3: // Italic
+ pen.Italic(true)
+ case 4: // Underline
+ nextParam, _, ok := params.Param(i+1, 0)
+ if hasMore && ok { // Only accept subparameters i.e. separated by ":"
+ switch nextParam {
+ case 0, 1, 2, 3, 4, 5:
+ i++
+ switch nextParam {
+ case 0: // No Underline
+ pen.UnderlineStyle(NoUnderline)
+ case 1: // Single Underline
+ pen.UnderlineStyle(SingleUnderline)
+ case 2: // Double Underline
+ pen.UnderlineStyle(DoubleUnderline)
+ case 3: // Curly Underline
+ pen.UnderlineStyle(CurlyUnderline)
+ case 4: // Dotted Underline
+ pen.UnderlineStyle(DottedUnderline)
+ case 5: // Dashed Underline
+ pen.UnderlineStyle(DashedUnderline)
+ }
+ }
+ } else {
+ // Single Underline
+ pen.Underline(true)
+ }
+ case 5: // Slow Blink
+ pen.SlowBlink(true)
+ case 6: // Rapid Blink
+ pen.RapidBlink(true)
+ case 7: // Reverse
+ pen.Reverse(true)
+ case 8: // Conceal
+ pen.Conceal(true)
+ case 9: // Crossed-out/Strikethrough
+ pen.Strikethrough(true)
+ case 22: // Normal Intensity (not bold or faint)
+ pen.Bold(false).Faint(false)
+ case 23: // Not italic, not Fraktur
+ pen.Italic(false)
+ case 24: // Not underlined
+ pen.Underline(false)
+ case 25: // Blink off
+ pen.SlowBlink(false).RapidBlink(false)
+ case 27: // Positive (not reverse)
+ pen.Reverse(false)
+ case 28: // Reveal
+ pen.Conceal(false)
+ case 29: // Not crossed out
+ pen.Strikethrough(false)
+ case 30, 31, 32, 33, 34, 35, 36, 37: // Set foreground
+ pen.Foreground(ansi.Black + ansi.BasicColor(param-30)) //nolint:gosec
+ case 38: // Set foreground 256 or truecolor
+ var c color.Color
+ n := ReadStyleColor(params[i:], &c)
+ if n > 0 {
+ pen.Foreground(c)
+ i += n - 1
+ }
+ case 39: // Default foreground
+ pen.Foreground(nil)
+ case 40, 41, 42, 43, 44, 45, 46, 47: // Set background
+ pen.Background(ansi.Black + ansi.BasicColor(param-40)) //nolint:gosec
+ case 48: // Set background 256 or truecolor
+ var c color.Color
+ n := ReadStyleColor(params[i:], &c)
+ if n > 0 {
+ pen.Background(c)
+ i += n - 1
+ }
+ case 49: // Default Background
+ pen.Background(nil)
+ case 58: // Set underline color
+ var c color.Color
+ n := ReadStyleColor(params[i:], &c)
+ if n > 0 {
+ pen.UnderlineColor(c)
+ i += n - 1
+ }
+ case 59: // Default underline color
+ pen.UnderlineColor(nil)
+ case 90, 91, 92, 93, 94, 95, 96, 97: // Set bright foreground
+ pen.Foreground(ansi.BrightBlack + ansi.BasicColor(param-90)) //nolint:gosec
+ case 100, 101, 102, 103, 104, 105, 106, 107: // Set bright background
+ pen.Background(ansi.BrightBlack + ansi.BasicColor(param-100)) //nolint:gosec
+ }
+ }
+}
+
+// ReadLink reads a hyperlink escape sequence from a data buffer.
+func ReadLink(p []byte, link *Link) {
+ params := bytes.Split(p, []byte{';'})
+ if len(params) != 3 {
+ return
+ }
+ link.Params = string(params[1])
+ link.URL = string(params[2])
+}
+
+// ReadStyleColor reads a color from a list of parameters.
+// See [ansi.ReadStyleColor] for more information.
+func ReadStyleColor(params ansi.Params, c *color.Color) int {
+ return ansi.ReadStyleColor(params, c)
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/style.go b/vendor/github.com/charmbracelet/x/cellbuf/style.go
new file mode 100644
index 00000000..82c4afb7
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/style.go
@@ -0,0 +1,31 @@
+package cellbuf
+
+import (
+ "github.com/charmbracelet/colorprofile"
+)
+
+// Convert converts a style to respect the given color profile.
+func ConvertStyle(s Style, p colorprofile.Profile) Style {
+ switch p {
+ case colorprofile.TrueColor:
+ return s
+ case colorprofile.Ascii:
+ s.Fg = nil
+ s.Bg = nil
+ s.Ul = nil
+ case colorprofile.NoTTY:
+ return Style{}
+ }
+
+ if s.Fg != nil {
+ s.Fg = p.Convert(s.Fg)
+ }
+ if s.Bg != nil {
+ s.Bg = p.Convert(s.Bg)
+ }
+ if s.Ul != nil {
+ s.Ul = p.Convert(s.Ul)
+ }
+
+ return s
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/tabstop.go b/vendor/github.com/charmbracelet/x/cellbuf/tabstop.go
new file mode 100644
index 00000000..24eec449
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/tabstop.go
@@ -0,0 +1,137 @@
+package cellbuf
+
+// DefaultTabInterval is the default tab interval.
+const DefaultTabInterval = 8
+
+// TabStops represents horizontal line tab stops.
+type TabStops struct {
+ stops []int
+ interval int
+ width int
+}
+
+// NewTabStops creates a new set of tab stops from a number of columns and an
+// interval.
+func NewTabStops(width, interval int) *TabStops {
+ ts := new(TabStops)
+ ts.interval = interval
+ ts.width = width
+ ts.stops = make([]int, (width+(interval-1))/interval)
+ ts.init(0, width)
+ return ts
+}
+
+// DefaultTabStops creates a new set of tab stops with the default interval.
+func DefaultTabStops(cols int) *TabStops {
+ return NewTabStops(cols, DefaultTabInterval)
+}
+
+// Resize resizes the tab stops to the given width.
+func (ts *TabStops) Resize(width int) {
+ if width == ts.width {
+ return
+ }
+
+ if width < ts.width {
+ size := (width + (ts.interval - 1)) / ts.interval
+ ts.stops = ts.stops[:size]
+ } else {
+ size := (width - ts.width + (ts.interval - 1)) / ts.interval
+ ts.stops = append(ts.stops, make([]int, size)...)
+ }
+
+ ts.init(ts.width, width)
+ ts.width = width
+}
+
+// IsStop returns true if the given column is a tab stop.
+func (ts TabStops) IsStop(col int) bool {
+ mask := ts.mask(col)
+ i := col >> 3
+ if i < 0 || i >= len(ts.stops) {
+ return false
+ }
+ return ts.stops[i]&mask != 0
+}
+
+// Next returns the next tab stop after the given column.
+func (ts TabStops) Next(col int) int {
+ return ts.Find(col, 1)
+}
+
+// Prev returns the previous tab stop before the given column.
+func (ts TabStops) Prev(col int) int {
+ return ts.Find(col, -1)
+}
+
+// Find returns the prev/next tab stop before/after the given column and delta.
+// If delta is positive, it returns the next tab stop after the given column.
+// If delta is negative, it returns the previous tab stop before the given column.
+// If delta is zero, it returns the given column.
+func (ts TabStops) Find(col, delta int) int {
+ if delta == 0 {
+ return col
+ }
+
+ var prev bool
+ count := delta
+ if count < 0 {
+ count = -count
+ prev = true
+ }
+
+ for count > 0 {
+ if !prev {
+ if col >= ts.width-1 {
+ return col
+ }
+
+ col++
+ } else {
+ if col < 1 {
+ return col
+ }
+
+ col--
+ }
+
+ if ts.IsStop(col) {
+ count--
+ }
+ }
+
+ return col
+}
+
+// Set adds a tab stop at the given column.
+func (ts *TabStops) Set(col int) {
+ mask := ts.mask(col)
+ ts.stops[col>>3] |= mask
+}
+
+// Reset removes the tab stop at the given column.
+func (ts *TabStops) Reset(col int) {
+ mask := ts.mask(col)
+ ts.stops[col>>3] &= ^mask
+}
+
+// Clear removes all tab stops.
+func (ts *TabStops) Clear() {
+ ts.stops = make([]int, len(ts.stops))
+}
+
+// mask returns the mask for the given column.
+func (ts *TabStops) mask(col int) int {
+ return 1 << (col & (ts.interval - 1))
+}
+
+// init initializes the tab stops starting from col until width.
+func (ts *TabStops) init(col, width int) {
+ for x := col; x < width; x++ {
+ if x%ts.interval == 0 {
+ ts.Set(x)
+ } else {
+ ts.Reset(x)
+ }
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/utils.go b/vendor/github.com/charmbracelet/x/cellbuf/utils.go
new file mode 100644
index 00000000..b0452fa9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/utils.go
@@ -0,0 +1,38 @@
+package cellbuf
+
+import (
+ "strings"
+)
+
+// Height returns the height of a string.
+func Height(s string) int {
+ return strings.Count(s, "\n") + 1
+}
+
+func min(a, b int) int { //nolint:predeclared
+ if a > b {
+ return b
+ }
+ return a
+}
+
+func max(a, b int) int { //nolint:predeclared
+ if a > b {
+ return a
+ }
+ return b
+}
+
+func clamp(v, low, high int) int {
+ if high < low {
+ low, high = high, low
+ }
+ return min(high, max(low, v))
+}
+
+func abs(a int) int {
+ if a < 0 {
+ return -a
+ }
+ return a
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/wrap.go b/vendor/github.com/charmbracelet/x/cellbuf/wrap.go
new file mode 100644
index 00000000..59a2a337
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/wrap.go
@@ -0,0 +1,178 @@
+package cellbuf
+
+import (
+ "bytes"
+ "unicode"
+ "unicode/utf8"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// Wrap returns a string that is wrapped to the specified limit applying any
+// ANSI escape sequences in the string. It tries to wrap the string at word
+// boundaries, but will break words if necessary.
+//
+// The breakpoints string is a list of characters that are considered
+// breakpoints for word wrapping. A hyphen (-) is always considered a
+// breakpoint.
+//
+// Note: breakpoints must be a string of 1-cell wide rune characters.
+func Wrap(s string, limit int, breakpoints string) string {
+ if len(s) == 0 {
+ return ""
+ }
+
+ if limit < 1 {
+ return s
+ }
+
+ p := ansi.GetParser()
+ defer ansi.PutParser(p)
+
+ var (
+ buf bytes.Buffer
+ word bytes.Buffer
+ space bytes.Buffer
+ style, curStyle Style
+ link, curLink Link
+ curWidth int
+ wordLen int
+ )
+
+ addSpace := func() {
+ curWidth += space.Len()
+ buf.Write(space.Bytes())
+ space.Reset()
+ }
+
+ addWord := func() {
+ if word.Len() == 0 {
+ return
+ }
+
+ curLink = link
+ curStyle = style
+
+ addSpace()
+ curWidth += wordLen
+ buf.Write(word.Bytes())
+ word.Reset()
+ wordLen = 0
+ }
+
+ addNewline := func() {
+ if !curStyle.Empty() {
+ buf.WriteString(ansi.ResetStyle)
+ }
+ if !curLink.Empty() {
+ buf.WriteString(ansi.ResetHyperlink())
+ }
+ buf.WriteByte('\n')
+ if !curLink.Empty() {
+ buf.WriteString(ansi.SetHyperlink(curLink.URL, curLink.Params))
+ }
+ if !curStyle.Empty() {
+ buf.WriteString(curStyle.Sequence())
+ }
+ curWidth = 0
+ space.Reset()
+ }
+
+ var state byte
+ for len(s) > 0 {
+ seq, width, n, newState := ansi.DecodeSequence(s, state, p)
+ switch width {
+ case 0:
+ if ansi.Equal(seq, "\t") {
+ addWord()
+ space.WriteString(seq)
+ break
+ } else if ansi.Equal(seq, "\n") {
+ if wordLen == 0 {
+ if curWidth+space.Len() > limit {
+ curWidth = 0
+ } else {
+ // preserve whitespaces
+ buf.Write(space.Bytes())
+ }
+ space.Reset()
+ }
+
+ addWord()
+ addNewline()
+ break
+ } else if ansi.HasCsiPrefix(seq) && p.Command() == 'm' {
+ // SGR style sequence [ansi.SGR]
+ ReadStyle(p.Params(), &style)
+ } else if ansi.HasOscPrefix(seq) && p.Command() == 8 {
+ // Hyperlink sequence [ansi.SetHyperlink]
+ ReadLink(p.Data(), &link)
+ }
+
+ word.WriteString(seq)
+ default:
+ if len(seq) == 1 {
+ // ASCII
+ r, _ := utf8.DecodeRuneInString(seq)
+ if unicode.IsSpace(r) {
+ addWord()
+ space.WriteRune(r)
+ break
+ } else if r == '-' || runeContainsAny(r, breakpoints) {
+ addSpace()
+ if curWidth+wordLen+width <= limit {
+ addWord()
+ buf.WriteString(seq)
+ curWidth += width
+ break
+ }
+ }
+ }
+
+ if wordLen+width > limit {
+ // Hardwrap the word if it's too long
+ addWord()
+ }
+
+ word.WriteString(seq)
+ wordLen += width
+
+ if curWidth+wordLen+space.Len() > limit {
+ addNewline()
+ }
+ }
+
+ s = s[n:]
+ state = newState
+ }
+
+ if wordLen == 0 {
+ if curWidth+space.Len() > limit {
+ curWidth = 0
+ } else {
+ // preserve whitespaces
+ buf.Write(space.Bytes())
+ }
+ space.Reset()
+ }
+
+ addWord()
+
+ if !curLink.Empty() {
+ buf.WriteString(ansi.ResetHyperlink())
+ }
+ if !curStyle.Empty() {
+ buf.WriteString(ansi.ResetStyle)
+ }
+
+ return buf.String()
+}
+
+func runeContainsAny[T string | []rune](r rune, s T) bool {
+ for _, c := range []rune(s) {
+ if c == r {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/charmbracelet/x/cellbuf/writer.go b/vendor/github.com/charmbracelet/x/cellbuf/writer.go
new file mode 100644
index 00000000..ae8b2a81
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/cellbuf/writer.go
@@ -0,0 +1,339 @@
+package cellbuf
+
+import (
+ "bytes"
+ "fmt"
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// CellBuffer is a cell buffer that represents a set of cells in a screen or a
+// grid.
+type CellBuffer interface {
+ // Cell returns the cell at the given position.
+ Cell(x, y int) *Cell
+ // SetCell sets the cell at the given position to the given cell. It
+ // returns whether the cell was set successfully.
+ SetCell(x, y int, c *Cell) bool
+ // Bounds returns the bounds of the cell buffer.
+ Bounds() Rectangle
+}
+
+// FillRect fills the rectangle within the cell buffer with the given cell.
+// This will not fill cells outside the bounds of the cell buffer.
+func FillRect(s CellBuffer, c *Cell, rect Rectangle) {
+ for y := rect.Min.Y; y < rect.Max.Y; y++ {
+ for x := rect.Min.X; x < rect.Max.X; x++ {
+ s.SetCell(x, y, c) //nolint:errcheck
+ }
+ }
+}
+
+// Fill fills the cell buffer with the given cell.
+func Fill(s CellBuffer, c *Cell) {
+ FillRect(s, c, s.Bounds())
+}
+
+// ClearRect clears the rectangle within the cell buffer with blank cells.
+func ClearRect(s CellBuffer, rect Rectangle) {
+ FillRect(s, nil, rect)
+}
+
+// Clear clears the cell buffer with blank cells.
+func Clear(s CellBuffer) {
+ Fill(s, nil)
+}
+
+// SetContentRect clears the rectangle within the cell buffer with blank cells,
+// and sets the given string as its content. If the height or width of the
+// string exceeds the height or width of the cell buffer, it will be truncated.
+func SetContentRect(s CellBuffer, str string, rect Rectangle) {
+ // Replace all "\n" with "\r\n" to ensure the cursor is reset to the start
+ // of the line. Make sure we don't replace "\r\n" with "\r\r\n".
+ str = strings.ReplaceAll(str, "\r\n", "\n")
+ str = strings.ReplaceAll(str, "\n", "\r\n")
+ ClearRect(s, rect)
+ printString(s, ansi.GraphemeWidth, rect.Min.X, rect.Min.Y, rect, str, true, "")
+}
+
+// SetContent clears the cell buffer with blank cells, and sets the given string
+// as its content. If the height or width of the string exceeds the height or
+// width of the cell buffer, it will be truncated.
+func SetContent(s CellBuffer, str string) {
+ SetContentRect(s, str, s.Bounds())
+}
+
+// Render returns a string representation of the grid with ANSI escape sequences.
+func Render(d CellBuffer) string {
+ var buf bytes.Buffer
+ height := d.Bounds().Dy()
+ for y := 0; y < height; y++ {
+ _, line := RenderLine(d, y)
+ buf.WriteString(line)
+ if y < height-1 {
+ buf.WriteString("\r\n")
+ }
+ }
+ return buf.String()
+}
+
+// RenderLine returns a string representation of the yth line of the grid along
+// with the width of the line.
+func RenderLine(d CellBuffer, n int) (w int, line string) {
+ var pen Style
+ var link Link
+ var buf bytes.Buffer
+ var pendingLine string
+ var pendingWidth int // this ignores space cells until we hit a non-space cell
+
+ writePending := func() {
+ // If there's no pending line, we don't need to do anything.
+ if len(pendingLine) == 0 {
+ return
+ }
+ buf.WriteString(pendingLine)
+ w += pendingWidth
+ pendingWidth = 0
+ pendingLine = ""
+ }
+
+ for x := 0; x < d.Bounds().Dx(); x++ {
+ if cell := d.Cell(x, n); cell != nil && cell.Width > 0 {
+ // Convert the cell's style and link to the given color profile.
+ cellStyle := cell.Style
+ cellLink := cell.Link
+ if cellStyle.Empty() && !pen.Empty() {
+ writePending()
+ buf.WriteString(ansi.ResetStyle) //nolint:errcheck
+ pen.Reset()
+ }
+ if !cellStyle.Equal(&pen) {
+ writePending()
+ seq := cellStyle.DiffSequence(pen)
+ buf.WriteString(seq) // nolint:errcheck
+ pen = cellStyle
+ }
+
+ // Write the URL escape sequence
+ if cellLink != link && link.URL != "" {
+ writePending()
+ buf.WriteString(ansi.ResetHyperlink()) //nolint:errcheck
+ link.Reset()
+ }
+ if cellLink != link {
+ writePending()
+ buf.WriteString(ansi.SetHyperlink(cellLink.URL, cellLink.Params)) //nolint:errcheck
+ link = cellLink
+ }
+
+ // We only write the cell content if it's not empty. If it is, we
+ // append it to the pending line and width to be evaluated later.
+ if cell.Equal(&BlankCell) {
+ pendingLine += cell.String()
+ pendingWidth += cell.Width
+ } else {
+ writePending()
+ buf.WriteString(cell.String())
+ w += cell.Width
+ }
+ }
+ }
+ if link.URL != "" {
+ buf.WriteString(ansi.ResetHyperlink()) //nolint:errcheck
+ }
+ if !pen.Empty() {
+ buf.WriteString(ansi.ResetStyle) //nolint:errcheck
+ }
+ return w, strings.TrimRight(buf.String(), " ") // Trim trailing spaces
+}
+
+// ScreenWriter represents a writer that writes to a [Screen] parsing ANSI
+// escape sequences and Unicode characters and converting them into cells that
+// can be written to a cell [Buffer].
+type ScreenWriter struct {
+ *Screen
+}
+
+// NewScreenWriter creates a new ScreenWriter that writes to the given Screen.
+// This is a convenience function for creating a ScreenWriter.
+func NewScreenWriter(s *Screen) *ScreenWriter {
+ return &ScreenWriter{s}
+}
+
+// Write writes the given bytes to the screen.
+// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape
+// sequences.
+func (s *ScreenWriter) Write(p []byte) (n int, err error) {
+ printString(s.Screen, s.method,
+ s.cur.X, s.cur.Y, s.Bounds(),
+ p, false, "")
+ return len(p), nil
+}
+
+// SetContent clears the screen with blank cells, and sets the given string as
+// its content. If the height or width of the string exceeds the height or
+// width of the screen, it will be truncated.
+//
+// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape sequences.
+func (s *ScreenWriter) SetContent(str string) {
+ s.SetContentRect(str, s.Bounds())
+}
+
+// SetContentRect clears the rectangle within the screen with blank cells, and
+// sets the given string as its content. If the height or width of the string
+// exceeds the height or width of the screen, it will be truncated.
+//
+// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape
+// sequences.
+func (s *ScreenWriter) SetContentRect(str string, rect Rectangle) {
+ // Replace all "\n" with "\r\n" to ensure the cursor is reset to the start
+ // of the line. Make sure we don't replace "\r\n" with "\r\r\n".
+ str = strings.ReplaceAll(str, "\r\n", "\n")
+ str = strings.ReplaceAll(str, "\n", "\r\n")
+ s.ClearRect(rect)
+ printString(s.Screen, s.method,
+ rect.Min.X, rect.Min.Y, rect,
+ str, true, "")
+}
+
+// Print prints the string at the current cursor position. It will wrap the
+// string to the width of the screen if it exceeds the width of the screen.
+// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape
+// sequences.
+func (s *ScreenWriter) Print(str string, v ...interface{}) {
+ if len(v) > 0 {
+ str = fmt.Sprintf(str, v...)
+ }
+ printString(s.Screen, s.method,
+ s.cur.X, s.cur.Y, s.Bounds(),
+ str, false, "")
+}
+
+// PrintAt prints the string at the given position. It will wrap the string to
+// the width of the screen if it exceeds the width of the screen.
+// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape
+// sequences.
+func (s *ScreenWriter) PrintAt(x, y int, str string, v ...interface{}) {
+ if len(v) > 0 {
+ str = fmt.Sprintf(str, v...)
+ }
+ printString(s.Screen, s.method,
+ x, y, s.Bounds(),
+ str, false, "")
+}
+
+// PrintCrop prints the string at the current cursor position and truncates the
+// text if it exceeds the width of the screen. Use tail to specify a string to
+// append if the string is truncated.
+// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape
+// sequences.
+func (s *ScreenWriter) PrintCrop(str string, tail string) {
+ printString(s.Screen, s.method,
+ s.cur.X, s.cur.Y, s.Bounds(),
+ str, true, tail)
+}
+
+// PrintCropAt prints the string at the given position and truncates the text
+// if it exceeds the width of the screen. Use tail to specify a string to append
+// if the string is truncated.
+// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape
+// sequences.
+func (s *ScreenWriter) PrintCropAt(x, y int, str string, tail string) {
+ printString(s.Screen, s.method,
+ x, y, s.Bounds(),
+ str, true, tail)
+}
+
+// printString draws a string starting at the given position.
+func printString[T []byte | string](
+ s CellBuffer,
+ m ansi.Method,
+ x, y int,
+ bounds Rectangle, str T,
+ truncate bool, tail string,
+) {
+ p := ansi.GetParser()
+ defer ansi.PutParser(p)
+
+ var tailc Cell
+ if truncate && len(tail) > 0 {
+ if m == ansi.WcWidth {
+ tailc = *NewCellString(tail)
+ } else {
+ tailc = *NewGraphemeCell(tail)
+ }
+ }
+
+ decoder := ansi.DecodeSequenceWc[T]
+ if m == ansi.GraphemeWidth {
+ decoder = ansi.DecodeSequence[T]
+ }
+
+ var cell Cell
+ var style Style
+ var link Link
+ var state byte
+ for len(str) > 0 {
+ seq, width, n, newState := decoder(str, state, p)
+
+ switch width {
+ case 1, 2, 3, 4: // wide cells can go up to 4 cells wide
+ cell.Width += width
+ cell.Append([]rune(string(seq))...)
+
+ if !truncate && x+cell.Width > bounds.Max.X && y+1 < bounds.Max.Y {
+ // Wrap the string to the width of the window
+ x = bounds.Min.X
+ y++
+ }
+ if Pos(x, y).In(bounds) {
+ if truncate && tailc.Width > 0 && x+cell.Width > bounds.Max.X-tailc.Width {
+ // Truncate the string and append the tail if any.
+ cell := tailc
+ cell.Style = style
+ cell.Link = link
+ s.SetCell(x, y, &cell)
+ x += tailc.Width
+ } else {
+ // Print the cell to the screen
+ cell.Style = style
+ cell.Link = link
+ s.SetCell(x, y, &cell) //nolint:errcheck
+ x += width
+ }
+ }
+
+ // String is too long for the line, truncate it.
+ // Make sure we reset the cell for the next iteration.
+ cell.Reset()
+ default:
+ // Valid sequences always have a non-zero Cmd.
+ // TODO: Handle cursor movement and other sequences
+ switch {
+ case ansi.HasCsiPrefix(seq) && p.Command() == 'm':
+ // SGR - Select Graphic Rendition
+ ReadStyle(p.Params(), &style)
+ case ansi.HasOscPrefix(seq) && p.Command() == 8:
+ // Hyperlinks
+ ReadLink(p.Data(), &link)
+ case ansi.Equal(seq, T("\n")):
+ y++
+ case ansi.Equal(seq, T("\r")):
+ x = bounds.Min.X
+ default:
+ cell.Append([]rune(string(seq))...)
+ }
+ }
+
+ // Advance the state and data
+ state = newState
+ str = str[n:]
+ }
+
+ // Make sure to set the last cell if it's not empty.
+ if !cell.Empty() {
+ s.SetCell(x, y, &cell) //nolint:errcheck
+ cell.Reset()
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/term/LICENSE b/vendor/github.com/charmbracelet/x/term/LICENSE
new file mode 100644
index 00000000..65a5654e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Charmbracelet, Inc.
+
+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.
diff --git a/vendor/github.com/charmbracelet/x/term/term.go b/vendor/github.com/charmbracelet/x/term/term.go
new file mode 100644
index 00000000..58d6522c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term.go
@@ -0,0 +1,49 @@
+package term
+
+// State contains platform-specific state of a terminal.
+type State struct {
+ state
+}
+
+// IsTerminal returns whether the given file descriptor is a terminal.
+func IsTerminal(fd uintptr) bool {
+ return isTerminal(fd)
+}
+
+// MakeRaw puts the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd uintptr) (*State, error) {
+ return makeRaw(fd)
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd uintptr) (*State, error) {
+ return getState(fd)
+}
+
+// SetState sets the given state of the terminal.
+func SetState(fd uintptr, state *State) error {
+ return setState(fd, state)
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd uintptr, oldState *State) error {
+ return restore(fd, oldState)
+}
+
+// GetSize returns the visible dimensions of the given terminal.
+//
+// These dimensions don't include any scrollback buffer height.
+func GetSize(fd uintptr) (width, height int, err error) {
+ return getSize(fd)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo. This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd uintptr) ([]byte, error) {
+ return readPassword(fd)
+}
diff --git a/vendor/github.com/charmbracelet/x/term/term_other.go b/vendor/github.com/charmbracelet/x/term/term_other.go
new file mode 100644
index 00000000..092c7e9d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_other.go
@@ -0,0 +1,39 @@
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !zos && !windows && !solaris && !plan9
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!zos,!windows,!solaris,!plan9
+
+package term
+
+import (
+ "fmt"
+ "runtime"
+)
+
+type state struct{}
+
+func isTerminal(fd uintptr) bool {
+ return false
+}
+
+func makeRaw(fd uintptr) (*State, error) {
+ return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getState(fd uintptr) (*State, error) {
+ return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func restore(fd uintptr, state *State) error {
+ return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getSize(fd uintptr) (width, height int, err error) {
+ return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func setState(fd uintptr, state *State) error {
+ return fmt.Errorf("terminal: SetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func readPassword(fd uintptr) ([]byte, error) {
+ return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
diff --git a/vendor/github.com/charmbracelet/x/term/term_unix.go b/vendor/github.com/charmbracelet/x/term/term_unix.go
new file mode 100644
index 00000000..1459cb1b
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_unix.go
@@ -0,0 +1,96 @@
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package term
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+type state struct {
+ unix.Termios
+}
+
+func isTerminal(fd uintptr) bool {
+ _, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ return err == nil
+}
+
+func makeRaw(fd uintptr) (*State, error) {
+ termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ if err != nil {
+ return nil, err
+ }
+
+ oldState := State{state{Termios: *termios}}
+
+ // This attempts to replicate the behaviour documented for cfmakeraw in
+ // the termios(3) manpage.
+ termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
+ termios.Oflag &^= unix.OPOST
+ termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
+ termios.Cflag &^= unix.CSIZE | unix.PARENB
+ termios.Cflag |= unix.CS8
+ termios.Cc[unix.VMIN] = 1
+ termios.Cc[unix.VTIME] = 0
+ if err := unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios); err != nil {
+ return nil, err
+ }
+
+ return &oldState, nil
+}
+
+func setState(fd uintptr, state *State) error {
+ var termios *unix.Termios
+ if state != nil {
+ termios = &state.Termios
+ }
+ return unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios)
+}
+
+func getState(fd uintptr) (*State, error) {
+ termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ if err != nil {
+ return nil, err
+ }
+
+ return &State{state{Termios: *termios}}, nil
+}
+
+func restore(fd uintptr, state *State) error {
+ return unix.IoctlSetTermios(int(fd), ioctlWriteTermios, &state.Termios)
+}
+
+func getSize(fd uintptr) (width, height int, err error) {
+ ws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ)
+ if err != nil {
+ return 0, 0, err
+ }
+ return int(ws.Col), int(ws.Row), nil
+}
+
+// passwordReader is an io.Reader that reads from a specific file descriptor.
+type passwordReader int
+
+func (r passwordReader) Read(buf []byte) (int, error) {
+ return unix.Read(int(r), buf)
+}
+
+func readPassword(fd uintptr) ([]byte, error) {
+ termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ if err != nil {
+ return nil, err
+ }
+
+ newState := *termios
+ newState.Lflag &^= unix.ECHO
+ newState.Lflag |= unix.ICANON | unix.ISIG
+ newState.Iflag |= unix.ICRNL
+ if err := unix.IoctlSetTermios(int(fd), ioctlWriteTermios, &newState); err != nil {
+ return nil, err
+ }
+
+ defer unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios)
+
+ return readPasswordLine(passwordReader(fd))
+}
diff --git a/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go b/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go
new file mode 100644
index 00000000..b435031a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go
@@ -0,0 +1,11 @@
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package term
+
+import "golang.org/x/sys/unix"
+
+const (
+ ioctlReadTermios = unix.TIOCGETA
+ ioctlWriteTermios = unix.TIOCSETA
+)
diff --git a/vendor/github.com/charmbracelet/x/term/term_unix_other.go b/vendor/github.com/charmbracelet/x/term/term_unix_other.go
new file mode 100644
index 00000000..ee2a29eb
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_unix_other.go
@@ -0,0 +1,11 @@
+//go:build aix || linux || solaris || zos
+// +build aix linux solaris zos
+
+package term
+
+import "golang.org/x/sys/unix"
+
+const (
+ ioctlReadTermios = unix.TCGETS
+ ioctlWriteTermios = unix.TCSETS
+)
diff --git a/vendor/github.com/charmbracelet/x/term/term_windows.go b/vendor/github.com/charmbracelet/x/term/term_windows.go
new file mode 100644
index 00000000..fe7afdec
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_windows.go
@@ -0,0 +1,87 @@
+//go:build windows
+// +build windows
+
+package term
+
+import (
+ "os"
+
+ "golang.org/x/sys/windows"
+)
+
+type state struct {
+ Mode uint32
+}
+
+func isTerminal(fd uintptr) bool {
+ var st uint32
+ err := windows.GetConsoleMode(windows.Handle(fd), &st)
+ return err == nil
+}
+
+func makeRaw(fd uintptr) (*State, error) {
+ var st uint32
+ if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+ return nil, err
+ }
+ raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
+ raw |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT
+ if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
+ return nil, err
+ }
+ return &State{state{st}}, nil
+}
+
+func setState(fd uintptr, state *State) error {
+ var mode uint32
+ if state != nil {
+ mode = state.Mode
+ }
+ return windows.SetConsoleMode(windows.Handle(fd), mode)
+}
+
+func getState(fd uintptr) (*State, error) {
+ var st uint32
+ if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+ return nil, err
+ }
+ return &State{state{st}}, nil
+}
+
+func restore(fd uintptr, state *State) error {
+ return windows.SetConsoleMode(windows.Handle(fd), state.Mode)
+}
+
+func getSize(fd uintptr) (width, height int, err error) {
+ var info windows.ConsoleScreenBufferInfo
+ if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
+ return 0, 0, err
+ }
+ return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil
+}
+
+func readPassword(fd uintptr) ([]byte, error) {
+ var st uint32
+ if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+ return nil, err
+ }
+ old := st
+
+ st &^= (windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT)
+ st |= (windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_PROCESSED_INPUT)
+ if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
+ return nil, err
+ }
+
+ defer windows.SetConsoleMode(windows.Handle(fd), old)
+
+ var h windows.Handle
+ p, _ := windows.GetCurrentProcess()
+ if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil {
+ return nil, err
+ }
+
+ f := os.NewFile(uintptr(h), "stdin")
+ defer f.Close()
+ return readPasswordLine(f)
+}
diff --git a/vendor/github.com/charmbracelet/x/term/terminal.go b/vendor/github.com/charmbracelet/x/term/terminal.go
new file mode 100644
index 00000000..8963163f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/terminal.go
@@ -0,0 +1,12 @@
+package term
+
+import (
+ "io"
+)
+
+// File represents a file that has a file descriptor and can be read from,
+// written to, and closed.
+type File interface {
+ io.ReadWriteCloser
+ Fd() uintptr
+}
diff --git a/vendor/github.com/charmbracelet/x/term/util.go b/vendor/github.com/charmbracelet/x/term/util.go
new file mode 100644
index 00000000..b7313418
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/util.go
@@ -0,0 +1,47 @@
+package term
+
+import (
+ "io"
+ "runtime"
+)
+
+// readPasswordLine reads from reader until it finds \n or io.EOF.
+// The slice returned does not include the \n.
+// readPasswordLine also ignores any \r it finds.
+// Windows uses \r as end of line. So, on Windows, readPasswordLine
+// reads until it finds \r and ignores any \n it finds during processing.
+func readPasswordLine(reader io.Reader) ([]byte, error) {
+ var buf [1]byte
+ var ret []byte
+
+ for {
+ n, err := reader.Read(buf[:])
+ if n > 0 {
+ switch buf[0] {
+ case '\b':
+ if len(ret) > 0 {
+ ret = ret[:len(ret)-1]
+ }
+ case '\n':
+ if runtime.GOOS != "windows" {
+ return ret, nil
+ }
+ // otherwise ignore \n
+ case '\r':
+ if runtime.GOOS == "windows" {
+ return ret, nil
+ }
+ // otherwise ignore \r
+ default:
+ ret = append(ret, buf[0])
+ }
+ continue
+ }
+ if err != nil {
+ if err == io.EOF && len(ret) > 0 {
+ return ret, nil
+ }
+ return ret, err
+ }
+ }
+}
diff --git a/vendor/github.com/ckaznocha/intrange/.golangci.yml b/vendor/github.com/ckaznocha/intrange/.golangci.yml
index b240f85c..74a80105 100644
--- a/vendor/github.com/ckaznocha/intrange/.golangci.yml
+++ b/vendor/github.com/ckaznocha/intrange/.golangci.yml
@@ -15,6 +15,7 @@ linters-settings:
local-prefixes: github.com/ckaznocha/intrange
govet:
enable:
+ - appends
- asmdecl
- assign
- atomic
@@ -22,10 +23,11 @@ linters-settings:
- bools
- buildtag
- cgocall
- - composite
- - copylock
- - copyloopvar
+ - composites
+ - copylocks
- deepequalerrors
+ - defers
+ - directive
- errorsas
- fieldalignment
- findcall
@@ -37,18 +39,25 @@ linters-settings:
- nilfunc
- nilness
- printf
+ - reflectvaluecompare
- shadow
- shift
+ - sigchanyzer
+ - slog
- sortslice
- stdmethods
+ - stdversion
- stringintconv
- structtag
- testinggoroutine
- tests
+ - timeformat
- unmarshal
- unreachable
- unsafeptr
- unusedresult
+ - unusedwrite
+ - waitgroup
misspell:
locale: US
linters:
diff --git a/vendor/github.com/ckaznocha/intrange/intrange.go b/vendor/github.com/ckaznocha/intrange/intrange.go
index 229c847d..79aca797 100644
--- a/vendor/github.com/ckaznocha/intrange/intrange.go
+++ b/vendor/github.com/ckaznocha/intrange/intrange.go
@@ -265,6 +265,15 @@ func checkForStmt(pass *analysis.Pass, forStmt *ast.ForStmt) {
replacement = fmt.Sprintf("range %s", rangeX)
}
+ if isFunctionOrMethodCall(operand) {
+ pass.Report(analysis.Diagnostic{
+ Pos: forStmt.Pos(),
+ Message: msg + "\nBecause the key is returned by a function or method, take care to consider side effects.",
+ })
+
+ return
+ }
+
pass.Report(analysis.Diagnostic{
Pos: forStmt.Pos(),
Message: msg,
@@ -315,12 +324,11 @@ func checkRangeStmt(pass *analysis.Pass, rangeStmt *ast.RangeStmt) {
return
}
- fn, ok := x.Fun.(*ast.Ident)
- if !ok {
+ if _, ok = x.Fun.(*ast.Ident); !ok {
return
}
- if fn.Name != "len" || len(x.Args) != 1 {
+ if !isLen(x) {
return
}
@@ -385,7 +393,7 @@ func checkRangeStmt(pass *analysis.Pass, rangeStmt *ast.RangeStmt) {
func findNExpr(expr ast.Expr) ast.Expr {
switch e := expr.(type) {
case *ast.CallExpr:
- if fun, ok := e.Fun.(*ast.Ident); ok && fun.Name == "len" && len(e.Args) == 1 {
+ if isLen(e) {
return findNExpr(e.Args[0])
}
@@ -439,6 +447,8 @@ func recursiveOperandToString(
return recursiveOperandToString(e.X, false) + "[" + recursiveOperandToString(e.Index, false) + "]"
case *ast.BinaryExpr:
return recursiveOperandToString(e.X, false) + " " + e.Op.String() + " " + recursiveOperandToString(e.Y, false)
+ case *ast.StarExpr:
+ return "*" + recursiveOperandToString(e.X, false)
default:
return ""
}
@@ -526,19 +536,7 @@ func isNumberLit(exp ast.Expr) bool {
case *ast.CallExpr:
switch fun := lit.Fun.(type) {
case *ast.Ident:
- switch fun.Name {
- case
- "int",
- "int8",
- "int16",
- "int32",
- "int64",
- "uint",
- "uint8",
- "uint16",
- "uint32",
- "uint64":
- default:
+ if !isIntCast(fun) {
return false
}
default:
@@ -573,19 +571,7 @@ func compareNumberLit(exp ast.Expr, val int) bool {
case *ast.CallExpr:
switch fun := lit.Fun.(type) {
case *ast.Ident:
- switch fun.Name {
- case
- "int",
- "int8",
- "int16",
- "int32",
- "int64",
- "uint",
- "uint8",
- "uint16",
- "uint32",
- "uint64":
- default:
+ if !isIntCast(fun) {
return false
}
default:
@@ -623,5 +609,58 @@ func operandToString(
return s
}
+ if operandIdent, ok := operand.(*ast.Ident); ok {
+ if operandType := pass.TypesInfo.TypeOf(operandIdent); operandType != nil &&
+ operandType == t {
+ return s
+ }
+ }
+
return t.String() + "(" + s + ")"
}
+
+func isFunctionOrMethodCall(expr ast.Expr) bool {
+ e, ok := expr.(*ast.CallExpr)
+ if !ok {
+ return false
+ }
+
+ fun, ok := e.Fun.(*ast.Ident)
+ if !ok {
+ return true
+ }
+
+ if isLen(e) || isIntCast(fun) {
+ return false
+ }
+
+ return true
+}
+
+func isIntCast(ident *ast.Ident) bool {
+ switch ident.Name {
+ case
+ "int",
+ "int8",
+ "int16",
+ "int32",
+ "int64",
+ "uint",
+ "uint8",
+ "uint16",
+ "uint32",
+ "uint64":
+ return true
+ default:
+ return false
+ }
+}
+
+func isLen(exp *ast.CallExpr) bool {
+ fun, ok := exp.Fun.(*ast.Ident)
+ if !ok {
+ return false
+ }
+
+ return fun.Name == "len" && len(exp.Args) == 1
+}
diff --git a/vendor/github.com/daixiang0/gci/pkg/section/standard_list.go b/vendor/github.com/daixiang0/gci/pkg/section/standard_list.go
index 5a2dcdc8..2fddded7 100644
--- a/vendor/github.com/daixiang0/gci/pkg/section/standard_list.go
+++ b/vendor/github.com/daixiang0/gci/pkg/section/standard_list.go
@@ -1,6 +1,6 @@
package section
-// Code generated based on go1.23.0 X:boringcrypto,arenas. DO NOT EDIT.
+// Code generated based on go1.24.0 X:boringcrypto,arenas,synctest. DO NOT EDIT.
var standardPackages = map[string]struct{}{
"archive/tar": {},
@@ -28,13 +28,18 @@ var standardPackages = map[string]struct{}{
"crypto/ecdsa": {},
"crypto/ed25519": {},
"crypto/elliptic": {},
+ "crypto/fips140": {},
+ "crypto/hkdf": {},
"crypto/hmac": {},
"crypto/md5": {},
+ "crypto/mlkem": {},
+ "crypto/pbkdf2": {},
"crypto/rand": {},
"crypto/rc4": {},
"crypto/rsa": {},
"crypto/sha1": {},
"crypto/sha256": {},
+ "crypto/sha3": {},
"crypto/sha512": {},
"crypto/subtle": {},
"crypto/tls": {},
@@ -161,6 +166,7 @@ var standardPackages = map[string]struct{}{
"testing/iotest": {},
"testing/quick": {},
"testing/slogtest": {},
+ "testing/synctest": {},
"text/scanner": {},
"text/tabwriter": {},
"text/template": {},
@@ -172,4 +178,5 @@ var standardPackages = map[string]struct{}{
"unicode/utf8": {},
"unique": {},
"unsafe": {},
+ "weak": {},
}
diff --git a/vendor/github.com/dave/dst/.gitignore b/vendor/github.com/dave/dst/.gitignore
new file mode 100644
index 00000000..5a391e10
--- /dev/null
+++ b/vendor/github.com/dave/dst/.gitignore
@@ -0,0 +1,4 @@
+*.iml
+.DS_Store
+.idea/
+coverage.out
diff --git a/vendor/github.com/dave/dst/.travis.yml b/vendor/github.com/dave/dst/.travis.yml
new file mode 100644
index 00000000..f2af0532
--- /dev/null
+++ b/vendor/github.com/dave/dst/.travis.yml
@@ -0,0 +1,15 @@
+language: go
+go:
+ - 1.x
+notificaitons:
+ email:
+ recipients: dave@brophy.uk
+ on_failure: always
+install:
+# - go get -u github.com/dave/courtney
+ - go get -t -v ./...
+script:
+ - go test ./...
+# - courtney -v -timeout 20m
+#after_success:
+# - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/dave/dst/LICENSE b/vendor/github.com/dave/dst/LICENSE
new file mode 100644
index 00000000..95bfa5be
--- /dev/null
+++ b/vendor/github.com/dave/dst/LICENSE
@@ -0,0 +1,51 @@
+MIT License
+
+Copyright (c) 2018 David Brophy
+
+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.
+
+This package was forked from https://github.com/golang/go/tree/master/src/go/ast - original license:
+
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/vendor/github.com/dave/dst/README.md b/vendor/github.com/dave/dst/README.md
new file mode 100644
index 00000000..337781b8
--- /dev/null
+++ b/vendor/github.com/dave/dst/README.md
@@ -0,0 +1,706 @@
+[](https://travis-ci.org/dave/dst)
+[](https://godoc.org/github.com/dave/dst/decorator)
+[](https://codecov.io/gh/dave/dst)
+
+[](https://sourcegraph.com/github.com/dave/dst?badge)
+
+# Decorated Syntax Tree
+
+The `dst` package enables manipulation of a Go syntax tree with high fidelity. Decorations (e.g.
+comments and line spacing) remain attached to the correct nodes as the tree is modified.
+
+## Where does `go/ast` break?
+
+The `go/ast` package wasn't created with source manipulation as an intended use-case. Comments are
+stored by their byte offset instead of attached to nodes, so re-arranging nodes breaks the output.
+See [this Go issue](https://github.com/golang/go/issues/20744) for more information.
+
+Consider this example where we want to reverse the order of the two statements. As you can see the
+comments don't remain attached to the correct nodes:
+
+```go
+code := `package a
+
+func main(){
+ var a int // foo
+ var b string // bar
+}
+`
+fset := token.NewFileSet()
+f, err := parser.ParseFile(fset, "", code, parser.ParseComments)
+if err != nil {
+ panic(err)
+}
+
+list := f.Decls[0].(*ast.FuncDecl).Body.List
+list[0], list[1] = list[1], list[0]
+
+if err := format.Node(os.Stdout, fset, f); err != nil {
+ panic(err)
+}
+
+//Output:
+//package a
+//
+//func main() {
+// // foo
+// var b string
+// var a int
+// // bar
+//}
+```
+
+Here's the same example using `dst`:
+
+```go
+code := `package a
+
+func main(){
+ var a int // foo
+ var b string // bar
+}
+`
+f, err := decorator.Parse(code)
+if err != nil {
+ panic(err)
+}
+
+list := f.Decls[0].(*dst.FuncDecl).Body.List
+list[0], list[1] = list[1], list[0]
+
+if err := decorator.Print(f); err != nil {
+ panic(err)
+}
+
+//Output:
+//package a
+//
+//func main() {
+// var b string // bar
+// var a int // foo
+//}
+```
+
+## Usage
+
+Parsing a source file to `dst` and printing the results after modification can be accomplished with
+several `Parse` and `Print` convenience functions in the [decorator](https://godoc.org/github.com/dave/dst/decorator)
+package.
+
+For more fine-grained control you can use [Decorator](https://godoc.org/github.com/dave/dst/decorator#Decorator)
+to convert from `ast` to `dst`, and [Restorer](https://godoc.org/github.com/dave/dst/decorator#Restorer)
+to convert back again.
+
+### Comments
+
+Comments are added at decoration attachment points. [See here](https://github.com/dave/dst/blob/master/decorations-types-generated.go)
+for a full list of these points, along with demonstration code of where they are rendered in the
+output.
+
+The decoration attachment points have convenience functions `Append`, `Prepend`, `Replace`, `Clear`
+and `All` to accomplish common tasks. Use the full text of your comment including the `//` or `/**/`
+markers. When adding a line comment, a newline is automatically rendered.
+
+```go
+code := `package main
+
+func main() {
+ println("Hello World!")
+}`
+f, err := decorator.Parse(code)
+if err != nil {
+ panic(err)
+}
+
+call := f.Decls[0].(*dst.FuncDecl).Body.List[0].(*dst.ExprStmt).X.(*dst.CallExpr)
+
+call.Decs.Start.Append("// you can add comments at the start...")
+call.Decs.Fun.Append("/* ...in the middle... */")
+call.Decs.End.Append("// or at the end.")
+
+if err := decorator.Print(f); err != nil {
+ panic(err)
+}
+
+//Output:
+//package main
+//
+//func main() {
+// // you can add comments at the start...
+// println /* ...in the middle... */ ("Hello World!") // or at the end.
+//}
+```
+
+### Spacing
+
+The `Before` property marks the node as having a line space (new line or empty line) before the node.
+These spaces are rendered before any decorations attached to the `Start` decoration point. The `After`
+property is similar but rendered after the node (and after any `End` decorations).
+
+```go
+code := `package main
+
+func main() {
+ println(a, b, c)
+}`
+f, err := decorator.Parse(code)
+if err != nil {
+ panic(err)
+}
+
+call := f.Decls[0].(*dst.FuncDecl).Body.List[0].(*dst.ExprStmt).X.(*dst.CallExpr)
+
+call.Decs.Before = dst.EmptyLine
+call.Decs.After = dst.EmptyLine
+
+for _, v := range call.Args {
+ v := v.(*dst.Ident)
+ v.Decs.Before = dst.NewLine
+ v.Decs.After = dst.NewLine
+}
+
+if err := decorator.Print(f); err != nil {
+ panic(err)
+}
+
+//Output:
+//package main
+//
+//func main() {
+//
+// println(
+// a,
+// b,
+// c,
+// )
+//
+//}
+```
+
+### Decorations
+
+The common decoration properties (`Start`, `End`, `Before` and `After`) occur on all nodes, and can be
+accessed with the `Decorations()` method on the `Node` interface:
+
+```go
+code := `package main
+
+func main() {
+ var i int
+ i++
+ println(i)
+}`
+f, err := decorator.Parse(code)
+if err != nil {
+ panic(err)
+}
+
+list := f.Decls[0].(*dst.FuncDecl).Body.List
+
+list[0].Decorations().Before = dst.EmptyLine
+list[0].Decorations().End.Append("// the Decorations method allows access to the common")
+list[1].Decorations().End.Append("// decoration properties (Before, Start, End and After)")
+list[2].Decorations().End.Append("// for all nodes.")
+list[2].Decorations().After = dst.EmptyLine
+
+if err := decorator.Print(f); err != nil {
+ panic(err)
+}
+
+//Output:
+//package main
+//
+//func main() {
+//
+// var i int // the Decorations method allows access to the common
+// i++ // decoration properties (Before, Start, End and After)
+// println(i) // for all nodes.
+//
+//}
+```
+
+#### dstutil.Decorations
+
+While debugging, it is often useful to have a list of all decorations attached to a node. The
+[dstutil](https://github.com/dave/dst/tree/master/dstutil) package provides a helper function `Decorations` which
+returns a list of the attachment points and all decorations for any node:
+
+```go
+code := `package main
+
+// main comment
+// is multi line
+func main() {
+
+ if true {
+
+ // foo
+ println( /* foo inline */ "foo")
+ } else if false {
+ println /* bar inline */ ("bar")
+
+ // bar after
+
+ } else {
+ // empty block
+ }
+}`
+
+f, err := decorator.Parse(code)
+if err != nil {
+ panic(err)
+}
+
+dst.Inspect(f, func(node dst.Node) bool {
+ if node == nil {
+ return false
+ }
+ before, after, points := dstutil.Decorations(node)
+ var info string
+ if before != dst.None {
+ info += fmt.Sprintf("- Before: %s\n", before)
+ }
+ for _, point := range points {
+ if len(point.Decs) == 0 {
+ continue
+ }
+ info += fmt.Sprintf("- %s: [", point.Name)
+ for i, dec := range point.Decs {
+ if i > 0 {
+ info += ", "
+ }
+ info += fmt.Sprintf("%q", dec)
+ }
+ info += "]\n"
+ }
+ if after != dst.None {
+ info += fmt.Sprintf("- After: %s\n", after)
+ }
+ if info != "" {
+ fmt.Printf("%T\n%s\n", node, info)
+ }
+ return true
+})
+
+//Output:
+//*dst.FuncDecl
+//- Before: NewLine
+//- Start: ["// main comment", "// is multi line"]
+//
+//*dst.IfStmt
+//- Before: NewLine
+//- After: NewLine
+//
+//*dst.ExprStmt
+//- Before: NewLine
+//- Start: ["// foo"]
+//- After: NewLine
+//
+//*dst.CallExpr
+//- Lparen: ["/* foo inline */"]
+//
+//*dst.ExprStmt
+//- Before: NewLine
+//- End: ["\n", "\n", "// bar after"]
+//- After: NewLine
+//
+//*dst.CallExpr
+//- Fun: ["/* bar inline */"]
+//
+//*dst.BlockStmt
+//- Lbrace: ["\n", "// empty block"]
+```
+
+### Newlines
+
+The `Before` and `After` properties cover the majority of cases, but occasionally a newline needs to
+be rendered inside a node. Simply add a `\n` decoration to accomplish this.
+
+### Clone
+
+Re-using an existing node elsewhere in the tree will panic when the tree is restored to `ast`. Instead,
+use the `Clone` function to make a deep copy of the node before re-use:
+
+```go
+code := `package main
+
+var i /* a */ int`
+
+f, err := decorator.Parse(code)
+if err != nil {
+ panic(err)
+}
+
+cloned := dst.Clone(f.Decls[0]).(*dst.GenDecl)
+
+cloned.Decs.Before = dst.NewLine
+cloned.Specs[0].(*dst.ValueSpec).Names[0].Name = "j"
+cloned.Specs[0].(*dst.ValueSpec).Names[0].Decs.End.Replace("/* b */")
+
+f.Decls = append(f.Decls, cloned)
+
+if err := decorator.Print(f); err != nil {
+ panic(err)
+}
+
+//Output:
+//package main
+//
+//var i /* a */ int
+//var j /* b */ int
+```
+
+### Apply
+
+The [dstutil](https://github.com/dave/dst/tree/master/dstutil) package is a fork of `golang.org/x/tools/go/ast/astutil`,
+and provides the `Apply` function with similar semantics.
+
+### Imports
+
+The decorator can automatically manage the `import` block, which is a non-trivial task.
+
+Use [NewDecoratorWithImports](https://godoc.org/github.com/dave/dst/decorator#NewDecoratorWithImports)
+and [NewRestorerWithImports](https://godoc.org/github.com/dave/dst/decorator#NewRestorerWithImports)
+to create an import aware decorator / restorer.
+
+During decoration, remote identifiers are normalised - `*ast.SelectorExpr` nodes that represent
+qualified identifiers are replaced with `*dst.Ident` nodes with the `Path` field set to the path of
+the imported package.
+
+When adding a qualified identifier node, there is no need to use `*dst.SelectorExpr` - just add a
+`*dst.Ident` and set `Path` to the imported package path. The restorer will wrap it in a
+`*ast.SelectorExpr` where appropriate when converting back to ast, and also update the import
+block.
+
+To enable import management, the decorator must be able to resolve the imported package for
+selector expressions and identifiers, and the restorer must be able to resolve the name of a
+package given it's path. Several implementations for these resolvers are provided, and the best
+method will depend on the environment. [See below](#resolvers) for more details.
+
+### Load
+
+The [Load](https://godoc.org/github.com/dave/dst/decorator#Load) convenience function uses
+`go/packages` to load packages and decorate all loaded ast files, with import management enabled:
+
+```go
+// Create a simple module in a temporary directory
+dir, err := tempDir(map[string]string{
+ "go.mod": "module root",
+ "main.go": "package main \n\n func main() {}",
+})
+defer os.RemoveAll(dir)
+if err != nil {
+ panic(err)
+}
+
+// Use the Load convenience function that calls go/packages to load the package. All loaded
+// ast files are decorated to dst.
+pkgs, err := decorator.Load(&packages.Config{Dir: dir, Mode: packages.LoadSyntax}, "root")
+if err != nil {
+ panic(err)
+}
+p := pkgs[0]
+f := p.Syntax[0]
+
+// Add a call expression. Note we don't have to use a SelectorExpr - just adding an Ident with
+// the imported package path will do. The restorer will add SelectorExpr where appropriate when
+// converting back to ast. Note the new Path field on *dst.Ident. Set this to the package path
+// of the imported package, and the restorer will automatically add the import to the import
+// block.
+b := f.Decls[0].(*dst.FuncDecl).Body
+b.List = append(b.List, &dst.ExprStmt{
+ X: &dst.CallExpr{
+ Fun: &dst.Ident{Path: "fmt", Name: "Println"},
+ Args: []dst.Expr{
+ &dst.BasicLit{Kind: token.STRING, Value: strconv.Quote("Hello, World!")},
+ },
+ },
+})
+
+// Create a restorer with the import manager enabled, and print the result. As you can see, the
+// import block is automatically managed, and the Println ident is converted to a SelectorExpr:
+r := decorator.NewRestorerWithImports("root", gopackages.New(dir))
+if err := r.Print(p.Syntax[0]); err != nil {
+ panic(err)
+}
+
+//Output:
+//package main
+//
+//import "fmt"
+//
+//func main() { fmt.Println("Hello, World!") }
+```
+
+### Mappings
+
+The decorator exposes `Dst.Nodes` and `Ast.Nodes` which map between `ast.Node` and `dst.Node`. This
+enables systems that refer to `ast` nodes (such as `go/types`) to be used:
+
+```go
+code := `package main
+
+func main() {
+ var i int
+ i++
+ println(i)
+}`
+
+// Parse the code to AST
+fset := token.NewFileSet()
+astFile, err := parser.ParseFile(fset, "", code, parser.ParseComments)
+if err != nil {
+ panic(err)
+}
+
+// Invoke the type checker using AST as input
+typesInfo := types.Info{
+ Defs: make(map[*ast.Ident]types.Object),
+ Uses: make(map[*ast.Ident]types.Object),
+}
+conf := &types.Config{}
+if _, err := conf.Check("", fset, []*ast.File{astFile}, &typesInfo); err != nil {
+ panic(err)
+}
+
+// Create a new decorator, which will track the mapping between ast and dst nodes
+dec := decorator.NewDecorator(fset)
+
+// Decorate the *ast.File to give us a *dst.File
+f, err := dec.DecorateFile(astFile)
+if err != nil {
+ panic(err)
+}
+
+// Find the *dst.Ident for the definition of "i"
+dstDef := f.Decls[0].(*dst.FuncDecl).Body.List[0].(*dst.DeclStmt).Decl.(*dst.GenDecl).Specs[0].(*dst.ValueSpec).Names[0]
+
+// Find the *ast.Ident using the Ast.Nodes mapping
+astDef := dec.Ast.Nodes[dstDef].(*ast.Ident)
+
+// Find the types.Object corresponding to "i"
+obj := typesInfo.Defs[astDef]
+
+// Find all the uses of that object
+var astUses []*ast.Ident
+for id, ob := range typesInfo.Uses {
+ if ob != obj {
+ continue
+ }
+ astUses = append(astUses, id)
+}
+
+// Find each *dst.Ident in the Dst.Nodes mapping
+var dstUses []*dst.Ident
+for _, id := range astUses {
+ dstUses = append(dstUses, dec.Dst.Nodes[id].(*dst.Ident))
+}
+
+// Change the name of the original definition and all uses
+dstDef.Name = "foo"
+for _, id := range dstUses {
+ id.Name = "foo"
+}
+
+// Print the DST
+if err := decorator.Print(f); err != nil {
+ panic(err)
+}
+
+//Output:
+//package main
+//
+//func main() {
+// var foo int
+// foo++
+// println(foo)
+//}
+```
+
+## Resolvers
+
+There are two separate interfaces defined by the [resolver package](https://github.com/dave/dst/tree/master/decorator/resolver)
+which allow the decorator and restorer to automatically manage the imports block.
+
+The decorator uses a `DecoratorResolver` which resolves the package path of any `*ast.Ident`. This is
+complicated by dot-import syntax ([see below](#dot-imports)).
+
+The restorer uses a `RestorerResolver` which resolves the name of any package given the path. This
+is complicated by vendoring and Go modules.
+
+When `Resolver` is set on `Decorator` or `Restorer`, the `Path` property must be set to the local
+package path.
+
+Several implementations of both interfaces that are suitable for different environments are
+provided:
+
+### DecoratorResolver
+
+#### gotypes
+
+The [gotypes](https://github.com/dave/dst/blob/master/decorator/resolver/gotypes/resolver.go)
+package provides a `DecoratorResolver` with full dot-import compatibility. However it requires full
+export data for all imported packages, so the `Uses` map from `go/types.Info` is required. There
+are several methods of generating `go/types.Info`. Using `golang.org/x/tools/go/packages.Load` is
+recommended for full Go modules compatibility. See the [decorator.Load](https://godoc.org/github.com/dave/dst/decorator#Load)
+convenience function to automate this.
+
+#### goast
+
+The [goast](https://github.com/dave/dst/blob/master/decorator/resolver/goast/resolver.go) package
+provides a simplified `DecoratorResolver` that only needs to scan a single ast file. This is unable
+to resolve identifiers from dot-imported packages, so will panic if a dot-import is encountered in
+the import block. It uses the provided `RestorerResolver` to resolve the names of all imported
+packages. If no `RestorerResolver` is provided, the [guess](#guess-and-simple) implementation is used.
+
+### RestorerResolver
+
+#### gopackages
+
+The [gopackages](https://github.com/dave/dst/blob/master/decorator/resolver/gopackages/resolver.go)
+package provides a `RestorerResolver` with full compatibility with Go modules. It uses
+`golang.org/x/tools/go/packages` to load the package data. This may be very slow, and uses the `go`
+command line tool to query package data, so may not be compatible with some environments.
+
+#### gobuild
+
+The [gobuild](https://github.com/dave/dst/blob/master/decorator/resolver/gobuild/resolver.go)
+package provides an alternative `RestorerResolver` that uses the legacy `go/build` system to load
+the imported package data. This may be needed in some circumstances and provides better performance
+than `go/packages`. However, this is not Go modules aware.
+
+#### guess and simple
+
+The [guess](https://github.com/dave/dst/blob/master/decorator/resolver/guess/resolver.go) and
+[simple](https://github.com/dave/dst/blob/master/decorator/resolver/simple/resolver.go) packages
+provide simple `RestorerResolver` implementations that may be useful in certain circumstances, or
+where performance is critical. `simple` resolves paths only if they occur in a provided map.
+`guess` guesses the package name based on the last part of the path.
+
+### Example
+
+Here's an example of supplying resolvers for the decorator and restorer:
+
+```go
+code := `package main
+
+ import "fmt"
+
+ func main() {
+ fmt.Println("a")
+ }`
+
+dec := decorator.NewDecoratorWithImports(token.NewFileSet(), "main", goast.New())
+
+f, err := dec.Parse(code)
+if err != nil {
+ panic(err)
+}
+
+f.Decls[1].(*dst.FuncDecl).Body.List[0].(*dst.ExprStmt).X.(*dst.CallExpr).Args = []dst.Expr{
+ &dst.CallExpr{
+ Fun: &dst.Ident{Name: "A", Path: "foo.bar/baz"},
+ },
+}
+
+res := decorator.NewRestorerWithImports("main", guess.New())
+if err := res.Print(f); err != nil {
+ panic(err)
+}
+
+//Output:
+//package main
+//
+//import (
+// "fmt"
+//
+// "foo.bar/baz"
+//)
+//
+//func main() {
+// fmt.Println(baz.A())
+//}
+```
+
+### Alias
+
+To control the alias of imports, use a `FileRestorer`:
+
+```go
+code := `package main
+
+ import "fmt"
+
+ func main() {
+ fmt.Println("a")
+ }`
+
+dec := decorator.NewDecoratorWithImports(token.NewFileSet(), "main", goast.New())
+
+f, err := dec.Parse(code)
+if err != nil {
+ panic(err)
+}
+
+res := decorator.NewRestorerWithImports("main", guess.New())
+
+fr := res.FileRestorer()
+fr.Alias["fmt"] = "fmt1"
+
+if err := fr.Print(f); err != nil {
+ panic(err)
+}
+
+//Output:
+//package main
+//
+//import fmt1 "fmt"
+//
+//func main() {
+// fmt1.Println("a")
+//}
+```
+
+### Details
+
+For more information on exactly how the imports block is managed, read through the [test
+cases](https://github.com/dave/dst/blob/master/decorator/restorer_resolver_test.go).
+
+### Dot-imports
+
+Consider this file...
+
+```go
+package main
+
+import (
+ . "a"
+)
+
+func main() {
+ B()
+ C()
+}
+```
+
+`B` and `C` could be local identifiers from a different file in this package,
+or from the imported package `a`. If only one is from `a` and it is removed, we should remove the
+import when we restore to `ast`. Thus the resolver needs to be able to resolve the package using
+the full info from `go/types`.
+
+## Status
+
+This package is well tested and used in many projects. The API should be considered stable going forward.
+
+## Chat?
+
+Feel free to create an [issue](https://github.com/dave/dst/issues) or chat in the
+[#dst](https://gophers.slack.com/messages/CCVL24MTQ) Gophers Slack channel.
+
+## Contributing
+
+For further developing or contributing to `dst`, check out [these notes](https://github.com/dave/dst/blob/master/contributing.md).
+
+## Special thanks
+
+Thanks very much to [hawkinsw](https://github.com/hawkinsw) for taking on the task of adding generics compatibility to `dst`.
\ No newline at end of file
diff --git a/vendor/github.com/dave/dst/README.md.tpl b/vendor/github.com/dave/dst/README.md.tpl
new file mode 100644
index 00000000..26691f9b
--- /dev/null
+++ b/vendor/github.com/dave/dst/README.md.tpl
@@ -0,0 +1,239 @@
+[](https://travis-ci.org/dave/dst)
+[](https://godoc.org/github.com/dave/dst/decorator)
+[](https://codecov.io/gh/dave/dst)
+
+[](https://sourcegraph.com/github.com/dave/dst?badge)
+
+# Decorated Syntax Tree
+
+The `dst` package enables manipulation of a Go syntax tree with high fidelity. Decorations (e.g.
+comments and line spacing) remain attached to the correct nodes as the tree is modified.
+
+## Where does `go/ast` break?
+
+The `go/ast` package wasn't created with source manipulation as an intended use-case. Comments are
+stored by their byte offset instead of attached to nodes, so re-arranging nodes breaks the output.
+See [this Go issue](https://github.com/golang/go/issues/20744) for more information.
+
+Consider this example where we want to reverse the order of the two statements. As you can see the
+comments don't remain attached to the correct nodes:
+
+{{ "ExampleAstBroken" | example }}
+
+Here's the same example using `dst`:
+
+{{ "ExampleDstFixed" | example }}
+
+## Usage
+
+Parsing a source file to `dst` and printing the results after modification can be accomplished with
+several `Parse` and `Print` convenience functions in the [decorator](https://godoc.org/github.com/dave/dst/decorator)
+package.
+
+For more fine-grained control you can use [Decorator](https://godoc.org/github.com/dave/dst/decorator#Decorator)
+to convert from `ast` to `dst`, and [Restorer](https://godoc.org/github.com/dave/dst/decorator#Restorer)
+to convert back again.
+
+### Comments
+
+Comments are added at decoration attachment points. [See here](https://github.com/dave/dst/blob/master/decorations-types-generated.go)
+for a full list of these points, along with demonstration code of where they are rendered in the
+output.
+
+The decoration attachment points have convenience functions `Append`, `Prepend`, `Replace`, `Clear`
+and `All` to accomplish common tasks. Use the full text of your comment including the `//` or `/**/`
+markers. When adding a line comment, a newline is automatically rendered.
+
+{{ "ExampleComment" | example }}
+
+### Spacing
+
+The `Before` property marks the node as having a line space (new line or empty line) before the node.
+These spaces are rendered before any decorations attached to the `Start` decoration point. The `After`
+property is similar but rendered after the node (and after any `End` decorations).
+
+{{ "ExampleSpace" | example }}
+
+### Decorations
+
+The common decoration properties (`Start`, `End`, `Before` and `After`) occur on all nodes, and can be
+accessed with the `Decorations()` method on the `Node` interface:
+
+{{ "ExampleDecorated" | example }}
+
+#### dstutil.Decorations
+
+While debugging, it is often useful to have a list of all decorations attached to a node. The
+[dstutil](https://github.com/dave/dst/tree/master/dstutil) package provides a helper function `Decorations` which
+returns a list of the attachment points and all decorations for any node:
+
+{{ "ExampleDecorationPoints" | example }}
+
+### Newlines
+
+The `Before` and `After` properties cover the majority of cases, but occasionally a newline needs to
+be rendered inside a node. Simply add a `\n` decoration to accomplish this.
+
+### Clone
+
+Re-using an existing node elsewhere in the tree will panic when the tree is restored to `ast`. Instead,
+use the `Clone` function to make a deep copy of the node before re-use:
+
+{{ "ExampleClone" | example }}
+
+### Apply
+
+The [dstutil](https://github.com/dave/dst/tree/master/dstutil) package is a fork of `golang.org/x/tools/go/ast/astutil`,
+and provides the `Apply` function with similar semantics.
+
+### Imports
+
+The decorator can automatically manage the `import` block, which is a non-trivial task.
+
+Use [NewDecoratorWithImports](https://godoc.org/github.com/dave/dst/decorator#NewDecoratorWithImports)
+and [NewRestorerWithImports](https://godoc.org/github.com/dave/dst/decorator#NewRestorerWithImports)
+to create an import aware decorator / restorer.
+
+During decoration, remote identifiers are normalised - `*ast.SelectorExpr` nodes that represent
+qualified identifiers are replaced with `*dst.Ident` nodes with the `Path` field set to the path of
+the imported package.
+
+When adding a qualified identifier node, there is no need to use `*dst.SelectorExpr` - just add a
+`*dst.Ident` and set `Path` to the imported package path. The restorer will wrap it in a
+`*ast.SelectorExpr` where appropriate when converting back to ast, and also update the import
+block.
+
+To enable import management, the decorator must be able to resolve the imported package for
+selector expressions and identifiers, and the restorer must be able to resolve the name of a
+package given it's path. Several implementations for these resolvers are provided, and the best
+method will depend on the environment. [See below](#resolvers) for more details.
+
+### Load
+
+The [Load](https://godoc.org/github.com/dave/dst/decorator#Load) convenience function uses
+`go/packages` to load packages and decorate all loaded ast files, with import management enabled:
+
+{{ "ExampleImports" | example }}
+
+### Mappings
+
+The decorator exposes `Dst.Nodes` and `Ast.Nodes` which map between `ast.Node` and `dst.Node`. This
+enables systems that refer to `ast` nodes (such as `go/types`) to be used:
+
+{{ "ExampleTypes" | example }}
+
+## Resolvers
+
+There are two separate interfaces defined by the [resolver package](https://github.com/dave/dst/tree/master/decorator/resolver)
+which allow the decorator and restorer to automatically manage the imports block.
+
+The decorator uses a `DecoratorResolver` which resolves the package path of any `*ast.Ident`. This is
+complicated by dot-import syntax ([see below](#dot-imports)).
+
+The restorer uses a `RestorerResolver` which resolves the name of any package given the path. This
+is complicated by vendoring and Go modules.
+
+When `Resolver` is set on `Decorator` or `Restorer`, the `Path` property must be set to the local
+package path.
+
+Several implementations of both interfaces that are suitable for different environments are
+provided:
+
+### DecoratorResolver
+
+#### gotypes
+
+The [gotypes](https://github.com/dave/dst/blob/master/decorator/resolver/gotypes/resolver.go)
+package provides a `DecoratorResolver` with full dot-import compatibility. However it requires full
+export data for all imported packages, so the `Uses` map from `go/types.Info` is required. There
+are several methods of generating `go/types.Info`. Using `golang.org/x/tools/go/packages.Load` is
+recommended for full Go modules compatibility. See the [decorator.Load](https://godoc.org/github.com/dave/dst/decorator#Load)
+convenience function to automate this.
+
+#### goast
+
+The [goast](https://github.com/dave/dst/blob/master/decorator/resolver/goast/resolver.go) package
+provides a simplified `DecoratorResolver` that only needs to scan a single ast file. This is unable
+to resolve identifiers from dot-imported packages, so will panic if a dot-import is encountered in
+the import block. It uses the provided `RestorerResolver` to resolve the names of all imported
+packages. If no `RestorerResolver` is provided, the [guess](#guess-and-simple) implementation is used.
+
+### RestorerResolver
+
+#### gopackages
+
+The [gopackages](https://github.com/dave/dst/blob/master/decorator/resolver/gopackages/resolver.go)
+package provides a `RestorerResolver` with full compatibility with Go modules. It uses
+`golang.org/x/tools/go/packages` to load the package data. This may be very slow, and uses the `go`
+command line tool to query package data, so may not be compatible with some environments.
+
+#### gobuild
+
+The [gobuild](https://github.com/dave/dst/blob/master/decorator/resolver/gobuild/resolver.go)
+package provides an alternative `RestorerResolver` that uses the legacy `go/build` system to load
+the imported package data. This may be needed in some circumstances and provides better performance
+than `go/packages`. However, this is not Go modules aware.
+
+#### guess and simple
+
+The [guess](https://github.com/dave/dst/blob/master/decorator/resolver/guess/resolver.go) and
+[simple](https://github.com/dave/dst/blob/master/decorator/resolver/simple/resolver.go) packages
+provide simple `RestorerResolver` implementations that may be useful in certain circumstances, or
+where performance is critical. `simple` resolves paths only if they occur in a provided map.
+`guess` guesses the package name based on the last part of the path.
+
+### Example
+
+Here's an example of supplying resolvers for the decorator and restorer:
+
+{{ "ExampleManualImports" | example }}
+
+### Alias
+
+To control the alias of imports, use a `FileRestorer`:
+
+{{ "ExampleAlias" | example }}
+
+### Details
+
+For more information on exactly how the imports block is managed, read through the [test
+cases](https://github.com/dave/dst/blob/master/decorator/restorer_resolver_test.go).
+
+### Dot-imports
+
+Consider this file...
+
+```go
+package main
+
+import (
+ . "a"
+)
+
+func main() {
+ B()
+ C()
+}
+```
+
+`B` and `C` could be local identifiers from a different file in this package,
+or from the imported package `a`. If only one is from `a` and it is removed, we should remove the
+import when we restore to `ast`. Thus the resolver needs to be able to resolve the package using
+the full info from `go/types`.
+
+## Status
+
+This package is well tested and used in many projects. The API should be considered stable going forward.
+
+## Chat?
+
+Feel free to create an [issue](https://github.com/dave/dst/issues) or chat in the
+[#dst](https://gophers.slack.com/messages/CCVL24MTQ) Gophers Slack channel.
+
+## Contributing
+
+For further developing or contributing to `dst`, check out [these notes](https://github.com/dave/dst/blob/master/contributing.md).
+
+## Special thanks
+
+Thanks very much to [hawkinsw](https://github.com/hawkinsw) for taking on the task of adding generics compatibility to `dst`.
\ No newline at end of file
diff --git a/vendor/github.com/dave/dst/clone-generated.go b/vendor/github.com/dave/dst/clone-generated.go
new file mode 100644
index 00000000..ab228749
--- /dev/null
+++ b/vendor/github.com/dave/dst/clone-generated.go
@@ -0,0 +1,1628 @@
+package dst
+
+import "fmt"
+
+// Clone returns a deep copy of the node, ready to be re-used elsewhere in the tree.
+func Clone(n Node) Node {
+ switch n := n.(type) {
+ case *ArrayType:
+ out := &ArrayType{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Lbrack
+ out.Decs.Lbrack = append(out.Decs.Lbrack, n.Decs.Lbrack...)
+
+ // Node: Len
+ if n.Len != nil {
+ out.Len = Clone(n.Len).(Expr)
+ }
+
+ // Decoration: Len
+ out.Decs.Len = append(out.Decs.Len, n.Decs.Len...)
+
+ // Node: Elt
+ if n.Elt != nil {
+ out.Elt = Clone(n.Elt).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *AssignStmt:
+ out := &AssignStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // List: Lhs
+ for _, v := range n.Lhs {
+ out.Lhs = append(out.Lhs, Clone(v).(Expr))
+ }
+
+ // Token: Tok
+ out.Tok = n.Tok
+
+ // Decoration: Tok
+ out.Decs.Tok = append(out.Decs.Tok, n.Decs.Tok...)
+
+ // List: Rhs
+ for _, v := range n.Rhs {
+ out.Rhs = append(out.Rhs, Clone(v).(Expr))
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *BadDecl:
+ out := &BadDecl{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Bad
+ out.Length = n.Length
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *BadExpr:
+ out := &BadExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Bad
+ out.Length = n.Length
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *BadStmt:
+ out := &BadStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Bad
+ out.Length = n.Length
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *BasicLit:
+ out := &BasicLit{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // String: Value
+ out.Value = n.Value
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ // Value: Kind
+ out.Kind = n.Kind
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *BinaryExpr:
+ out := &BinaryExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: X
+ out.Decs.X = append(out.Decs.X, n.Decs.X...)
+
+ // Token: Op
+ out.Op = n.Op
+
+ // Decoration: Op
+ out.Decs.Op = append(out.Decs.Op, n.Decs.Op...)
+
+ // Node: Y
+ if n.Y != nil {
+ out.Y = Clone(n.Y).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *BlockStmt:
+ out := &BlockStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Lbrace
+ out.Decs.Lbrace = append(out.Decs.Lbrace, n.Decs.Lbrace...)
+
+ // List: List
+ for _, v := range n.List {
+ out.List = append(out.List, Clone(v).(Stmt))
+ }
+
+ // Token: Rbrace
+ out.RbraceHasNoPos = n.RbraceHasNoPos
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *BranchStmt:
+ out := &BranchStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Token: Tok
+ out.Tok = n.Tok
+
+ // Decoration: Tok
+ out.Decs.Tok = append(out.Decs.Tok, n.Decs.Tok...)
+
+ // Node: Label
+ if n.Label != nil {
+ out.Label = Clone(n.Label).(*Ident)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *CallExpr:
+ out := &CallExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: Fun
+ if n.Fun != nil {
+ out.Fun = Clone(n.Fun).(Expr)
+ }
+
+ // Decoration: Fun
+ out.Decs.Fun = append(out.Decs.Fun, n.Decs.Fun...)
+
+ // Decoration: Lparen
+ out.Decs.Lparen = append(out.Decs.Lparen, n.Decs.Lparen...)
+
+ // List: Args
+ for _, v := range n.Args {
+ out.Args = append(out.Args, Clone(v).(Expr))
+ }
+
+ // Token: Ellipsis
+ out.Ellipsis = n.Ellipsis
+
+ // Decoration: Ellipsis
+ out.Decs.Ellipsis = append(out.Decs.Ellipsis, n.Decs.Ellipsis...)
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *CaseClause:
+ out := &CaseClause{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Case
+ out.Decs.Case = append(out.Decs.Case, n.Decs.Case...)
+
+ // List: List
+ for _, v := range n.List {
+ out.List = append(out.List, Clone(v).(Expr))
+ }
+
+ // Decoration: Colon
+ out.Decs.Colon = append(out.Decs.Colon, n.Decs.Colon...)
+
+ // List: Body
+ for _, v := range n.Body {
+ out.Body = append(out.Body, Clone(v).(Stmt))
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *ChanType:
+ out := &ChanType{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Begin
+ out.Decs.Begin = append(out.Decs.Begin, n.Decs.Begin...)
+
+ // Decoration: Arrow
+ out.Decs.Arrow = append(out.Decs.Arrow, n.Decs.Arrow...)
+
+ // Node: Value
+ if n.Value != nil {
+ out.Value = Clone(n.Value).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ // Value: Dir
+ out.Dir = n.Dir
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *CommClause:
+ out := &CommClause{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Case
+ out.Decs.Case = append(out.Decs.Case, n.Decs.Case...)
+
+ // Node: Comm
+ if n.Comm != nil {
+ out.Comm = Clone(n.Comm).(Stmt)
+ }
+
+ // Decoration: Comm
+ out.Decs.Comm = append(out.Decs.Comm, n.Decs.Comm...)
+
+ // Decoration: Colon
+ out.Decs.Colon = append(out.Decs.Colon, n.Decs.Colon...)
+
+ // List: Body
+ for _, v := range n.Body {
+ out.Body = append(out.Body, Clone(v).(Stmt))
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *CompositeLit:
+ out := &CompositeLit{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = Clone(n.Type).(Expr)
+ }
+
+ // Decoration: Type
+ out.Decs.Type = append(out.Decs.Type, n.Decs.Type...)
+
+ // Decoration: Lbrace
+ out.Decs.Lbrace = append(out.Decs.Lbrace, n.Decs.Lbrace...)
+
+ // List: Elts
+ for _, v := range n.Elts {
+ out.Elts = append(out.Elts, Clone(v).(Expr))
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ // Value: Incomplete
+ out.Incomplete = n.Incomplete
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *DeclStmt:
+ out := &DeclStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: Decl
+ if n.Decl != nil {
+ out.Decl = Clone(n.Decl).(Decl)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *DeferStmt:
+ out := &DeferStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Defer
+ out.Decs.Defer = append(out.Decs.Defer, n.Decs.Defer...)
+
+ // Node: Call
+ if n.Call != nil {
+ out.Call = Clone(n.Call).(*CallExpr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *Ellipsis:
+ out := &Ellipsis{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Ellipsis
+ out.Decs.Ellipsis = append(out.Decs.Ellipsis, n.Decs.Ellipsis...)
+
+ // Node: Elt
+ if n.Elt != nil {
+ out.Elt = Clone(n.Elt).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *EmptyStmt:
+ out := &EmptyStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ // Value: Implicit
+ out.Implicit = n.Implicit
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *ExprStmt:
+ out := &ExprStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *Field:
+ out := &Field{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // List: Names
+ for _, v := range n.Names {
+ out.Names = append(out.Names, Clone(v).(*Ident))
+ }
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = Clone(n.Type).(Expr)
+ }
+
+ // Decoration: Type
+ out.Decs.Type = append(out.Decs.Type, n.Decs.Type...)
+
+ // Node: Tag
+ if n.Tag != nil {
+ out.Tag = Clone(n.Tag).(*BasicLit)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *FieldList:
+ out := &FieldList{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Token: Opening
+ out.Opening = n.Opening
+
+ // Decoration: Opening
+ out.Decs.Opening = append(out.Decs.Opening, n.Decs.Opening...)
+
+ // List: List
+ for _, v := range n.List {
+ out.List = append(out.List, Clone(v).(*Field))
+ }
+
+ // Token: Closing
+ out.Closing = n.Closing
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *File:
+ out := &File{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Package
+ out.Decs.Package = append(out.Decs.Package, n.Decs.Package...)
+
+ // Node: Name
+ if n.Name != nil {
+ out.Name = Clone(n.Name).(*Ident)
+ }
+
+ // Decoration: Name
+ out.Decs.Name = append(out.Decs.Name, n.Decs.Name...)
+
+ // List: Decls
+ for _, v := range n.Decls {
+ out.Decls = append(out.Decls, Clone(v).(Decl))
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ // Scope: Scope
+ out.Scope = CloneScope(n.Scope)
+
+ // List: Imports
+ for _, v := range n.Imports {
+ out.Imports = append(out.Imports, Clone(v).(*ImportSpec))
+ }
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *ForStmt:
+ out := &ForStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: For
+ out.Decs.For = append(out.Decs.For, n.Decs.For...)
+
+ // Node: Init
+ if n.Init != nil {
+ out.Init = Clone(n.Init).(Stmt)
+ }
+
+ // Decoration: Init
+ out.Decs.Init = append(out.Decs.Init, n.Decs.Init...)
+
+ // Node: Cond
+ if n.Cond != nil {
+ out.Cond = Clone(n.Cond).(Expr)
+ }
+
+ // Decoration: Cond
+ out.Decs.Cond = append(out.Decs.Cond, n.Decs.Cond...)
+
+ // Node: Post
+ if n.Post != nil {
+ out.Post = Clone(n.Post).(Stmt)
+ }
+
+ // Decoration: Post
+ out.Decs.Post = append(out.Decs.Post, n.Decs.Post...)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = Clone(n.Body).(*BlockStmt)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *FuncDecl:
+ out := &FuncDecl{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Init: Type
+ out.Type = &FuncType{}
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Token: Func
+ out.Type.Func = n.Type.Func
+
+ // Decoration: Func
+ out.Decs.Func = append(out.Decs.Func, n.Decs.Func...)
+
+ // Node: Recv
+ if n.Recv != nil {
+ out.Recv = Clone(n.Recv).(*FieldList)
+ }
+
+ // Decoration: Recv
+ out.Decs.Recv = append(out.Decs.Recv, n.Decs.Recv...)
+
+ // Node: Name
+ if n.Name != nil {
+ out.Name = Clone(n.Name).(*Ident)
+ }
+
+ // Decoration: Name
+ out.Decs.Name = append(out.Decs.Name, n.Decs.Name...)
+
+ // Node: TypeParams
+ if n.Type.TypeParams != nil {
+ out.Type.TypeParams = Clone(n.Type.TypeParams).(*FieldList)
+ }
+
+ // Decoration: TypeParams
+ out.Decs.TypeParams = append(out.Decs.TypeParams, n.Decs.TypeParams...)
+
+ // Node: Params
+ if n.Type.Params != nil {
+ out.Type.Params = Clone(n.Type.Params).(*FieldList)
+ }
+
+ // Decoration: Params
+ out.Decs.Params = append(out.Decs.Params, n.Decs.Params...)
+
+ // Node: Results
+ if n.Type.Results != nil {
+ out.Type.Results = Clone(n.Type.Results).(*FieldList)
+ }
+
+ // Decoration: Results
+ out.Decs.Results = append(out.Decs.Results, n.Decs.Results...)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = Clone(n.Body).(*BlockStmt)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *FuncLit:
+ out := &FuncLit{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = Clone(n.Type).(*FuncType)
+ }
+
+ // Decoration: Type
+ out.Decs.Type = append(out.Decs.Type, n.Decs.Type...)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = Clone(n.Body).(*BlockStmt)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *FuncType:
+ out := &FuncType{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Token: Func
+ out.Func = n.Func
+
+ // Decoration: Func
+ out.Decs.Func = append(out.Decs.Func, n.Decs.Func...)
+
+ // Node: TypeParams
+ if n.TypeParams != nil {
+ out.TypeParams = Clone(n.TypeParams).(*FieldList)
+ }
+
+ // Decoration: TypeParams
+ out.Decs.TypeParams = append(out.Decs.TypeParams, n.Decs.TypeParams...)
+
+ // Node: Params
+ if n.Params != nil {
+ out.Params = Clone(n.Params).(*FieldList)
+ }
+
+ // Decoration: Params
+ out.Decs.Params = append(out.Decs.Params, n.Decs.Params...)
+
+ // Node: Results
+ if n.Results != nil {
+ out.Results = Clone(n.Results).(*FieldList)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *GenDecl:
+ out := &GenDecl{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Token: Tok
+ out.Tok = n.Tok
+
+ // Decoration: Tok
+ out.Decs.Tok = append(out.Decs.Tok, n.Decs.Tok...)
+
+ // Token: Lparen
+ out.Lparen = n.Lparen
+
+ // Decoration: Lparen
+ out.Decs.Lparen = append(out.Decs.Lparen, n.Decs.Lparen...)
+
+ // List: Specs
+ for _, v := range n.Specs {
+ out.Specs = append(out.Specs, Clone(v).(Spec))
+ }
+
+ // Token: Rparen
+ out.Rparen = n.Rparen
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *GoStmt:
+ out := &GoStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Go
+ out.Decs.Go = append(out.Decs.Go, n.Decs.Go...)
+
+ // Node: Call
+ if n.Call != nil {
+ out.Call = Clone(n.Call).(*CallExpr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *Ident:
+ out := &Ident{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: X
+ out.Decs.X = append(out.Decs.X, n.Decs.X...)
+
+ // String: Name
+ out.Name = n.Name
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ // Object: Obj
+ out.Obj = CloneObject(n.Obj)
+
+ // Path: Path
+ out.Path = n.Path
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *IfStmt:
+ out := &IfStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: If
+ out.Decs.If = append(out.Decs.If, n.Decs.If...)
+
+ // Node: Init
+ if n.Init != nil {
+ out.Init = Clone(n.Init).(Stmt)
+ }
+
+ // Decoration: Init
+ out.Decs.Init = append(out.Decs.Init, n.Decs.Init...)
+
+ // Node: Cond
+ if n.Cond != nil {
+ out.Cond = Clone(n.Cond).(Expr)
+ }
+
+ // Decoration: Cond
+ out.Decs.Cond = append(out.Decs.Cond, n.Decs.Cond...)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = Clone(n.Body).(*BlockStmt)
+ }
+
+ // Decoration: Else
+ out.Decs.Else = append(out.Decs.Else, n.Decs.Else...)
+
+ // Node: Else
+ if n.Else != nil {
+ out.Else = Clone(n.Else).(Stmt)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *ImportSpec:
+ out := &ImportSpec{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: Name
+ if n.Name != nil {
+ out.Name = Clone(n.Name).(*Ident)
+ }
+
+ // Decoration: Name
+ out.Decs.Name = append(out.Decs.Name, n.Decs.Name...)
+
+ // Node: Path
+ if n.Path != nil {
+ out.Path = Clone(n.Path).(*BasicLit)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *IncDecStmt:
+ out := &IncDecStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: X
+ out.Decs.X = append(out.Decs.X, n.Decs.X...)
+
+ // Token: Tok
+ out.Tok = n.Tok
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *IndexExpr:
+ out := &IndexExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: X
+ out.Decs.X = append(out.Decs.X, n.Decs.X...)
+
+ // Decoration: Lbrack
+ out.Decs.Lbrack = append(out.Decs.Lbrack, n.Decs.Lbrack...)
+
+ // Node: Index
+ if n.Index != nil {
+ out.Index = Clone(n.Index).(Expr)
+ }
+
+ // Decoration: Index
+ out.Decs.Index = append(out.Decs.Index, n.Decs.Index...)
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *IndexListExpr:
+ out := &IndexListExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: X
+ out.Decs.X = append(out.Decs.X, n.Decs.X...)
+
+ // Decoration: Lbrack
+ out.Decs.Lbrack = append(out.Decs.Lbrack, n.Decs.Lbrack...)
+
+ // List: Indices
+ for _, v := range n.Indices {
+ out.Indices = append(out.Indices, Clone(v).(Expr))
+ }
+
+ // Decoration: Indices
+ out.Decs.Indices = append(out.Decs.Indices, n.Decs.Indices...)
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *InterfaceType:
+ out := &InterfaceType{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Interface
+ out.Decs.Interface = append(out.Decs.Interface, n.Decs.Interface...)
+
+ // Node: Methods
+ if n.Methods != nil {
+ out.Methods = Clone(n.Methods).(*FieldList)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ // Value: Incomplete
+ out.Incomplete = n.Incomplete
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *KeyValueExpr:
+ out := &KeyValueExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: Key
+ if n.Key != nil {
+ out.Key = Clone(n.Key).(Expr)
+ }
+
+ // Decoration: Key
+ out.Decs.Key = append(out.Decs.Key, n.Decs.Key...)
+
+ // Decoration: Colon
+ out.Decs.Colon = append(out.Decs.Colon, n.Decs.Colon...)
+
+ // Node: Value
+ if n.Value != nil {
+ out.Value = Clone(n.Value).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *LabeledStmt:
+ out := &LabeledStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: Label
+ if n.Label != nil {
+ out.Label = Clone(n.Label).(*Ident)
+ }
+
+ // Decoration: Label
+ out.Decs.Label = append(out.Decs.Label, n.Decs.Label...)
+
+ // Decoration: Colon
+ out.Decs.Colon = append(out.Decs.Colon, n.Decs.Colon...)
+
+ // Node: Stmt
+ if n.Stmt != nil {
+ out.Stmt = Clone(n.Stmt).(Stmt)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *MapType:
+ out := &MapType{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Map
+ out.Decs.Map = append(out.Decs.Map, n.Decs.Map...)
+
+ // Node: Key
+ if n.Key != nil {
+ out.Key = Clone(n.Key).(Expr)
+ }
+
+ // Decoration: Key
+ out.Decs.Key = append(out.Decs.Key, n.Decs.Key...)
+
+ // Node: Value
+ if n.Value != nil {
+ out.Value = Clone(n.Value).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *Package:
+ out := &Package{}
+
+ // Value: Name
+ out.Name = n.Name
+
+ // Scope: Scope
+ out.Scope = CloneScope(n.Scope)
+
+ // Map: Imports
+ out.Imports = map[string]*Object{}
+ for k, v := range n.Imports {
+ out.Imports[k] = CloneObject(v)
+ }
+
+ // Map: Files
+ out.Files = map[string]*File{}
+ for k, v := range n.Files {
+ out.Files[k] = Clone(v).(*File)
+ }
+
+ return out
+ case *ParenExpr:
+ out := &ParenExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Lparen
+ out.Decs.Lparen = append(out.Decs.Lparen, n.Decs.Lparen...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: X
+ out.Decs.X = append(out.Decs.X, n.Decs.X...)
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *RangeStmt:
+ out := &RangeStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: For
+ out.Decs.For = append(out.Decs.For, n.Decs.For...)
+
+ // Node: Key
+ if n.Key != nil {
+ out.Key = Clone(n.Key).(Expr)
+ }
+
+ // Decoration: Key
+ out.Decs.Key = append(out.Decs.Key, n.Decs.Key...)
+
+ // Node: Value
+ if n.Value != nil {
+ out.Value = Clone(n.Value).(Expr)
+ }
+
+ // Decoration: Value
+ out.Decs.Value = append(out.Decs.Value, n.Decs.Value...)
+
+ // Token: Tok
+ out.Tok = n.Tok
+
+ // Decoration: Range
+ out.Decs.Range = append(out.Decs.Range, n.Decs.Range...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: X
+ out.Decs.X = append(out.Decs.X, n.Decs.X...)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = Clone(n.Body).(*BlockStmt)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *ReturnStmt:
+ out := &ReturnStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Return
+ out.Decs.Return = append(out.Decs.Return, n.Decs.Return...)
+
+ // List: Results
+ for _, v := range n.Results {
+ out.Results = append(out.Results, Clone(v).(Expr))
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *SelectStmt:
+ out := &SelectStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Select
+ out.Decs.Select = append(out.Decs.Select, n.Decs.Select...)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = Clone(n.Body).(*BlockStmt)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *SelectorExpr:
+ out := &SelectorExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: X
+ out.Decs.X = append(out.Decs.X, n.Decs.X...)
+
+ // Node: Sel
+ if n.Sel != nil {
+ out.Sel = Clone(n.Sel).(*Ident)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *SendStmt:
+ out := &SendStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: Chan
+ if n.Chan != nil {
+ out.Chan = Clone(n.Chan).(Expr)
+ }
+
+ // Decoration: Chan
+ out.Decs.Chan = append(out.Decs.Chan, n.Decs.Chan...)
+
+ // Decoration: Arrow
+ out.Decs.Arrow = append(out.Decs.Arrow, n.Decs.Arrow...)
+
+ // Node: Value
+ if n.Value != nil {
+ out.Value = Clone(n.Value).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *SliceExpr:
+ out := &SliceExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: X
+ out.Decs.X = append(out.Decs.X, n.Decs.X...)
+
+ // Decoration: Lbrack
+ out.Decs.Lbrack = append(out.Decs.Lbrack, n.Decs.Lbrack...)
+
+ // Node: Low
+ if n.Low != nil {
+ out.Low = Clone(n.Low).(Expr)
+ }
+
+ // Decoration: Low
+ out.Decs.Low = append(out.Decs.Low, n.Decs.Low...)
+
+ // Node: High
+ if n.High != nil {
+ out.High = Clone(n.High).(Expr)
+ }
+
+ // Decoration: High
+ out.Decs.High = append(out.Decs.High, n.Decs.High...)
+
+ // Node: Max
+ if n.Max != nil {
+ out.Max = Clone(n.Max).(Expr)
+ }
+
+ // Decoration: Max
+ out.Decs.Max = append(out.Decs.Max, n.Decs.Max...)
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ // Value: Slice3
+ out.Slice3 = n.Slice3
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *StarExpr:
+ out := &StarExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Star
+ out.Decs.Star = append(out.Decs.Star, n.Decs.Star...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *StructType:
+ out := &StructType{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Struct
+ out.Decs.Struct = append(out.Decs.Struct, n.Decs.Struct...)
+
+ // Node: Fields
+ if n.Fields != nil {
+ out.Fields = Clone(n.Fields).(*FieldList)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ // Value: Incomplete
+ out.Incomplete = n.Incomplete
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *SwitchStmt:
+ out := &SwitchStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Switch
+ out.Decs.Switch = append(out.Decs.Switch, n.Decs.Switch...)
+
+ // Node: Init
+ if n.Init != nil {
+ out.Init = Clone(n.Init).(Stmt)
+ }
+
+ // Decoration: Init
+ out.Decs.Init = append(out.Decs.Init, n.Decs.Init...)
+
+ // Node: Tag
+ if n.Tag != nil {
+ out.Tag = Clone(n.Tag).(Expr)
+ }
+
+ // Decoration: Tag
+ out.Decs.Tag = append(out.Decs.Tag, n.Decs.Tag...)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = Clone(n.Body).(*BlockStmt)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *TypeAssertExpr:
+ out := &TypeAssertExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: X
+ out.Decs.X = append(out.Decs.X, n.Decs.X...)
+
+ // Decoration: Lparen
+ out.Decs.Lparen = append(out.Decs.Lparen, n.Decs.Lparen...)
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = Clone(n.Type).(Expr)
+ }
+
+ // Decoration: Type
+ out.Decs.Type = append(out.Decs.Type, n.Decs.Type...)
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *TypeSpec:
+ out := &TypeSpec{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Node: Name
+ if n.Name != nil {
+ out.Name = Clone(n.Name).(*Ident)
+ }
+
+ // Token: Assign
+ out.Assign = n.Assign
+
+ // Decoration: Name
+ out.Decs.Name = append(out.Decs.Name, n.Decs.Name...)
+
+ // Node: TypeParams
+ if n.TypeParams != nil {
+ out.TypeParams = Clone(n.TypeParams).(*FieldList)
+ }
+
+ // Decoration: TypeParams
+ out.Decs.TypeParams = append(out.Decs.TypeParams, n.Decs.TypeParams...)
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = Clone(n.Type).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *TypeSwitchStmt:
+ out := &TypeSwitchStmt{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Decoration: Switch
+ out.Decs.Switch = append(out.Decs.Switch, n.Decs.Switch...)
+
+ // Node: Init
+ if n.Init != nil {
+ out.Init = Clone(n.Init).(Stmt)
+ }
+
+ // Decoration: Init
+ out.Decs.Init = append(out.Decs.Init, n.Decs.Init...)
+
+ // Node: Assign
+ if n.Assign != nil {
+ out.Assign = Clone(n.Assign).(Stmt)
+ }
+
+ // Decoration: Assign
+ out.Decs.Assign = append(out.Decs.Assign, n.Decs.Assign...)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = Clone(n.Body).(*BlockStmt)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *UnaryExpr:
+ out := &UnaryExpr{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // Token: Op
+ out.Op = n.Op
+
+ // Decoration: Op
+ out.Decs.Op = append(out.Decs.Op, n.Decs.Op...)
+
+ // Node: X
+ if n.X != nil {
+ out.X = Clone(n.X).(Expr)
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ case *ValueSpec:
+ out := &ValueSpec{}
+
+ out.Decs.Before = n.Decs.Before
+
+ // Decoration: Start
+ out.Decs.Start = append(out.Decs.Start, n.Decs.Start...)
+
+ // List: Names
+ for _, v := range n.Names {
+ out.Names = append(out.Names, Clone(v).(*Ident))
+ }
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = Clone(n.Type).(Expr)
+ }
+
+ // Decoration: Assign
+ out.Decs.Assign = append(out.Decs.Assign, n.Decs.Assign...)
+
+ // List: Values
+ for _, v := range n.Values {
+ out.Values = append(out.Values, Clone(v).(Expr))
+ }
+
+ // Decoration: End
+ out.Decs.End = append(out.Decs.End, n.Decs.End...)
+
+ out.Decs.After = n.Decs.After
+
+ return out
+ default:
+ panic(fmt.Sprintf("%T", n))
+ }
+}
diff --git a/vendor/github.com/dave/dst/clone.go b/vendor/github.com/dave/dst/clone.go
new file mode 100644
index 00000000..3f1e5f82
--- /dev/null
+++ b/vendor/github.com/dave/dst/clone.go
@@ -0,0 +1,11 @@
+package dst
+
+// CloneObject returns nil: After cloning a node, it should not be attached to the same object / scope.
+func CloneObject(o *Object) *Object {
+ return nil
+}
+
+// CloneScope returns nil: After cloning a node, it should not be attached to the same object / scope.
+func CloneScope(s *Scope) *Scope {
+ return nil
+}
diff --git a/vendor/github.com/dave/dst/contributing.md b/vendor/github.com/dave/dst/contributing.md
new file mode 100644
index 00000000..dc024060
--- /dev/null
+++ b/vendor/github.com/dave/dst/contributing.md
@@ -0,0 +1,78 @@
+# Building / Developing / Contributing
+
+The `dst` package relies heavily on code generation. So heavily, in fact, that `README.md` is
+itself generated by a preprocessor! Here are a few tips/tricks to get started developing `dst`.
+
+## Adding Features, Fixing Bugs
+
+Generally speaking, code handling node annotation is generated from the files in the `gendst` directory.
+In order to add/change decorations, edit the `gendst/data.go` file. Once you have made your edits, you can
+regenerate the library's source code based on those changes by
+
+1. `go run github.com/dave/dst/gendst`: This command will build and run a program generated from the
+ source code in the `gendst` folder that regenerates all the dst source fiels to reflect the changes
+ that you just made in the `gendst/data.go` file.
+
+Whenever you make a change to the `gendst/data.go` file, you must perform the aforementioned step.
+
+If you add a Node to the `gendst/data.go` file, you will need to make corresponding additions to non-generated
+files as well. Those files include, but are not limited to,:
+
+- `dst.go`
+- `walk.go`
+- `dstutil/rewrite.go`
+
+Depending on the changes that you have made to the description of the decorated Nodes, you may have to change some, none,
+or all of those files listed above (or even others that are not listed!).
+
+## Adding/Running Tests
+
+Any changes to the decorations of Nodes (or the addition of new Nodes) should be accompanied
+by an entry in `gendst/positions.go`.
+
+The format of the file is ...
+
+```
+//
+// startLine {
+ for i := startLine; i < endLine; i++ {
+ // we avoid the lines that follow the lines in the comment
+ avoid[i+1] = true
+ }
+ }
+ }
+ }
+ }
+
+ // avoid newlines inside multi-line (back-quoted) strings or bad nodes
+ for _, frag := range f.fragments {
+ switch frag := frag.(type) {
+ case *stringFragment:
+ if !strings.HasPrefix(frag.String, "`") {
+ continue
+ }
+
+ startLine := f.Fset.Position(frag.Pos).Line
+ endLine := f.Fset.Position(frag.Pos + token.Pos(len(frag.String))).Line
+
+ // multi line string
+ if endLine > startLine {
+ for i := startLine; i < endLine; i++ {
+ // we avoid the lines that follow the lines in the string
+ avoid[i+1] = true
+ }
+ }
+
+ case *badFragment:
+
+ // Newlines inside bad nodes are not printed by the formatter, so there is no
+ // need to reconstruct them in the restorer.
+
+ startLine := f.Fset.Position(frag.Pos).Line
+ endLine := f.Fset.Position(frag.Pos + token.Pos(frag.Length)).Line
+
+ if endLine > startLine {
+ for i := startLine; i < endLine; i++ {
+ // we avoid the lines that follow the lines in the node
+ avoid[i+1] = true
+ }
+ }
+ }
+ }
+
+ // Finding the positions of each newline is not easy. We step through the file one byte
+ // at a time and get the line number from the FileSet. As the line number increments,
+ // we know where the newlines are.
+ line := 1
+ tokenf := f.Fset.File(astf.Pos())
+ max := tokenf.Base() + tokenf.Size()
+ for i := tokenf.Base(); i < max; i++ {
+ pos := f.Fset.Position(token.Pos(i))
+ if pos.Line != line {
+
+ // if the line number has changed, we're on a new line
+
+ line = pos.Line
+
+ if avoid[line] {
+ // ignore if it's in the avoid list - e.g. inside a comment or multi-line
+ // string
+ continue
+ }
+
+ // peek ahead to the next position in the fset. If we're on another new line,
+ // we have an empty line:
+ nextLine := line
+ if i < max-1 {
+ // can't peek forward at the end of the file
+ nextLine = f.Fset.Position(token.Pos(i + 1)).Line
+ }
+
+ if nextLine != line {
+ // add an empty line fragment
+ f.addNewlineFragment(token.Pos(i-1), true)
+
+ // for empty lines, increment past the second "\n" manually:
+ line = nextLine
+ i++
+
+ } else {
+ // add a new line fragment
+ f.addNewlineFragment(token.Pos(i-1), false)
+ }
+
+ }
+ }
+ }
+
+ switch val := node.(type) {
+ case *ast.File:
+ processFile(val)
+ case *ast.Package:
+ for _, file := range val.Files {
+ processFile(file)
+ }
+ }
+
+ }
+
+ // the comments and newline fragments will be after the node fragments, so we sort the entire
+ // list by fset position, ensuring that fragments with equal position stay in the original
+ // order. This ensures that decorations get added to the correct attachment points (which may
+ // occur at the same fset position).
+ sort.SliceStable(f.fragments, func(i, j int) bool {
+ return f.fragments[i].Position() < f.fragments[j].Position()
+ })
+
+ // We calculate the indent of the start and end of each node and comment. This is used to
+ // during the decoration attachment algorithm to correctly attach hanging indent comments. See
+ // issues 9 and 18 for more info.
+ currentIndent := 0
+ for i, frag := range f.fragments {
+ if i == 0 || f.fragments[i-1].Newline() {
+ currentIndent = f.Fset.Position(frag.Position()).Column
+ }
+ switch frag := frag.(type) {
+ case *decorationFragment:
+ switch frag.Name {
+ case "Start":
+ f.startIndents[frag.Node] = currentIndent
+ case "End":
+ f.endIndents[frag.Node] = currentIndent
+ }
+ case *commentFragment:
+ frag.Indent = currentIndent
+ }
+ }
+}
+
+func (f *fileDecorator) link() {
+
+ // Pass 1: associate comment groups with decorations. Sweep up any other comments / new-lines /
+ // empty-lines and associate with the same decoration.
+ for i, frag := range f.fragments {
+ switch frag := frag.(type) {
+ case *decorationFragment:
+
+ // Special case for hanging indent (See https://github.com/dave/dst/issues/18)
+ //
+ // If we're on the End decoration of a Stmt or Decl, and indents: end == start+1 (OR
+ // it's a case / comm clause), then search forward over empty lines for all comments
+ // with the same indent as the End decoration.
+ //
+ // These should be attached to the end node. We also search for subsequent comments that
+ // have the same indent as the Start. If the next decoration node is the start of a Stmt
+ // or Decl with the same indent as the original node, these are attached there.
+
+ if frag.Name != "End" {
+ continue
+ }
+ _, stmt := frag.Node.(ast.Stmt)
+ _, decl := frag.Node.(ast.Decl)
+ if !stmt && !decl {
+ continue
+ }
+
+ if _, labeledStmt := frag.Node.(*ast.LabeledStmt); labeledStmt {
+ // Special case: labeled statements shouldn't be treated in the same way.
+ continue
+ }
+
+ start := f.startIndents[frag.Node]
+ end := f.endIndents[frag.Node]
+
+ _, caseClause := frag.Node.(*ast.CaseClause)
+ _, commClause := frag.Node.(*ast.CommClause)
+ if start == end && (caseClause || commClause) {
+ // special case for case / comm clause with no items... the clause node starts and
+ // ends on the same line, but comments can still be hanging. We spoof an indented
+ // end position:
+ end++
+ }
+
+ if end != start+1 {
+ continue
+ }
+
+ frags, next := f.findIndentedComments(i+1, [2]int{end, start})
+ endFrags := frags[0]
+ nextFrags := frags[1]
+ if len(endFrags) > 0 {
+ // if endFrags ends with a newline, don't attach it because it was in between the
+ // two groups, so should be left unattached so we can attach it as spacing in the
+ // second pass
+ _, nl := endFrags[len(endFrags)-1].(*newlineFragment)
+ if nl {
+ f.attachToDecoration(endFrags[0:len(endFrags)-1], f.decorations, frag)
+ } else {
+ f.attachToDecoration(endFrags, f.decorations, frag)
+ }
+ }
+ if len(nextFrags) > 0 && next != nil {
+ _, nextStmt := next.Node.(ast.Stmt)
+ _, nextDecl := next.Node.(ast.Decl)
+ nextStart := f.startIndents[next.Node]
+ if (nextStmt || nextDecl) && nextStart == start {
+ f.attachToDecoration(nextFrags, f.decorations, next)
+ }
+ }
+
+ case *commentFragment:
+
+ if frag.Attached != nil {
+ continue
+ }
+
+ // Comments (or comment groups) attach to decoration points in this precedence:
+ //
+ // 1) Before the comment on the same line
+ // 2) After the comment on the same line
+ // 3) After the comment on subsequent lines (but stopping at empty lines)
+ // 4) Before the comment on previous lines (but stopping at empty lines)
+ // 5) After the comment on subsequent lines
+ // 6) Before the comment on previous lines
+ //
+ // We always stop at tokens, strings. If we get to the end without finding a decoration point we panic.
+
+ var frags []fragment // comment / new-line / empty-line
+ var dec *decorationFragment
+ var found bool
+ var try int
+ for !found {
+ try++
+ switch try {
+ case 1:
+ // Before the comment on the same line (search backwards and stop at any newline)
+ frags, dec, found = f.findDecoration(true, true, i, -1, false)
+ case 2:
+ // After the comment on the same line
+ // After the comment on line+1 (search forwards and stop at any empty line)
+ frags, dec, found = f.findDecoration(false, true, i, 1, false)
+ case 3:
+ // Before the comment on line-1 (search backwards and stop at any empty line)
+ frags, dec, found = f.findDecoration(false, true, i, -1, false)
+ case 4:
+ // After the comment on line+2 (search forwards)
+ frags, dec, found = f.findDecoration(false, false, i, 1, false)
+ case 5:
+ // After the comment on line-2 (search backwards)
+ frags, dec, found = f.findDecoration(false, false, i, -1, false)
+ default:
+ panic("no decoration found for " + frag.Text)
+ }
+ }
+ f.attachToDecoration(frags, f.decorations, dec)
+ }
+ }
+
+ // Pass 2: associate any new-lines / empty-lines that have not been added to decorations to node
+ // spacing. If they can't be attached as node spacing, attach them as decorations.
+ for i, frag := range f.fragments {
+ switch frag := frag.(type) {
+ case *newlineFragment:
+
+ if frag.Attached != nil {
+ continue
+ }
+
+ // If the newline is directly before / after a node, we can set the Before / After spacing
+ // of the node decoration instead of adding the newline as a decoration.
+ nodeBefore, _, foundBefore := f.findNode(i, 1)
+ nodeAfter, _, foundAfter := f.findNode(i, -1)
+ if foundBefore || foundAfter {
+ spaceType := dst.NewLine
+ if frag.Empty {
+ spaceType = dst.EmptyLine
+ }
+ if foundBefore {
+ f.before[nodeBefore] = spaceType
+ }
+ if foundAfter {
+ f.after[nodeAfter] = spaceType
+ }
+ continue
+ }
+
+ // If this newline can't be associated with a node, attach it to the next / previous
+ // decoration location:
+ var dec *decorationFragment
+ var found bool
+ var try int
+ for !found {
+ try++
+ switch try {
+ case 1:
+ // search backwards but stop at any token
+ _, dec, found = f.findDecoration(false, false, i, -1, false)
+ case 2:
+ // search forwards but stop at any token
+ _, dec, found = f.findDecoration(false, false, i, 1, false)
+ default:
+ panic("no decoration found for newline")
+ }
+ }
+ appendNewLine(f.decorations, dec.Node, dec.Name, frag.Empty)
+ }
+ }
+
+ return
+}
+
+func appendDecoration(m map[ast.Node]map[string][]string, n ast.Node, pos, text string) {
+ if m[n] == nil {
+ m[n] = map[string][]string{}
+ }
+ m[n][pos] = append(m[n][pos], text)
+}
+
+func appendNewLine(m map[ast.Node]map[string][]string, n ast.Node, pos string, empty bool) {
+ if m[n] == nil {
+ m[n] = map[string][]string{}
+ }
+ num := 1
+ if empty {
+ num = 2
+ }
+ decs := m[n][pos]
+ if len(decs) > 0 && strings.HasPrefix(decs[len(decs)-1], "//") {
+ num--
+ }
+ for i := 0; i < num; i++ {
+ m[n][pos] = append(m[n][pos], "\n")
+ }
+}
+
+func (f *fileDecorator) attachToDecoration(frags []fragment, decorations map[ast.Node]map[string][]string, dec *decorationFragment) {
+ for _, fr := range frags {
+ switch fr := fr.(type) {
+ case *commentFragment:
+ appendDecoration(decorations, dec.Node, dec.Name, fr.Text)
+ fr.Attached = dec
+ case *newlineFragment:
+ appendNewLine(decorations, dec.Node, dec.Name, fr.Empty)
+ fr.Attached = dec
+ }
+ }
+}
+
+func (f *fileDecorator) findDecoration(stopAtNewline, stopAtEmptyLine bool, from int, direction int, onlyClause bool) (swept []fragment, dec *decorationFragment, found bool) {
+ var frags []fragment
+ for i := from; i < len(f.fragments) && i >= 0; i += direction {
+ switch current := f.fragments[i].(type) {
+ case *decorationFragment:
+ if onlyClause {
+ switch current.Node.(type) {
+ case *ast.CommClause, *ast.CaseClause:
+ if current.Name == "Start" {
+ return frags, current, true
+ }
+ return
+ default:
+ return
+ }
+ }
+ return frags, current, true
+ case *newlineFragment:
+ if stopAtNewline {
+ return
+ }
+ if stopAtEmptyLine && current.Empty {
+ return
+ }
+ if current.Attached != nil {
+ continue
+ }
+ if direction == 1 {
+ frags = append(frags, current)
+ } else {
+ frags = append([]fragment{current}, frags...)
+ }
+ case *commentFragment:
+ if current.Attached != nil {
+ continue
+ }
+ if direction == 1 {
+ frags = append(frags, current)
+ } else {
+ frags = append([]fragment{current}, frags...)
+ }
+ case *tokenFragment, *stringFragment:
+ return
+ }
+ }
+ return
+}
+
+func (f *fileDecorator) findNode(from int, direction int) (node ast.Node, dec *decorationFragment, found bool) {
+
+ var name string
+ switch direction {
+ case 1:
+ name = "Start"
+ case -1:
+ name = "End"
+ }
+
+ for i := from; i < len(f.fragments) && i >= 0; i += direction {
+ switch frag := f.fragments[i].(type) {
+ case *decorationFragment:
+ if frag.Name == name {
+ return frag.Node, frag, true
+ }
+ return
+ case *commentFragment:
+ if frag.Attached != nil && frag.Attached.Name == name {
+ return frag.Attached.Node, frag.Attached, true
+ }
+ case *newlineFragment:
+ if frag.Attached != nil && frag.Attached.Name == name {
+ return frag.Attached.Node, frag.Attached, true
+ }
+ case *tokenFragment, *stringFragment:
+ return
+ }
+ }
+ return
+}
+
+func (f *fileDecorator) findIndentedComments(from int, indents [2]int) (frags [2][]fragment, nextDecoration *decorationFragment) {
+ var stage int
+ var pastNewline bool // while this is false, we're on the same line that the stmt ended, so we accept all comments regardless of the indent (e.g. empty clauses) - see "hanging-indent-same-line" test case.
+ for i := from; i < len(f.fragments); i++ {
+ switch current := f.fragments[i].(type) {
+ case *decorationFragment:
+ return frags, current
+ case *newlineFragment:
+ pastNewline = true
+ frags[stage] = append(frags[stage], current)
+ case *commentFragment:
+ if !pastNewline {
+ frags[stage] = append(frags[stage], current)
+ continue
+ }
+ if stage == 0 {
+ // Check indent matches. If not, move to second stage or exit if that doesn't match.
+ if current.Indent != indents[0] {
+ if current.Indent == indents[1] {
+ stage = 1
+ } else {
+ return
+ }
+ }
+ } else if stage == 1 {
+ if current.Indent != indents[1] {
+ return
+ }
+ }
+ frags[stage] = append(frags[stage], current)
+ case *tokenFragment, *stringFragment:
+ return
+ }
+ }
+ return
+}
+
+type fragment interface {
+ Position() token.Pos
+ Newline() bool // True if the fragment ends in a newline ("\n" or "//...")
+}
+
+type tokenFragment struct {
+ Node ast.Node
+ Token token.Token
+ Pos token.Pos
+}
+
+type stringFragment struct {
+ Node ast.Node
+ String string
+ Pos token.Pos
+}
+
+type badFragment struct {
+ Node ast.Node
+ Pos token.Pos
+ Length int
+}
+
+type commentFragment struct {
+ Text string
+ Pos token.Pos
+ Attached *decorationFragment // where did we attach this comment in pass 1?
+ Indent int // indent if this comment follows a newline
+}
+
+type newlineFragment struct {
+ Pos token.Pos
+ Empty bool // true if this newline is an empty line (e.g. follows a "//" comment or "\n")
+ Attached *decorationFragment // where did we attach this comment in pass 1?
+}
+
+type decorationFragment struct {
+ Node ast.Node
+ Name string
+ Pos token.Pos
+}
+
+func (v *tokenFragment) Position() token.Pos { return v.Pos }
+func (v *stringFragment) Position() token.Pos { return v.Pos }
+func (v *commentFragment) Position() token.Pos { return v.Pos }
+func (v *newlineFragment) Position() token.Pos { return v.Pos }
+func (v *decorationFragment) Position() token.Pos { return v.Pos }
+func (v *badFragment) Position() token.Pos { return v.Pos }
+
+func (v *tokenFragment) Newline() bool { return false }
+func (v *stringFragment) Newline() bool { return false }
+func (v *commentFragment) Newline() bool { return strings.HasPrefix(v.Text, "//") }
+func (v *newlineFragment) Newline() bool { return true }
+func (v *decorationFragment) Newline() bool { return false }
+func (v *badFragment) Newline() bool { return false }
+
+func (f fileDecorator) debug(w io.Writer) {
+ formatPos := func(s token.Position) string {
+ return s.String()[strings.Index(s.String(), ":")+1:]
+ }
+ nodeType := func(n ast.Node) string {
+ return strings.Replace(fmt.Sprintf("%T", n), "*ast.", "", -1)
+ }
+ for _, v := range f.fragments {
+ switch v := v.(type) {
+ case *newlineFragment:
+ if v.Empty {
+ fmt.Fprintf(w, "Empty line %s\n", formatPos(f.Fset.Position(v.Pos)))
+ } else {
+ fmt.Fprintf(w, "New line %s\n", formatPos(f.Fset.Position(v.Pos)))
+ }
+ case *tokenFragment:
+ fmt.Fprintf(w, "%s %q %s\n", nodeType(v.Node), v.Token, formatPos(f.Fset.Position(v.Pos)))
+ case *stringFragment:
+ fmt.Fprintf(w, "%s %q %s\n", nodeType(v.Node), v.String, formatPos(f.Fset.Position(v.Pos)))
+ case *decorationFragment:
+ fmt.Fprintf(w, "%s %s %s\n", nodeType(v.Node), v.Name, formatPos(f.Fset.Position(v.Pos)))
+ case *commentFragment:
+ fmt.Fprintf(w, "%q %s\n", v.Text, formatPos(f.Fset.Position(v.Pos)))
+ case *badFragment:
+ fmt.Fprintf(w, "%s %d %s\n", nodeType(v.Node), v.Length, formatPos(f.Fset.Position(v.Pos)))
+ default:
+ fmt.Fprintf(w, "%T %s\n", v, formatPos(f.Fset.Position(v.Position())))
+ }
+ }
+}
diff --git a/vendor/github.com/dave/dst/decorator/decorator-node-generated.go b/vendor/github.com/dave/dst/decorator/decorator-node-generated.go
new file mode 100644
index 00000000..72044ec7
--- /dev/null
+++ b/vendor/github.com/dave/dst/decorator/decorator-node-generated.go
@@ -0,0 +1,2379 @@
+package decorator
+
+import (
+ "github.com/dave/dst"
+ "go/ast"
+ "go/token"
+)
+
+func (f *fileDecorator) decorateNode(parent ast.Node, parentName, parentField, parentFieldType string, n ast.Node) (dst.Node, error) {
+ if dn, ok := f.Dst.Nodes[n]; ok {
+ return dn, nil
+ }
+ switch n := n.(type) {
+ case *ast.ArrayType:
+ out := &dst.ArrayType{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Lbrack
+
+ // Node: Len
+ if n.Len != nil {
+ child, err := f.decorateNode(n, "ArrayType", "Len", "Expr", n.Len)
+ if err != nil {
+ return nil, err
+ }
+ out.Len = child.(dst.Expr)
+ }
+
+ // Token: Rbrack
+
+ // Node: Elt
+ if n.Elt != nil {
+ child, err := f.decorateNode(n, "ArrayType", "Elt", "Expr", n.Elt)
+ if err != nil {
+ return nil, err
+ }
+ out.Elt = child.(dst.Expr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Lbrack"]; ok {
+ out.Decs.Lbrack = decs
+ }
+ if decs, ok := nd["Len"]; ok {
+ out.Decs.Len = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.AssignStmt:
+ out := &dst.AssignStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // List: Lhs
+ for _, v := range n.Lhs {
+ child, err := f.decorateNode(n, "AssignStmt", "Lhs", "Expr", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Lhs = append(out.Lhs, child.(dst.Expr))
+ }
+
+ // Token: Tok
+ out.Tok = n.Tok
+
+ // List: Rhs
+ for _, v := range n.Rhs {
+ child, err := f.decorateNode(n, "AssignStmt", "Rhs", "Expr", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Rhs = append(out.Rhs, child.(dst.Expr))
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Tok"]; ok {
+ out.Decs.Tok = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.BadDecl:
+ out := &dst.BadDecl{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Bad
+ out.Length = int(n.To - n.From)
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.BadExpr:
+ out := &dst.BadExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Bad
+ out.Length = int(n.To - n.From)
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.BadStmt:
+ out := &dst.BadStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Bad
+ out.Length = int(n.To - n.From)
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.BasicLit:
+ out := &dst.BasicLit{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // String: Value
+ out.Value = n.Value
+
+ // Value: Kind
+ out.Kind = n.Kind
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.BinaryExpr:
+ out := &dst.BinaryExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "BinaryExpr", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ // Token: Op
+ out.Op = n.Op
+
+ // Node: Y
+ if n.Y != nil {
+ child, err := f.decorateNode(n, "BinaryExpr", "Y", "Expr", n.Y)
+ if err != nil {
+ return nil, err
+ }
+ out.Y = child.(dst.Expr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["X"]; ok {
+ out.Decs.X = decs
+ }
+ if decs, ok := nd["Op"]; ok {
+ out.Decs.Op = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.BlockStmt:
+ out := &dst.BlockStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Lbrace
+
+ // List: List
+ for _, v := range n.List {
+ child, err := f.decorateNode(n, "BlockStmt", "List", "Stmt", v)
+ if err != nil {
+ return nil, err
+ }
+ out.List = append(out.List, child.(dst.Stmt))
+ }
+
+ // Token: Rbrace
+ if n.Rbrace == token.NoPos {
+ out.RbraceHasNoPos = true
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Lbrace"]; ok {
+ out.Decs.Lbrace = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.BranchStmt:
+ out := &dst.BranchStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Tok
+ out.Tok = n.Tok
+
+ // Node: Label
+ if n.Label != nil {
+ child, err := f.decorateNode(n, "BranchStmt", "Label", "Ident", n.Label)
+ if err != nil {
+ return nil, err
+ }
+ out.Label = child.(*dst.Ident)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Tok"]; ok {
+ out.Decs.Tok = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.CallExpr:
+ out := &dst.CallExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: Fun
+ if n.Fun != nil {
+ child, err := f.decorateNode(n, "CallExpr", "Fun", "Expr", n.Fun)
+ if err != nil {
+ return nil, err
+ }
+ out.Fun = child.(dst.Expr)
+ }
+
+ // Token: Lparen
+
+ // List: Args
+ for _, v := range n.Args {
+ child, err := f.decorateNode(n, "CallExpr", "Args", "Expr", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Args = append(out.Args, child.(dst.Expr))
+ }
+
+ // Token: Ellipsis
+ out.Ellipsis = n.Ellipsis.IsValid()
+
+ // Token: Rparen
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Fun"]; ok {
+ out.Decs.Fun = decs
+ }
+ if decs, ok := nd["Lparen"]; ok {
+ out.Decs.Lparen = decs
+ }
+ if decs, ok := nd["Ellipsis"]; ok {
+ out.Decs.Ellipsis = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.CaseClause:
+ out := &dst.CaseClause{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Case
+
+ // List: List
+ for _, v := range n.List {
+ child, err := f.decorateNode(n, "CaseClause", "List", "Expr", v)
+ if err != nil {
+ return nil, err
+ }
+ out.List = append(out.List, child.(dst.Expr))
+ }
+
+ // Token: Colon
+
+ // List: Body
+ for _, v := range n.Body {
+ child, err := f.decorateNode(n, "CaseClause", "Body", "Stmt", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Body = append(out.Body, child.(dst.Stmt))
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Case"]; ok {
+ out.Decs.Case = decs
+ }
+ if decs, ok := nd["Colon"]; ok {
+ out.Decs.Colon = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.ChanType:
+ out := &dst.ChanType{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Begin
+
+ // Token: Chan
+
+ // Token: Arrow
+
+ // Node: Value
+ if n.Value != nil {
+ child, err := f.decorateNode(n, "ChanType", "Value", "Expr", n.Value)
+ if err != nil {
+ return nil, err
+ }
+ out.Value = child.(dst.Expr)
+ }
+
+ // Value: Dir
+ out.Dir = dst.ChanDir(n.Dir)
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Begin"]; ok {
+ out.Decs.Begin = decs
+ }
+ if decs, ok := nd["Arrow"]; ok {
+ out.Decs.Arrow = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.CommClause:
+ out := &dst.CommClause{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Case
+
+ // Node: Comm
+ if n.Comm != nil {
+ child, err := f.decorateNode(n, "CommClause", "Comm", "Stmt", n.Comm)
+ if err != nil {
+ return nil, err
+ }
+ out.Comm = child.(dst.Stmt)
+ }
+
+ // Token: Colon
+
+ // List: Body
+ for _, v := range n.Body {
+ child, err := f.decorateNode(n, "CommClause", "Body", "Stmt", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Body = append(out.Body, child.(dst.Stmt))
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Case"]; ok {
+ out.Decs.Case = decs
+ }
+ if decs, ok := nd["Comm"]; ok {
+ out.Decs.Comm = decs
+ }
+ if decs, ok := nd["Colon"]; ok {
+ out.Decs.Colon = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.CompositeLit:
+ out := &dst.CompositeLit{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: Type
+ if n.Type != nil {
+ child, err := f.decorateNode(n, "CompositeLit", "Type", "Expr", n.Type)
+ if err != nil {
+ return nil, err
+ }
+ out.Type = child.(dst.Expr)
+ }
+
+ // Token: Lbrace
+
+ // List: Elts
+ for _, v := range n.Elts {
+ child, err := f.decorateNode(n, "CompositeLit", "Elts", "Expr", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Elts = append(out.Elts, child.(dst.Expr))
+ }
+
+ // Token: Rbrace
+
+ // Value: Incomplete
+ out.Incomplete = n.Incomplete
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Type"]; ok {
+ out.Decs.Type = decs
+ }
+ if decs, ok := nd["Lbrace"]; ok {
+ out.Decs.Lbrace = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.DeclStmt:
+ out := &dst.DeclStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: Decl
+ if n.Decl != nil {
+ child, err := f.decorateNode(n, "DeclStmt", "Decl", "Decl", n.Decl)
+ if err != nil {
+ return nil, err
+ }
+ out.Decl = child.(dst.Decl)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.DeferStmt:
+ out := &dst.DeferStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Defer
+
+ // Node: Call
+ if n.Call != nil {
+ child, err := f.decorateNode(n, "DeferStmt", "Call", "CallExpr", n.Call)
+ if err != nil {
+ return nil, err
+ }
+ out.Call = child.(*dst.CallExpr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Defer"]; ok {
+ out.Decs.Defer = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.Ellipsis:
+ out := &dst.Ellipsis{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Ellipsis
+
+ // Node: Elt
+ if n.Elt != nil {
+ child, err := f.decorateNode(n, "Ellipsis", "Elt", "Expr", n.Elt)
+ if err != nil {
+ return nil, err
+ }
+ out.Elt = child.(dst.Expr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Ellipsis"]; ok {
+ out.Decs.Ellipsis = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.EmptyStmt:
+ out := &dst.EmptyStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Semicolon
+
+ // Value: Implicit
+ out.Implicit = n.Implicit
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.ExprStmt:
+ out := &dst.ExprStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "ExprStmt", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.Field:
+ out := &dst.Field{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // List: Names
+ for _, v := range n.Names {
+ child, err := f.decorateNode(n, "Field", "Names", "Ident", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Names = append(out.Names, child.(*dst.Ident))
+ }
+
+ // Node: Type
+ if n.Type != nil {
+ child, err := f.decorateNode(n, "Field", "Type", "Expr", n.Type)
+ if err != nil {
+ return nil, err
+ }
+ out.Type = child.(dst.Expr)
+ }
+
+ // Node: Tag
+ if n.Tag != nil {
+ child, err := f.decorateNode(n, "Field", "Tag", "BasicLit", n.Tag)
+ if err != nil {
+ return nil, err
+ }
+ out.Tag = child.(*dst.BasicLit)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Type"]; ok {
+ out.Decs.Type = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.FieldList:
+ out := &dst.FieldList{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Opening
+ out.Opening = n.Opening.IsValid()
+
+ // List: List
+ for _, v := range n.List {
+ child, err := f.decorateNode(n, "FieldList", "List", "Field", v)
+ if err != nil {
+ return nil, err
+ }
+ out.List = append(out.List, child.(*dst.Field))
+ }
+
+ // Token: Closing
+ out.Closing = n.Closing.IsValid()
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Opening"]; ok {
+ out.Decs.Opening = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.File:
+ out := &dst.File{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Package
+
+ // Node: Name
+ if n.Name != nil {
+ child, err := f.decorateNode(n, "File", "Name", "Ident", n.Name)
+ if err != nil {
+ return nil, err
+ }
+ out.Name = child.(*dst.Ident)
+ }
+
+ // List: Decls
+ for _, v := range n.Decls {
+ child, err := f.decorateNode(n, "File", "Decls", "Decl", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Decls = append(out.Decls, child.(dst.Decl))
+ }
+
+ // Scope: Scope
+ scope, err := f.decorateScope(n.Scope)
+ if err != nil {
+ return nil, err
+ }
+ out.Scope = scope
+
+ // List: Imports
+ for _, v := range n.Imports {
+ child, err := f.decorateNode(n, "File", "Imports", "ImportSpec", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Imports = append(out.Imports, child.(*dst.ImportSpec))
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Package"]; ok {
+ out.Decs.Package = decs
+ }
+ if decs, ok := nd["Name"]; ok {
+ out.Decs.Name = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.ForStmt:
+ out := &dst.ForStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: For
+
+ // Node: Init
+ if n.Init != nil {
+ child, err := f.decorateNode(n, "ForStmt", "Init", "Stmt", n.Init)
+ if err != nil {
+ return nil, err
+ }
+ out.Init = child.(dst.Stmt)
+ }
+
+ // Token: InitSemicolon
+
+ // Node: Cond
+ if n.Cond != nil {
+ child, err := f.decorateNode(n, "ForStmt", "Cond", "Expr", n.Cond)
+ if err != nil {
+ return nil, err
+ }
+ out.Cond = child.(dst.Expr)
+ }
+
+ // Token: CondSemicolon
+
+ // Node: Post
+ if n.Post != nil {
+ child, err := f.decorateNode(n, "ForStmt", "Post", "Stmt", n.Post)
+ if err != nil {
+ return nil, err
+ }
+ out.Post = child.(dst.Stmt)
+ }
+
+ // Node: Body
+ if n.Body != nil {
+ child, err := f.decorateNode(n, "ForStmt", "Body", "BlockStmt", n.Body)
+ if err != nil {
+ return nil, err
+ }
+ out.Body = child.(*dst.BlockStmt)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["For"]; ok {
+ out.Decs.For = decs
+ }
+ if decs, ok := nd["Init"]; ok {
+ out.Decs.Init = decs
+ }
+ if decs, ok := nd["Cond"]; ok {
+ out.Decs.Cond = decs
+ }
+ if decs, ok := nd["Post"]; ok {
+ out.Decs.Post = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.FuncDecl:
+ out := &dst.FuncDecl{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Init: Type
+ out.Type = &dst.FuncType{}
+ f.Dst.Nodes[n.Type] = out.Type
+ f.Ast.Nodes[out.Type] = n.Type
+
+ // Token: Func
+ out.Type.Func = true
+
+ // Node: Recv
+ if n.Recv != nil {
+ child, err := f.decorateNode(n, "FuncDecl", "Recv", "FieldList", n.Recv)
+ if err != nil {
+ return nil, err
+ }
+ out.Recv = child.(*dst.FieldList)
+ }
+
+ // Node: Name
+ if n.Name != nil {
+ child, err := f.decorateNode(n, "FuncDecl", "Name", "Ident", n.Name)
+ if err != nil {
+ return nil, err
+ }
+ out.Name = child.(*dst.Ident)
+ }
+
+ // Node: TypeParams
+ if n.Type.TypeParams != nil {
+ child, err := f.decorateNode(n, "FuncDecl", "TypeParams", "FieldList", n.Type.TypeParams)
+ if err != nil {
+ return nil, err
+ }
+ out.Type.TypeParams = child.(*dst.FieldList)
+ }
+
+ // Node: Params
+ if n.Type.Params != nil {
+ child, err := f.decorateNode(n, "FuncDecl", "Params", "FieldList", n.Type.Params)
+ if err != nil {
+ return nil, err
+ }
+ out.Type.Params = child.(*dst.FieldList)
+ }
+
+ // Node: Results
+ if n.Type.Results != nil {
+ child, err := f.decorateNode(n, "FuncDecl", "Results", "FieldList", n.Type.Results)
+ if err != nil {
+ return nil, err
+ }
+ out.Type.Results = child.(*dst.FieldList)
+ }
+
+ // Node: Body
+ if n.Body != nil {
+ child, err := f.decorateNode(n, "FuncDecl", "Body", "BlockStmt", n.Body)
+ if err != nil {
+ return nil, err
+ }
+ out.Body = child.(*dst.BlockStmt)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Func"]; ok {
+ out.Decs.Func = decs
+ }
+ if decs, ok := nd["Recv"]; ok {
+ out.Decs.Recv = decs
+ }
+ if decs, ok := nd["Name"]; ok {
+ out.Decs.Name = decs
+ }
+ if decs, ok := nd["TypeParams"]; ok {
+ out.Decs.TypeParams = decs
+ }
+ if decs, ok := nd["Params"]; ok {
+ out.Decs.Params = decs
+ }
+ if decs, ok := nd["Results"]; ok {
+ out.Decs.Results = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.FuncLit:
+ out := &dst.FuncLit{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: Type
+ if n.Type != nil {
+ child, err := f.decorateNode(n, "FuncLit", "Type", "FuncType", n.Type)
+ if err != nil {
+ return nil, err
+ }
+ out.Type = child.(*dst.FuncType)
+ }
+
+ // Node: Body
+ if n.Body != nil {
+ child, err := f.decorateNode(n, "FuncLit", "Body", "BlockStmt", n.Body)
+ if err != nil {
+ return nil, err
+ }
+ out.Body = child.(*dst.BlockStmt)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Type"]; ok {
+ out.Decs.Type = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.FuncType:
+ out := &dst.FuncType{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Func
+ out.Func = n.Func.IsValid()
+
+ // Node: TypeParams
+ if n.TypeParams != nil {
+ child, err := f.decorateNode(n, "FuncType", "TypeParams", "FieldList", n.TypeParams)
+ if err != nil {
+ return nil, err
+ }
+ out.TypeParams = child.(*dst.FieldList)
+ }
+
+ // Node: Params
+ if n.Params != nil {
+ child, err := f.decorateNode(n, "FuncType", "Params", "FieldList", n.Params)
+ if err != nil {
+ return nil, err
+ }
+ out.Params = child.(*dst.FieldList)
+ }
+
+ // Node: Results
+ if n.Results != nil {
+ child, err := f.decorateNode(n, "FuncType", "Results", "FieldList", n.Results)
+ if err != nil {
+ return nil, err
+ }
+ out.Results = child.(*dst.FieldList)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Func"]; ok {
+ out.Decs.Func = decs
+ }
+ if decs, ok := nd["TypeParams"]; ok {
+ out.Decs.TypeParams = decs
+ }
+ if decs, ok := nd["Params"]; ok {
+ out.Decs.Params = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.GenDecl:
+ out := &dst.GenDecl{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Tok
+ out.Tok = n.Tok
+
+ // Token: Lparen
+ out.Lparen = n.Lparen.IsValid()
+
+ // List: Specs
+ for _, v := range n.Specs {
+ child, err := f.decorateNode(n, "GenDecl", "Specs", "Spec", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Specs = append(out.Specs, child.(dst.Spec))
+ }
+
+ // Token: Rparen
+ out.Rparen = n.Rparen.IsValid()
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Tok"]; ok {
+ out.Decs.Tok = decs
+ }
+ if decs, ok := nd["Lparen"]; ok {
+ out.Decs.Lparen = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.GoStmt:
+ out := &dst.GoStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Go
+
+ // Node: Call
+ if n.Call != nil {
+ child, err := f.decorateNode(n, "GoStmt", "Call", "CallExpr", n.Call)
+ if err != nil {
+ return nil, err
+ }
+ out.Call = child.(*dst.CallExpr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Go"]; ok {
+ out.Decs.Go = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.Ident:
+ out := &dst.Ident{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // String: Name
+ out.Name = n.Name
+
+ // Object: Obj
+ ob, err := f.decorateObject(n.Obj)
+ if err != nil {
+ return nil, err
+ }
+ out.Obj = ob
+
+ // Path: Path
+ if f.Resolver != nil {
+ path, err := f.resolvePath(false, parent, parentName, parentField, parentFieldType, n)
+ if err != nil {
+ return nil, err
+ }
+ out.Path = path
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["X"]; ok {
+ out.Decs.X = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.IfStmt:
+ out := &dst.IfStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: If
+
+ // Node: Init
+ if n.Init != nil {
+ child, err := f.decorateNode(n, "IfStmt", "Init", "Stmt", n.Init)
+ if err != nil {
+ return nil, err
+ }
+ out.Init = child.(dst.Stmt)
+ }
+
+ // Node: Cond
+ if n.Cond != nil {
+ child, err := f.decorateNode(n, "IfStmt", "Cond", "Expr", n.Cond)
+ if err != nil {
+ return nil, err
+ }
+ out.Cond = child.(dst.Expr)
+ }
+
+ // Node: Body
+ if n.Body != nil {
+ child, err := f.decorateNode(n, "IfStmt", "Body", "BlockStmt", n.Body)
+ if err != nil {
+ return nil, err
+ }
+ out.Body = child.(*dst.BlockStmt)
+ }
+
+ // Token: ElseTok
+
+ // Node: Else
+ if n.Else != nil {
+ child, err := f.decorateNode(n, "IfStmt", "Else", "Stmt", n.Else)
+ if err != nil {
+ return nil, err
+ }
+ out.Else = child.(dst.Stmt)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["If"]; ok {
+ out.Decs.If = decs
+ }
+ if decs, ok := nd["Init"]; ok {
+ out.Decs.Init = decs
+ }
+ if decs, ok := nd["Cond"]; ok {
+ out.Decs.Cond = decs
+ }
+ if decs, ok := nd["Else"]; ok {
+ out.Decs.Else = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.ImportSpec:
+ out := &dst.ImportSpec{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: Name
+ if n.Name != nil {
+ child, err := f.decorateNode(n, "ImportSpec", "Name", "Ident", n.Name)
+ if err != nil {
+ return nil, err
+ }
+ out.Name = child.(*dst.Ident)
+ }
+
+ // Node: Path
+ if n.Path != nil {
+ child, err := f.decorateNode(n, "ImportSpec", "Path", "BasicLit", n.Path)
+ if err != nil {
+ return nil, err
+ }
+ out.Path = child.(*dst.BasicLit)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Name"]; ok {
+ out.Decs.Name = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.IncDecStmt:
+ out := &dst.IncDecStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "IncDecStmt", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ // Token: Tok
+ out.Tok = n.Tok
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["X"]; ok {
+ out.Decs.X = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.IndexExpr:
+ out := &dst.IndexExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "IndexExpr", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ // Token: Lbrack
+
+ // Node: Index
+ if n.Index != nil {
+ child, err := f.decorateNode(n, "IndexExpr", "Index", "Expr", n.Index)
+ if err != nil {
+ return nil, err
+ }
+ out.Index = child.(dst.Expr)
+ }
+
+ // Token: Rbrack
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["X"]; ok {
+ out.Decs.X = decs
+ }
+ if decs, ok := nd["Lbrack"]; ok {
+ out.Decs.Lbrack = decs
+ }
+ if decs, ok := nd["Index"]; ok {
+ out.Decs.Index = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.IndexListExpr:
+ out := &dst.IndexListExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "IndexListExpr", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ // Token: Lbrack
+
+ // List: Indices
+ for _, v := range n.Indices {
+ child, err := f.decorateNode(n, "IndexListExpr", "Indices", "Expr", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Indices = append(out.Indices, child.(dst.Expr))
+ }
+
+ // Token: Rbrack
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["X"]; ok {
+ out.Decs.X = decs
+ }
+ if decs, ok := nd["Lbrack"]; ok {
+ out.Decs.Lbrack = decs
+ }
+ if decs, ok := nd["Indices"]; ok {
+ out.Decs.Indices = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.InterfaceType:
+ out := &dst.InterfaceType{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Interface
+
+ // Node: Methods
+ if n.Methods != nil {
+ child, err := f.decorateNode(n, "InterfaceType", "Methods", "FieldList", n.Methods)
+ if err != nil {
+ return nil, err
+ }
+ out.Methods = child.(*dst.FieldList)
+ }
+
+ // Value: Incomplete
+ out.Incomplete = n.Incomplete
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Interface"]; ok {
+ out.Decs.Interface = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.KeyValueExpr:
+ out := &dst.KeyValueExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: Key
+ if n.Key != nil {
+ child, err := f.decorateNode(n, "KeyValueExpr", "Key", "Expr", n.Key)
+ if err != nil {
+ return nil, err
+ }
+ out.Key = child.(dst.Expr)
+ }
+
+ // Token: Colon
+
+ // Node: Value
+ if n.Value != nil {
+ child, err := f.decorateNode(n, "KeyValueExpr", "Value", "Expr", n.Value)
+ if err != nil {
+ return nil, err
+ }
+ out.Value = child.(dst.Expr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Key"]; ok {
+ out.Decs.Key = decs
+ }
+ if decs, ok := nd["Colon"]; ok {
+ out.Decs.Colon = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.LabeledStmt:
+ out := &dst.LabeledStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: Label
+ if n.Label != nil {
+ child, err := f.decorateNode(n, "LabeledStmt", "Label", "Ident", n.Label)
+ if err != nil {
+ return nil, err
+ }
+ out.Label = child.(*dst.Ident)
+ }
+
+ // Token: Colon
+
+ // Node: Stmt
+ if n.Stmt != nil {
+ child, err := f.decorateNode(n, "LabeledStmt", "Stmt", "Stmt", n.Stmt)
+ if err != nil {
+ return nil, err
+ }
+ out.Stmt = child.(dst.Stmt)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Label"]; ok {
+ out.Decs.Label = decs
+ }
+ if decs, ok := nd["Colon"]; ok {
+ out.Decs.Colon = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.MapType:
+ out := &dst.MapType{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Map
+
+ // Token: Lbrack
+
+ // Node: Key
+ if n.Key != nil {
+ child, err := f.decorateNode(n, "MapType", "Key", "Expr", n.Key)
+ if err != nil {
+ return nil, err
+ }
+ out.Key = child.(dst.Expr)
+ }
+
+ // Token: Rbrack
+
+ // Node: Value
+ if n.Value != nil {
+ child, err := f.decorateNode(n, "MapType", "Value", "Expr", n.Value)
+ if err != nil {
+ return nil, err
+ }
+ out.Value = child.(dst.Expr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Map"]; ok {
+ out.Decs.Map = decs
+ }
+ if decs, ok := nd["Key"]; ok {
+ out.Decs.Key = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.Package:
+ out := &dst.Package{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ // Value: Name
+ out.Name = n.Name
+
+ // Scope: Scope
+ scope, err := f.decorateScope(n.Scope)
+ if err != nil {
+ return nil, err
+ }
+ out.Scope = scope
+
+ // Map: Imports
+ out.Imports = map[string]*dst.Object{}
+ for k, v := range n.Imports {
+ ob, err := f.decorateObject(v)
+ if err != nil {
+ return nil, err
+ }
+ out.Imports[k] = ob
+ }
+
+ // Map: Files
+ out.Files = map[string]*dst.File{}
+ for k, v := range n.Files {
+ child, err := f.decorateNode(n, "Package", "Files", "File", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Files[k] = child.(*dst.File)
+ }
+
+ return out, nil
+ case *ast.ParenExpr:
+ out := &dst.ParenExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Lparen
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "ParenExpr", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ // Token: Rparen
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Lparen"]; ok {
+ out.Decs.Lparen = decs
+ }
+ if decs, ok := nd["X"]; ok {
+ out.Decs.X = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.RangeStmt:
+ out := &dst.RangeStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: For
+
+ // Node: Key
+ if n.Key != nil {
+ child, err := f.decorateNode(n, "RangeStmt", "Key", "Expr", n.Key)
+ if err != nil {
+ return nil, err
+ }
+ out.Key = child.(dst.Expr)
+ }
+
+ // Token: Comma
+
+ // Node: Value
+ if n.Value != nil {
+ child, err := f.decorateNode(n, "RangeStmt", "Value", "Expr", n.Value)
+ if err != nil {
+ return nil, err
+ }
+ out.Value = child.(dst.Expr)
+ }
+
+ // Token: Tok
+ out.Tok = n.Tok
+
+ // Token: Range
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "RangeStmt", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ // Node: Body
+ if n.Body != nil {
+ child, err := f.decorateNode(n, "RangeStmt", "Body", "BlockStmt", n.Body)
+ if err != nil {
+ return nil, err
+ }
+ out.Body = child.(*dst.BlockStmt)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["For"]; ok {
+ out.Decs.For = decs
+ }
+ if decs, ok := nd["Key"]; ok {
+ out.Decs.Key = decs
+ }
+ if decs, ok := nd["Value"]; ok {
+ out.Decs.Value = decs
+ }
+ if decs, ok := nd["Range"]; ok {
+ out.Decs.Range = decs
+ }
+ if decs, ok := nd["X"]; ok {
+ out.Decs.X = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.ReturnStmt:
+ out := &dst.ReturnStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Return
+
+ // List: Results
+ for _, v := range n.Results {
+ child, err := f.decorateNode(n, "ReturnStmt", "Results", "Expr", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Results = append(out.Results, child.(dst.Expr))
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Return"]; ok {
+ out.Decs.Return = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.SelectStmt:
+ out := &dst.SelectStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Select
+
+ // Node: Body
+ if n.Body != nil {
+ child, err := f.decorateNode(n, "SelectStmt", "Body", "BlockStmt", n.Body)
+ if err != nil {
+ return nil, err
+ }
+ out.Body = child.(*dst.BlockStmt)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Select"]; ok {
+ out.Decs.Select = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.SelectorExpr:
+
+ // Special case for *ast.SelectorExpr - replace with Ident if needed
+ id, err := f.decorateSelectorExpr(parent, parentName, parentField, parentFieldType, n)
+ if err != nil {
+ return nil, err
+ }
+ if id != nil {
+ return id, nil
+ }
+
+ out := &dst.SelectorExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "SelectorExpr", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ // Token: Period
+
+ // Node: Sel
+ if n.Sel != nil {
+ child, err := f.decorateNode(n, "SelectorExpr", "Sel", "Ident", n.Sel)
+ if err != nil {
+ return nil, err
+ }
+ out.Sel = child.(*dst.Ident)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["X"]; ok {
+ out.Decs.X = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.SendStmt:
+ out := &dst.SendStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: Chan
+ if n.Chan != nil {
+ child, err := f.decorateNode(n, "SendStmt", "Chan", "Expr", n.Chan)
+ if err != nil {
+ return nil, err
+ }
+ out.Chan = child.(dst.Expr)
+ }
+
+ // Token: Arrow
+
+ // Node: Value
+ if n.Value != nil {
+ child, err := f.decorateNode(n, "SendStmt", "Value", "Expr", n.Value)
+ if err != nil {
+ return nil, err
+ }
+ out.Value = child.(dst.Expr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Chan"]; ok {
+ out.Decs.Chan = decs
+ }
+ if decs, ok := nd["Arrow"]; ok {
+ out.Decs.Arrow = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.SliceExpr:
+ out := &dst.SliceExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "SliceExpr", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ // Token: Lbrack
+
+ // Node: Low
+ if n.Low != nil {
+ child, err := f.decorateNode(n, "SliceExpr", "Low", "Expr", n.Low)
+ if err != nil {
+ return nil, err
+ }
+ out.Low = child.(dst.Expr)
+ }
+
+ // Token: Colon1
+
+ // Node: High
+ if n.High != nil {
+ child, err := f.decorateNode(n, "SliceExpr", "High", "Expr", n.High)
+ if err != nil {
+ return nil, err
+ }
+ out.High = child.(dst.Expr)
+ }
+
+ // Token: Colon2
+
+ // Node: Max
+ if n.Max != nil {
+ child, err := f.decorateNode(n, "SliceExpr", "Max", "Expr", n.Max)
+ if err != nil {
+ return nil, err
+ }
+ out.Max = child.(dst.Expr)
+ }
+
+ // Token: Rbrack
+
+ // Value: Slice3
+ out.Slice3 = n.Slice3
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["X"]; ok {
+ out.Decs.X = decs
+ }
+ if decs, ok := nd["Lbrack"]; ok {
+ out.Decs.Lbrack = decs
+ }
+ if decs, ok := nd["Low"]; ok {
+ out.Decs.Low = decs
+ }
+ if decs, ok := nd["High"]; ok {
+ out.Decs.High = decs
+ }
+ if decs, ok := nd["Max"]; ok {
+ out.Decs.Max = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.StarExpr:
+ out := &dst.StarExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Star
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "StarExpr", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Star"]; ok {
+ out.Decs.Star = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.StructType:
+ out := &dst.StructType{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Struct
+
+ // Node: Fields
+ if n.Fields != nil {
+ child, err := f.decorateNode(n, "StructType", "Fields", "FieldList", n.Fields)
+ if err != nil {
+ return nil, err
+ }
+ out.Fields = child.(*dst.FieldList)
+ }
+
+ // Value: Incomplete
+ out.Incomplete = n.Incomplete
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Struct"]; ok {
+ out.Decs.Struct = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.SwitchStmt:
+ out := &dst.SwitchStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Switch
+
+ // Node: Init
+ if n.Init != nil {
+ child, err := f.decorateNode(n, "SwitchStmt", "Init", "Stmt", n.Init)
+ if err != nil {
+ return nil, err
+ }
+ out.Init = child.(dst.Stmt)
+ }
+
+ // Node: Tag
+ if n.Tag != nil {
+ child, err := f.decorateNode(n, "SwitchStmt", "Tag", "Expr", n.Tag)
+ if err != nil {
+ return nil, err
+ }
+ out.Tag = child.(dst.Expr)
+ }
+
+ // Node: Body
+ if n.Body != nil {
+ child, err := f.decorateNode(n, "SwitchStmt", "Body", "BlockStmt", n.Body)
+ if err != nil {
+ return nil, err
+ }
+ out.Body = child.(*dst.BlockStmt)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Switch"]; ok {
+ out.Decs.Switch = decs
+ }
+ if decs, ok := nd["Init"]; ok {
+ out.Decs.Init = decs
+ }
+ if decs, ok := nd["Tag"]; ok {
+ out.Decs.Tag = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.TypeAssertExpr:
+ out := &dst.TypeAssertExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "TypeAssertExpr", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ // Token: Period
+
+ // Token: Lparen
+
+ // Node: Type
+ if n.Type != nil {
+ child, err := f.decorateNode(n, "TypeAssertExpr", "Type", "Expr", n.Type)
+ if err != nil {
+ return nil, err
+ }
+ out.Type = child.(dst.Expr)
+ }
+
+ // Token: TypeToken
+
+ // Token: Rparen
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["X"]; ok {
+ out.Decs.X = decs
+ }
+ if decs, ok := nd["Lparen"]; ok {
+ out.Decs.Lparen = decs
+ }
+ if decs, ok := nd["Type"]; ok {
+ out.Decs.Type = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.TypeSpec:
+ out := &dst.TypeSpec{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Node: Name
+ if n.Name != nil {
+ child, err := f.decorateNode(n, "TypeSpec", "Name", "Ident", n.Name)
+ if err != nil {
+ return nil, err
+ }
+ out.Name = child.(*dst.Ident)
+ }
+
+ // Token: Assign
+ out.Assign = n.Assign.IsValid()
+
+ // Node: TypeParams
+ if n.TypeParams != nil {
+ child, err := f.decorateNode(n, "TypeSpec", "TypeParams", "FieldList", n.TypeParams)
+ if err != nil {
+ return nil, err
+ }
+ out.TypeParams = child.(*dst.FieldList)
+ }
+
+ // Node: Type
+ if n.Type != nil {
+ child, err := f.decorateNode(n, "TypeSpec", "Type", "Expr", n.Type)
+ if err != nil {
+ return nil, err
+ }
+ out.Type = child.(dst.Expr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Name"]; ok {
+ out.Decs.Name = decs
+ }
+ if decs, ok := nd["TypeParams"]; ok {
+ out.Decs.TypeParams = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.TypeSwitchStmt:
+ out := &dst.TypeSwitchStmt{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Switch
+
+ // Node: Init
+ if n.Init != nil {
+ child, err := f.decorateNode(n, "TypeSwitchStmt", "Init", "Stmt", n.Init)
+ if err != nil {
+ return nil, err
+ }
+ out.Init = child.(dst.Stmt)
+ }
+
+ // Node: Assign
+ if n.Assign != nil {
+ child, err := f.decorateNode(n, "TypeSwitchStmt", "Assign", "Stmt", n.Assign)
+ if err != nil {
+ return nil, err
+ }
+ out.Assign = child.(dst.Stmt)
+ }
+
+ // Node: Body
+ if n.Body != nil {
+ child, err := f.decorateNode(n, "TypeSwitchStmt", "Body", "BlockStmt", n.Body)
+ if err != nil {
+ return nil, err
+ }
+ out.Body = child.(*dst.BlockStmt)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Switch"]; ok {
+ out.Decs.Switch = decs
+ }
+ if decs, ok := nd["Init"]; ok {
+ out.Decs.Init = decs
+ }
+ if decs, ok := nd["Assign"]; ok {
+ out.Decs.Assign = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.UnaryExpr:
+ out := &dst.UnaryExpr{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // Token: Op
+ out.Op = n.Op
+
+ // Node: X
+ if n.X != nil {
+ child, err := f.decorateNode(n, "UnaryExpr", "X", "Expr", n.X)
+ if err != nil {
+ return nil, err
+ }
+ out.X = child.(dst.Expr)
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Op"]; ok {
+ out.Decs.Op = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ case *ast.ValueSpec:
+ out := &dst.ValueSpec{}
+ f.Dst.Nodes[n] = out
+ f.Ast.Nodes[out] = n
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ // List: Names
+ for _, v := range n.Names {
+ child, err := f.decorateNode(n, "ValueSpec", "Names", "Ident", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Names = append(out.Names, child.(*dst.Ident))
+ }
+
+ // Node: Type
+ if n.Type != nil {
+ child, err := f.decorateNode(n, "ValueSpec", "Type", "Expr", n.Type)
+ if err != nil {
+ return nil, err
+ }
+ out.Type = child.(dst.Expr)
+ }
+
+ // Token: Assign
+
+ // List: Values
+ for _, v := range n.Values {
+ child, err := f.decorateNode(n, "ValueSpec", "Values", "Expr", v)
+ if err != nil {
+ return nil, err
+ }
+ out.Values = append(out.Values, child.(dst.Expr))
+ }
+
+ if nd, ok := f.decorations[n]; ok {
+ if decs, ok := nd["Start"]; ok {
+ out.Decs.Start = decs
+ }
+ if decs, ok := nd["Assign"]; ok {
+ out.Decs.Assign = decs
+ }
+ if decs, ok := nd["End"]; ok {
+ out.Decs.End = decs
+ }
+ }
+
+ return out, nil
+ }
+ return nil, nil
+}
diff --git a/vendor/github.com/dave/dst/decorator/decorator.go b/vendor/github.com/dave/dst/decorator/decorator.go
new file mode 100644
index 00000000..dc9eaef7
--- /dev/null
+++ b/vendor/github.com/dave/dst/decorator/decorator.go
@@ -0,0 +1,560 @@
+package decorator
+
+import (
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "io"
+ "os"
+ "strings"
+
+ "github.com/dave/dst"
+ "github.com/dave/dst/decorator/resolver"
+ "github.com/dave/dst/decorator/resolver/gotypes"
+ "github.com/dave/dst/dstutil"
+ "golang.org/x/tools/go/packages"
+)
+
+// NewDecorator returns a new decorator. If fset is nil, a new FileSet is created.
+func NewDecorator(fset *token.FileSet) *Decorator {
+ if fset == nil {
+ fset = token.NewFileSet()
+ }
+ return &Decorator{
+ Map: newMap(),
+ Filenames: map[*dst.File]string{},
+ Fset: fset,
+ }
+}
+
+// NewDecoratorWithImports returns a new decorator with import management enabled.
+func NewDecoratorWithImports(fset *token.FileSet, path string, resolver resolver.DecoratorResolver) *Decorator {
+ dec := NewDecorator(fset)
+ dec.Path = path
+ dec.Resolver = resolver
+ return dec
+}
+
+// NewDecoratorFromPackage returns a new decorator configured to decorate files in pkg.
+func NewDecoratorFromPackage(pkg *packages.Package) *Decorator {
+ return NewDecoratorWithImports(pkg.Fset, pkg.PkgPath, gotypes.New(pkg.TypesInfo.Uses))
+}
+
+// Decorator converts ast nodes into dst nodes, and converts decoration info from the ast fileset
+// to the dst nodes. Create a new Decorator for each package you need to decorate.
+type Decorator struct {
+ Map // Mapping between ast and dst Nodes, Objects and Scopes
+ Filenames map[*dst.File]string // Source file names
+ Fset *token.FileSet // The ast FileSet containing ast decoration info for the files
+
+ // If a Resolver is provided, it is used to resolve remote identifiers from *ast.Ident and
+ // *ast.SelectorExpr nodes. Usually a remote identifier is a SelectorExpr qualified identifier,
+ // but in the case of dot-imports they can be simply Ident nodes. During decoration, remote
+ // identifiers are replaced with *dst.Ident with Path set to the path of imported package.
+ Resolver resolver.DecoratorResolver
+ // Local package path - required if Resolver is set.
+ Path string
+ // By default local idents are left with an empty Path, so they stay local if the local package
+ // is renamed. Setting ResolveLocalPath to true prevents this, so all idents will have the
+ // package path added.
+ ResolveLocalPath bool
+}
+
+// Parse uses parser.ParseFile to parse and decorate a Go source file. The src parameter should
+// be string, []byte, or io.Reader.
+func (d *Decorator) Parse(src interface{}) (*dst.File, error) {
+ return d.ParseFile("", src, parser.ParseComments)
+}
+
+// ParseFile uses parser.ParseFile to parse and decorate a Go source file. The ParseComments flag
+// is added to mode if it doesn't exist.
+func (d *Decorator) ParseFile(filename string, src interface{}, mode parser.Mode) (*dst.File, error) {
+
+ // If ParseFile returns an error and also a non-nil file, the errors were just parse errors so
+ // we should continue decorating the file and return the error.
+ f, perr := parser.ParseFile(d.Fset, filename, src, mode|parser.ParseComments)
+ if perr != nil && f == nil {
+ return nil, perr
+ }
+
+ file, err := d.DecorateFile(f)
+ if err != nil {
+ return nil, err
+ }
+
+ return file, perr
+}
+
+// ParseDir uses parser.ParseDir to parse and decorate a directory containing Go source. The
+// ParseComments flag is added to mode if it doesn't exist.
+func (d *Decorator) ParseDir(dir string, filter func(os.FileInfo) bool, mode parser.Mode) (map[string]*dst.Package, error) {
+ pkgs, err := parser.ParseDir(d.Fset, dir, filter, mode|parser.ParseComments)
+ if err != nil {
+ return nil, err
+ }
+ out := map[string]*dst.Package{}
+ for k, v := range pkgs {
+ pkg, err := d.DecorateNode(v)
+ if err != nil {
+ return nil, err
+ }
+ out[k] = pkg.(*dst.Package)
+ }
+ return out, nil
+}
+
+// DecorateFile decorates *ast.File and returns *dst.File
+func (d *Decorator) DecorateFile(f *ast.File) (*dst.File, error) {
+ file, err := d.DecorateNode(f)
+ if err != nil {
+ return nil, err
+ }
+ return file.(*dst.File), nil
+}
+
+// DecorateNode decorates ast.Node and returns dst.Node
+func (d *Decorator) DecorateNode(n ast.Node) (dst.Node, error) {
+
+ if d.Resolver == nil && d.Path != "" {
+ panic("Decorator Path should be empty when Resolver is nil")
+ }
+
+ if d.Resolver != nil && d.Path == "" {
+ panic("Decorator Path should be set when Resolver is set")
+ }
+
+ fd := d.newFileDecorator()
+ if f, ok := n.(*ast.File); ok {
+ fd.file = f
+ }
+ fd.fragment(n)
+ fd.link()
+
+ out, err := fd.decorateNode(nil, "", "", "", n)
+ if err != nil {
+ return nil, err
+ }
+
+ //fmt.Println("\nFragments:")
+ //fd.debug(os.Stdout)
+
+ //fmt.Println("\nDecorator:")
+ //debug(os.Stdout, out)
+
+ // Populate Info with filenames if we're decorating a File or Package.
+ switch n := n.(type) {
+ case *ast.Package:
+ for k, v := range n.Files {
+ d.Filenames[d.Dst.Nodes[v].(*dst.File)] = k
+ }
+ case *ast.File:
+ d.Filenames[out.(*dst.File)] = d.Fset.File(n.Pos()).Name()
+ }
+
+ return out, nil
+}
+
+func (pd *Decorator) newFileDecorator() *fileDecorator {
+ return &fileDecorator{
+ Decorator: pd,
+ startIndents: map[ast.Node]int{},
+ endIndents: map[ast.Node]int{},
+ before: map[ast.Node]dst.SpaceType{},
+ after: map[ast.Node]dst.SpaceType{},
+ decorations: map[ast.Node]map[string][]string{},
+ }
+}
+
+type fileDecorator struct {
+ *Decorator
+ file *ast.File // file we're decorating in for import name resolution - can be nil if we're just decorating an isolated node
+ cursor int
+ fragments []fragment
+ startIndents map[ast.Node]int
+ endIndents map[ast.Node]int
+ before, after map[ast.Node]dst.SpaceType
+ decorations map[ast.Node]map[string][]string
+}
+
+// We never need to resolve idents that are in these fields (decorateSelectorExpr will override
+// this check with the force parameter for SelectorExpr.Sel when needed).
+var avoid = map[string]bool{
+ "Field.Names": true,
+ "LabeledStmt.Label": true,
+ "BranchStmt.Label": true,
+ "ImportSpec.Name": true,
+ "ValueSpec.Names": true,
+ "TypeSpec.Name": true,
+ "FuncDecl.Name": true,
+ "File.Name": true,
+ "SelectorExpr.Sel": true,
+}
+
+// decorateSelectorExpr is a special case for decorating a SelectorExpr, which might return an
+// Ident if the resolver determines that the SelectorExpr represents a qualified ident.
+func (f *fileDecorator) decorateSelectorExpr(parent ast.Node, parentName, parentField, parentFieldType string, n *ast.SelectorExpr) (dst.Node, error) {
+
+ if f.Resolver == nil {
+ // continue to default logic in decorateNode
+ return nil, nil
+ }
+
+ // resolve the path with force == true, so we skip the tests that would normally prevent the
+ // Sel field of SelectorExpr from being resolved.
+ path, err := f.resolvePath(true, n, "SelectorExpr", "Sel", "Ident", n.Sel)
+ if err != nil {
+ return nil, err
+ }
+
+ if path == "" {
+ // path == "" -> not a qualified ident -> continue to default logic in decorateNode
+ return nil, nil
+ }
+
+ // replace *ast.SelectorExpr with *dst.Ident and merge decorations
+ out := &dst.Ident{}
+ f.Dst.Nodes[n] = out
+ f.Dst.Nodes[n.X] = out
+ f.Dst.Nodes[n.Sel] = out
+ f.Ast.Nodes[out] = n
+
+ // String: Name
+ out.Name = n.Sel.Name
+
+ // Object: Obj
+ ob, err := f.decorateObject(n.Sel.Obj)
+ if err != nil {
+ return nil, err
+ }
+ out.Obj = ob
+
+ // Path: Path
+ out.Path = path
+
+ /*
+ We must merge the SelectorExpr decorations into an Ident. The Ident has an X decoration
+ attachment point, but we don't have a simple place to store the decorations and line
+ spacing from the X / Sel child nodes. This is rather an edge case, but we can fix it by
+ merging the line-spacing with decorations (line spacing becomes "\n" decorations) and
+ adding these to the Ident decorations. This will mean that decorated / restored code with
+ no mutations should be byte-perfect, which is essential.
+
+ Here's a list of the decorations / line spacings we're merging:
+
+ {1}{2}{3}{4}[ X ].{5}{6}{7}{8}{9}[ Sel ]{10}{11}{12}{13}
+
+ 1: SelectorExpr Before Space - f.before[n]
+
+ 2: SelectorExpr Start Decoration - f.decorations[n]["Start"]
+ 3: X Before Space - f.before[n.X]
+ 4: X Start Decoration - f.decorations[n.X]["Start"]
+
+ 5: X End Decoration - f.decorations[n.X]["End"]
+ 6: X After Space - f.after[n.X]
+ 7: SelectorExpr X Decoration - f.decorations[n]["X"]
+ 8: Sel Before Space - f.before[n.Sel]
+ 9: Sel Start Decoration - f.decorations[n.Sel]["Start"]
+
+ 10: Sel End decoration - f.decorations[n.Sel]["End"]
+ 11: Sel After Space - f.after[n.Sel]
+ 12: SelectorExpr End Decoration - f.decorations[n]["End"]
+
+ 13: SelectorExpr After Space - f.after[n]
+
+ 1: set Ident.Before
+ 2-4: merge into Ident.Start
+ 5-9: merge into Ident.X
+ 10-12: merge into Ident.End
+ 13: set Ident.After
+ */
+
+ out.Decs.Before = f.before[n]
+ out.Decs.After = f.after[n]
+
+ var nStart, xBefore, xStart, xEnd, xAfter, nX, sBefore, sStart, sEnd, sAfter, nEnd interface{}
+
+ xBefore = f.before[n.X]
+ xAfter = f.after[n.X]
+
+ sBefore = f.before[n.Sel]
+ sAfter = f.after[n.Sel]
+
+ if decs, ok := f.decorations[n]; ok {
+ nStart = decs["Start"]
+ nX = decs["X"]
+ nEnd = decs["End"]
+ }
+ if decs, ok := f.decorations[n.X]; ok {
+ xStart = decs["Start"]
+ xEnd = decs["End"]
+ }
+ if decs, ok := f.decorations[n.Sel]; ok {
+ sStart = decs["Start"]
+ sEnd = decs["End"]
+ }
+
+ if iStart := mergeDecorations(nStart, xBefore, xStart); len(iStart) > 0 {
+ out.Decs.Start.Append(iStart...)
+ }
+
+ if iX := mergeDecorations(xEnd, xAfter, nX, sBefore, sStart); len(iX) > 0 {
+ out.Decs.X.Append(iX...)
+ }
+
+ if iEnd := mergeDecorations(sEnd, sAfter, nEnd); len(iEnd) > 0 {
+ out.Decs.End.Append(iEnd...)
+ }
+
+ return out, nil
+
+}
+
+func (f *fileDecorator) resolvePath(force bool, parent ast.Node, parentName, parentField, parentFieldType string, id *ast.Ident) (string, error) {
+
+ if f.Resolver == nil {
+ panic("resolvePath needs a Resolver")
+ }
+
+ if !force {
+ if avoid[parentName+"."+parentField] {
+ return "", nil
+ }
+ if parentFieldType != "Expr" {
+ panic(fmt.Sprintf("decorateIdent: unsupported parentName %s, parentField %s, parentFieldType %s", parentName, parentField, parentFieldType))
+ }
+ }
+
+ path, err := f.Resolver.ResolveIdent(f.file, parent, parentField, id)
+ if err != nil {
+ return "", err
+ }
+
+ path = stripVendor(path)
+
+ if !f.ResolveLocalPath && path == stripVendor(f.Path) {
+ return "", nil
+ }
+
+ return path, nil
+}
+
+func stripVendor(path string) string {
+ findVendor := func(path string) (index int, ok bool) {
+ // Two cases, depending on internal at start of string or not.
+ // The order matters: we must return the index of the final element,
+ // because the final one is where the effective import path starts.
+ switch {
+ case strings.Contains(path, "/vendor/"):
+ return strings.LastIndex(path, "/vendor/") + 1, true
+ case strings.HasPrefix(path, "vendor/"):
+ return 0, true
+ }
+ return 0, false
+ }
+ i, ok := findVendor(path)
+ if !ok {
+ return path
+ }
+ return path[i+len("vendor/"):]
+}
+
+func (f *fileDecorator) decorateObject(o *ast.Object) (*dst.Object, error) {
+
+ if o == nil {
+ return nil, nil
+ }
+
+ if do, ok := f.Dst.Objects[o]; ok {
+ return do, nil
+ }
+
+ /*
+ // An Object describes a named language entity such as a package,
+ // constant, type, variable, function (incl. methods), or label.
+ //
+ // The Data fields contains object-specific data:
+ //
+ // Kind Data type Data value
+ // Pkg *Scope package scope
+ // Con int iota for the respective declaration
+ //
+ type Object struct {
+ Kind ObjKind
+ Name string // declared name
+ Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil
+ Data interface{} // object-specific data; or nil
+ Type interface{} // placeholder for type information; may be nil
+ }
+ */
+
+ out := &dst.Object{}
+ f.Dst.Objects[o] = out
+ f.Ast.Objects[out] = o
+ out.Kind = dst.ObjKind(o.Kind)
+ out.Name = o.Name
+
+ switch decl := o.Decl.(type) {
+ case *ast.Scope:
+ s, err := f.decorateScope(decl)
+ if err != nil {
+ return nil, err
+ }
+ out.Decl = s
+ case ast.Node:
+ n, err := f.decorateNode(nil, "", "", "", decl)
+ if err != nil {
+ return nil, err
+ }
+ out.Decl = n
+ case nil:
+ default:
+ panic(fmt.Sprintf("o.Decl is %T", o.Data))
+ }
+
+ switch data := o.Data.(type) {
+ case int:
+ out.Data = data
+ case *ast.Scope:
+ s, err := f.decorateScope(data)
+ if err != nil {
+ return nil, err
+ }
+ out.Data = s
+ case ast.Node:
+ n, err := f.decorateNode(nil, "", "", "", data)
+ if err != nil {
+ return nil, err
+ }
+ out.Data = n
+ case nil:
+ default:
+ panic(fmt.Sprintf("o.Data is %T", o.Data))
+ }
+
+ return out, nil
+}
+
+func (f *fileDecorator) decorateScope(s *ast.Scope) (*dst.Scope, error) {
+
+ if s == nil {
+ return nil, nil
+ }
+
+ if ds, ok := f.Dst.Scopes[s]; ok {
+ return ds, nil
+ }
+
+ /*
+ // A Scope maintains the set of named language entities declared
+ // in the scope and a link to the immediately surrounding (outer)
+ // scope.
+ //
+ type Scope struct {
+ Outer *Scope
+ Objects map[string]*Object
+ }
+ */
+
+ out := &dst.Scope{}
+ f.Dst.Scopes[s] = out
+ f.Ast.Scopes[out] = s
+
+ outer, err := f.decorateScope(s.Outer)
+ if err != nil {
+ return nil, err
+ }
+ out.Outer = outer
+ out.Objects = map[string]*dst.Object{}
+
+ for k, v := range s.Objects {
+ ob, err := f.decorateObject(v)
+ if err != nil {
+ return nil, err
+ }
+ out.Objects[k] = ob
+ }
+
+ return out, nil
+}
+
+func debug(w io.Writer, file dst.Node) {
+ var result string
+ nodeType := func(n dst.Node) string {
+ return strings.Replace(fmt.Sprintf("%T", n), "*dst.", "", -1)
+ }
+ dst.Inspect(file, func(n dst.Node) bool {
+ if n == nil {
+ return false
+ }
+ var out string
+ before, after, points := dstutil.Decorations(n)
+ switch before {
+ case dst.NewLine:
+ out += " [New line before]"
+ case dst.EmptyLine:
+ out += " [Empty line before]"
+ }
+ for _, point := range points {
+ if len(point.Decs) > 0 {
+ var values string
+ for i, dec := range point.Decs {
+ if i > 0 {
+ values += " "
+ }
+ values += fmt.Sprintf("%q", dec)
+ }
+ out += fmt.Sprintf(" [%s %s]", point.Name, values)
+ }
+ }
+ switch after {
+ case dst.NewLine:
+ out += " [New line after]"
+ case dst.EmptyLine:
+ out += " [Empty line after]"
+ }
+ if out != "" {
+ result += nodeType(n) + out + "\n"
+ }
+ return true
+ })
+ fmt.Fprint(w, result)
+}
+
+// mergeDecorations merges several decoration lists and line spaces into a single decoration list
+func mergeDecorations(decorationsOrLineSpace ...interface{}) []string {
+ var endsWithNewLine bool
+ var out []string
+ for _, v := range decorationsOrLineSpace {
+ switch v := v.(type) {
+ case nil:
+ // nothing
+ case []string:
+ if len(v) == 0 {
+ continue
+ }
+ out = append(out, v...)
+ endsWithNewLine = v[len(v)-1] == "\n" || strings.HasPrefix(v[len(v)-1], "//")
+ case dst.SpaceType:
+ switch v {
+ case dst.NewLine:
+ if endsWithNewLine {
+ // nothing to do
+ } else {
+ out = append(out, "\n")
+ }
+ endsWithNewLine = true
+ case dst.EmptyLine:
+ if endsWithNewLine {
+ out = append(out, "\n")
+ } else {
+ out = append(out, "\n", "\n")
+ }
+ endsWithNewLine = true
+ }
+ default:
+ panic(fmt.Sprintf("%T", v))
+ }
+ }
+ return out
+}
diff --git a/vendor/github.com/dave/dst/decorator/helpers.go b/vendor/github.com/dave/dst/decorator/helpers.go
new file mode 100644
index 00000000..679b6e70
--- /dev/null
+++ b/vendor/github.com/dave/dst/decorator/helpers.go
@@ -0,0 +1,64 @@
+package decorator
+
+import (
+ "go/ast"
+ "go/format"
+ "go/parser"
+ "go/token"
+ "io"
+ "os"
+
+ "github.com/dave/dst"
+)
+
+// Parse uses parser.ParseFile to parse and decorate a Go source file. The src parameter should
+// be string, []byte, or io.Reader.
+func Parse(src interface{}) (*dst.File, error) {
+ return NewDecorator(token.NewFileSet()).Parse(src)
+}
+
+// ParseFile uses parser.ParseFile to parse and decorate a Go source file. The ParseComments flag is
+// added to mode if it doesn't exist.
+func ParseFile(fset *token.FileSet, filename string, src interface{}, mode parser.Mode) (*dst.File, error) {
+ return NewDecorator(fset).ParseFile(filename, src, mode)
+}
+
+// ParseDir uses parser.ParseDir to parse and decorate a directory containing Go source. The
+// ParseComments flag is added to mode if it doesn't exist.
+func ParseDir(fset *token.FileSet, dir string, filter func(os.FileInfo) bool, mode parser.Mode) (map[string]*dst.Package, error) {
+ return NewDecorator(fset).ParseDir(dir, filter, mode)
+}
+
+// Decorate decorates an ast.Node and returns a dst.Node.
+func Decorate(fset *token.FileSet, n ast.Node) (dst.Node, error) {
+ return NewDecorator(fset).DecorateNode(n)
+}
+
+// Decorate decorates a *ast.File and returns a *dst.File.
+func DecorateFile(fset *token.FileSet, f *ast.File) (*dst.File, error) {
+ return NewDecorator(fset).DecorateFile(f)
+}
+
+// Print uses format.Node to print a *dst.File to stdout
+func Print(f *dst.File) error {
+ return Fprint(os.Stdout, f)
+}
+
+// Fprint uses format.Node to print a *dst.File to a writer
+func Fprint(w io.Writer, f *dst.File) error {
+ fset, af, err := RestoreFile(f)
+ if err != nil {
+ return err
+ }
+ return format.Node(w, fset, af)
+}
+
+// RestoreFile restores a *dst.File to a *token.FileSet and a *ast.File
+func RestoreFile(file *dst.File) (*token.FileSet, *ast.File, error) {
+ r := NewRestorer()
+ f, err := r.RestoreFile(file)
+ if err != nil {
+ return nil, nil, err
+ }
+ return r.Fset, f, nil
+}
diff --git a/vendor/github.com/dave/dst/decorator/load.go b/vendor/github.com/dave/dst/decorator/load.go
new file mode 100644
index 00000000..3e109f11
--- /dev/null
+++ b/vendor/github.com/dave/dst/decorator/load.go
@@ -0,0 +1,119 @@
+package decorator
+
+import (
+ "bytes"
+ "errors"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+
+ "github.com/dave/dst"
+ "github.com/dave/dst/decorator/resolver"
+ "github.com/dave/dst/decorator/resolver/gopackages"
+ "golang.org/x/tools/go/packages"
+)
+
+func Load(cfg *packages.Config, patterns ...string) ([]*Package, error) {
+
+ if cfg == nil {
+ cfg = &packages.Config{Mode: packages.LoadSyntax}
+ }
+
+ if cfg.Mode&packages.NeedSyntax == 0 {
+ return nil, errors.New("config mode should include NeedSyntax")
+ }
+
+ pkgs, err := packages.Load(cfg, patterns...)
+ if err != nil {
+ return nil, err
+ }
+
+ dpkgs := map[*packages.Package]*Package{}
+
+ var convert func(p *packages.Package) (*Package, error)
+ convert = func(pkg *packages.Package) (*Package, error) {
+ if dp, ok := dpkgs[pkg]; ok {
+ return dp, nil
+ }
+ p := &Package{
+ Package: pkg,
+ Imports: map[string]*Package{},
+ }
+ dpkgs[pkg] = p
+ if len(pkg.Syntax) > 0 {
+
+ // Only decorate files in the GoFiles list. Syntax also has preprocessed cgo files which
+ // break things.
+ goFiles := make(map[string]bool, len(pkg.GoFiles))
+ for _, fpath := range pkg.GoFiles {
+ goFiles[fpath] = true
+ }
+
+ p.Decorator = NewDecoratorFromPackage(pkg)
+ for _, f := range pkg.Syntax {
+ fpath := pkg.Fset.File(f.Pos()).Name()
+ if !goFiles[fpath] {
+ continue
+ }
+ file, err := p.Decorator.DecorateFile(f)
+ if err != nil {
+ return nil, err
+ }
+ p.Syntax = append(p.Syntax, file)
+ }
+
+ dir, _ := filepath.Split(pkg.Fset.File(pkg.Syntax[0].Pos()).Name())
+ p.Dir = dir
+
+ for path, imp := range pkg.Imports {
+ dimp, err := convert(imp)
+ if err != nil {
+ return nil, err
+ }
+ p.Imports[path] = dimp
+ }
+ }
+ return p, nil
+ }
+
+ var out []*Package
+ for _, pkg := range pkgs {
+ p, err := convert(pkg)
+ if err != nil {
+ return nil, err
+ }
+ out = append(out, p)
+ }
+
+ return out, nil
+}
+
+type Package struct {
+ *packages.Package
+ Dir string
+ Decorator *Decorator
+ Imports map[string]*Package
+ Syntax []*dst.File
+}
+
+func (p *Package) Save() error {
+ return p.save(gopackages.New(p.Dir), ioutil.WriteFile)
+}
+
+func (p *Package) SaveWithResolver(resolver resolver.RestorerResolver) error {
+ return p.save(resolver, ioutil.WriteFile)
+}
+
+func (p *Package) save(resolver resolver.RestorerResolver, writeFile func(filename string, data []byte, perm os.FileMode) error) error {
+ r := NewRestorerWithImports(p.PkgPath, resolver)
+ for _, file := range p.Syntax {
+ buf := &bytes.Buffer{}
+ if err := r.Fprint(buf, file); err != nil {
+ return err
+ }
+ if err := writeFile(p.Decorator.Filenames[file], buf.Bytes(), 0666); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/dave/dst/decorator/map.go b/vendor/github.com/dave/dst/decorator/map.go
new file mode 100644
index 00000000..48d4adfe
--- /dev/null
+++ b/vendor/github.com/dave/dst/decorator/map.go
@@ -0,0 +1,42 @@
+package decorator
+
+import (
+ "go/ast"
+
+ "github.com/dave/dst"
+)
+
+func newMap() Map {
+ return Map{
+ Ast: AstMap{
+ Nodes: map[dst.Node]ast.Node{},
+ Scopes: map[*dst.Scope]*ast.Scope{},
+ Objects: map[*dst.Object]*ast.Object{},
+ },
+ Dst: DstMap{
+ Nodes: map[ast.Node]dst.Node{},
+ Scopes: map[*ast.Scope]*dst.Scope{},
+ Objects: map[*ast.Object]*dst.Object{},
+ },
+ }
+}
+
+// Map holds a record of the mapping between ast and dst nodes, objects and scopes.
+type Map struct {
+ Ast AstMap
+ Dst DstMap
+}
+
+// AstMap holds a record of the mapping from dst to ast nodes, objects and scopes.
+type AstMap struct {
+ Nodes map[dst.Node]ast.Node // Mapping from dst to ast Nodes
+ Objects map[*dst.Object]*ast.Object // Mapping from dst to ast Objects
+ Scopes map[*dst.Scope]*ast.Scope // Mapping from dst to ast Scopes
+}
+
+// DstMap holds a record of the mapping from ast to dst nodes, objects and scopes.
+type DstMap struct {
+ Nodes map[ast.Node]dst.Node // Mapping from ast to dst Nodes
+ Objects map[*ast.Object]*dst.Object // Mapping from ast to dst Objects
+ Scopes map[*ast.Scope]*dst.Scope // Mapping from ast to dst Scopes
+}
diff --git a/vendor/github.com/dave/dst/decorator/resolver/gopackages/resolver.go b/vendor/github.com/dave/dst/decorator/resolver/gopackages/resolver.go
new file mode 100644
index 00000000..7295d7df
--- /dev/null
+++ b/vendor/github.com/dave/dst/decorator/resolver/gopackages/resolver.go
@@ -0,0 +1,61 @@
+package gopackages
+
+import (
+ "fmt"
+
+ "github.com/dave/dst/decorator/resolver"
+ "golang.org/x/tools/go/packages"
+)
+
+func New(dir string) *RestorerResolver {
+ return &RestorerResolver{Dir: dir}
+}
+
+func WithConfig(dir string, config packages.Config) *RestorerResolver {
+ return &RestorerResolver{Config: config, Dir: dir}
+}
+
+func WithHints(dir string, hints map[string]string) *RestorerResolver {
+ return &RestorerResolver{Dir: dir, Hints: hints}
+}
+
+type RestorerResolver struct {
+ Dir string
+ Config packages.Config
+
+ // Hints (package path -> name) is first checked before asking the packages package
+ Hints map[string]string
+}
+
+func (r *RestorerResolver) ResolvePackage(path string) (string, error) {
+
+ if name, ok := r.Hints[path]; ok {
+ return name, nil
+ }
+
+ if r.Dir != "" {
+ r.Config.Dir = r.Dir
+ }
+ r.Config.Mode = packages.LoadTypes
+ r.Config.Tests = false
+
+ pkgs, err := packages.Load(&r.Config, "pattern="+path)
+ if err != nil {
+ return "", err
+ }
+
+ if len(pkgs) > 1 {
+ return "", fmt.Errorf("%d packages found for %s, %s", len(pkgs), path, r.Config.Dir)
+ }
+ if len(pkgs) == 0 {
+ return "", resolver.ErrPackageNotFound
+ }
+
+ p := pkgs[0]
+
+ if len(p.Errors) > 0 {
+ return "", p.Errors[0]
+ }
+
+ return p.Name, nil
+}
diff --git a/vendor/github.com/dave/dst/decorator/resolver/gotypes/resolver.go b/vendor/github.com/dave/dst/decorator/resolver/gotypes/resolver.go
new file mode 100644
index 00000000..b79e5621
--- /dev/null
+++ b/vendor/github.com/dave/dst/decorator/resolver/gotypes/resolver.go
@@ -0,0 +1,64 @@
+package gotypes
+
+import (
+ "errors"
+ "go/ast"
+ "go/types"
+)
+
+func New(uses map[*ast.Ident]types.Object) *DecoratorResolver {
+ return &DecoratorResolver{Uses: uses}
+}
+
+type DecoratorResolver struct {
+ Uses map[*ast.Ident]types.Object // Types info - must include Uses
+}
+
+func (r *DecoratorResolver) ResolveIdent(file *ast.File, parent ast.Node, parentField string, id *ast.Ident) (string, error) {
+
+ if r.Uses == nil {
+ return "", errors.New("gotypes.DecoratorResolver needs Uses in types info")
+ }
+
+ if se, ok := parent.(*ast.SelectorExpr); ok && parentField == "Sel" {
+
+ // if the parent is a SelectorExpr and this Ident is in the Sel field, only resolve the path
+ // if X is a package identifier
+
+ xid, ok := se.X.(*ast.Ident)
+ if !ok {
+ // x is not an ident -> not a qualified identifier
+ return "", nil
+ }
+ obj, ok := r.Uses[xid]
+ if !ok {
+ // not found in uses -> not a qualified identifier
+ return "", nil
+ }
+ pn, ok := obj.(*types.PkgName)
+ if !ok {
+ // not a pkgname -> not a remote identifier
+ return "", nil
+ }
+ return pn.Imported().Path(), nil
+ }
+
+ obj, ok := r.Uses[id]
+ if !ok {
+ // not found in uses -> not a remote identifier
+ return "", nil
+ }
+
+ if v, ok := obj.(*types.Var); ok && v.IsField() {
+ // field ident (e.g. name of a field in a composite literal) -> doesn't need qualified ident
+ return "", nil
+ }
+
+ pkg := obj.Pkg()
+ if pkg == nil {
+ // pre-defined idents in the universe scope - e.g. "byte"
+ return "", nil
+ }
+
+ return pkg.Path(), nil
+}
diff --git a/vendor/github.com/dave/dst/decorator/resolver/resolver.go b/vendor/github.com/dave/dst/decorator/resolver/resolver.go
new file mode 100644
index 00000000..ccda1919
--- /dev/null
+++ b/vendor/github.com/dave/dst/decorator/resolver/resolver.go
@@ -0,0 +1,26 @@
+package resolver
+
+import (
+ "errors"
+ "go/ast"
+)
+
+// RestorerResolver resolves a package path to a package name.
+type RestorerResolver interface {
+ ResolvePackage(path string) (string, error)
+}
+
+// DecoratorResolver resolves an identifier to a local or remote reference.
+//
+// Returns path == "" if the node is not a local or remote reference (e.g. a field in a composite
+// literal, the selector in a selector expression etc.).
+//
+// Returns path == "" is the node is a local reference.
+//
+// Returns path != "" is the node is a remote reference.
+type DecoratorResolver interface {
+ ResolveIdent(file *ast.File, parent ast.Node, parentField string, id *ast.Ident) (path string, err error)
+}
+
+// ErrPackageNotFound means the package is not found
+var ErrPackageNotFound = errors.New("package not found")
diff --git a/vendor/github.com/dave/dst/decorator/restorer-generated.go b/vendor/github.com/dave/dst/decorator/restorer-generated.go
new file mode 100644
index 00000000..4b5728ff
--- /dev/null
+++ b/vendor/github.com/dave/dst/decorator/restorer-generated.go
@@ -0,0 +1,1956 @@
+package decorator
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+
+ "github.com/dave/dst"
+)
+
+func (r *FileRestorer) restoreNode(n dst.Node, parentName, parentField, parentFieldType string, allowDuplicate bool) ast.Node {
+ if an, ok := r.Ast.Nodes[n]; ok {
+ if allowDuplicate {
+ return an
+ } else {
+ panic(fmt.Sprintf("duplicate node: %#v", n))
+ }
+ }
+ switch n := n.(type) {
+ case *dst.ArrayType:
+ out := &ast.ArrayType{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Lbrack
+ out.Lbrack = r.cursor
+ r.cursor += token.Pos(len(token.LBRACK.String()))
+
+ // Decoration: Lbrack
+ r.applyDecorations(out, "Lbrack", n.Decs.Lbrack, false)
+
+ // Node: Len
+ if n.Len != nil {
+ out.Len = r.restoreNode(n.Len, "ArrayType", "Len", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Token: Rbrack
+ r.cursor += token.Pos(len(token.RBRACK.String()))
+
+ // Decoration: Len
+ r.applyDecorations(out, "Len", n.Decs.Len, false)
+
+ // Node: Elt
+ if n.Elt != nil {
+ out.Elt = r.restoreNode(n.Elt, "ArrayType", "Elt", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.AssignStmt:
+ out := &ast.AssignStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // List: Lhs
+ for _, v := range n.Lhs {
+ out.Lhs = append(out.Lhs, r.restoreNode(v, "AssignStmt", "Lhs", "Expr", allowDuplicate).(ast.Expr))
+ }
+
+ // Token: Tok
+ out.Tok = n.Tok
+ out.TokPos = r.cursor
+ r.cursor += token.Pos(len(n.Tok.String()))
+
+ // Decoration: Tok
+ r.applyDecorations(out, "Tok", n.Decs.Tok, false)
+
+ // List: Rhs
+ for _, v := range n.Rhs {
+ out.Rhs = append(out.Rhs, r.restoreNode(v, "AssignStmt", "Rhs", "Expr", allowDuplicate).(ast.Expr))
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.BadDecl:
+ out := &ast.BadDecl{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Bad
+ out.From = r.cursor
+ r.cursor += token.Pos(n.Length)
+ out.To = r.cursor
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.BadExpr:
+ out := &ast.BadExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Bad
+ out.From = r.cursor
+ r.cursor += token.Pos(n.Length)
+ out.To = r.cursor
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.BadStmt:
+ out := &ast.BadStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Bad
+ out.From = r.cursor
+ r.cursor += token.Pos(n.Length)
+ out.To = r.cursor
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.BasicLit:
+ out := &ast.BasicLit{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // String: Value
+ r.applyLiteral(n.Value)
+ out.ValuePos = r.cursor
+ out.Value = n.Value
+ r.cursor += token.Pos(len(n.Value))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+
+ // Value: Kind
+ out.Kind = n.Kind
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.BinaryExpr:
+ out := &ast.BinaryExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "BinaryExpr", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // Token: Op
+ out.Op = n.Op
+ out.OpPos = r.cursor
+ r.cursor += token.Pos(len(n.Op.String()))
+
+ // Decoration: Op
+ r.applyDecorations(out, "Op", n.Decs.Op, false)
+
+ // Node: Y
+ if n.Y != nil {
+ out.Y = r.restoreNode(n.Y, "BinaryExpr", "Y", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.BlockStmt:
+ out := &ast.BlockStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Lbrace
+ out.Lbrace = r.cursor
+ r.cursor += token.Pos(len(token.LBRACE.String()))
+
+ // Decoration: Lbrace
+ r.applyDecorations(out, "Lbrace", n.Decs.Lbrace, false)
+
+ // List: List
+ for _, v := range n.List {
+ out.List = append(out.List, r.restoreNode(v, "BlockStmt", "List", "Stmt", allowDuplicate).(ast.Stmt))
+ }
+
+ // Token: Rbrace
+ if n.RbraceHasNoPos {
+ out.Rbrace = token.NoPos
+ } else {
+ out.Rbrace = r.cursor
+ }
+ r.cursor += token.Pos(len(token.RBRACE.String()))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.BranchStmt:
+ out := &ast.BranchStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Tok
+ out.Tok = n.Tok
+ out.TokPos = r.cursor
+ r.cursor += token.Pos(len(n.Tok.String()))
+
+ // Decoration: Tok
+ r.applyDecorations(out, "Tok", n.Decs.Tok, false)
+
+ // Node: Label
+ if n.Label != nil {
+ out.Label = r.restoreNode(n.Label, "BranchStmt", "Label", "Ident", allowDuplicate).(*ast.Ident)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.CallExpr:
+ out := &ast.CallExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: Fun
+ if n.Fun != nil {
+ out.Fun = r.restoreNode(n.Fun, "CallExpr", "Fun", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: Fun
+ r.applyDecorations(out, "Fun", n.Decs.Fun, false)
+
+ // Token: Lparen
+ out.Lparen = r.cursor
+ r.cursor += token.Pos(len(token.LPAREN.String()))
+
+ // Decoration: Lparen
+ r.applyDecorations(out, "Lparen", n.Decs.Lparen, false)
+
+ // List: Args
+ for _, v := range n.Args {
+ out.Args = append(out.Args, r.restoreNode(v, "CallExpr", "Args", "Expr", allowDuplicate).(ast.Expr))
+ }
+
+ // Token: Ellipsis
+ if n.Ellipsis {
+ out.Ellipsis = r.cursor
+ r.cursor += token.Pos(len(token.ELLIPSIS.String()))
+ }
+
+ // Decoration: Ellipsis
+ r.applyDecorations(out, "Ellipsis", n.Decs.Ellipsis, false)
+
+ // Token: Rparen
+ out.Rparen = r.cursor
+ r.cursor += token.Pos(len(token.RPAREN.String()))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.CaseClause:
+ out := &ast.CaseClause{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Case
+ out.Case = r.cursor
+ r.cursor += token.Pos(len(func() token.Token {
+ if n.List == nil {
+ return token.DEFAULT
+ }
+ return token.CASE
+ }().String()))
+
+ // Decoration: Case
+ r.applyDecorations(out, "Case", n.Decs.Case, false)
+
+ // List: List
+ for _, v := range n.List {
+ out.List = append(out.List, r.restoreNode(v, "CaseClause", "List", "Expr", allowDuplicate).(ast.Expr))
+ }
+
+ // Token: Colon
+ out.Colon = r.cursor
+ r.cursor += token.Pos(len(token.COLON.String()))
+
+ // Decoration: Colon
+ r.applyDecorations(out, "Colon", n.Decs.Colon, false)
+
+ // List: Body
+ for _, v := range n.Body {
+ out.Body = append(out.Body, r.restoreNode(v, "CaseClause", "Body", "Stmt", allowDuplicate).(ast.Stmt))
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.ChanType:
+ out := &ast.ChanType{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Begin
+ out.Begin = r.cursor
+ r.cursor += token.Pos(len(func() token.Token {
+ if n.Dir == dst.RECV {
+ return token.ARROW
+ }
+ return token.CHAN
+ }().String()))
+
+ // Token: Chan
+ if n.Dir == dst.RECV {
+ r.cursor += token.Pos(len(token.CHAN.String()))
+ }
+
+ // Decoration: Begin
+ r.applyDecorations(out, "Begin", n.Decs.Begin, false)
+
+ // Token: Arrow
+ if n.Dir == dst.SEND {
+ out.Arrow = r.cursor
+ r.cursor += token.Pos(len(token.ARROW.String()))
+ }
+
+ // Decoration: Arrow
+ r.applyDecorations(out, "Arrow", n.Decs.Arrow, false)
+
+ // Node: Value
+ if n.Value != nil {
+ out.Value = r.restoreNode(n.Value, "ChanType", "Value", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+
+ // Value: Dir
+ out.Dir = ast.ChanDir(n.Dir)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.CommClause:
+ out := &ast.CommClause{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Case
+ out.Case = r.cursor
+ r.cursor += token.Pos(len(func() token.Token {
+ if n.Comm == nil {
+ return token.DEFAULT
+ }
+ return token.CASE
+ }().String()))
+
+ // Decoration: Case
+ r.applyDecorations(out, "Case", n.Decs.Case, false)
+
+ // Node: Comm
+ if n.Comm != nil {
+ out.Comm = r.restoreNode(n.Comm, "CommClause", "Comm", "Stmt", allowDuplicate).(ast.Stmt)
+ }
+
+ // Decoration: Comm
+ r.applyDecorations(out, "Comm", n.Decs.Comm, false)
+
+ // Token: Colon
+ out.Colon = r.cursor
+ r.cursor += token.Pos(len(token.COLON.String()))
+
+ // Decoration: Colon
+ r.applyDecorations(out, "Colon", n.Decs.Colon, false)
+
+ // List: Body
+ for _, v := range n.Body {
+ out.Body = append(out.Body, r.restoreNode(v, "CommClause", "Body", "Stmt", allowDuplicate).(ast.Stmt))
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.CompositeLit:
+ out := &ast.CompositeLit{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = r.restoreNode(n.Type, "CompositeLit", "Type", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: Type
+ r.applyDecorations(out, "Type", n.Decs.Type, false)
+
+ // Token: Lbrace
+ out.Lbrace = r.cursor
+ r.cursor += token.Pos(len(token.LBRACE.String()))
+
+ // Decoration: Lbrace
+ r.applyDecorations(out, "Lbrace", n.Decs.Lbrace, false)
+
+ // List: Elts
+ for _, v := range n.Elts {
+ out.Elts = append(out.Elts, r.restoreNode(v, "CompositeLit", "Elts", "Expr", allowDuplicate).(ast.Expr))
+ }
+
+ // Token: Rbrace
+ out.Rbrace = r.cursor
+ r.cursor += token.Pos(len(token.RBRACE.String()))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+
+ // Value: Incomplete
+ out.Incomplete = n.Incomplete
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.DeclStmt:
+ out := &ast.DeclStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: Decl
+ if n.Decl != nil {
+ out.Decl = r.restoreNode(n.Decl, "DeclStmt", "Decl", "Decl", allowDuplicate).(ast.Decl)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.DeferStmt:
+ out := &ast.DeferStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Defer
+ out.Defer = r.cursor
+ r.cursor += token.Pos(len(token.DEFER.String()))
+
+ // Decoration: Defer
+ r.applyDecorations(out, "Defer", n.Decs.Defer, false)
+
+ // Node: Call
+ if n.Call != nil {
+ out.Call = r.restoreNode(n.Call, "DeferStmt", "Call", "CallExpr", allowDuplicate).(*ast.CallExpr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.Ellipsis:
+ out := &ast.Ellipsis{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Ellipsis
+ out.Ellipsis = r.cursor
+ r.cursor += token.Pos(len(token.ELLIPSIS.String()))
+
+ // Decoration: Ellipsis
+ r.applyDecorations(out, "Ellipsis", n.Decs.Ellipsis, false)
+
+ // Node: Elt
+ if n.Elt != nil {
+ out.Elt = r.restoreNode(n.Elt, "Ellipsis", "Elt", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.EmptyStmt:
+ out := &ast.EmptyStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Semicolon
+ if !n.Implicit {
+ out.Semicolon = r.cursor
+ r.cursor += token.Pos(len(token.ARROW.String()))
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+
+ // Value: Implicit
+ out.Implicit = n.Implicit
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.ExprStmt:
+ out := &ast.ExprStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "ExprStmt", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.Field:
+ out := &ast.Field{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // List: Names
+ for _, v := range n.Names {
+ out.Names = append(out.Names, r.restoreNode(v, "Field", "Names", "Ident", allowDuplicate).(*ast.Ident))
+ }
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = r.restoreNode(n.Type, "Field", "Type", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: Type
+ r.applyDecorations(out, "Type", n.Decs.Type, false)
+
+ // Node: Tag
+ if n.Tag != nil {
+ out.Tag = r.restoreNode(n.Tag, "Field", "Tag", "BasicLit", allowDuplicate).(*ast.BasicLit)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.FieldList:
+ out := &ast.FieldList{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Opening
+ if n.Opening {
+ out.Opening = r.cursor
+ r.cursor += token.Pos(len(token.LPAREN.String()))
+ }
+
+ // Decoration: Opening
+ r.applyDecorations(out, "Opening", n.Decs.Opening, false)
+
+ // List: List
+ for _, v := range n.List {
+ out.List = append(out.List, r.restoreNode(v, "FieldList", "List", "Field", allowDuplicate).(*ast.Field))
+ }
+
+ // Token: Closing
+ if n.Closing {
+ out.Closing = r.cursor
+ r.cursor += token.Pos(len(token.RPAREN.String()))
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.File:
+ out := &ast.File{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Package
+ out.Package = r.cursor
+ r.cursor += token.Pos(len(token.PACKAGE.String()))
+
+ // Decoration: Package
+ r.applyDecorations(out, "Package", n.Decs.Package, false)
+
+ // Node: Name
+ if n.Name != nil {
+ out.Name = r.restoreNode(n.Name, "File", "Name", "Ident", allowDuplicate).(*ast.Ident)
+ }
+
+ // Decoration: Name
+ r.applyDecorations(out, "Name", n.Decs.Name, false)
+
+ // List: Decls
+ for _, v := range n.Decls {
+ out.Decls = append(out.Decls, r.restoreNode(v, "File", "Decls", "Decl", allowDuplicate).(ast.Decl))
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+
+ // Scope: Scope
+ out.Scope = r.restoreScope(n.Scope)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.ForStmt:
+ out := &ast.ForStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: For
+ out.For = r.cursor
+ r.cursor += token.Pos(len(token.FOR.String()))
+
+ // Decoration: For
+ r.applyDecorations(out, "For", n.Decs.For, false)
+
+ // Node: Init
+ if n.Init != nil {
+ out.Init = r.restoreNode(n.Init, "ForStmt", "Init", "Stmt", allowDuplicate).(ast.Stmt)
+ }
+
+ // Token: InitSemicolon
+ if n.Init != nil {
+ r.cursor += token.Pos(len(token.SEMICOLON.String()))
+ }
+
+ // Decoration: Init
+ r.applyDecorations(out, "Init", n.Decs.Init, false)
+
+ // Node: Cond
+ if n.Cond != nil {
+ out.Cond = r.restoreNode(n.Cond, "ForStmt", "Cond", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Token: CondSemicolon
+ if n.Post != nil {
+ r.cursor += token.Pos(len(token.SEMICOLON.String()))
+ }
+
+ // Decoration: Cond
+ r.applyDecorations(out, "Cond", n.Decs.Cond, false)
+
+ // Node: Post
+ if n.Post != nil {
+ out.Post = r.restoreNode(n.Post, "ForStmt", "Post", "Stmt", allowDuplicate).(ast.Stmt)
+ }
+
+ // Decoration: Post
+ r.applyDecorations(out, "Post", n.Decs.Post, false)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = r.restoreNode(n.Body, "ForStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.FuncDecl:
+ out := &ast.FuncDecl{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Init: Type
+ out.Type = &ast.FuncType{}
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Special decoration: Start
+ r.applyDecorations(out, "Start", n.Type.Decs.Start, false)
+
+ // Token: Func
+ if true {
+ out.Type.Func = r.cursor
+ r.cursor += token.Pos(len(token.FUNC.String()))
+ }
+
+ // Decoration: Func
+ r.applyDecorations(out, "Func", n.Decs.Func, false)
+
+ // Special decoration: Func
+ r.applyDecorations(out, "Func", n.Type.Decs.Func, false)
+
+ // Node: Recv
+ if n.Recv != nil {
+ out.Recv = r.restoreNode(n.Recv, "FuncDecl", "Recv", "FieldList", allowDuplicate).(*ast.FieldList)
+ }
+
+ // Decoration: Recv
+ r.applyDecorations(out, "Recv", n.Decs.Recv, false)
+
+ // Node: Name
+ if n.Name != nil {
+ out.Name = r.restoreNode(n.Name, "FuncDecl", "Name", "Ident", allowDuplicate).(*ast.Ident)
+ }
+
+ // Decoration: Name
+ r.applyDecorations(out, "Name", n.Decs.Name, false)
+
+ // Node: TypeParams
+ if n.Type.TypeParams != nil {
+ out.Type.TypeParams = r.restoreNode(n.Type.TypeParams, "FuncDecl", "TypeParams", "FieldList", allowDuplicate).(*ast.FieldList)
+ }
+
+ // Decoration: TypeParams
+ r.applyDecorations(out, "TypeParams", n.Decs.TypeParams, false)
+
+ // Special decoration: TypeParams
+ r.applyDecorations(out, "TypeParams", n.Type.Decs.TypeParams, false)
+
+ // Node: Params
+ if n.Type.Params != nil {
+ out.Type.Params = r.restoreNode(n.Type.Params, "FuncDecl", "Params", "FieldList", allowDuplicate).(*ast.FieldList)
+ }
+
+ // Decoration: Params
+ r.applyDecorations(out, "Params", n.Decs.Params, false)
+
+ // Special decoration: Params
+ r.applyDecorations(out, "Params", n.Type.Decs.Params, false)
+
+ // Node: Results
+ if n.Type.Results != nil {
+ out.Type.Results = r.restoreNode(n.Type.Results, "FuncDecl", "Results", "FieldList", allowDuplicate).(*ast.FieldList)
+ }
+
+ // Decoration: Results
+ r.applyDecorations(out, "Results", n.Decs.Results, false)
+
+ // Special decoration: End
+ r.applyDecorations(out, "End", n.Type.Decs.End, false)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = r.restoreNode(n.Body, "FuncDecl", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.FuncLit:
+ out := &ast.FuncLit{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = r.restoreNode(n.Type, "FuncLit", "Type", "FuncType", allowDuplicate).(*ast.FuncType)
+ }
+
+ // Decoration: Type
+ r.applyDecorations(out, "Type", n.Decs.Type, false)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = r.restoreNode(n.Body, "FuncLit", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.FuncType:
+ out := &ast.FuncType{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Func
+ if n.Func {
+ out.Func = r.cursor
+ r.cursor += token.Pos(len(token.FUNC.String()))
+ }
+
+ // Decoration: Func
+ r.applyDecorations(out, "Func", n.Decs.Func, false)
+
+ // Node: TypeParams
+ if n.TypeParams != nil {
+ out.TypeParams = r.restoreNode(n.TypeParams, "FuncType", "TypeParams", "FieldList", allowDuplicate).(*ast.FieldList)
+ }
+
+ // Decoration: TypeParams
+ r.applyDecorations(out, "TypeParams", n.Decs.TypeParams, false)
+
+ // Node: Params
+ if n.Params != nil {
+ out.Params = r.restoreNode(n.Params, "FuncType", "Params", "FieldList", allowDuplicate).(*ast.FieldList)
+ }
+
+ // Decoration: Params
+ r.applyDecorations(out, "Params", n.Decs.Params, false)
+
+ // Node: Results
+ if n.Results != nil {
+ out.Results = r.restoreNode(n.Results, "FuncType", "Results", "FieldList", allowDuplicate).(*ast.FieldList)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.GenDecl:
+ out := &ast.GenDecl{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Tok
+ out.Tok = n.Tok
+ out.TokPos = r.cursor
+ r.cursor += token.Pos(len(n.Tok.String()))
+
+ // Decoration: Tok
+ r.applyDecorations(out, "Tok", n.Decs.Tok, false)
+
+ // Token: Lparen
+ if n.Lparen {
+ out.Lparen = r.cursor
+ r.cursor += token.Pos(len(token.LPAREN.String()))
+ }
+
+ // Decoration: Lparen
+ r.applyDecorations(out, "Lparen", n.Decs.Lparen, false)
+
+ // List: Specs
+ for _, v := range n.Specs {
+ out.Specs = append(out.Specs, r.restoreNode(v, "GenDecl", "Specs", "Spec", allowDuplicate).(ast.Spec))
+ }
+
+ // Token: Rparen
+ if n.Rparen {
+ out.Rparen = r.cursor
+ r.cursor += token.Pos(len(token.RPAREN.String()))
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.GoStmt:
+ out := &ast.GoStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Go
+ out.Go = r.cursor
+ r.cursor += token.Pos(len(token.GO.String()))
+
+ // Decoration: Go
+ r.applyDecorations(out, "Go", n.Decs.Go, false)
+
+ // Node: Call
+ if n.Call != nil {
+ out.Call = r.restoreNode(n.Call, "GoStmt", "Call", "CallExpr", allowDuplicate).(*ast.CallExpr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.Ident:
+
+ // Special case for *dst.Ident - replace with SelectorExpr if needed
+ sel := r.restoreIdent(n, parentName, parentField, parentFieldType, allowDuplicate)
+ if sel != nil {
+ return sel
+ }
+
+ out := &ast.Ident{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // String: Name
+ out.NamePos = r.cursor
+ out.Name = n.Name
+ r.cursor += token.Pos(len(n.Name))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+
+ // Object: Obj
+ out.Obj = r.restoreObject(n.Obj)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.IfStmt:
+ out := &ast.IfStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: If
+ out.If = r.cursor
+ r.cursor += token.Pos(len(token.IF.String()))
+
+ // Decoration: If
+ r.applyDecorations(out, "If", n.Decs.If, false)
+
+ // Node: Init
+ if n.Init != nil {
+ out.Init = r.restoreNode(n.Init, "IfStmt", "Init", "Stmt", allowDuplicate).(ast.Stmt)
+ }
+
+ // Decoration: Init
+ r.applyDecorations(out, "Init", n.Decs.Init, false)
+
+ // Node: Cond
+ if n.Cond != nil {
+ out.Cond = r.restoreNode(n.Cond, "IfStmt", "Cond", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: Cond
+ r.applyDecorations(out, "Cond", n.Decs.Cond, false)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = r.restoreNode(n.Body, "IfStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt)
+ }
+
+ // Token: ElseTok
+ if n.Else != nil {
+ r.cursor += token.Pos(len(token.ELSE.String()))
+ }
+
+ // Decoration: Else
+ r.applyDecorations(out, "Else", n.Decs.Else, false)
+
+ // Node: Else
+ if n.Else != nil {
+ out.Else = r.restoreNode(n.Else, "IfStmt", "Else", "Stmt", allowDuplicate).(ast.Stmt)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.ImportSpec:
+ out := &ast.ImportSpec{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: Name
+ if n.Name != nil {
+ out.Name = r.restoreNode(n.Name, "ImportSpec", "Name", "Ident", allowDuplicate).(*ast.Ident)
+ }
+
+ // Decoration: Name
+ r.applyDecorations(out, "Name", n.Decs.Name, false)
+
+ // Node: Path
+ if n.Path != nil {
+ out.Path = r.restoreNode(n.Path, "ImportSpec", "Path", "BasicLit", allowDuplicate).(*ast.BasicLit)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.IncDecStmt:
+ out := &ast.IncDecStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "IncDecStmt", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // Token: Tok
+ out.Tok = n.Tok
+ out.TokPos = r.cursor
+ r.cursor += token.Pos(len(n.Tok.String()))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.IndexExpr:
+ out := &ast.IndexExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "IndexExpr", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // Token: Lbrack
+ out.Lbrack = r.cursor
+ r.cursor += token.Pos(len(token.LBRACK.String()))
+
+ // Decoration: Lbrack
+ r.applyDecorations(out, "Lbrack", n.Decs.Lbrack, false)
+
+ // Node: Index
+ if n.Index != nil {
+ out.Index = r.restoreNode(n.Index, "IndexExpr", "Index", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: Index
+ r.applyDecorations(out, "Index", n.Decs.Index, false)
+
+ // Token: Rbrack
+ out.Rbrack = r.cursor
+ r.cursor += token.Pos(len(token.RBRACK.String()))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.IndexListExpr:
+ out := &ast.IndexListExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "IndexListExpr", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // Token: Lbrack
+ out.Lbrack = r.cursor
+ r.cursor += token.Pos(len(token.LBRACK.String()))
+
+ // Decoration: Lbrack
+ r.applyDecorations(out, "Lbrack", n.Decs.Lbrack, false)
+
+ // List: Indices
+ for _, v := range n.Indices {
+ out.Indices = append(out.Indices, r.restoreNode(v, "IndexListExpr", "Indices", "Expr", allowDuplicate).(ast.Expr))
+ }
+
+ // Decoration: Indices
+ r.applyDecorations(out, "Indices", n.Decs.Indices, false)
+
+ // Token: Rbrack
+ out.Rbrack = r.cursor
+ r.cursor += token.Pos(len(token.RBRACK.String()))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.InterfaceType:
+ out := &ast.InterfaceType{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Interface
+ out.Interface = r.cursor
+ r.cursor += token.Pos(len(token.INTERFACE.String()))
+
+ // Decoration: Interface
+ r.applyDecorations(out, "Interface", n.Decs.Interface, false)
+
+ // Node: Methods
+ if n.Methods != nil {
+ out.Methods = r.restoreNode(n.Methods, "InterfaceType", "Methods", "FieldList", allowDuplicate).(*ast.FieldList)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+
+ // Value: Incomplete
+ out.Incomplete = n.Incomplete
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.KeyValueExpr:
+ out := &ast.KeyValueExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: Key
+ if n.Key != nil {
+ out.Key = r.restoreNode(n.Key, "KeyValueExpr", "Key", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: Key
+ r.applyDecorations(out, "Key", n.Decs.Key, false)
+
+ // Token: Colon
+ out.Colon = r.cursor
+ r.cursor += token.Pos(len(token.COLON.String()))
+
+ // Decoration: Colon
+ r.applyDecorations(out, "Colon", n.Decs.Colon, false)
+
+ // Node: Value
+ if n.Value != nil {
+ out.Value = r.restoreNode(n.Value, "KeyValueExpr", "Value", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.LabeledStmt:
+ out := &ast.LabeledStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: Label
+ if n.Label != nil {
+ out.Label = r.restoreNode(n.Label, "LabeledStmt", "Label", "Ident", allowDuplicate).(*ast.Ident)
+ }
+
+ // Decoration: Label
+ r.applyDecorations(out, "Label", n.Decs.Label, false)
+
+ // Token: Colon
+ out.Colon = r.cursor
+ r.cursor += token.Pos(len(token.COLON.String()))
+
+ // Decoration: Colon
+ r.applyDecorations(out, "Colon", n.Decs.Colon, false)
+
+ // Node: Stmt
+ if n.Stmt != nil {
+ out.Stmt = r.restoreNode(n.Stmt, "LabeledStmt", "Stmt", "Stmt", allowDuplicate).(ast.Stmt)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.MapType:
+ out := &ast.MapType{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Map
+ out.Map = r.cursor
+ r.cursor += token.Pos(len(token.MAP.String()))
+
+ // Token: Lbrack
+ r.cursor += token.Pos(len(token.LBRACK.String()))
+
+ // Decoration: Map
+ r.applyDecorations(out, "Map", n.Decs.Map, false)
+
+ // Node: Key
+ if n.Key != nil {
+ out.Key = r.restoreNode(n.Key, "MapType", "Key", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Token: Rbrack
+ r.cursor += token.Pos(len(token.RBRACK.String()))
+
+ // Decoration: Key
+ r.applyDecorations(out, "Key", n.Decs.Key, false)
+
+ // Node: Value
+ if n.Value != nil {
+ out.Value = r.restoreNode(n.Value, "MapType", "Value", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.Package:
+ out := &ast.Package{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+
+ // Value: Name
+ out.Name = n.Name
+
+ // Scope: Scope
+ out.Scope = r.restoreScope(n.Scope)
+
+ // Map: Imports
+ out.Imports = map[string]*ast.Object{}
+ for k, v := range n.Imports {
+ out.Imports[k] = r.restoreObject(v)
+ }
+
+ // Map: Files
+ out.Files = map[string]*ast.File{}
+ for k, v := range n.Files {
+ out.Files[k] = r.restoreNode(v, "Package", "Files", "File", allowDuplicate).(*ast.File)
+ }
+
+ return out
+ case *dst.ParenExpr:
+ out := &ast.ParenExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Lparen
+ out.Lparen = r.cursor
+ r.cursor += token.Pos(len(token.LPAREN.String()))
+
+ // Decoration: Lparen
+ r.applyDecorations(out, "Lparen", n.Decs.Lparen, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "ParenExpr", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // Token: Rparen
+ out.Rparen = r.cursor
+ r.cursor += token.Pos(len(token.RPAREN.String()))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.RangeStmt:
+ out := &ast.RangeStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: For
+ out.For = r.cursor
+ r.cursor += token.Pos(len(token.FOR.String()))
+
+ // Decoration: For
+ r.applyDecorations(out, "For", n.Decs.For, false)
+
+ // Node: Key
+ if n.Key != nil {
+ out.Key = r.restoreNode(n.Key, "RangeStmt", "Key", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Token: Comma
+ if n.Value != nil {
+ r.cursor += token.Pos(len(token.COMMA.String()))
+ }
+
+ // Decoration: Key
+ r.applyDecorations(out, "Key", n.Decs.Key, false)
+
+ // Node: Value
+ if n.Value != nil {
+ out.Value = r.restoreNode(n.Value, "RangeStmt", "Value", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: Value
+ r.applyDecorations(out, "Value", n.Decs.Value, false)
+
+ // Token: Tok
+ if n.Tok != token.ILLEGAL {
+ out.Tok = n.Tok
+ out.TokPos = r.cursor
+ r.cursor += token.Pos(len(n.Tok.String()))
+ }
+
+ // Token: Range
+ r.cursor += token.Pos(len(token.RANGE.String()))
+
+ // Decoration: Range
+ r.applyDecorations(out, "Range", n.Decs.Range, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "RangeStmt", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = r.restoreNode(n.Body, "RangeStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.ReturnStmt:
+ out := &ast.ReturnStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Return
+ out.Return = r.cursor
+ r.cursor += token.Pos(len(token.RETURN.String()))
+
+ // Decoration: Return
+ r.applyDecorations(out, "Return", n.Decs.Return, false)
+
+ // List: Results
+ for _, v := range n.Results {
+ out.Results = append(out.Results, r.restoreNode(v, "ReturnStmt", "Results", "Expr", allowDuplicate).(ast.Expr))
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.SelectStmt:
+ out := &ast.SelectStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Select
+ out.Select = r.cursor
+ r.cursor += token.Pos(len(token.SELECT.String()))
+
+ // Decoration: Select
+ r.applyDecorations(out, "Select", n.Decs.Select, false)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = r.restoreNode(n.Body, "SelectStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.SelectorExpr:
+ out := &ast.SelectorExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "SelectorExpr", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Token: Period
+ r.cursor += token.Pos(len(token.PERIOD.String()))
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // Node: Sel
+ if n.Sel != nil {
+ out.Sel = r.restoreNode(n.Sel, "SelectorExpr", "Sel", "Ident", allowDuplicate).(*ast.Ident)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.SendStmt:
+ out := &ast.SendStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: Chan
+ if n.Chan != nil {
+ out.Chan = r.restoreNode(n.Chan, "SendStmt", "Chan", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: Chan
+ r.applyDecorations(out, "Chan", n.Decs.Chan, false)
+
+ // Token: Arrow
+ out.Arrow = r.cursor
+ r.cursor += token.Pos(len(token.ARROW.String()))
+
+ // Decoration: Arrow
+ r.applyDecorations(out, "Arrow", n.Decs.Arrow, false)
+
+ // Node: Value
+ if n.Value != nil {
+ out.Value = r.restoreNode(n.Value, "SendStmt", "Value", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.SliceExpr:
+ out := &ast.SliceExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "SliceExpr", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // Token: Lbrack
+ out.Lbrack = r.cursor
+ r.cursor += token.Pos(len(token.LBRACK.String()))
+
+ // Decoration: Lbrack
+ r.applyDecorations(out, "Lbrack", n.Decs.Lbrack, false)
+
+ // Node: Low
+ if n.Low != nil {
+ out.Low = r.restoreNode(n.Low, "SliceExpr", "Low", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Token: Colon1
+ r.cursor += token.Pos(len(token.COLON.String()))
+
+ // Decoration: Low
+ r.applyDecorations(out, "Low", n.Decs.Low, false)
+
+ // Node: High
+ if n.High != nil {
+ out.High = r.restoreNode(n.High, "SliceExpr", "High", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Token: Colon2
+ if n.Slice3 {
+ r.cursor += token.Pos(len(token.COLON.String()))
+ }
+
+ // Decoration: High
+ r.applyDecorations(out, "High", n.Decs.High, false)
+
+ // Node: Max
+ if n.Max != nil {
+ out.Max = r.restoreNode(n.Max, "SliceExpr", "Max", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: Max
+ r.applyDecorations(out, "Max", n.Decs.Max, false)
+
+ // Token: Rbrack
+ out.Rbrack = r.cursor
+ r.cursor += token.Pos(len(token.RBRACK.String()))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+
+ // Value: Slice3
+ out.Slice3 = n.Slice3
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.StarExpr:
+ out := &ast.StarExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Star
+ out.Star = r.cursor
+ r.cursor += token.Pos(len(token.MUL.String()))
+
+ // Decoration: Star
+ r.applyDecorations(out, "Star", n.Decs.Star, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "StarExpr", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.StructType:
+ out := &ast.StructType{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Struct
+ out.Struct = r.cursor
+ r.cursor += token.Pos(len(token.STRUCT.String()))
+
+ // Decoration: Struct
+ r.applyDecorations(out, "Struct", n.Decs.Struct, false)
+
+ // Node: Fields
+ if n.Fields != nil {
+ out.Fields = r.restoreNode(n.Fields, "StructType", "Fields", "FieldList", allowDuplicate).(*ast.FieldList)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+
+ // Value: Incomplete
+ out.Incomplete = n.Incomplete
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.SwitchStmt:
+ out := &ast.SwitchStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Switch
+ out.Switch = r.cursor
+ r.cursor += token.Pos(len(token.SWITCH.String()))
+
+ // Decoration: Switch
+ r.applyDecorations(out, "Switch", n.Decs.Switch, false)
+
+ // Node: Init
+ if n.Init != nil {
+ out.Init = r.restoreNode(n.Init, "SwitchStmt", "Init", "Stmt", allowDuplicate).(ast.Stmt)
+ }
+
+ // Decoration: Init
+ r.applyDecorations(out, "Init", n.Decs.Init, false)
+
+ // Node: Tag
+ if n.Tag != nil {
+ out.Tag = r.restoreNode(n.Tag, "SwitchStmt", "Tag", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: Tag
+ r.applyDecorations(out, "Tag", n.Decs.Tag, false)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = r.restoreNode(n.Body, "SwitchStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.TypeAssertExpr:
+ out := &ast.TypeAssertExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "TypeAssertExpr", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Token: Period
+ r.cursor += token.Pos(len(token.PERIOD.String()))
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // Token: Lparen
+ out.Lparen = r.cursor
+ r.cursor += token.Pos(len(token.LPAREN.String()))
+
+ // Decoration: Lparen
+ r.applyDecorations(out, "Lparen", n.Decs.Lparen, false)
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = r.restoreNode(n.Type, "TypeAssertExpr", "Type", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Token: TypeToken
+ if n.Type == nil {
+ r.cursor += token.Pos(len(token.TYPE.String()))
+ }
+
+ // Decoration: Type
+ r.applyDecorations(out, "Type", n.Decs.Type, false)
+
+ // Token: Rparen
+ out.Rparen = r.cursor
+ r.cursor += token.Pos(len(token.RPAREN.String()))
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.TypeSpec:
+ out := &ast.TypeSpec{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: Name
+ if n.Name != nil {
+ out.Name = r.restoreNode(n.Name, "TypeSpec", "Name", "Ident", allowDuplicate).(*ast.Ident)
+ }
+
+ // Token: Assign
+ if n.Assign {
+ out.Assign = r.cursor
+ r.cursor += token.Pos(len(token.ASSIGN.String()))
+ }
+
+ // Decoration: Name
+ r.applyDecorations(out, "Name", n.Decs.Name, false)
+
+ // Node: TypeParams
+ if n.TypeParams != nil {
+ out.TypeParams = r.restoreNode(n.TypeParams, "TypeSpec", "TypeParams", "FieldList", allowDuplicate).(*ast.FieldList)
+ }
+
+ // Decoration: TypeParams
+ r.applyDecorations(out, "TypeParams", n.Decs.TypeParams, false)
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = r.restoreNode(n.Type, "TypeSpec", "Type", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.TypeSwitchStmt:
+ out := &ast.TypeSwitchStmt{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Switch
+ out.Switch = r.cursor
+ r.cursor += token.Pos(len(token.SWITCH.String()))
+
+ // Decoration: Switch
+ r.applyDecorations(out, "Switch", n.Decs.Switch, false)
+
+ // Node: Init
+ if n.Init != nil {
+ out.Init = r.restoreNode(n.Init, "TypeSwitchStmt", "Init", "Stmt", allowDuplicate).(ast.Stmt)
+ }
+
+ // Decoration: Init
+ r.applyDecorations(out, "Init", n.Decs.Init, false)
+
+ // Node: Assign
+ if n.Assign != nil {
+ out.Assign = r.restoreNode(n.Assign, "TypeSwitchStmt", "Assign", "Stmt", allowDuplicate).(ast.Stmt)
+ }
+
+ // Decoration: Assign
+ r.applyDecorations(out, "Assign", n.Decs.Assign, false)
+
+ // Node: Body
+ if n.Body != nil {
+ out.Body = r.restoreNode(n.Body, "TypeSwitchStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.UnaryExpr:
+ out := &ast.UnaryExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Token: Op
+ out.Op = n.Op
+ out.OpPos = r.cursor
+ r.cursor += token.Pos(len(n.Op.String()))
+
+ // Decoration: Op
+ r.applyDecorations(out, "Op", n.Decs.Op, false)
+
+ // Node: X
+ if n.X != nil {
+ out.X = r.restoreNode(n.X, "UnaryExpr", "X", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ case *dst.ValueSpec:
+ out := &ast.ValueSpec{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // List: Names
+ for _, v := range n.Names {
+ out.Names = append(out.Names, r.restoreNode(v, "ValueSpec", "Names", "Ident", allowDuplicate).(*ast.Ident))
+ }
+
+ // Node: Type
+ if n.Type != nil {
+ out.Type = r.restoreNode(n.Type, "ValueSpec", "Type", "Expr", allowDuplicate).(ast.Expr)
+ }
+
+ // Token: Assign
+ if n.Values != nil {
+ r.cursor += token.Pos(len(token.ASSIGN.String()))
+ }
+
+ // Decoration: Assign
+ r.applyDecorations(out, "Assign", n.Decs.Assign, false)
+
+ // List: Values
+ for _, v := range n.Values {
+ out.Values = append(out.Values, r.restoreNode(v, "ValueSpec", "Values", "Expr", allowDuplicate).(ast.Expr))
+ }
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+ default:
+ panic(fmt.Sprintf("%T", n))
+ }
+}
diff --git a/vendor/github.com/dave/dst/decorator/restorer.go b/vendor/github.com/dave/dst/decorator/restorer.go
new file mode 100644
index 00000000..57717834
--- /dev/null
+++ b/vendor/github.com/dave/dst/decorator/restorer.go
@@ -0,0 +1,823 @@
+package decorator
+
+import (
+ "fmt"
+ "go/ast"
+ "go/format"
+ "go/token"
+ "io"
+ "os"
+ "sort"
+ "strconv"
+ "strings"
+
+ "github.com/dave/dst"
+ "github.com/dave/dst/decorator/resolver"
+)
+
+// NewRestorer returns a restorer.
+func NewRestorer() *Restorer {
+ return &Restorer{
+ Map: newMap(),
+ Fset: token.NewFileSet(),
+ }
+}
+
+// NewRestorerWithImports returns a restorer with import management attributes set.
+func NewRestorerWithImports(path string, resolver resolver.RestorerResolver) *Restorer {
+ res := NewRestorer()
+ res.Path = path
+ res.Resolver = resolver
+ return res
+}
+
+// Restorer restores dst.Node to ast.Node
+type Restorer struct {
+ Map
+ Fset *token.FileSet // Fset is the *token.FileSet in use. Set this to use a pre-existing FileSet.
+ Extras bool // Resore Objects, Scopes etc. Not needed for printing the resultant AST. If set to true, Objects and Scopes must be carefully managed to avoid duplicate nodes.
+
+ // If a Resolver is provided, the names of all imported packages are resolved, and the imports
+ // block is updated. All remote identifiers are updated (sometimes this involves changing
+ // SelectorExpr.X.Name, or even swapping between Ident and SelectorExpr). To force specific
+ // import alias names, use the FileRestorer.Alias map.
+ Resolver resolver.RestorerResolver
+ // Local package path - required if Resolver is set.
+ Path string
+}
+
+// Print uses format.Node to print a *dst.File to stdout
+func (pr *Restorer) Print(f *dst.File) error {
+ return pr.Fprint(os.Stdout, f)
+}
+
+// Fprint uses format.Node to print a *dst.File to a writer
+func (pr *Restorer) Fprint(w io.Writer, f *dst.File) error {
+ af, err := pr.RestoreFile(f)
+ if err != nil {
+ return err
+ }
+ return format.Node(w, pr.Fset, af)
+}
+
+// RestoreFile restores a *dst.File to an *ast.File
+func (pr *Restorer) RestoreFile(file *dst.File) (*ast.File, error) {
+ return pr.FileRestorer().RestoreFile(file)
+}
+
+// FileRestorer restores a specific file with extra options
+func (pr *Restorer) FileRestorer() *FileRestorer {
+ return &FileRestorer{
+ Restorer: pr,
+ Alias: map[string]string{},
+ }
+}
+
+// FileRestorer restores a specific file with extra options
+type FileRestorer struct {
+ *Restorer
+ Alias map[string]string // Map of package path -> package alias for imports
+ Name string // The name of the restored file in the FileSet. Can usually be left empty.
+ file *dst.File
+ lines []int
+ comments []*ast.CommentGroup
+ base int
+ cursor token.Pos
+ nodeDecl map[*ast.Object]dst.Node // Objects that have a ast.Node Decl (look up after file has been rendered)
+ nodeData map[*ast.Object]dst.Node // Objects that have a ast.Node Data (look up after file has been rendered)
+ cursorAtNewLine token.Pos // The cursor position directly after adding a newline decoration (or a line comment which ends in a "\n"). If we're still at this cursor position when we add a line space, reduce the "\n" by one.
+ packageNames map[string]string // names in the code of all imported packages ("." for dot-imports)
+}
+
+// Print uses format.Node to print a *dst.File to stdout
+func (r *FileRestorer) Print(f *dst.File) error {
+ return r.Fprint(os.Stdout, f)
+}
+
+// Fprint uses format.Node to print a *dst.File to a writer
+func (r *FileRestorer) Fprint(w io.Writer, f *dst.File) error {
+ af, err := r.RestoreFile(f)
+ if err != nil {
+ return err
+ }
+ return format.Node(w, r.Fset, af)
+}
+
+// RestoreFile restores a *dst.File to *ast.File
+func (r *FileRestorer) RestoreFile(file *dst.File) (*ast.File, error) {
+
+ if r.Resolver == nil && r.Path != "" {
+ panic("Restorer Path should be empty when Resolver is nil")
+ }
+
+ if r.Resolver != nil && r.Path == "" {
+ panic("Restorer Path should be set when Resolver is set")
+ }
+
+ if r.Fset == nil {
+ r.Fset = token.NewFileSet()
+ }
+
+ // reset the FileRestorer, but leave Name and the Alias map unchanged
+
+ r.file = file
+ r.lines = []int{0} // initialise with the first line at Pos 0
+ r.nodeDecl = map[*ast.Object]dst.Node{}
+ r.nodeData = map[*ast.Object]dst.Node{}
+ r.packageNames = map[string]string{}
+ r.comments = []*ast.CommentGroup{}
+ r.cursorAtNewLine = 0
+ r.packageNames = map[string]string{}
+
+ r.base = r.Fset.Base() // base is the pos that the file will start at in the fset
+ r.cursor = token.Pos(r.base)
+
+ if err := r.updateImports(); err != nil {
+ return nil, err
+ }
+
+ // restore the file, populate comments and lines
+ f := r.restoreNode(r.file, "", "", "", false).(*ast.File)
+
+ for _, cg := range r.comments {
+ f.Comments = append(f.Comments, cg)
+ }
+
+ ff := r.Fset.AddFile(r.Name, r.base, r.fileSize())
+ if !ff.SetLines(r.lines) {
+ panic("ff.SetLines failed")
+ }
+
+ if r.Extras {
+ // Sometimes new nodes are created here (e.g. in RangeStmt the "Object" is an AssignStmt
+ // which never occurs in the actual code). These shouldn't have position information but
+ // perhaps it doesn't matter?
+ for o, dn := range r.nodeDecl {
+ o.Decl = r.restoreNode(dn, "", "", "", true)
+ }
+ for o, dn := range r.nodeData {
+ o.Data = r.restoreNode(dn, "", "", "", true)
+ }
+ }
+
+ return f, nil
+}
+
+func (r *FileRestorer) updateImports() error {
+
+ if r.Resolver == nil {
+ return nil
+ }
+
+ // list of the import block(s)
+ var blocks []*dst.GenDecl
+
+ // hasCgoBlock is only true if the "C" import is on it's own in a block at the start of the
+ // file. If so, this is avoided. If there are no more imports in the file, and a new block is
+ // added, it should be added below this block.
+ var hasCgoBlock bool
+
+ // map of package path -> alias for all packages currently in the imports block(s). Alias can
+ // be an alias, an empty string, "_" or "."
+ importsFound := map[string]string{}
+
+ // a list of all packages that occur in the source (package path -> true)
+ packagesInUse := map[string]bool{}
+
+ // a list of all the imports that will be in the imports block after the update
+ importsRequired := map[string]bool{}
+
+ dst.Inspect(r.file, func(n dst.Node) bool {
+ switch n := n.(type) {
+ case *dst.Ident:
+ if n.Path == "" {
+ return true
+ }
+ if n.Path == r.Path {
+ return true
+ }
+ packagesInUse[n.Path] = true
+ importsRequired[n.Path] = true
+
+ case *dst.GenDecl:
+ if n.Tok != token.IMPORT {
+ return true
+ }
+ // if this block has 1 spec and it's the "C" import, ignore it.
+ if len(n.Specs) == 1 && mustUnquote(n.Specs[0].(*dst.ImportSpec).Path.Value) == "C" {
+ hasCgoBlock = true
+ return true
+ }
+ blocks = append(blocks, n)
+
+ case *dst.ImportSpec:
+ path := mustUnquote(n.Path.Value)
+ if n.Name == nil {
+ importsFound[path] = ""
+ } else {
+ importsFound[path] = n.Name.Name
+ }
+ if path == "C" {
+ // never remove the "C" import
+ importsRequired["C"] = true
+ }
+ }
+ return true
+ })
+
+ // resolved names of all packages in use
+ resolved := map[string]string{}
+
+ // the effective alias requested - the manually supplied alias will override the alias from the
+ // import block
+ effectiveAlias := map[string]string{}
+ for path, alias := range importsFound {
+ if alias == "" {
+ continue
+ }
+ if a, ok := r.Alias[path]; ok && a == "" {
+ continue
+ }
+ if alias == "_" && packagesInUse[path] {
+ continue
+ }
+ effectiveAlias[path] = alias
+ }
+ for path, alias := range r.Alias {
+ if alias == "" {
+ continue
+ }
+ if alias == "_" && packagesInUse[path] {
+ continue
+ }
+ effectiveAlias[path] = alias
+ }
+
+ // any anonymous imports
+ for path, alias := range effectiveAlias {
+ if alias == "_" {
+ importsRequired[path] = true
+ }
+ }
+
+ for path := range packagesInUse {
+ if _, ok := effectiveAlias[path]; ok {
+ // no need to resolve the path of a package that has an alias
+ continue
+ }
+ name, err := r.Resolver.ResolvePackage(path)
+ if err != nil {
+ return fmt.Errorf("could not resolve package %s: %w", path, err)
+ }
+ resolved[path] = name
+ }
+
+ // We sort the required imports so that the order going into the alias conflict detection
+ // routine is determinate. Without this, in a conflict, the package that receives the automatic
+ // renamed alias would be different every time.
+ importsRequiredOrdered := make([]string, len(importsRequired))
+ i := 0
+ for path := range importsRequired {
+ importsRequiredOrdered[i] = path
+ i++
+ }
+ sort.Slice(importsRequiredOrdered, func(i, j int) bool { return packagePathOrderLess(importsRequiredOrdered[i], importsRequiredOrdered[j]) })
+
+ // alias in the imports block (alias, empty string, "_" or "."
+ aliases := map[string]string{}
+
+ // name in the code (name or empty string for dot imports). This is consumed later by the
+ // restoreIdent method, so is a field on FileRestorer.
+ r.packageNames = map[string]string{}
+
+ // conflict returns true if the provided name already exists in the packageNames list
+ conflict := func(name string) bool {
+ for _, n := range r.packageNames {
+ if name == n {
+ return true
+ }
+ }
+ return false
+ }
+
+ // findAlias finds a unique alias given a path and a preferred alias
+ findAlias := func(path, preferred string) (name, alias string) {
+
+ // if we pass in a preferred alias we should always return an alias even when the alias
+ // matches the package name. If for some reason the source file has aliased an import with
+ // the package name, we shouldn't remove this.
+ aliased := preferred != ""
+
+ if !aliased {
+ // if there is no preferred alias, we look up the name of the package in the resolved
+ // names map.
+ preferred = resolved[path]
+ }
+
+ // if the current name has a conflict, increment a modifier until a non-conflicting name is
+ // found
+ modifier := 1
+ current := preferred
+ for conflict(current) {
+ current = fmt.Sprintf("%s%d", preferred, modifier)
+ modifier++
+ }
+
+ if !aliased && current == resolved[path] {
+ // if we didn't supply an alias and the resultant name matches the default package name,
+ // return empty string for alias indicating that no alias is required.
+ return current, ""
+ }
+
+ return current, current
+ }
+
+ for _, path := range importsRequiredOrdered {
+
+ alias := effectiveAlias[path]
+
+ if alias == "." || alias == "_" {
+ // no conflict checking for dot-imports or anonymous imports
+ r.packageNames[path], aliases[path] = "", alias
+ continue
+ }
+
+ // regular imports have a unique name chosen.
+ r.packageNames[path], aliases[path] = findAlias(path, alias)
+ }
+
+ // make any additions
+ var added bool
+ for _, path := range importsRequiredOrdered {
+
+ if _, ok := importsFound[path]; ok {
+ continue
+ }
+
+ added = true
+
+ // if there's currently no import blocks, we must create one
+ if len(blocks) == 0 {
+ gd := &dst.GenDecl{
+ Tok: token.IMPORT,
+ // make sure it has an empty line before and after
+ Decs: dst.GenDeclDecorations{
+ NodeDecs: dst.NodeDecs{Before: dst.EmptyLine, After: dst.EmptyLine},
+ },
+ }
+ if hasCgoBlock {
+ // special case for if we have the "C" import
+ r.file.Decls = append([]dst.Decl{r.file.Decls[0], gd}, r.file.Decls[1:]...)
+ } else {
+ r.file.Decls = append([]dst.Decl{gd}, r.file.Decls...)
+ }
+ blocks = append(blocks, gd)
+ }
+
+ is := &dst.ImportSpec{
+ Path: &dst.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("%q", path)},
+ }
+ if aliases[path] != "" {
+ is.Name = &dst.Ident{
+ Name: aliases[path],
+ }
+ }
+ blocks[0].Specs = append(blocks[0].Specs, is)
+ }
+
+ if added {
+ // rearrange import block
+ sort.Slice(blocks[0].Specs, func(i, j int) bool {
+ return packagePathOrderLess(
+ mustUnquote(blocks[0].Specs[i].(*dst.ImportSpec).Path.Value),
+ mustUnquote(blocks[0].Specs[j].(*dst.ImportSpec).Path.Value),
+ )
+ })
+ }
+
+ // import blocks that are empty will be removed from the File Decls list later
+ deleteBlocks := map[dst.Decl]bool{}
+
+ // update / delete any import specs from all blocks
+ for _, block := range blocks {
+ specs := make([]dst.Spec, 0, len(block.Specs))
+ for _, spec := range block.Specs {
+ spec := spec.(*dst.ImportSpec)
+ path := mustUnquote(spec.Path.Value)
+ if importsRequired[path] {
+ if spec.Name == nil && aliases[path] != "" {
+ // missing alias
+ spec.Name = &dst.Ident{Name: aliases[path]}
+ } else if spec.Name != nil && aliases[path] == "" {
+ // alias needs to be removed
+ spec.Name = nil
+ } else if spec.Name != nil && aliases[path] != spec.Name.Name {
+ // alias wrong
+ spec.Name.Name = aliases[path]
+ }
+ specs = append(specs, spec)
+ }
+ }
+
+ count := len(specs)
+
+ if count != len(block.Specs) {
+
+ block.Specs = specs
+
+ if count == 0 {
+ deleteBlocks[block] = true
+ } else if count == 1 {
+ block.Lparen = false
+ block.Rparen = false
+ } else {
+ block.Lparen = true
+ block.Rparen = true
+ }
+ }
+ }
+
+ if added {
+ // imports with a period in the path are assumed to not be standard library packages, so
+ // get a newline separating them from standard library packages. We remove any other
+ // newlines found in this block. We do this after the deletions because the first non-stdlib
+ // import might be deleted.
+ var foundDomainImport bool
+ for _, spec := range blocks[0].Specs {
+ path := mustUnquote(spec.(*dst.ImportSpec).Path.Value)
+ if strings.Contains(path, ".") && !foundDomainImport {
+ // first non-std-lib import -> empty line above
+ spec.Decorations().Before = dst.EmptyLine
+ spec.Decorations().After = dst.NewLine
+ foundDomainImport = true
+ continue
+ }
+ // all other specs, just newlines
+ spec.Decorations().Before = dst.NewLine
+ spec.Decorations().After = dst.NewLine
+ }
+
+ if len(blocks[0].Specs) == 1 {
+ blocks[0].Lparen = false
+ blocks[0].Rparen = false
+ } else {
+ blocks[0].Lparen = true
+ blocks[0].Rparen = true
+ }
+ }
+
+ // finally remove any deleted blocks from the File Decls list
+ if len(deleteBlocks) > 0 {
+ decls := make([]dst.Decl, 0, len(r.file.Decls))
+ for _, decl := range r.file.Decls {
+ if deleteBlocks[decl] {
+ continue
+ }
+ decls = append(decls, decl)
+ }
+ r.file.Decls = decls
+ }
+
+ return nil
+}
+
+// restoreIdent is a special case for restoring an ident. If the ident has a path and the imported
+// package is not a dot-import, we restore the Ident to a *ast.SelectorExpr with the correct name
+// in the X field.
+func (r *FileRestorer) restoreIdent(n *dst.Ident, parentName, parentField, parentFieldType string, allowDuplicate bool) ast.Node {
+
+ if r.Resolver == nil && n.Path != "" {
+ panic("This syntax has been decorated with import management enabled, but the restorer does not have import management enabled. Use NewRestorerWithImports to create a restorer with import management. See the Imports section of the readme for more information.")
+ }
+
+ var name string
+ if r.Resolver != nil && n.Path != "" {
+
+ if avoid[parentName+"."+parentField] {
+ panic(fmt.Sprintf("Path %s set on illegal Ident %s: parentName %s, parentField %s, parentFieldType %s", n.Path, n.Name, parentName, parentField, parentFieldType))
+ }
+
+ if n.Path != r.Path {
+ name = r.packageNames[n.Path]
+ }
+
+ if name == "." {
+ name = ""
+ }
+ }
+
+ if name == "" {
+ // continue to run standard Ident restore
+ return nil
+ }
+
+ // restore to a SelectorExpr
+ out := &ast.SelectorExpr{}
+ r.Ast.Nodes[n] = out
+ r.Dst.Nodes[out] = n
+ r.Dst.Nodes[out.Sel] = n
+ r.Dst.Nodes[out.X] = n
+ r.applySpace(n, "Before", n.Decs.Before)
+
+ // Decoration: Start
+ r.applyDecorations(out, "Start", n.Decs.Start, false)
+
+ // Node: X
+ out.X = r.restoreNode(dst.NewIdent(name), "SelectorExpr", "X", "Expr", allowDuplicate).(ast.Expr)
+
+ // Token: Period
+ r.cursor += token.Pos(len(token.PERIOD.String()))
+
+ // Decoration: X
+ r.applyDecorations(out, "X", n.Decs.X, false)
+
+ // Node: Sel
+ out.Sel = r.restoreNode(dst.NewIdent(n.Name), "SelectorExpr", "Sel", "Ident", allowDuplicate).(*ast.Ident)
+
+ // Decoration: End
+ r.applyDecorations(out, "End", n.Decs.End, true)
+ r.applySpace(n, "After", n.Decs.After)
+
+ return out
+
+}
+
+func packagePathOrderLess(pi, pj string) bool {
+ // package paths with a . should be ordered after those without
+ idot := strings.Contains(pi, ".")
+ jdot := strings.Contains(pj, ".")
+ if idot != jdot {
+ return jdot
+ }
+ return pi < pj
+}
+
+func (r *FileRestorer) fileSize() int {
+
+ // If a comment is at the end of a file, it will extend past the current cursor position...
+
+ // end pos of file
+ end := int(r.cursor)
+
+ // check that none of the comments or newlines extend past the file end position. If so, increment.
+ for _, cg := range r.comments {
+ if int(cg.End()) >= end {
+ end = int(cg.End()) + 1
+ }
+ }
+ for _, lineOffset := range r.lines {
+ pos := lineOffset + r.base // remember lines are relative to the file base
+ if pos >= end {
+ end = pos + 1
+ }
+ }
+
+ return end - r.base
+}
+
+func (r *FileRestorer) applyLiteral(text string) {
+ isMultiLine := strings.HasPrefix(text, "`") && strings.Contains(text, "\n")
+ if !isMultiLine {
+ return
+ }
+ for charIndex, char := range text {
+ if char == '\n' {
+ lineOffset := int(r.cursor) - r.base + charIndex // remember lines are relative to the file base
+ r.lines = append(r.lines, lineOffset)
+ }
+ }
+}
+
+func (r *FileRestorer) hasCommentField(n ast.Node) bool {
+ switch n.(type) {
+ case *ast.Field, *ast.ValueSpec, *ast.TypeSpec, *ast.ImportSpec:
+ return true
+ }
+ return false
+}
+
+func (r *FileRestorer) addCommentField(n ast.Node, slash token.Pos, text string) {
+ c := &ast.Comment{Slash: slash, Text: text}
+ switch n := n.(type) {
+ case *ast.Field:
+ if n.Comment == nil {
+ n.Comment = &ast.CommentGroup{}
+ r.comments = append(r.comments, n.Comment)
+ }
+ n.Comment.List = append(n.Comment.List, c)
+ case *ast.ImportSpec:
+ if n.Comment == nil {
+ n.Comment = &ast.CommentGroup{}
+ r.comments = append(r.comments, n.Comment)
+ }
+ n.Comment.List = append(n.Comment.List, c)
+ case *ast.ValueSpec:
+ if n.Comment == nil {
+ n.Comment = &ast.CommentGroup{}
+ r.comments = append(r.comments, n.Comment)
+ }
+ n.Comment.List = append(n.Comment.List, c)
+ case *ast.TypeSpec:
+ if n.Comment == nil {
+ n.Comment = &ast.CommentGroup{}
+ r.comments = append(r.comments, n.Comment)
+ }
+ n.Comment.List = append(n.Comment.List, c)
+ }
+}
+
+func (r *FileRestorer) applyDecorations(node ast.Node, name string, decorations dst.Decorations, end bool) {
+ firstLine := true
+ _, isNodeFile := node.(*ast.File)
+ isPackageComment := isNodeFile && name == "Start"
+
+ for _, d := range decorations {
+
+ isNewline := d == "\n"
+ isLineComment := strings.HasPrefix(d, "//")
+ isInlineComment := strings.HasPrefix(d, "/*")
+ isComment := isLineComment || isInlineComment
+ isMultiLineComment := isInlineComment && strings.Contains(d, "\n")
+
+ if end && r.cursorAtNewLine == r.cursor {
+ r.cursor++ // indent all comments in "End" decorations
+ }
+
+ // for multi-line comments, add a newline for each \n
+ if isMultiLineComment {
+ for charIndex, char := range d {
+ if char == '\n' {
+ lineOffset := int(r.cursor) - r.base + charIndex // remember lines are relative to the file base
+ r.lines = append(r.lines, lineOffset)
+ }
+ }
+ }
+
+ // if the decoration is a comment, add it and advance the cursor
+ if isComment {
+ if firstLine && end && r.hasCommentField(node) {
+ // for comments on the same line as the end of a node that has a Comment field, we
+ // add the comment to the node instead of the file.
+ r.addCommentField(node, r.cursor, d)
+ } else {
+ r.comments = append(r.comments, &ast.CommentGroup{List: []*ast.Comment{{Slash: r.cursor, Text: d}}})
+ }
+ r.cursor += token.Pos(len(d))
+ }
+
+ // for newline decorations and also line-comments, add a newline
+ if isLineComment || isNewline {
+ lineOffset := int(r.cursor) - r.base // remember lines are relative to the file base
+ r.lines = append(r.lines, lineOffset)
+ r.cursor++
+
+ r.cursorAtNewLine = r.cursor
+ }
+
+ if isNewline || isLineComment {
+ firstLine = false
+ }
+ }
+ if isPackageComment {
+ // This fixes https://github.com/dave/dst/issues/69
+ r.cursor++
+ }
+}
+
+func (r *FileRestorer) applySpace(node dst.Node, position string, space dst.SpaceType) {
+ switch node.(type) {
+ case *dst.BadDecl, *dst.BadExpr, *dst.BadStmt:
+ if position == "After" {
+ // BadXXX are always followed by an empty line
+ space = dst.EmptyLine
+ }
+ }
+ var newlines int
+ switch space {
+ case dst.NewLine:
+ newlines = 1
+ case dst.EmptyLine:
+ newlines = 2
+ }
+ if r.cursor == r.cursorAtNewLine {
+ newlines--
+ }
+ for i := 0; i < newlines; i++ {
+
+ // Advance the cursor one more byte for all newlines, so we step over any required
+ // separator char - e.g. comma. See net-hook test
+ r.cursor++
+
+ lineOffset := int(r.cursor) - r.base // remember lines are relative to the file base
+ r.lines = append(r.lines, lineOffset)
+ r.cursor++
+ r.cursorAtNewLine = r.cursor
+ }
+}
+
+func (r *FileRestorer) restoreObject(o *dst.Object) *ast.Object {
+ if !r.Extras {
+ return nil
+ }
+ if o == nil {
+ return nil
+ }
+ if ro, ok := r.Ast.Objects[o]; ok {
+ return ro
+ }
+ /*
+ // An Object describes a named language entity such as a package,
+ // constant, type, variable, function (incl. methods), or label.
+ //
+ // The Data fields contains object-specific data:
+ //
+ // Kind Data type Data value
+ // Pkg *Scope package scope
+ // Con int iota for the respective declaration
+ //
+ type Object struct {
+ Kind ObjKind
+ Name string // declared name
+ Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil
+ Data interface{} // object-specific data; or nil
+ Type interface{} // placeholder for type information; may be nil
+ }
+ */
+ out := &ast.Object{}
+
+ r.Ast.Objects[o] = out
+ r.Dst.Objects[out] = o
+
+ out.Kind = ast.ObjKind(o.Kind)
+ out.Name = o.Name
+
+ switch decl := o.Decl.(type) {
+ case *dst.Scope:
+ out.Decl = r.restoreScope(decl)
+ case dst.Node:
+ // Can't use restoreNode here because we aren't at the right cursor position, so we store a link
+ // to the Object and Node so we can look the Nodes up in the cache after the file is fully processed.
+ r.nodeDecl[out] = decl
+ case nil:
+ default:
+ panic(fmt.Sprintf("o.Decl is %T", o.Decl))
+ }
+
+ switch data := o.Data.(type) {
+ case int:
+ out.Data = data
+ case *dst.Scope:
+ out.Data = r.restoreScope(data)
+ case dst.Node:
+ // Can't use restoreNode here because we aren't at the right cursor position, so we store a link
+ // to the Object and Node so we can look the Nodes up in the cache after the file is fully processed.
+ r.nodeData[out] = data
+ case nil:
+ default:
+ panic(fmt.Sprintf("o.Data is %T", o.Data))
+ }
+
+ return out
+}
+
+func (r *FileRestorer) restoreScope(s *dst.Scope) *ast.Scope {
+ if !r.Extras {
+ return nil
+ }
+ if s == nil {
+ return nil
+ }
+ if rs, ok := r.Ast.Scopes[s]; ok {
+ return rs
+ }
+ /*
+ // A Scope maintains the set of named language entities declared
+ // in the scope and a link to the immediately surrounding (outer)
+ // scope.
+ //
+ type Scope struct {
+ Outer *Scope
+ Objects map[string]*Object
+ }
+ */
+ out := &ast.Scope{}
+
+ r.Ast.Scopes[s] = out
+ r.Dst.Scopes[out] = s
+
+ out.Outer = r.restoreScope(s.Outer)
+ out.Objects = map[string]*ast.Object{}
+ for k, v := range s.Objects {
+ out.Objects[k] = r.restoreObject(v)
+ }
+
+ return out
+}
+
+func mustUnquote(s string) string {
+ out, err := strconv.Unquote(s)
+ if err != nil {
+ panic(err)
+ }
+ return out
+}
diff --git a/vendor/github.com/dave/dst/dst.go b/vendor/github.com/dave/dst/dst.go
new file mode 100644
index 00000000..803eb9a8
--- /dev/null
+++ b/vendor/github.com/dave/dst/dst.go
@@ -0,0 +1,664 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package dst declares the types used to represent decorated syntax
+// trees for Go packages.
+package dst
+
+import (
+ "go/token"
+)
+
+// ----------------------------------------------------------------------------
+// Interfaces
+//
+// There are 3 main classes of nodes: Expressions and type nodes,
+// statement nodes, and declaration nodes. The node names usually
+// match the corresponding Go spec production names to which they
+// correspond. The node fields correspond to the individual parts
+// of the respective productions.
+//
+// All nodes contain position information marking the beginning of
+// the corresponding source text segment; it is accessible via the
+// Pos accessor method. Nodes may contain additional position info
+// for language constructs where comments may be found between parts
+// of the construct (typically any larger, parenthesized subpart).
+// That position information is needed to properly position comments
+// when printing the construct.
+
+// Node is satisfied by all nodes types.
+type Node interface {
+ // Decorations returns the common Node decorations (Before, After, Start, End). This returns nil for Package nodes.
+ Decorations() *NodeDecs
+}
+
+// All expression nodes implement the Expr interface.
+type Expr interface {
+ Node
+ exprNode()
+}
+
+// All statement nodes implement the Stmt interface.
+type Stmt interface {
+ Node
+ stmtNode()
+}
+
+// All declaration nodes implement the Decl interface.
+type Decl interface {
+ Node
+ declNode()
+}
+
+// ----------------------------------------------------------------------------
+// Expressions and types
+
+// A Field represents a Field declaration list in a struct type,
+// a method list in an interface type, or a parameter/result declaration
+// in a signature.
+// Field.Names is nil for unnamed parameters (parameter lists which only contain types)
+// and embedded struct fields. In the latter case, the field name is the type name.
+//
+type Field struct {
+ Names []*Ident // field/method/(type) parameter names; or nil
+ Type Expr // field/method/parameter type; or nil
+ Tag *BasicLit // field tag; or nil
+ Decs FieldDecorations
+}
+
+// A FieldList represents a list of Fields, enclosed by parentheses,
+// curly braces, or square brackets.
+type FieldList struct {
+ Opening bool
+ List []*Field // field list; or nil
+ Closing bool
+ Decs FieldListDecorations
+}
+
+// NumFields returns the number of parameters or struct fields represented by a FieldList.
+func (f *FieldList) NumFields() int {
+ n := 0
+ if f != nil {
+ for _, g := range f.List {
+ m := len(g.Names)
+ if m == 0 {
+ m = 1
+ }
+ n += m
+ }
+ }
+ return n
+}
+
+// An expression is represented by a tree consisting of one
+// or more of the following concrete expression nodes.
+type (
+ // A BadExpr node is a placeholder for an expression containing
+ // syntax errors for which a correct expression node cannot be
+ // created.
+ BadExpr struct {
+ Length int // position range of bad expression
+ Decs BadExprDecorations
+ }
+
+ // An Ident node represents an identifier.
+ Ident struct {
+ Name string // identifier name
+ Obj *Object // denoted object; or nil
+ Path string // path of the imported package, if this identifier is not local
+ Decs IdentDecorations
+ }
+
+ // An Ellipsis node stands for the "..." type in a
+ // parameter list or the "..." length in an array type.
+ //
+ Ellipsis struct {
+ Elt Expr // ellipsis element type (parameter lists only); or nil
+ Decs EllipsisDecorations
+ }
+
+ // A BasicLit node represents a literal of basic type.
+ BasicLit struct {
+ Kind token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
+ Value string // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o`
+ Decs BasicLitDecorations
+ }
+
+ // A FuncLit node represents a function literal.
+ FuncLit struct {
+ Type *FuncType // function type
+ Body *BlockStmt // function body
+ Decs FuncLitDecorations
+ }
+
+ // A CompositeLit node represents a composite literal.
+ CompositeLit struct {
+ Type Expr // literal type; or nil
+ Elts []Expr // list of composite elements; or nil
+ Incomplete bool // true if (source) expressions are missing in the Elts list
+ Decs CompositeLitDecorations
+ }
+
+ // A ParenExpr node represents a parenthesized expression.
+ ParenExpr struct {
+ X Expr // parenthesized expression
+ Decs ParenExprDecorations
+ }
+
+ // A SelectorExpr node represents an expression followed by a selector.
+ SelectorExpr struct {
+ X Expr // expression
+ Sel *Ident // field selector
+ Decs SelectorExprDecorations
+ }
+
+ // An IndexExpr node represents an expression followed by an index.
+ IndexExpr struct {
+ X Expr // expression
+ Index Expr // index expression
+ Decs IndexExprDecorations
+ }
+
+ // An IndexListExpr node represents an expression followed by multiple
+ // indices.
+ IndexListExpr struct {
+ X Expr // expression
+ Indices []Expr
+ Decs IndexListExprDecorations
+ }
+
+ // An SliceExpr node represents an expression followed by slice indices.
+ SliceExpr struct {
+ X Expr // expression
+ Low Expr // begin of slice range; or nil
+ High Expr // end of slice range; or nil
+ Max Expr // maximum capacity of slice; or nil
+ Slice3 bool // true if 3-index slice (2 colons present)
+ Decs SliceExprDecorations
+ }
+
+ // A TypeAssertExpr node represents an expression followed by a
+ // type assertion.
+ //
+ TypeAssertExpr struct {
+ X Expr // expression
+ Type Expr // asserted type; nil means type switch X.(type)
+ Decs TypeAssertExprDecorations
+ }
+
+ // A CallExpr node represents an expression followed by an argument list.
+ CallExpr struct {
+ Fun Expr // function expression
+ Args []Expr // function arguments; or nil
+ Ellipsis bool
+ Decs CallExprDecorations
+ }
+
+ // A StarExpr node represents an expression of the form "*" Expression.
+ // Semantically it could be a unary "*" expression, or a pointer type.
+ //
+ StarExpr struct {
+ X Expr // operand
+ Decs StarExprDecorations
+ }
+
+ // A UnaryExpr node represents a unary expression.
+ // Unary "*" expressions are represented via StarExpr nodes.
+ //
+ UnaryExpr struct {
+ Op token.Token // operator
+ X Expr // operand
+ Decs UnaryExprDecorations
+ }
+
+ // A BinaryExpr node represents a binary expression.
+ BinaryExpr struct {
+ X Expr // left operand
+ Op token.Token // operator
+ Y Expr // right operand
+ Decs BinaryExprDecorations
+ }
+
+ // A KeyValueExpr node represents (key : value) pairs
+ // in composite literals.
+ //
+ KeyValueExpr struct {
+ Key Expr
+ Value Expr
+ Decs KeyValueExprDecorations
+ }
+)
+
+// The direction of a channel type is indicated by a bit
+// mask including one or both of the following constants.
+type ChanDir int
+
+const (
+ SEND ChanDir = 1 << iota
+ RECV
+)
+
+// A type is represented by a tree consisting of one
+// or more of the following type-specific expression
+// nodes.
+type (
+ // An ArrayType node represents an array or slice type.
+ ArrayType struct {
+ Len Expr // Ellipsis node for [...]T array types, nil for slice types
+ Elt Expr // element type
+ Decs ArrayTypeDecorations
+ }
+
+ // A StructType node represents a struct type.
+ StructType struct {
+ Fields *FieldList // list of field declarations
+ Incomplete bool // true if (source) fields are missing in the Fields list
+ Decs StructTypeDecorations
+ }
+
+ // Pointer types are represented via StarExpr nodes.
+
+ // A FuncType node represents a function type.
+ FuncType struct {
+ Func bool
+ TypeParams *FieldList // type parameters; or nil
+ Params *FieldList // (incoming) parameters; non-nil
+ Results *FieldList // (outgoing) results; or nil
+ Decs FuncTypeDecorations
+ }
+
+ // An InterfaceType node represents an interface type.
+ InterfaceType struct {
+ Methods *FieldList // list of embedded interfaces, methods, or types
+ Incomplete bool // true if (source) methods or types are missing in the Methods list
+ Decs InterfaceTypeDecorations
+ }
+
+ // A MapType node represents a map type.
+ MapType struct {
+ Key Expr
+ Value Expr
+ Decs MapTypeDecorations
+ }
+
+ // A ChanType node represents a channel type.
+ ChanType struct {
+ Dir ChanDir // channel direction
+ Value Expr // value type
+ Decs ChanTypeDecorations
+ }
+)
+
+// exprNode() ensures that only expression/type nodes can be
+// assigned to an Expr.
+func (*BadExpr) exprNode() {}
+func (*Ident) exprNode() {}
+func (*Ellipsis) exprNode() {}
+func (*BasicLit) exprNode() {}
+func (*FuncLit) exprNode() {}
+func (*CompositeLit) exprNode() {}
+func (*ParenExpr) exprNode() {}
+func (*SelectorExpr) exprNode() {}
+func (*IndexExpr) exprNode() {}
+func (*IndexListExpr) exprNode() {}
+func (*SliceExpr) exprNode() {}
+func (*TypeAssertExpr) exprNode() {}
+func (*CallExpr) exprNode() {}
+func (*StarExpr) exprNode() {}
+func (*UnaryExpr) exprNode() {}
+func (*BinaryExpr) exprNode() {}
+func (*KeyValueExpr) exprNode() {}
+
+func (*ArrayType) exprNode() {}
+func (*StructType) exprNode() {}
+func (*FuncType) exprNode() {}
+func (*InterfaceType) exprNode() {}
+func (*MapType) exprNode() {}
+func (*ChanType) exprNode() {}
+
+// ----------------------------------------------------------------------------
+// Convenience functions for Idents
+
+// NewIdent creates a new Ident without position.
+// Useful for ASTs generated by code other than the Go parser.
+func NewIdent(name string) *Ident { return &Ident{name, nil, "", IdentDecorations{}} }
+
+// IsExported reports whether name starts with an upper-case letter.
+func IsExported(name string) bool { return token.IsExported(name) }
+
+// IsExported reports whether id starts with an upper-case letter.
+func (id *Ident) IsExported() bool { return token.IsExported(id.Name) }
+
+func (id *Ident) String() string {
+ if id != nil {
+ if id.Path != "" {
+ return id.Path + "." + id.Name
+ }
+ return id.Name
+ }
+ return ""
+}
+
+// ----------------------------------------------------------------------------
+// Statements
+
+// A statement is represented by a tree consisting of one
+// or more of the following concrete statement nodes.
+type (
+ // A BadStmt node is a placeholder for statements containing
+ // syntax errors for which no correct statement nodes can be
+ // created.
+ //
+ BadStmt struct {
+ Length int // position range of bad statement
+ Decs BadStmtDecorations
+ }
+
+ // A DeclStmt node represents a declaration in a statement list.
+ DeclStmt struct {
+ Decl Decl // *GenDecl with CONST, TYPE, or VAR token
+ Decs DeclStmtDecorations
+ }
+
+ // An EmptyStmt node represents an empty statement.
+ // The "position" of the empty statement is the position
+ // of the immediately following (explicit or implicit) semicolon.
+ //
+ EmptyStmt struct {
+ Implicit bool // if set, ";" was omitted in the source
+ Decs EmptyStmtDecorations
+ }
+
+ // A LabeledStmt node represents a labeled statement.
+ LabeledStmt struct {
+ Label *Ident
+ Stmt Stmt
+ Decs LabeledStmtDecorations
+ }
+
+ // An ExprStmt node represents a (stand-alone) expression
+ // in a statement list.
+ //
+ ExprStmt struct {
+ X Expr // expression
+ Decs ExprStmtDecorations
+ }
+
+ // A SendStmt node represents a send statement.
+ SendStmt struct {
+ Chan Expr
+ Value Expr
+ Decs SendStmtDecorations
+ }
+
+ // An IncDecStmt node represents an increment or decrement statement.
+ IncDecStmt struct {
+ X Expr
+ Tok token.Token // INC or DEC
+ Decs IncDecStmtDecorations
+ }
+
+ // An AssignStmt node represents an assignment or
+ // a short variable declaration.
+ //
+ AssignStmt struct {
+ Lhs []Expr
+ Tok token.Token // assignment token, DEFINE
+ Rhs []Expr
+ Decs AssignStmtDecorations
+ }
+
+ // A GoStmt node represents a go statement.
+ GoStmt struct {
+ Call *CallExpr
+ Decs GoStmtDecorations
+ }
+
+ // A DeferStmt node represents a defer statement.
+ DeferStmt struct {
+ Call *CallExpr
+ Decs DeferStmtDecorations
+ }
+
+ // A ReturnStmt node represents a return statement.
+ ReturnStmt struct {
+ Results []Expr // result expressions; or nil
+ Decs ReturnStmtDecorations
+ }
+
+ // A BranchStmt node represents a break, continue, goto,
+ // or fallthrough statement.
+ //
+ BranchStmt struct {
+ Tok token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
+ Label *Ident // label name; or nil
+ Decs BranchStmtDecorations
+ }
+
+ // A BlockStmt node represents a braced statement list.
+ BlockStmt struct {
+ List []Stmt
+ RbraceHasNoPos bool // Rbrace may be absent due to syntax error, so we duplicate this in the output for compatibility.
+ Decs BlockStmtDecorations
+ }
+
+ // An IfStmt node represents an if statement.
+ IfStmt struct {
+ Init Stmt // initialization statement; or nil
+ Cond Expr // condition
+ Body *BlockStmt
+ Else Stmt // else branch; or nil
+ Decs IfStmtDecorations
+ }
+
+ // A CaseClause represents a case of an expression or type switch statement.
+ CaseClause struct {
+ List []Expr // list of expressions or types; nil means default case
+ Body []Stmt // statement list; or nil
+ Decs CaseClauseDecorations
+ }
+
+ // A SwitchStmt node represents an expression switch statement.
+ SwitchStmt struct {
+ Init Stmt // initialization statement; or nil
+ Tag Expr // tag expression; or nil
+ Body *BlockStmt // CaseClauses only
+ Decs SwitchStmtDecorations
+ }
+
+ // A TypeSwitchStmt node represents a type switch statement.
+ TypeSwitchStmt struct {
+ Init Stmt // initialization statement; or nil
+ Assign Stmt // x := y.(type) or y.(type)
+ Body *BlockStmt // CaseClauses only
+ Decs TypeSwitchStmtDecorations
+ }
+
+ // A CommClause node represents a case of a select statement.
+ CommClause struct {
+ Comm Stmt // send or receive statement; nil means default case
+ Body []Stmt // statement list; or nil
+ Decs CommClauseDecorations
+ }
+
+ // A SelectStmt node represents a select statement.
+ SelectStmt struct {
+ Body *BlockStmt // CommClauses only
+ Decs SelectStmtDecorations
+ }
+
+ // A ForStmt represents a for statement.
+ ForStmt struct {
+ Init Stmt // initialization statement; or nil
+ Cond Expr // condition; or nil
+ Post Stmt // post iteration statement; or nil
+ Body *BlockStmt
+ Decs ForStmtDecorations
+ }
+
+ // A RangeStmt represents a for statement with a range clause.
+ RangeStmt struct {
+ Key, Value Expr // Key, Value may be nil
+ Tok token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE
+ X Expr // value to range over
+ Body *BlockStmt
+ Decs RangeStmtDecorations
+ }
+)
+
+// stmtNode() ensures that only statement nodes can be
+// assigned to a Stmt.
+func (*BadStmt) stmtNode() {}
+func (*DeclStmt) stmtNode() {}
+func (*EmptyStmt) stmtNode() {}
+func (*LabeledStmt) stmtNode() {}
+func (*ExprStmt) stmtNode() {}
+func (*SendStmt) stmtNode() {}
+func (*IncDecStmt) stmtNode() {}
+func (*AssignStmt) stmtNode() {}
+func (*GoStmt) stmtNode() {}
+func (*DeferStmt) stmtNode() {}
+func (*ReturnStmt) stmtNode() {}
+func (*BranchStmt) stmtNode() {}
+func (*BlockStmt) stmtNode() {}
+func (*IfStmt) stmtNode() {}
+func (*CaseClause) stmtNode() {}
+func (*SwitchStmt) stmtNode() {}
+func (*TypeSwitchStmt) stmtNode() {}
+func (*CommClause) stmtNode() {}
+func (*SelectStmt) stmtNode() {}
+func (*ForStmt) stmtNode() {}
+func (*RangeStmt) stmtNode() {}
+
+// ----------------------------------------------------------------------------
+// Declarations
+
+// A Spec node represents a single (non-parenthesized) import,
+// constant, type, or variable declaration.
+type (
+ // The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
+ Spec interface {
+ Node
+ specNode()
+ }
+
+ // An ImportSpec node represents a single package import.
+ ImportSpec struct {
+ Name *Ident // local package name (including "."); or nil
+ Path *BasicLit // import path
+ Decs ImportSpecDecorations
+ }
+
+ // A ValueSpec node represents a constant or variable declaration
+ // (ConstSpec or VarSpec production).
+ //
+ ValueSpec struct {
+ Names []*Ident // value names (len(Names) > 0)
+ Type Expr // value type; or nil
+ Values []Expr // initial values; or nil
+ Decs ValueSpecDecorations
+ }
+
+ // A TypeSpec node represents a type declaration (TypeSpec production).
+ TypeSpec struct {
+ Name *Ident // type name
+ TypeParams *FieldList // type parameters; or nil
+ Assign bool // position of '=', if any
+ Type Expr // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
+ Decs TypeSpecDecorations
+ }
+)
+
+// Pos and End implementations for spec nodes.
+
+// specNode() ensures that only spec nodes can be
+// assigned to a Spec.
+func (*ImportSpec) specNode() {}
+func (*ValueSpec) specNode() {}
+func (*TypeSpec) specNode() {}
+
+// A declaration is represented by one of the following declaration nodes.
+type (
+ // A BadDecl node is a placeholder for a declaration containing
+ // syntax errors for which a correct declaration node cannot be
+ // created.
+ //
+ BadDecl struct {
+ Length int // position range of bad declaration
+ Decs BadDeclDecorations
+ }
+
+ // A GenDecl node (generic declaration node) represents an import,
+ // constant, type or variable declaration. A valid Lparen position
+ // (Lparen.IsValid()) indicates a parenthesized declaration.
+ //
+ // Relationship between Tok value and Specs element type:
+ //
+ // token.IMPORT *ImportSpec
+ // token.CONST *ValueSpec
+ // token.TYPE *TypeSpec
+ // token.VAR *ValueSpec
+ //
+ GenDecl struct {
+ Tok token.Token // IMPORT, CONST, TYPE, or VAR
+ Lparen bool
+ Specs []Spec
+ Rparen bool
+ Decs GenDeclDecorations
+ }
+
+ // A FuncDecl node represents a function declaration.
+ FuncDecl struct {
+ Recv *FieldList // receiver (methods); or nil (functions)
+ Name *Ident // function/method name
+ Type *FuncType // function signature: type and value parameters, results, and position of "func" keyword
+ Body *BlockStmt // function body; or nil for external (non-Go) function
+ Decs FuncDeclDecorations
+ }
+)
+
+// declNode() ensures that only declaration nodes can be
+// assigned to a Decl.
+func (*BadDecl) declNode() {}
+func (*GenDecl) declNode() {}
+func (*FuncDecl) declNode() {}
+
+// ----------------------------------------------------------------------------
+// Files and packages
+
+// A File node represents a Go source file.
+//
+// The Comments list contains all comments in the source file in order of
+// appearance, including the comments that are pointed to from other nodes
+// via Doc and Comment fields.
+//
+// For correct printing of source code containing comments (using packages
+// go/format and go/printer), special care must be taken to update comments
+// when a File's syntax tree is modified: For printing, comments are interspersed
+// between tokens based on their position. If syntax tree nodes are
+// removed or moved, relevant comments in their vicinity must also be removed
+// (from the File.Comments list) or moved accordingly (by updating their
+// positions). A CommentMap may be used to facilitate some of these operations.
+//
+// Whether and how a comment is associated with a node depends on the
+// interpretation of the syntax tree by the manipulating program: Except for Doc
+// and Comment comments directly associated with nodes, the remaining comments
+// are "free-floating" (see also issues #18593, #20744).
+type File struct {
+ Name *Ident // package name
+ Decls []Decl // top-level declarations; or nil
+ Scope *Scope // package scope (this file only)
+ Imports []*ImportSpec // imports in this file
+ Unresolved []*Ident // unresolved identifiers in this file
+ Decs FileDecorations
+}
+
+// A Package node represents a set of source files
+// collectively building a Go package.
+type Package struct {
+ Name string // package name
+ Scope *Scope // package scope across all files
+ Imports map[string]*Object // map of package id -> package object
+ Files map[string]*File // Go source files by filename
+}
diff --git a/vendor/github.com/dave/dst/dstutil/decorations-generated.go b/vendor/github.com/dave/dst/dstutil/decorations-generated.go
new file mode 100644
index 00000000..b3e31579
--- /dev/null
+++ b/vendor/github.com/dave/dst/dstutil/decorations-generated.go
@@ -0,0 +1,369 @@
+package dstutil
+
+import "github.com/dave/dst"
+
+func decorations(n dst.Node) (before, after dst.SpaceType, points []DecorationPoint) {
+ switch n := n.(type) {
+ case *dst.ArrayType:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Lbrack", n.Decs.Lbrack})
+ points = append(points, DecorationPoint{"Len", n.Decs.Len})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.AssignStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Tok", n.Decs.Tok})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.BadDecl:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.BadExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.BadStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.BasicLit:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.BinaryExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"X", n.Decs.X})
+ points = append(points, DecorationPoint{"Op", n.Decs.Op})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.BlockStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Lbrace", n.Decs.Lbrace})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.BranchStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Tok", n.Decs.Tok})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.CallExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Fun", n.Decs.Fun})
+ points = append(points, DecorationPoint{"Lparen", n.Decs.Lparen})
+ points = append(points, DecorationPoint{"Ellipsis", n.Decs.Ellipsis})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.CaseClause:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Case", n.Decs.Case})
+ points = append(points, DecorationPoint{"Colon", n.Decs.Colon})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.ChanType:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Begin", n.Decs.Begin})
+ points = append(points, DecorationPoint{"Arrow", n.Decs.Arrow})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.CommClause:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Case", n.Decs.Case})
+ points = append(points, DecorationPoint{"Comm", n.Decs.Comm})
+ points = append(points, DecorationPoint{"Colon", n.Decs.Colon})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.CompositeLit:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Type", n.Decs.Type})
+ points = append(points, DecorationPoint{"Lbrace", n.Decs.Lbrace})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.DeclStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.DeferStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Defer", n.Decs.Defer})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.Ellipsis:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Ellipsis", n.Decs.Ellipsis})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.EmptyStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.ExprStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.Field:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Type", n.Decs.Type})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.FieldList:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Opening", n.Decs.Opening})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.File:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Package", n.Decs.Package})
+ points = append(points, DecorationPoint{"Name", n.Decs.Name})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.ForStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"For", n.Decs.For})
+ points = append(points, DecorationPoint{"Init", n.Decs.Init})
+ points = append(points, DecorationPoint{"Cond", n.Decs.Cond})
+ points = append(points, DecorationPoint{"Post", n.Decs.Post})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.FuncDecl:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Func", n.Decs.Func})
+ points = append(points, DecorationPoint{"Recv", n.Decs.Recv})
+ points = append(points, DecorationPoint{"Name", n.Decs.Name})
+ points = append(points, DecorationPoint{"TypeParams", n.Decs.TypeParams})
+ points = append(points, DecorationPoint{"Params", n.Decs.Params})
+ points = append(points, DecorationPoint{"Results", n.Decs.Results})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.FuncLit:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Type", n.Decs.Type})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.FuncType:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Func", n.Decs.Func})
+ points = append(points, DecorationPoint{"TypeParams", n.Decs.TypeParams})
+ points = append(points, DecorationPoint{"Params", n.Decs.Params})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.GenDecl:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Tok", n.Decs.Tok})
+ points = append(points, DecorationPoint{"Lparen", n.Decs.Lparen})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.GoStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Go", n.Decs.Go})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.Ident:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"X", n.Decs.X})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.IfStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"If", n.Decs.If})
+ points = append(points, DecorationPoint{"Init", n.Decs.Init})
+ points = append(points, DecorationPoint{"Cond", n.Decs.Cond})
+ points = append(points, DecorationPoint{"Else", n.Decs.Else})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.ImportSpec:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Name", n.Decs.Name})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.IncDecStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"X", n.Decs.X})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.IndexExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"X", n.Decs.X})
+ points = append(points, DecorationPoint{"Lbrack", n.Decs.Lbrack})
+ points = append(points, DecorationPoint{"Index", n.Decs.Index})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.IndexListExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"X", n.Decs.X})
+ points = append(points, DecorationPoint{"Lbrack", n.Decs.Lbrack})
+ points = append(points, DecorationPoint{"Indices", n.Decs.Indices})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.InterfaceType:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Interface", n.Decs.Interface})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.KeyValueExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Key", n.Decs.Key})
+ points = append(points, DecorationPoint{"Colon", n.Decs.Colon})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.LabeledStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Label", n.Decs.Label})
+ points = append(points, DecorationPoint{"Colon", n.Decs.Colon})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.MapType:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Map", n.Decs.Map})
+ points = append(points, DecorationPoint{"Key", n.Decs.Key})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.Package:
+ case *dst.ParenExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Lparen", n.Decs.Lparen})
+ points = append(points, DecorationPoint{"X", n.Decs.X})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.RangeStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"For", n.Decs.For})
+ points = append(points, DecorationPoint{"Key", n.Decs.Key})
+ points = append(points, DecorationPoint{"Value", n.Decs.Value})
+ points = append(points, DecorationPoint{"Range", n.Decs.Range})
+ points = append(points, DecorationPoint{"X", n.Decs.X})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.ReturnStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Return", n.Decs.Return})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.SelectStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Select", n.Decs.Select})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.SelectorExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"X", n.Decs.X})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.SendStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Chan", n.Decs.Chan})
+ points = append(points, DecorationPoint{"Arrow", n.Decs.Arrow})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.SliceExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"X", n.Decs.X})
+ points = append(points, DecorationPoint{"Lbrack", n.Decs.Lbrack})
+ points = append(points, DecorationPoint{"Low", n.Decs.Low})
+ points = append(points, DecorationPoint{"High", n.Decs.High})
+ points = append(points, DecorationPoint{"Max", n.Decs.Max})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.StarExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Star", n.Decs.Star})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.StructType:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Struct", n.Decs.Struct})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.SwitchStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Switch", n.Decs.Switch})
+ points = append(points, DecorationPoint{"Init", n.Decs.Init})
+ points = append(points, DecorationPoint{"Tag", n.Decs.Tag})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.TypeAssertExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"X", n.Decs.X})
+ points = append(points, DecorationPoint{"Lparen", n.Decs.Lparen})
+ points = append(points, DecorationPoint{"Type", n.Decs.Type})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.TypeSpec:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Name", n.Decs.Name})
+ points = append(points, DecorationPoint{"TypeParams", n.Decs.TypeParams})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.TypeSwitchStmt:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Switch", n.Decs.Switch})
+ points = append(points, DecorationPoint{"Init", n.Decs.Init})
+ points = append(points, DecorationPoint{"Assign", n.Decs.Assign})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.UnaryExpr:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Op", n.Decs.Op})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ case *dst.ValueSpec:
+ before = n.Decs.Before
+ after = n.Decs.After
+ points = append(points, DecorationPoint{"Start", n.Decs.Start})
+ points = append(points, DecorationPoint{"Assign", n.Decs.Assign})
+ points = append(points, DecorationPoint{"End", n.Decs.End})
+ }
+ return
+}
diff --git a/vendor/github.com/dave/dst/dstutil/decorations.go b/vendor/github.com/dave/dst/dstutil/decorations.go
new file mode 100644
index 00000000..bb875fcd
--- /dev/null
+++ b/vendor/github.com/dave/dst/dstutil/decorations.go
@@ -0,0 +1,14 @@
+package dstutil
+
+import "github.com/dave/dst"
+
+// Decorations returns information about all the decoration attachment points associated with a node
+func Decorations(n dst.Node) (before, after dst.SpaceType, info []DecorationPoint) {
+ return decorations(n)
+}
+
+// DecorationPoint contains the name of the decoration attachment point and a list of decorations attached there
+type DecorationPoint struct {
+ Name string
+ Decs []string
+}
diff --git a/vendor/github.com/dave/dst/dstutil/rewrite.go b/vendor/github.com/dave/dst/dstutil/rewrite.go
new file mode 100644
index 00000000..acb82c8a
--- /dev/null
+++ b/vendor/github.com/dave/dst/dstutil/rewrite.go
@@ -0,0 +1,465 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dstutil
+
+import (
+ "fmt"
+
+ "reflect"
+ "sort"
+
+ "github.com/dave/dst"
+)
+
+// An ApplyFunc is invoked by Apply for each node n, even if n is nil,
+// before and/or after the node's children, using a Cursor describing
+// the current node and providing operations on it.
+//
+// The return value of ApplyFunc controls the syntax tree traversal.
+// See Apply for details.
+type ApplyFunc func(*Cursor) bool
+
+// Apply traverses a syntax tree recursively, starting with root,
+// and calling pre and post for each node as described below.
+// Apply returns the syntax tree, possibly modified.
+//
+// If pre is not nil, it is called for each node before the node's
+// children are traversed (pre-order). If pre returns false, no
+// children are traversed, and post is not called for that node.
+//
+// If post is not nil, and a prior call of pre didn't return false,
+// post is called for each node after its children are traversed
+// (post-order). If post returns false, traversal is terminated and
+// Apply returns immediately.
+//
+// Only fields that refer to AST nodes are considered children;
+// i.e., token.Pos, Scopes, Objects, and fields of basic types
+// (strings, etc.) are ignored.
+//
+// Children are traversed in the order in which they appear in the
+// respective node's struct definition. A package's files are
+// traversed in the filenames' alphabetical order.
+//
+func Apply(root dst.Node, pre, post ApplyFunc) (result dst.Node) {
+ parent := &struct{ dst.Node }{root}
+ defer func() {
+ if r := recover(); r != nil && r != abort {
+ panic(r)
+ }
+ result = parent.Node
+ }()
+ a := &application{pre: pre, post: post}
+ a.apply(parent, "Node", nil, root)
+ return
+}
+
+var abort = new(int) // singleton, to signal termination of Apply
+
+// A Cursor describes a node encountered during Apply.
+// Information about the node and its parent is available
+// from the Node, Parent, Name, and Index methods.
+//
+// If p is a variable of type and value of the current parent node
+// c.Parent(), and f is the field identifier with name c.Name(),
+// the following invariants hold:
+//
+// p.f == c.Node() if c.Index() < 0
+// p.f[c.Index()] == c.Node() if c.Index() >= 0
+//
+// The methods Replace, Delete, InsertBefore, and InsertAfter
+// can be used to change the AST without disrupting Apply.
+type Cursor struct {
+ parent dst.Node
+ name string
+ iter *iterator // valid if non-nil
+ node dst.Node
+}
+
+// Node returns the current Node.
+func (c *Cursor) Node() dst.Node { return c.node }
+
+// Parent returns the parent of the current Node.
+func (c *Cursor) Parent() dst.Node { return c.parent }
+
+// Name returns the name of the parent Node field that contains the current Node.
+// If the parent is a *dst.Package and the current Node is a *dst.File, Name returns
+// the filename for the current Node.
+func (c *Cursor) Name() string { return c.name }
+
+// Index reports the index >= 0 of the current Node in the slice of Nodes that
+// contains it, or a value < 0 if the current Node is not part of a slice.
+// The index of the current node changes if InsertBefore is called while
+// processing the current node.
+func (c *Cursor) Index() int {
+ if c.iter != nil {
+ return c.iter.index
+ }
+ return -1
+}
+
+// field returns the current node's parent field value.
+func (c *Cursor) field() reflect.Value {
+ return reflect.Indirect(reflect.ValueOf(c.parent)).FieldByName(c.name)
+}
+
+// Replace replaces the current Node with n.
+// The replacement node is not walked by Apply.
+func (c *Cursor) Replace(n dst.Node) {
+ if _, ok := c.node.(*dst.File); ok {
+ file, ok := n.(*dst.File)
+ if !ok {
+ panic("attempt to replace *dst.File with non-*dst.File")
+ }
+ c.parent.(*dst.Package).Files[c.name] = file
+ return
+ }
+
+ v := c.field()
+ if i := c.Index(); i >= 0 {
+ v = v.Index(i)
+ }
+ v.Set(reflect.ValueOf(n))
+}
+
+// Delete deletes the current Node from its containing slice.
+// If the current Node is not part of a slice, Delete panics.
+// As a special case, if the current node is a package file,
+// Delete removes it from the package's Files map.
+func (c *Cursor) Delete() {
+ if _, ok := c.node.(*dst.File); ok {
+ delete(c.parent.(*dst.Package).Files, c.name)
+ return
+ }
+
+ i := c.Index()
+ if i < 0 {
+ panic("Delete node not contained in slice")
+ }
+ v := c.field()
+ l := v.Len()
+ reflect.Copy(v.Slice(i, l), v.Slice(i+1, l))
+ v.Index(l - 1).Set(reflect.Zero(v.Type().Elem()))
+ v.SetLen(l - 1)
+ c.iter.step--
+}
+
+// InsertAfter inserts n after the current Node in its containing slice.
+// If the current Node is not part of a slice, InsertAfter panics.
+// Apply does not walk n.
+func (c *Cursor) InsertAfter(n dst.Node) {
+ i := c.Index()
+ if i < 0 {
+ panic("InsertAfter node not contained in slice")
+ }
+ v := c.field()
+ v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
+ l := v.Len()
+ reflect.Copy(v.Slice(i+2, l), v.Slice(i+1, l))
+ v.Index(i + 1).Set(reflect.ValueOf(n))
+ c.iter.step++
+}
+
+// InsertBefore inserts n before the current Node in its containing slice.
+// If the current Node is not part of a slice, InsertBefore panics.
+// Apply will not walk n.
+func (c *Cursor) InsertBefore(n dst.Node) {
+ i := c.Index()
+ if i < 0 {
+ panic("InsertBefore node not contained in slice")
+ }
+ v := c.field()
+ v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
+ l := v.Len()
+ reflect.Copy(v.Slice(i+1, l), v.Slice(i, l))
+ v.Index(i).Set(reflect.ValueOf(n))
+ c.iter.index++
+}
+
+// application carries all the shared data so we can pass it around cheaply.
+type application struct {
+ pre, post ApplyFunc
+ cursor Cursor
+ iter iterator
+}
+
+func (a *application) apply(parent dst.Node, name string, iter *iterator, n dst.Node) {
+ // convert typed nil into untyped nil
+ if v := reflect.ValueOf(n); v.Kind() == reflect.Ptr && v.IsNil() {
+ n = nil
+ }
+
+ // avoid heap-allocating a new cursor for each apply call; reuse a.cursor instead
+ saved := a.cursor
+ a.cursor.parent = parent
+ a.cursor.name = name
+ a.cursor.iter = iter
+ a.cursor.node = n
+
+ if a.pre != nil && !a.pre(&a.cursor) {
+ a.cursor = saved
+ return
+ }
+
+ // walk children
+ // (the order of the cases matches the order of the corresponding node types in go/ast)
+ switch n := n.(type) {
+ case nil:
+ // nothing to do
+
+ case *dst.Field:
+ a.applyList(n, "Names")
+ a.apply(n, "Type", nil, n.Type)
+ a.apply(n, "Tag", nil, n.Tag)
+
+ case *dst.FieldList:
+ a.applyList(n, "List")
+
+ // Expressions
+ case *dst.BadExpr, *dst.Ident, *dst.BasicLit:
+ // nothing to do
+
+ case *dst.Ellipsis:
+ a.apply(n, "Elt", nil, n.Elt)
+
+ case *dst.FuncLit:
+ a.apply(n, "Type", nil, n.Type)
+ a.apply(n, "Body", nil, n.Body)
+
+ case *dst.CompositeLit:
+ a.apply(n, "Type", nil, n.Type)
+ a.applyList(n, "Elts")
+
+ case *dst.ParenExpr:
+ a.apply(n, "X", nil, n.X)
+
+ case *dst.SelectorExpr:
+ a.apply(n, "X", nil, n.X)
+ a.apply(n, "Sel", nil, n.Sel)
+
+ case *dst.IndexExpr:
+ a.apply(n, "X", nil, n.X)
+ a.apply(n, "Index", nil, n.Index)
+
+ case *dst.IndexListExpr:
+ a.apply(n, "X", nil, n.X)
+ a.applyList(n, "Indices")
+
+ case *dst.SliceExpr:
+ a.apply(n, "X", nil, n.X)
+ a.apply(n, "Low", nil, n.Low)
+ a.apply(n, "High", nil, n.High)
+ a.apply(n, "Max", nil, n.Max)
+
+ case *dst.TypeAssertExpr:
+ a.apply(n, "X", nil, n.X)
+ a.apply(n, "Type", nil, n.Type)
+
+ case *dst.CallExpr:
+ a.apply(n, "Fun", nil, n.Fun)
+ a.applyList(n, "Args")
+
+ case *dst.StarExpr:
+ a.apply(n, "X", nil, n.X)
+
+ case *dst.UnaryExpr:
+ a.apply(n, "X", nil, n.X)
+
+ case *dst.BinaryExpr:
+ a.apply(n, "X", nil, n.X)
+ a.apply(n, "Y", nil, n.Y)
+
+ case *dst.KeyValueExpr:
+ a.apply(n, "Key", nil, n.Key)
+ a.apply(n, "Value", nil, n.Value)
+
+ // Types
+ case *dst.ArrayType:
+ a.apply(n, "Len", nil, n.Len)
+ a.apply(n, "Elt", nil, n.Elt)
+
+ case *dst.StructType:
+ a.apply(n, "Fields", nil, n.Fields)
+
+ case *dst.FuncType:
+ a.apply(n, "TypeParams", nil, n.TypeParams)
+ a.apply(n, "Params", nil, n.Params)
+ a.apply(n, "Results", nil, n.Results)
+
+ case *dst.InterfaceType:
+ a.apply(n, "Methods", nil, n.Methods)
+
+ case *dst.MapType:
+ a.apply(n, "Key", nil, n.Key)
+ a.apply(n, "Value", nil, n.Value)
+
+ case *dst.ChanType:
+ a.apply(n, "Value", nil, n.Value)
+
+ // Statements
+ case *dst.BadStmt:
+ // nothing to do
+
+ case *dst.DeclStmt:
+ a.apply(n, "Decl", nil, n.Decl)
+
+ case *dst.EmptyStmt:
+ // nothing to do
+
+ case *dst.LabeledStmt:
+ a.apply(n, "Label", nil, n.Label)
+ a.apply(n, "Stmt", nil, n.Stmt)
+
+ case *dst.ExprStmt:
+ a.apply(n, "X", nil, n.X)
+
+ case *dst.SendStmt:
+ a.apply(n, "Chan", nil, n.Chan)
+ a.apply(n, "Value", nil, n.Value)
+
+ case *dst.IncDecStmt:
+ a.apply(n, "X", nil, n.X)
+
+ case *dst.AssignStmt:
+ a.applyList(n, "Lhs")
+ a.applyList(n, "Rhs")
+
+ case *dst.GoStmt:
+ a.apply(n, "Call", nil, n.Call)
+
+ case *dst.DeferStmt:
+ a.apply(n, "Call", nil, n.Call)
+
+ case *dst.ReturnStmt:
+ a.applyList(n, "Results")
+
+ case *dst.BranchStmt:
+ a.apply(n, "Label", nil, n.Label)
+
+ case *dst.BlockStmt:
+ a.applyList(n, "List")
+
+ case *dst.IfStmt:
+ a.apply(n, "Init", nil, n.Init)
+ a.apply(n, "Cond", nil, n.Cond)
+ a.apply(n, "Body", nil, n.Body)
+ a.apply(n, "Else", nil, n.Else)
+
+ case *dst.CaseClause:
+ a.applyList(n, "List")
+ a.applyList(n, "Body")
+
+ case *dst.SwitchStmt:
+ a.apply(n, "Init", nil, n.Init)
+ a.apply(n, "Tag", nil, n.Tag)
+ a.apply(n, "Body", nil, n.Body)
+
+ case *dst.TypeSwitchStmt:
+ a.apply(n, "Init", nil, n.Init)
+ a.apply(n, "Assign", nil, n.Assign)
+ a.apply(n, "Body", nil, n.Body)
+
+ case *dst.CommClause:
+ a.apply(n, "Comm", nil, n.Comm)
+ a.applyList(n, "Body")
+
+ case *dst.SelectStmt:
+ a.apply(n, "Body", nil, n.Body)
+
+ case *dst.ForStmt:
+ a.apply(n, "Init", nil, n.Init)
+ a.apply(n, "Cond", nil, n.Cond)
+ a.apply(n, "Post", nil, n.Post)
+ a.apply(n, "Body", nil, n.Body)
+
+ case *dst.RangeStmt:
+ a.apply(n, "Key", nil, n.Key)
+ a.apply(n, "Value", nil, n.Value)
+ a.apply(n, "X", nil, n.X)
+ a.apply(n, "Body", nil, n.Body)
+
+ // Declarations
+ case *dst.ImportSpec:
+ a.apply(n, "Name", nil, n.Name)
+ a.apply(n, "Path", nil, n.Path)
+
+ case *dst.ValueSpec:
+ a.applyList(n, "Names")
+ a.apply(n, "Type", nil, n.Type)
+ a.applyList(n, "Values")
+
+ case *dst.TypeSpec:
+ a.apply(n, "Name", nil, n.Name)
+ a.apply(n, "TypeParams", nil, n.TypeParams)
+ a.apply(n, "Type", nil, n.Type)
+
+ case *dst.BadDecl:
+ // nothing to do
+
+ case *dst.GenDecl:
+ a.applyList(n, "Specs")
+
+ case *dst.FuncDecl:
+ a.apply(n, "Recv", nil, n.Recv)
+ a.apply(n, "Name", nil, n.Name)
+ a.apply(n, "Type", nil, n.Type)
+ a.apply(n, "Body", nil, n.Body)
+
+ // Files and packages
+ case *dst.File:
+ a.apply(n, "Name", nil, n.Name)
+ a.applyList(n, "Decls")
+ // Don't walk n.Comments; they have either been walked already if
+ // they are Doc comments, or they can be easily walked explicitly.
+
+ case *dst.Package:
+ // collect and sort names for reproducible behavior
+ var names []string
+ for name := range n.Files {
+ names = append(names, name)
+ }
+ sort.Strings(names)
+ for _, name := range names {
+ a.apply(n, name, nil, n.Files[name])
+ }
+
+ default:
+ panic(fmt.Sprintf("Apply: unexpected node type %T", n))
+ }
+
+ if a.post != nil && !a.post(&a.cursor) {
+ panic(abort)
+ }
+
+ a.cursor = saved
+}
+
+// An iterator controls iteration over a slice of nodes.
+type iterator struct {
+ index, step int
+}
+
+func (a *application) applyList(parent dst.Node, name string) {
+ // avoid heap-allocating a new iterator for each applyList call; reuse a.iter instead
+ saved := a.iter
+ a.iter.index = 0
+ for {
+ // must reload parent.name each time, since cursor modifications might change it
+ v := reflect.Indirect(reflect.ValueOf(parent)).FieldByName(name)
+ if a.iter.index >= v.Len() {
+ break
+ }
+
+ // element x may be nil in a bad AST - be cautious
+ var x dst.Node
+ if e := v.Index(a.iter.index); e.IsValid() {
+ x = e.Interface().(dst.Node)
+ }
+
+ a.iter.step = 1
+ a.apply(parent, name, &a.iter, x)
+ a.iter.index += a.iter.step
+ }
+ a.iter = saved
+}
diff --git a/vendor/github.com/dave/dst/dstutil/util.go b/vendor/github.com/dave/dst/dstutil/util.go
new file mode 100644
index 00000000..98426227
--- /dev/null
+++ b/vendor/github.com/dave/dst/dstutil/util.go
@@ -0,0 +1,14 @@
+package dstutil
+
+import "github.com/dave/dst"
+
+// Unparen returns e with any enclosing parentheses stripped.
+func Unparen(e dst.Expr) dst.Expr {
+ for {
+ p, ok := e.(*dst.ParenExpr)
+ if !ok {
+ return e
+ }
+ e = p.X
+ }
+}
diff --git a/vendor/github.com/dave/dst/print.go b/vendor/github.com/dave/dst/print.go
new file mode 100644
index 00000000..0a4a35c4
--- /dev/null
+++ b/vendor/github.com/dave/dst/print.go
@@ -0,0 +1,245 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains printing support for ASTs.
+
+package dst
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "reflect"
+)
+
+// A FieldFilter may be provided to Fprint to control the output.
+type FieldFilter func(name string, value reflect.Value) bool
+
+// NotNilFilter returns true for field values that are not nil;
+// it returns false otherwise.
+func NotNilFilter(_ string, v reflect.Value) bool {
+ switch v.Kind() {
+ case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+ return !v.IsNil()
+ }
+ return true
+}
+
+// Fprint prints the (sub-)tree starting at AST node x to w.
+// If fset != nil, position information is interpreted relative
+// to that file set. Otherwise positions are printed as integer
+// values (file set specific offsets).
+//
+// A non-nil FieldFilter f may be provided to control the output:
+// struct fields for which f(fieldname, fieldvalue) is true are
+// printed; all others are filtered from the output. Unexported
+// struct fields are never printed.
+func Fprint(w io.Writer, x interface{}, f FieldFilter) error {
+ return fprint(w, x, f)
+}
+
+func fprint(w io.Writer, x interface{}, f FieldFilter) (err error) {
+ // setup printer
+ p := printer{
+ output: w,
+ filter: f,
+ ptrmap: make(map[interface{}]int),
+ last: '\n', // force printing of line number on first line
+ }
+
+ // install error handler
+ defer func() {
+ if e := recover(); e != nil {
+ err = e.(localError).err // re-panics if it's not a localError
+ }
+ }()
+
+ // print x
+ if x == nil {
+ p.printf("nil\n")
+ return
+ }
+ p.print(reflect.ValueOf(x))
+ p.printf("\n")
+
+ return
+}
+
+// Print prints x to standard output, skipping nil fields.
+// Print(fset, x) is the same as Fprint(os.Stdout, fset, x, NotNilFilter).
+func Print(x interface{}) error {
+ return Fprint(os.Stdout, x, NotNilFilter)
+}
+
+type printer struct {
+ output io.Writer
+ filter FieldFilter
+ ptrmap map[interface{}]int // *T -> line number
+ indent int // current indentation level
+ last byte // the last byte processed by Write
+ line int // current line number
+}
+
+var indent = []byte(". ")
+
+func (p *printer) Write(data []byte) (n int, err error) {
+ var m int
+ for i, b := range data {
+ // invariant: data[0:n] has been written
+ if b == '\n' {
+ m, err = p.output.Write(data[n : i+1])
+ n += m
+ if err != nil {
+ return
+ }
+ p.line++
+ } else if p.last == '\n' {
+ _, err = fmt.Fprintf(p.output, "%6d ", p.line)
+ if err != nil {
+ return
+ }
+ for j := p.indent; j > 0; j-- {
+ _, err = p.output.Write(indent)
+ if err != nil {
+ return
+ }
+ }
+ }
+ p.last = b
+ }
+ if len(data) > n {
+ m, err = p.output.Write(data[n:])
+ n += m
+ }
+ return
+}
+
+// localError wraps locally caught errors so we can distinguish
+// them from genuine panics which we don't want to return as errors.
+type localError struct {
+ err error
+}
+
+// printf is a convenience wrapper that takes care of print errors.
+func (p *printer) printf(format string, args ...interface{}) {
+ if _, err := fmt.Fprintf(p, format, args...); err != nil {
+ panic(localError{err})
+ }
+}
+
+// Implementation note: Print is written for AST nodes but could be
+// used to print arbitrary data structures; such a version should
+// probably be in a different package.
+//
+// Note: This code detects (some) cycles created via pointers but
+// not cycles that are created via slices or maps containing the
+// same slice or map. Code for general data structures probably
+// should catch those as well.
+
+func (p *printer) print(x reflect.Value) {
+ if !NotNilFilter("", x) {
+ p.printf("nil")
+ return
+ }
+
+ switch x.Kind() {
+ case reflect.Interface:
+ p.print(x.Elem())
+
+ case reflect.Map:
+ p.printf("%s (len = %d) {", x.Type(), x.Len())
+ if x.Len() > 0 {
+ p.indent++
+ p.printf("\n")
+ for _, key := range x.MapKeys() {
+ p.print(key)
+ p.printf(": ")
+ p.print(x.MapIndex(key))
+ p.printf("\n")
+ }
+ p.indent--
+ }
+ p.printf("}")
+
+ case reflect.Ptr:
+ p.printf("*")
+ // type-checked ASTs may contain cycles - use ptrmap
+ // to keep track of objects that have been printed
+ // already and print the respective line number instead
+ ptr := x.Interface()
+ if line, exists := p.ptrmap[ptr]; exists {
+ p.printf("(obj @ %d)", line)
+ } else {
+ p.ptrmap[ptr] = p.line
+ p.print(x.Elem())
+ }
+
+ case reflect.Array:
+ p.printf("%s {", x.Type())
+ if x.Len() > 0 {
+ p.indent++
+ p.printf("\n")
+ for i, n := 0, x.Len(); i < n; i++ {
+ p.printf("%d: ", i)
+ p.print(x.Index(i))
+ p.printf("\n")
+ }
+ p.indent--
+ }
+ p.printf("}")
+
+ case reflect.Slice:
+ if s, ok := x.Interface().([]byte); ok {
+ p.printf("%#q", s)
+ return
+ }
+ p.printf("%s (len = %d) {", x.Type(), x.Len())
+ if x.Len() > 0 {
+ p.indent++
+ p.printf("\n")
+ for i, n := 0, x.Len(); i < n; i++ {
+ p.printf("%d: ", i)
+ p.print(x.Index(i))
+ p.printf("\n")
+ }
+ p.indent--
+ }
+ p.printf("}")
+
+ case reflect.Struct:
+ t := x.Type()
+ p.printf("%s {", t)
+ p.indent++
+ first := true
+ for i, n := 0, t.NumField(); i < n; i++ {
+ // exclude non-exported fields because their
+ // values cannot be accessed via reflection
+ if name := t.Field(i).Name; IsExported(name) {
+ value := x.Field(i)
+ if p.filter == nil || p.filter(name, value) {
+ if first {
+ p.printf("\n")
+ first = false
+ }
+ p.printf("%s: ", name)
+ p.print(value)
+ p.printf("\n")
+ }
+ }
+ }
+ p.indent--
+ p.printf("}")
+
+ default:
+ v := x.Interface()
+ switch v := v.(type) {
+ case string:
+ // print strings in quotes
+ p.printf("%q", v)
+ return
+ }
+ // default
+ p.printf("%v", v)
+ }
+}
diff --git a/vendor/github.com/dave/dst/readme.go b/vendor/github.com/dave/dst/readme.go
new file mode 100644
index 00000000..7bb53bdc
--- /dev/null
+++ b/vendor/github.com/dave/dst/readme.go
@@ -0,0 +1,4 @@
+package dst
+
+//go:generate go get github.com/dave/rebecca/cmd/becca
+//go:generate becca -package=github.com/dave/dst
diff --git a/vendor/github.com/dave/dst/resolve.go b/vendor/github.com/dave/dst/resolve.go
new file mode 100644
index 00000000..e247bafb
--- /dev/null
+++ b/vendor/github.com/dave/dst/resolve.go
@@ -0,0 +1,170 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements NewPackage.
+
+package dst
+
+import (
+ "fmt"
+ "go/scanner"
+ "go/token"
+ "strconv"
+)
+
+type pkgBuilder struct {
+ fset *token.FileSet
+ errors scanner.ErrorList
+}
+
+func (p *pkgBuilder) error(msg string) {
+ p.errors.Add(p.fset.Position(token.NoPos), msg)
+}
+
+func (p *pkgBuilder) errorf(format string, args ...interface{}) {
+ p.error(fmt.Sprintf(format, args...))
+}
+
+func (p *pkgBuilder) declare(scope, altScope *Scope, obj *Object) {
+ alt := scope.Insert(obj)
+ if alt == nil && altScope != nil {
+ // see if there is a conflicting declaration in altScope
+ alt = altScope.Lookup(obj.Name)
+ }
+ if alt != nil {
+ p.error(fmt.Sprintf("%s redeclared in this block", obj.Name))
+ }
+}
+
+func resolve(scope *Scope, ident *Ident) bool {
+ for ; scope != nil; scope = scope.Outer {
+ if obj := scope.Lookup(ident.Name); obj != nil {
+ ident.Obj = obj
+ return true
+ }
+ }
+ return false
+}
+
+// An Importer resolves import paths to package Objects.
+// The imports map records the packages already imported,
+// indexed by package id (canonical import path).
+// An Importer must determine the canonical import path and
+// check the map to see if it is already present in the imports map.
+// If so, the Importer can return the map entry. Otherwise, the
+// Importer should load the package data for the given path into
+// a new *Object (pkg), record pkg in the imports map, and then
+// return pkg.
+type Importer func(imports map[string]*Object, path string) (pkg *Object, err error)
+
+// NewPackage creates a new Package node from a set of File nodes. It resolves
+// unresolved identifiers across files and updates each file's Unresolved list
+// accordingly. If a non-nil importer and universe scope are provided, they are
+// used to resolve identifiers not declared in any of the package files. Any
+// remaining unresolved identifiers are reported as undeclared. If the files
+// belong to different packages, one package name is selected and files with
+// different package names are reported and then ignored.
+// The result is a package node and a scanner.ErrorList if there were errors.
+//
+func NewPackage(fset *token.FileSet, files map[string]*File, importer Importer, universe *Scope) (*Package, error) {
+ var p pkgBuilder
+ p.fset = fset
+
+ // complete package scope
+ pkgName := ""
+ pkgScope := NewScope(universe)
+ for _, file := range files {
+ // package names must match
+ switch name := file.Name.Name; {
+ case pkgName == "":
+ pkgName = name
+ case name != pkgName:
+ p.errorf("package %s; expected %s", name, pkgName)
+ continue // ignore this file
+ }
+
+ // collect top-level file objects in package scope
+ for _, obj := range file.Scope.Objects {
+ p.declare(pkgScope, nil, obj)
+ }
+ }
+
+ // package global mapping of imported package ids to package objects
+ imports := make(map[string]*Object)
+
+ // complete file scopes with imports and resolve identifiers
+ for _, file := range files {
+ // ignore file if it belongs to a different package
+ // (error has already been reported)
+ if file.Name.Name != pkgName {
+ continue
+ }
+
+ // build file scope by processing all imports
+ importErrors := false
+ fileScope := NewScope(pkgScope)
+ for _, spec := range file.Imports {
+ if importer == nil {
+ importErrors = true
+ continue
+ }
+ path, _ := strconv.Unquote(spec.Path.Value)
+ pkg, err := importer(imports, path)
+ if err != nil {
+ p.errorf("could not import %s (%s)", path, err)
+ importErrors = true
+ continue
+ }
+ // TODO(gri) If a local package name != "." is provided,
+ // global identifier resolution could proceed even if the
+ // import failed. Consider adjusting the logic here a bit.
+
+ // local name overrides imported package name
+ name := pkg.Name
+ if spec.Name != nil {
+ name = spec.Name.Name
+ }
+
+ // add import to file scope
+ if name == "." {
+ // merge imported scope with file scope
+ for _, obj := range pkg.Data.(*Scope).Objects {
+ p.declare(fileScope, pkgScope, obj)
+ }
+ } else if name != "_" {
+ // declare imported package object in file scope
+ // (do not re-use pkg in the file scope but create
+ // a new object instead; the Decl field is different
+ // for different files)
+ obj := NewObj(Pkg, name)
+ obj.Decl = spec
+ obj.Data = pkg.Data
+ p.declare(fileScope, pkgScope, obj)
+ }
+ }
+
+ // resolve identifiers
+ if importErrors {
+ // don't use the universe scope without correct imports
+ // (objects in the universe may be shadowed by imports;
+ // with missing imports, identifiers might get resolved
+ // incorrectly to universe objects)
+ pkgScope.Outer = nil
+ }
+ i := 0
+ for _, ident := range file.Unresolved {
+ if !resolve(fileScope, ident) {
+ p.errorf("undeclared name: %s", ident.Name)
+ file.Unresolved[i] = ident
+ i++
+ }
+
+ }
+ file.Unresolved = file.Unresolved[0:i]
+ pkgScope.Outer = universe // reset universe scope
+ }
+
+ p.errors.Sort()
+ return &Package{pkgName, pkgScope, imports, files}, p.errors.Err()
+}
diff --git a/vendor/github.com/dave/dst/scope.go b/vendor/github.com/dave/dst/scope.go
new file mode 100644
index 00000000..c05ab700
--- /dev/null
+++ b/vendor/github.com/dave/dst/scope.go
@@ -0,0 +1,112 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements scopes and the objects they contain.
+
+package dst
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// A Scope maintains the set of named language entities declared
+// in the scope and a link to the immediately surrounding (outer)
+// scope.
+//
+type Scope struct {
+ Outer *Scope
+ Objects map[string]*Object
+}
+
+// NewScope creates a new scope nested in the outer scope.
+func NewScope(outer *Scope) *Scope {
+ const n = 4 // initial scope capacity
+ return &Scope{outer, make(map[string]*Object, n)}
+}
+
+// Lookup returns the object with the given name if it is
+// found in scope s, otherwise it returns nil. Outer scopes
+// are ignored.
+//
+func (s *Scope) Lookup(name string) *Object {
+ return s.Objects[name]
+}
+
+// Insert attempts to insert a named object obj into the scope s.
+// If the scope already contains an object alt with the same name,
+// Insert leaves the scope unchanged and returns alt. Otherwise
+// it inserts obj and returns nil.
+//
+func (s *Scope) Insert(obj *Object) (alt *Object) {
+ if alt = s.Objects[obj.Name]; alt == nil {
+ s.Objects[obj.Name] = obj
+ }
+ return
+}
+
+// Debugging support
+func (s *Scope) String() string {
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "scope %p {", s)
+ if s != nil && len(s.Objects) > 0 {
+ fmt.Fprintln(&buf)
+ for _, obj := range s.Objects {
+ fmt.Fprintf(&buf, "\t%s %s\n", obj.Kind, obj.Name)
+ }
+ }
+ fmt.Fprintf(&buf, "}\n")
+ return buf.String()
+}
+
+// ----------------------------------------------------------------------------
+// Objects
+
+// An Object describes a named language entity such as a package,
+// constant, type, variable, function (incl. methods), or label.
+//
+// The Data fields contains object-specific data:
+//
+// Kind Data type Data value
+// Pkg *Scope package scope
+// Con int iota for the respective declaration
+//
+type Object struct {
+ Kind ObjKind
+ Name string // declared name
+ Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil
+ Data interface{} // object-specific data; or nil
+ Type interface{} // placeholder for type information; may be nil
+}
+
+// NewObj creates a new object of a given kind and name.
+func NewObj(kind ObjKind, name string) *Object {
+ return &Object{Kind: kind, Name: name}
+}
+
+// ObjKind describes what an object represents.
+type ObjKind int
+
+// The list of possible Object kinds.
+const (
+ Bad ObjKind = iota // for error handling
+ Pkg // package
+ Con // constant
+ Typ // type
+ Var // variable
+ Fun // function or method
+ Lbl // label
+)
+
+var objKindStrings = [...]string{
+ Bad: "bad",
+ Pkg: "package",
+ Con: "const",
+ Typ: "type",
+ Var: "var",
+ Fun: "func",
+ Lbl: "label",
+}
+
+func (kind ObjKind) String() string { return objKindStrings[kind] }
diff --git a/vendor/github.com/dave/dst/walk.go b/vendor/github.com/dave/dst/walk.go
new file mode 100644
index 00000000..da7f97b2
--- /dev/null
+++ b/vendor/github.com/dave/dst/walk.go
@@ -0,0 +1,354 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dst
+
+import "fmt"
+
+// A Visitor's Visit method is invoked for each node encountered by Walk.
+// If the result visitor w is not nil, Walk visits each of the children
+// of node with the visitor w, followed by a call of w.Visit(nil).
+type Visitor interface {
+ Visit(node Node) (w Visitor)
+}
+
+// Helper functions for common node lists. They may be empty.
+
+func walkIdentList(v Visitor, list []*Ident) {
+ for _, x := range list {
+ Walk(v, x)
+ }
+}
+
+func walkExprList(v Visitor, list []Expr) {
+ for _, x := range list {
+ Walk(v, x)
+ }
+}
+
+func walkStmtList(v Visitor, list []Stmt) {
+ for _, x := range list {
+ Walk(v, x)
+ }
+}
+
+func walkDeclList(v Visitor, list []Decl) {
+ for _, x := range list {
+ Walk(v, x)
+ }
+}
+
+// TODO(gri): Investigate if providing a closure to Walk leads to
+// simpler use (and may help eliminate Inspect in turn).
+
+// Walk traverses an AST in depth-first order: It starts by calling
+// v.Visit(node); node must not be nil. If the visitor w returned by
+// v.Visit(node) is not nil, Walk is invoked recursively with visitor
+// w for each of the non-nil children of node, followed by a call of
+// w.Visit(nil).
+//
+func Walk(v Visitor, node Node) {
+ if v = v.Visit(node); v == nil {
+ return
+ }
+
+ // walk children
+ // (the order of the cases matches the order
+ // of the corresponding node types in ast.go)
+ switch n := node.(type) {
+ case *Field:
+ walkIdentList(v, n.Names)
+ Walk(v, n.Type)
+ if n.Tag != nil {
+ Walk(v, n.Tag)
+ }
+
+ case *FieldList:
+ for _, f := range n.List {
+ Walk(v, f)
+ }
+
+ // Expressions
+ case *BadExpr, *Ident, *BasicLit:
+ // nothing to do
+
+ case *Ellipsis:
+ if n.Elt != nil {
+ Walk(v, n.Elt)
+ }
+
+ case *FuncLit:
+ Walk(v, n.Type)
+ Walk(v, n.Body)
+
+ case *CompositeLit:
+ if n.Type != nil {
+ Walk(v, n.Type)
+ }
+ walkExprList(v, n.Elts)
+
+ case *ParenExpr:
+ Walk(v, n.X)
+
+ case *SelectorExpr:
+ Walk(v, n.X)
+ Walk(v, n.Sel)
+
+ case *IndexExpr:
+ Walk(v, n.X)
+ Walk(v, n.Index)
+
+ case *IndexListExpr:
+ Walk(v, n.X)
+ walkExprList(v, n.Indices)
+
+ case *SliceExpr:
+ Walk(v, n.X)
+ if n.Low != nil {
+ Walk(v, n.Low)
+ }
+ if n.High != nil {
+ Walk(v, n.High)
+ }
+ if n.Max != nil {
+ Walk(v, n.Max)
+ }
+
+ case *TypeAssertExpr:
+ Walk(v, n.X)
+ if n.Type != nil {
+ Walk(v, n.Type)
+ }
+
+ case *CallExpr:
+ Walk(v, n.Fun)
+ walkExprList(v, n.Args)
+
+ case *StarExpr:
+ Walk(v, n.X)
+
+ case *UnaryExpr:
+ Walk(v, n.X)
+
+ case *BinaryExpr:
+ Walk(v, n.X)
+ Walk(v, n.Y)
+
+ case *KeyValueExpr:
+ Walk(v, n.Key)
+ Walk(v, n.Value)
+
+ // Types
+ case *ArrayType:
+ if n.Len != nil {
+ Walk(v, n.Len)
+ }
+ Walk(v, n.Elt)
+
+ case *StructType:
+ Walk(v, n.Fields)
+
+ case *FuncType:
+ if n.TypeParams != nil {
+ Walk(v, n.TypeParams)
+ }
+ if n.Params != nil {
+ Walk(v, n.Params)
+ }
+ if n.Results != nil {
+ Walk(v, n.Results)
+ }
+
+ case *InterfaceType:
+ Walk(v, n.Methods)
+
+ case *MapType:
+ Walk(v, n.Key)
+ Walk(v, n.Value)
+
+ case *ChanType:
+ Walk(v, n.Value)
+
+ // Statements
+ case *BadStmt:
+ // nothing to do
+
+ case *DeclStmt:
+ Walk(v, n.Decl)
+
+ case *EmptyStmt:
+ // nothing to do
+
+ case *LabeledStmt:
+ Walk(v, n.Label)
+ Walk(v, n.Stmt)
+
+ case *ExprStmt:
+ Walk(v, n.X)
+
+ case *SendStmt:
+ Walk(v, n.Chan)
+ Walk(v, n.Value)
+
+ case *IncDecStmt:
+ Walk(v, n.X)
+
+ case *AssignStmt:
+ walkExprList(v, n.Lhs)
+ walkExprList(v, n.Rhs)
+
+ case *GoStmt:
+ Walk(v, n.Call)
+
+ case *DeferStmt:
+ Walk(v, n.Call)
+
+ case *ReturnStmt:
+ walkExprList(v, n.Results)
+
+ case *BranchStmt:
+ if n.Label != nil {
+ Walk(v, n.Label)
+ }
+
+ case *BlockStmt:
+ walkStmtList(v, n.List)
+
+ case *IfStmt:
+ if n.Init != nil {
+ Walk(v, n.Init)
+ }
+ Walk(v, n.Cond)
+ Walk(v, n.Body)
+ if n.Else != nil {
+ Walk(v, n.Else)
+ }
+
+ case *CaseClause:
+ walkExprList(v, n.List)
+ walkStmtList(v, n.Body)
+
+ case *SwitchStmt:
+ if n.Init != nil {
+ Walk(v, n.Init)
+ }
+ if n.Tag != nil {
+ Walk(v, n.Tag)
+ }
+ Walk(v, n.Body)
+
+ case *TypeSwitchStmt:
+ if n.Init != nil {
+ Walk(v, n.Init)
+ }
+ Walk(v, n.Assign)
+ Walk(v, n.Body)
+
+ case *CommClause:
+ if n.Comm != nil {
+ Walk(v, n.Comm)
+ }
+ walkStmtList(v, n.Body)
+
+ case *SelectStmt:
+ Walk(v, n.Body)
+
+ case *ForStmt:
+ if n.Init != nil {
+ Walk(v, n.Init)
+ }
+ if n.Cond != nil {
+ Walk(v, n.Cond)
+ }
+ if n.Post != nil {
+ Walk(v, n.Post)
+ }
+ Walk(v, n.Body)
+
+ case *RangeStmt:
+ if n.Key != nil {
+ Walk(v, n.Key)
+ }
+ if n.Value != nil {
+ Walk(v, n.Value)
+ }
+ Walk(v, n.X)
+ Walk(v, n.Body)
+
+ // Declarations
+ case *ImportSpec:
+ if n.Name != nil {
+ Walk(v, n.Name)
+ }
+ Walk(v, n.Path)
+
+ case *ValueSpec:
+ walkIdentList(v, n.Names)
+ if n.Type != nil {
+ Walk(v, n.Type)
+ }
+ walkExprList(v, n.Values)
+
+ case *TypeSpec:
+ Walk(v, n.Name)
+ if n.TypeParams != nil {
+ Walk(v, n.TypeParams)
+ }
+ Walk(v, n.Type)
+
+ case *BadDecl:
+ // nothing to do
+
+ case *GenDecl:
+ for _, s := range n.Specs {
+ Walk(v, s)
+ }
+
+ case *FuncDecl:
+ if n.Recv != nil {
+ Walk(v, n.Recv)
+ }
+ Walk(v, n.Name)
+ Walk(v, n.Type)
+ if n.Body != nil {
+ Walk(v, n.Body)
+ }
+
+ // Files and packages
+ case *File:
+ Walk(v, n.Name)
+ walkDeclList(v, n.Decls)
+ // don't walk n.Comments - they have been
+ // visited already through the individual
+ // nodes
+
+ case *Package:
+ for _, f := range n.Files {
+ Walk(v, f)
+ }
+
+ default:
+ panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n))
+ }
+
+ v.Visit(nil)
+}
+
+type inspector func(Node) bool
+
+func (f inspector) Visit(node Node) Visitor {
+ if f(node) {
+ return f
+ }
+ return nil
+}
+
+// Inspect traverses an AST in depth-first order: It starts by calling
+// f(node); node must not be nil. If f returns true, Inspect invokes f
+// recursively for each of the non-nil children of node, followed by a
+// call of f(nil).
+//
+func Inspect(node Node, f func(Node) bool) {
+ Walk(inspector(f), node)
+}
diff --git a/vendor/github.com/dlclark/regexp2/.gitignore b/vendor/github.com/dlclark/regexp2/.gitignore
new file mode 100644
index 00000000..fb844c33
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/.gitignore
@@ -0,0 +1,27 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
+*.out
+
+.DS_Store
diff --git a/vendor/github.com/dlclark/regexp2/.travis.yml b/vendor/github.com/dlclark/regexp2/.travis.yml
new file mode 100644
index 00000000..a2da6be4
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/.travis.yml
@@ -0,0 +1,7 @@
+language: go
+arch:
+ - AMD64
+ - ppc64le
+go:
+ - 1.9
+ - tip
diff --git a/vendor/github.com/dlclark/regexp2/ATTRIB b/vendor/github.com/dlclark/regexp2/ATTRIB
new file mode 100644
index 00000000..cdf4560b
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/ATTRIB
@@ -0,0 +1,133 @@
+============
+These pieces of code were ported from dotnet/corefx:
+
+syntax/charclass.go (from RegexCharClass.cs): ported to use the built-in Go unicode classes. Canonicalize is
+ a direct port, but most of the other code required large changes because the C# implementation
+ used a string to represent the CharSet data structure and I cleaned that up in my implementation.
+
+syntax/code.go (from RegexCode.cs): ported literally with various cleanups and layout to make it more Go-ish.
+
+syntax/escape.go (from RegexParser.cs): ported Escape method and added some optimizations. Unescape is inspired by
+ the C# implementation but couldn't be directly ported because of the lack of do-while syntax in Go.
+
+syntax/parser.go (from RegexpParser.cs and RegexOptions.cs): ported parser struct and associated methods as
+ literally as possible. Several language differences required changes. E.g. lack pre/post-fix increments as
+ expressions, lack of do-while loops, lack of overloads, etc.
+
+syntax/prefix.go (from RegexFCD.cs and RegexBoyerMoore.cs): ported as literally as possible and added support
+ for unicode chars that are longer than the 16-bit char in C# for the 32-bit rune in Go.
+
+syntax/replacerdata.go (from RegexReplacement.cs): conceptually ported and re-organized to handle differences
+ in charclass implementation, and fix odd code layout between RegexParser.cs, Regex.cs, and RegexReplacement.cs.
+
+syntax/tree.go (from RegexTree.cs and RegexNode.cs): ported literally as possible.
+
+syntax/writer.go (from RegexWriter.cs): ported literally with minor changes to make it more Go-ish.
+
+match.go (from RegexMatch.cs): ported, simplified, and changed to handle Go's lack of inheritence.
+
+regexp.go (from Regex.cs and RegexOptions.cs): conceptually serves the same "starting point", but is simplified
+ and changed to handle differences in C# strings and Go strings/runes.
+
+replace.go (from RegexReplacement.cs): ported closely and then cleaned up to combine the MatchEvaluator and
+ simple string replace implementations.
+
+runner.go (from RegexRunner.cs): ported literally as possible.
+
+regexp_test.go (from CaptureTests.cs and GroupNamesAndNumbers.cs): conceptually ported, but the code was
+ manually structured like Go tests.
+
+replace_test.go (from RegexReplaceStringTest0.cs): conceptually ported
+
+rtl_test.go (from RightToLeft.cs): conceptually ported
+---
+dotnet/corefx was released under this license:
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+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.
+
+============
+These pieces of code are copied from the Go framework:
+
+- The overall directory structure of regexp2 was inspired by the Go runtime regexp package.
+- The optimization in the escape method of syntax/escape.go is from the Go runtime QuoteMeta() func in regexp/regexp.go
+- The method signatures in regexp.go are designed to match the Go framework regexp methods closely
+- func regexp2.MustCompile and func quote are almost identifical to the regexp package versions
+- BenchmarkMatch* and TestProgramTooLong* funcs in regexp_performance_test.go were copied from the framework
+ regexp/exec_test.go
+---
+The Go framework was released under this license:
+
+Copyright (c) 2012 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+============
+Some test data were gathered from the Mono project.
+
+regexp_mono_test.go: ported from https://github.com/mono/mono/blob/master/mcs/class/System/Test/System.Text.RegularExpressions/PerlTrials.cs
+---
+Mono tests released under this license:
+
+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.
+
diff --git a/vendor/github.com/dlclark/regexp2/LICENSE b/vendor/github.com/dlclark/regexp2/LICENSE
new file mode 100644
index 00000000..fe83dfdc
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Doug Clark
+
+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.
diff --git a/vendor/github.com/dlclark/regexp2/README.md b/vendor/github.com/dlclark/regexp2/README.md
new file mode 100644
index 00000000..9cbc1d8d
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/README.md
@@ -0,0 +1,174 @@
+# regexp2 - full featured regular expressions for Go
+Regexp2 is a feature-rich RegExp engine for Go. It doesn't have constant time guarantees like the built-in `regexp` package, but it allows backtracking and is compatible with Perl5 and .NET. You'll likely be better off with the RE2 engine from the `regexp` package and should only use this if you need to write very complex patterns or require compatibility with .NET.
+
+## Basis of the engine
+The engine is ported from the .NET framework's System.Text.RegularExpressions.Regex engine. That engine was open sourced in 2015 under the MIT license. There are some fundamental differences between .NET strings and Go strings that required a bit of borrowing from the Go framework regex engine as well. I cleaned up a couple of the dirtier bits during the port (regexcharclass.cs was terrible), but the parse tree, code emmitted, and therefore patterns matched should be identical.
+
+## New Code Generation
+For extra performance use `regexp2` with [`regexp2cg`](https://github.com/dlclark/regexp2cg). It is a code generation utility for `regexp2` and you can likely improve your regexp runtime performance by 3-10x in hot code paths. As always you should benchmark your specifics to confirm the results. Give it a try!
+
+## Installing
+This is a go-gettable library, so install is easy:
+
+ go get github.com/dlclark/regexp2
+
+To use the new Code Generation (while it's in beta) you'll need to use the `code_gen` branch:
+
+ go get github.com/dlclark/regexp2@code_gen
+
+## Usage
+Usage is similar to the Go `regexp` package. Just like in `regexp`, you start by converting a regex into a state machine via the `Compile` or `MustCompile` methods. They ultimately do the same thing, but `MustCompile` will panic if the regex is invalid. You can then use the provided `Regexp` struct to find matches repeatedly. A `Regexp` struct is safe to use across goroutines.
+
+```go
+re := regexp2.MustCompile(`Your pattern`, 0)
+if isMatch, _ := re.MatchString(`Something to match`); isMatch {
+ //do something
+}
+```
+
+The only error that the `*Match*` methods *should* return is a Timeout if you set the `re.MatchTimeout` field. Any other error is a bug in the `regexp2` package. If you need more details about capture groups in a match then use the `FindStringMatch` method, like so:
+
+```go
+if m, _ := re.FindStringMatch(`Something to match`); m != nil {
+ // the whole match is always group 0
+ fmt.Printf("Group 0: %v\n", m.String())
+
+ // you can get all the groups too
+ gps := m.Groups()
+
+ // a group can be captured multiple times, so each cap is separately addressable
+ fmt.Printf("Group 1, first capture", gps[1].Captures[0].String())
+ fmt.Printf("Group 1, second capture", gps[1].Captures[1].String())
+}
+```
+
+Group 0 is embedded in the Match. Group 0 is an automatically-assigned group that encompasses the whole pattern. This means that `m.String()` is the same as `m.Group.String()` and `m.Groups()[0].String()`
+
+The __last__ capture is embedded in each group, so `g.String()` will return the same thing as `g.Capture.String()` and `g.Captures[len(g.Captures)-1].String()`.
+
+If you want to find multiple matches from a single input string you should use the `FindNextMatch` method. For example, to implement a function similar to `regexp.FindAllString`:
+
+```go
+func regexp2FindAllString(re *regexp2.Regexp, s string) []string {
+ var matches []string
+ m, _ := re.FindStringMatch(s)
+ for m != nil {
+ matches = append(matches, m.String())
+ m, _ = re.FindNextMatch(m)
+ }
+ return matches
+}
+```
+
+`FindNextMatch` is optmized so that it re-uses the underlying string/rune slice.
+
+The internals of `regexp2` always operate on `[]rune` so `Index` and `Length` data in a `Match` always reference a position in `rune`s rather than `byte`s (even if the input was given as a string). This is a dramatic difference between `regexp` and `regexp2`. It's advisable to use the provided `String()` methods to avoid having to work with indices.
+
+## Compare `regexp` and `regexp2`
+| Category | regexp | regexp2 |
+| --- | --- | --- |
+| Catastrophic backtracking possible | no, constant execution time guarantees | yes, if your pattern is at risk you can use the `re.MatchTimeout` field |
+| Python-style capture groups `(?Pre)` | yes | no (yes in RE2 compat mode) |
+| .NET-style capture groups `(?re)` or `(?'name're)` | no | yes |
+| comments `(?#comment)` | no | yes |
+| branch numbering reset `(?\|a\|b)` | no | no |
+| possessive match `(?>re)` | no | yes |
+| positive lookahead `(?=re)` | no | yes |
+| negative lookahead `(?!re)` | no | yes |
+| positive lookbehind `(?<=re)` | no | yes |
+| negative lookbehind `(?re)`)
+* change singleline behavior for `$` to only match end of string (like RE2) (see [#24](https://github.com/dlclark/regexp2/issues/24))
+* change the character classes `\d` `\s` and `\w` to match the same characters as RE2. NOTE: if you also use the `ECMAScript` option then this will change the `\s` character class to match ECMAScript instead of RE2. ECMAScript allows more whitespace characters in `\s` than RE2 (but still fewer than the the default behavior).
+* allow character escape sequences to have defaults. For example, by default `\_` isn't a known character escape and will fail to compile, but in RE2 mode it will match the literal character `_`
+
+```go
+re := regexp2.MustCompile(`Your RE2-compatible pattern`, regexp2.RE2)
+if isMatch, _ := re.MatchString(`Something to match`); isMatch {
+ //do something
+}
+```
+
+This feature is a work in progress and I'm open to ideas for more things to put here (maybe more relaxed character escaping rules?).
+
+## Catastrophic Backtracking and Timeouts
+
+`regexp2` supports features that can lead to catastrophic backtracking.
+`Regexp.MatchTimeout` can be set to to limit the impact of such behavior; the
+match will fail with an error after approximately MatchTimeout. No timeout
+checks are done by default.
+
+Timeout checking is not free. The current timeout checking implementation starts
+a background worker that updates a clock value approximately once every 100
+milliseconds. The matching code compares this value against the precomputed
+deadline for the match. The performance impact is as follows.
+
+1. A match with a timeout runs almost as fast as a match without a timeout.
+2. If any live matches have a timeout, there will be a background CPU load
+ (`~0.15%` currently on a modern machine). This load will remain constant
+ regardless of the number of matches done including matches done in parallel.
+3. If no live matches are using a timeout, the background load will remain
+ until the longest deadline (match timeout + the time when the match started)
+ is reached. E.g., if you set a timeout of one minute the load will persist
+ for approximately a minute even if the match finishes quickly.
+
+See [PR #58](https://github.com/dlclark/regexp2/pull/58) for more details and
+alternatives considered.
+
+## Goroutine leak error
+If you're using a library during unit tests (e.g. https://github.com/uber-go/goleak) that validates all goroutines are exited then you'll likely get an error if you or any of your dependencies use regex's with a MatchTimeout.
+To remedy the problem you'll need to tell the unit test to wait until the backgroup timeout goroutine is exited.
+
+```go
+func TestSomething(t *testing.T) {
+ defer goleak.VerifyNone(t)
+ defer regexp2.StopTimeoutClock()
+
+ // ... test
+}
+
+//or
+
+func TestMain(m *testing.M) {
+ // setup
+ // ...
+
+ // run
+ m.Run()
+
+ //tear down
+ regexp2.StopTimeoutClock()
+ goleak.VerifyNone(t)
+}
+```
+
+This will add ~100ms runtime to each test (or TestMain). If that's too much time you can set the clock cycle rate of the timeout goroutine in an init function in a test file. `regexp2.SetTimeoutCheckPeriod` isn't threadsafe so it must be setup before starting any regex's with Timeouts.
+
+```go
+func init() {
+ //speed up testing by making the timeout clock 1ms
+ regexp2.SetTimeoutCheckPeriod(time.Millisecond)
+}
+```
+
+## ECMAScript compatibility mode
+In this mode the engine provides compatibility with the [regex engine](https://tc39.es/ecma262/multipage/text-processing.html#sec-regexp-regular-expression-objects) described in the ECMAScript specification.
+
+Additionally a Unicode mode is provided which allows parsing of `\u{CodePoint}` syntax that is only when both are provided.
+
+## Library features that I'm still working on
+- Regex split
+
+## Potential bugs
+I've run a battery of tests against regexp2 from various sources and found the debug output matches the .NET engine, but .NET and Go handle strings very differently. I've attempted to handle these differences, but most of my testing deals with basic ASCII with a little bit of multi-byte Unicode. There's a chance that there are bugs in the string handling related to character sets with supplementary Unicode chars. Right-to-Left support is coded, but not well tested either.
+
+## Find a bug?
+I'm open to new issues and pull requests with tests if you find something odd!
diff --git a/vendor/github.com/dlclark/regexp2/fastclock.go b/vendor/github.com/dlclark/regexp2/fastclock.go
new file mode 100644
index 00000000..d256e63c
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/fastclock.go
@@ -0,0 +1,141 @@
+package regexp2
+
+import (
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// fasttime holds a time value (ticks since clock initialization)
+type fasttime int64
+
+// fastclock provides a fast clock implementation.
+//
+// A background goroutine periodically stores the current time
+// into an atomic variable.
+//
+// A deadline can be quickly checked for expiration by comparing
+// its value to the clock stored in the atomic variable.
+//
+// The goroutine automatically stops once clockEnd is reached.
+// (clockEnd covers the largest deadline seen so far + some
+// extra time). This ensures that if regexp2 with timeouts
+// stops being used we will stop background work.
+type fastclock struct {
+ // instances of atomicTime must be at the start of the struct (or at least 64-bit aligned)
+ // otherwise 32-bit architectures will panic
+
+ current atomicTime // Current time (approximate)
+ clockEnd atomicTime // When clock updater is supposed to stop (>= any existing deadline)
+
+ // current and clockEnd can be read via atomic loads.
+ // Reads and writes of other fields require mu to be held.
+ mu sync.Mutex
+ start time.Time // Time corresponding to fasttime(0)
+ running bool // Is a clock updater running?
+}
+
+var fast fastclock
+
+// reached returns true if current time is at or past t.
+func (t fasttime) reached() bool {
+ return fast.current.read() >= t
+}
+
+// makeDeadline returns a time that is approximately time.Now().Add(d)
+func makeDeadline(d time.Duration) fasttime {
+ // Increase the deadline since the clock we are reading may be
+ // just about to tick forwards.
+ end := fast.current.read() + durationToTicks(d+clockPeriod)
+
+ // Start or extend clock if necessary.
+ if end > fast.clockEnd.read() {
+ // If time.Since(last use) > timeout, there's a chance that
+ // fast.current will no longer be updated, which can lead to
+ // incorrect 'end' calculations that can trigger a false timeout
+ fast.mu.Lock()
+ if !fast.running && !fast.start.IsZero() {
+ // update fast.current
+ fast.current.write(durationToTicks(time.Since(fast.start)))
+ // recalculate our end value
+ end = fast.current.read() + durationToTicks(d+clockPeriod)
+ }
+ fast.mu.Unlock()
+ extendClock(end)
+ }
+
+ return end
+}
+
+// extendClock ensures that clock is live and will run until at least end.
+func extendClock(end fasttime) {
+ fast.mu.Lock()
+ defer fast.mu.Unlock()
+
+ if fast.start.IsZero() {
+ fast.start = time.Now()
+ }
+
+ // Extend the running time to cover end as well as a bit of slop.
+ if shutdown := end + durationToTicks(time.Second); shutdown > fast.clockEnd.read() {
+ fast.clockEnd.write(shutdown)
+ }
+
+ // Start clock if necessary
+ if !fast.running {
+ fast.running = true
+ go runClock()
+ }
+}
+
+// stop the timeout clock in the background
+// should only used for unit tests to abandon the background goroutine
+func stopClock() {
+ fast.mu.Lock()
+ if fast.running {
+ fast.clockEnd.write(fasttime(0))
+ }
+ fast.mu.Unlock()
+
+ // pause until not running
+ // get and release the lock
+ isRunning := true
+ for isRunning {
+ time.Sleep(clockPeriod / 2)
+ fast.mu.Lock()
+ isRunning = fast.running
+ fast.mu.Unlock()
+ }
+}
+
+func durationToTicks(d time.Duration) fasttime {
+ // Downscale nanoseconds to approximately a millisecond so that we can avoid
+ // overflow even if the caller passes in math.MaxInt64.
+ return fasttime(d) >> 20
+}
+
+const DefaultClockPeriod = 100 * time.Millisecond
+
+// clockPeriod is the approximate interval between updates of approximateClock.
+var clockPeriod = DefaultClockPeriod
+
+func runClock() {
+ fast.mu.Lock()
+ defer fast.mu.Unlock()
+
+ for fast.current.read() <= fast.clockEnd.read() {
+ // Unlock while sleeping.
+ fast.mu.Unlock()
+ time.Sleep(clockPeriod)
+ fast.mu.Lock()
+
+ newTime := durationToTicks(time.Since(fast.start))
+ fast.current.write(newTime)
+ }
+ fast.running = false
+}
+
+type atomicTime struct{ v int64 } // Should change to atomic.Int64 when we can use go 1.19
+
+func (t *atomicTime) read() fasttime { return fasttime(atomic.LoadInt64(&t.v)) }
+func (t *atomicTime) write(v fasttime) { atomic.StoreInt64(&t.v, int64(v)) }
diff --git a/vendor/github.com/dlclark/regexp2/match.go b/vendor/github.com/dlclark/regexp2/match.go
new file mode 100644
index 00000000..759cf8cc
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/match.go
@@ -0,0 +1,349 @@
+package regexp2
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// Match is a single regex result match that contains groups and repeated captures
+//
+// -Groups
+// -Capture
+type Match struct {
+ Group //embeded group 0
+
+ regex *Regexp
+ otherGroups []Group
+
+ // input to the match
+ textpos int
+ textstart int
+
+ capcount int
+ caps []int
+ sparseCaps map[int]int
+
+ // output from the match
+ matches [][]int
+ matchcount []int
+
+ // whether we've done any balancing with this match. If we
+ // have done balancing, we'll need to do extra work in Tidy().
+ balancing bool
+}
+
+// Group is an explicit or implit (group 0) matched group within the pattern
+type Group struct {
+ Capture // the last capture of this group is embeded for ease of use
+
+ Name string // group name
+ Captures []Capture // captures of this group
+}
+
+// Capture is a single capture of text within the larger original string
+type Capture struct {
+ // the original string
+ text []rune
+ // Index is the position in the underlying rune slice where the first character of
+ // captured substring was found. Even if you pass in a string this will be in Runes.
+ Index int
+ // Length is the number of runes in the captured substring.
+ Length int
+}
+
+// String returns the captured text as a String
+func (c *Capture) String() string {
+ return string(c.text[c.Index : c.Index+c.Length])
+}
+
+// Runes returns the captured text as a rune slice
+func (c *Capture) Runes() []rune {
+ return c.text[c.Index : c.Index+c.Length]
+}
+
+func newMatch(regex *Regexp, capcount int, text []rune, startpos int) *Match {
+ m := Match{
+ regex: regex,
+ matchcount: make([]int, capcount),
+ matches: make([][]int, capcount),
+ textstart: startpos,
+ balancing: false,
+ }
+ m.Name = "0"
+ m.text = text
+ m.matches[0] = make([]int, 2)
+ return &m
+}
+
+func newMatchSparse(regex *Regexp, caps map[int]int, capcount int, text []rune, startpos int) *Match {
+ m := newMatch(regex, capcount, text, startpos)
+ m.sparseCaps = caps
+ return m
+}
+
+func (m *Match) reset(text []rune, textstart int) {
+ m.text = text
+ m.textstart = textstart
+ for i := 0; i < len(m.matchcount); i++ {
+ m.matchcount[i] = 0
+ }
+ m.balancing = false
+}
+
+func (m *Match) tidy(textpos int) {
+
+ interval := m.matches[0]
+ m.Index = interval[0]
+ m.Length = interval[1]
+ m.textpos = textpos
+ m.capcount = m.matchcount[0]
+ //copy our root capture to the list
+ m.Group.Captures = []Capture{m.Group.Capture}
+
+ if m.balancing {
+ // The idea here is that we want to compact all of our unbalanced captures. To do that we
+ // use j basically as a count of how many unbalanced captures we have at any given time
+ // (really j is an index, but j/2 is the count). First we skip past all of the real captures
+ // until we find a balance captures. Then we check each subsequent entry. If it's a balance
+ // capture (it's negative), we decrement j. If it's a real capture, we increment j and copy
+ // it down to the last free position.
+ for cap := 0; cap < len(m.matchcount); cap++ {
+ limit := m.matchcount[cap] * 2
+ matcharray := m.matches[cap]
+
+ var i, j int
+
+ for i = 0; i < limit; i++ {
+ if matcharray[i] < 0 {
+ break
+ }
+ }
+
+ for j = i; i < limit; i++ {
+ if matcharray[i] < 0 {
+ // skip negative values
+ j--
+ } else {
+ // but if we find something positive (an actual capture), copy it back to the last
+ // unbalanced position.
+ if i != j {
+ matcharray[j] = matcharray[i]
+ }
+ j++
+ }
+ }
+
+ m.matchcount[cap] = j / 2
+ }
+
+ m.balancing = false
+ }
+}
+
+// isMatched tells if a group was matched by capnum
+func (m *Match) isMatched(cap int) bool {
+ return cap < len(m.matchcount) && m.matchcount[cap] > 0 && m.matches[cap][m.matchcount[cap]*2-1] != (-3+1)
+}
+
+// matchIndex returns the index of the last specified matched group by capnum
+func (m *Match) matchIndex(cap int) int {
+ i := m.matches[cap][m.matchcount[cap]*2-2]
+ if i >= 0 {
+ return i
+ }
+
+ return m.matches[cap][-3-i]
+}
+
+// matchLength returns the length of the last specified matched group by capnum
+func (m *Match) matchLength(cap int) int {
+ i := m.matches[cap][m.matchcount[cap]*2-1]
+ if i >= 0 {
+ return i
+ }
+
+ return m.matches[cap][-3-i]
+}
+
+// Nonpublic builder: add a capture to the group specified by "c"
+func (m *Match) addMatch(c, start, l int) {
+
+ if m.matches[c] == nil {
+ m.matches[c] = make([]int, 2)
+ }
+
+ capcount := m.matchcount[c]
+
+ if capcount*2+2 > len(m.matches[c]) {
+ oldmatches := m.matches[c]
+ newmatches := make([]int, capcount*8)
+ copy(newmatches, oldmatches[:capcount*2])
+ m.matches[c] = newmatches
+ }
+
+ m.matches[c][capcount*2] = start
+ m.matches[c][capcount*2+1] = l
+ m.matchcount[c] = capcount + 1
+ //log.Printf("addMatch: c=%v, i=%v, l=%v ... matches: %v", c, start, l, m.matches)
+}
+
+// Nonpublic builder: Add a capture to balance the specified group. This is used by the
+//
+// balanced match construct. (?...)
+//
+// If there were no such thing as backtracking, this would be as simple as calling RemoveMatch(c).
+// However, since we have backtracking, we need to keep track of everything.
+func (m *Match) balanceMatch(c int) {
+ m.balancing = true
+
+ // we'll look at the last capture first
+ capcount := m.matchcount[c]
+ target := capcount*2 - 2
+
+ // first see if it is negative, and therefore is a reference to the next available
+ // capture group for balancing. If it is, we'll reset target to point to that capture.
+ if m.matches[c][target] < 0 {
+ target = -3 - m.matches[c][target]
+ }
+
+ // move back to the previous capture
+ target -= 2
+
+ // if the previous capture is a reference, just copy that reference to the end. Otherwise, point to it.
+ if target >= 0 && m.matches[c][target] < 0 {
+ m.addMatch(c, m.matches[c][target], m.matches[c][target+1])
+ } else {
+ m.addMatch(c, -3-target, -4-target /* == -3 - (target + 1) */)
+ }
+}
+
+// Nonpublic builder: removes a group match by capnum
+func (m *Match) removeMatch(c int) {
+ m.matchcount[c]--
+}
+
+// GroupCount returns the number of groups this match has matched
+func (m *Match) GroupCount() int {
+ return len(m.matchcount)
+}
+
+// GroupByName returns a group based on the name of the group, or nil if the group name does not exist
+func (m *Match) GroupByName(name string) *Group {
+ num := m.regex.GroupNumberFromName(name)
+ if num < 0 {
+ return nil
+ }
+ return m.GroupByNumber(num)
+}
+
+// GroupByNumber returns a group based on the number of the group, or nil if the group number does not exist
+func (m *Match) GroupByNumber(num int) *Group {
+ // check our sparse map
+ if m.sparseCaps != nil {
+ if newNum, ok := m.sparseCaps[num]; ok {
+ num = newNum
+ }
+ }
+ if num >= len(m.matchcount) || num < 0 {
+ return nil
+ }
+
+ if num == 0 {
+ return &m.Group
+ }
+
+ m.populateOtherGroups()
+
+ return &m.otherGroups[num-1]
+}
+
+// Groups returns all the capture groups, starting with group 0 (the full match)
+func (m *Match) Groups() []Group {
+ m.populateOtherGroups()
+ g := make([]Group, len(m.otherGroups)+1)
+ g[0] = m.Group
+ copy(g[1:], m.otherGroups)
+ return g
+}
+
+func (m *Match) populateOtherGroups() {
+ // Construct all the Group objects first time called
+ if m.otherGroups == nil {
+ m.otherGroups = make([]Group, len(m.matchcount)-1)
+ for i := 0; i < len(m.otherGroups); i++ {
+ m.otherGroups[i] = newGroup(m.regex.GroupNameFromNumber(i+1), m.text, m.matches[i+1], m.matchcount[i+1])
+ }
+ }
+}
+
+func (m *Match) groupValueAppendToBuf(groupnum int, buf *bytes.Buffer) {
+ c := m.matchcount[groupnum]
+ if c == 0 {
+ return
+ }
+
+ matches := m.matches[groupnum]
+
+ index := matches[(c-1)*2]
+ last := index + matches[(c*2)-1]
+
+ for ; index < last; index++ {
+ buf.WriteRune(m.text[index])
+ }
+}
+
+func newGroup(name string, text []rune, caps []int, capcount int) Group {
+ g := Group{}
+ g.text = text
+ if capcount > 0 {
+ g.Index = caps[(capcount-1)*2]
+ g.Length = caps[(capcount*2)-1]
+ }
+ g.Name = name
+ g.Captures = make([]Capture, capcount)
+ for i := 0; i < capcount; i++ {
+ g.Captures[i] = Capture{
+ text: text,
+ Index: caps[i*2],
+ Length: caps[i*2+1],
+ }
+ }
+ //log.Printf("newGroup! capcount %v, %+v", capcount, g)
+
+ return g
+}
+
+func (m *Match) dump() string {
+ buf := &bytes.Buffer{}
+ buf.WriteRune('\n')
+ if len(m.sparseCaps) > 0 {
+ for k, v := range m.sparseCaps {
+ fmt.Fprintf(buf, "Slot %v -> %v\n", k, v)
+ }
+ }
+
+ for i, g := range m.Groups() {
+ fmt.Fprintf(buf, "Group %v (%v), %v caps:\n", i, g.Name, len(g.Captures))
+
+ for _, c := range g.Captures {
+ fmt.Fprintf(buf, " (%v, %v) %v\n", c.Index, c.Length, c.String())
+ }
+ }
+ /*
+ for i := 0; i < len(m.matchcount); i++ {
+ fmt.Fprintf(buf, "\nGroup %v (%v):\n", i, m.regex.GroupNameFromNumber(i))
+
+ for j := 0; j < m.matchcount[i]; j++ {
+ text := ""
+
+ if m.matches[i][j*2] >= 0 {
+ start := m.matches[i][j*2]
+ text = m.text[start : start+m.matches[i][j*2+1]]
+ }
+
+ fmt.Fprintf(buf, " (%v, %v) %v\n", m.matches[i][j*2], m.matches[i][j*2+1], text)
+ }
+ }
+ */
+ return buf.String()
+}
diff --git a/vendor/github.com/dlclark/regexp2/regexp.go b/vendor/github.com/dlclark/regexp2/regexp.go
new file mode 100644
index 00000000..a7ddbaf3
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/regexp.go
@@ -0,0 +1,395 @@
+/*
+Package regexp2 is a regexp package that has an interface similar to Go's framework regexp engine but uses a
+more feature full regex engine behind the scenes.
+
+It doesn't have constant time guarantees, but it allows backtracking and is compatible with Perl5 and .NET.
+You'll likely be better off with the RE2 engine from the regexp package and should only use this if you
+need to write very complex patterns or require compatibility with .NET.
+*/
+package regexp2
+
+import (
+ "errors"
+ "math"
+ "strconv"
+ "sync"
+ "time"
+
+ "github.com/dlclark/regexp2/syntax"
+)
+
+var (
+ // DefaultMatchTimeout used when running regexp matches -- "forever"
+ DefaultMatchTimeout = time.Duration(math.MaxInt64)
+ // DefaultUnmarshalOptions used when unmarshaling a regex from text
+ DefaultUnmarshalOptions = None
+)
+
+// Regexp is the representation of a compiled regular expression.
+// A Regexp is safe for concurrent use by multiple goroutines.
+type Regexp struct {
+ // A match will time out if it takes (approximately) more than
+ // MatchTimeout. This is a safety check in case the match
+ // encounters catastrophic backtracking. The default value
+ // (DefaultMatchTimeout) causes all time out checking to be
+ // suppressed.
+ MatchTimeout time.Duration
+
+ // read-only after Compile
+ pattern string // as passed to Compile
+ options RegexOptions // options
+
+ caps map[int]int // capnum->index
+ capnames map[string]int //capture group name -> index
+ capslist []string //sorted list of capture group names
+ capsize int // size of the capture array
+
+ code *syntax.Code // compiled program
+
+ // cache of machines for running regexp
+ muRun *sync.Mutex
+ runner []*runner
+}
+
+// Compile parses a regular expression and returns, if successful,
+// a Regexp object that can be used to match against text.
+func Compile(expr string, opt RegexOptions) (*Regexp, error) {
+ // parse it
+ tree, err := syntax.Parse(expr, syntax.RegexOptions(opt))
+ if err != nil {
+ return nil, err
+ }
+
+ // translate it to code
+ code, err := syntax.Write(tree)
+ if err != nil {
+ return nil, err
+ }
+
+ // return it
+ return &Regexp{
+ pattern: expr,
+ options: opt,
+ caps: code.Caps,
+ capnames: tree.Capnames,
+ capslist: tree.Caplist,
+ capsize: code.Capsize,
+ code: code,
+ MatchTimeout: DefaultMatchTimeout,
+ muRun: &sync.Mutex{},
+ }, nil
+}
+
+// MustCompile is like Compile but panics if the expression cannot be parsed.
+// It simplifies safe initialization of global variables holding compiled regular
+// expressions.
+func MustCompile(str string, opt RegexOptions) *Regexp {
+ regexp, error := Compile(str, opt)
+ if error != nil {
+ panic(`regexp2: Compile(` + quote(str) + `): ` + error.Error())
+ }
+ return regexp
+}
+
+// Escape adds backslashes to any special characters in the input string
+func Escape(input string) string {
+ return syntax.Escape(input)
+}
+
+// Unescape removes any backslashes from previously-escaped special characters in the input string
+func Unescape(input string) (string, error) {
+ return syntax.Unescape(input)
+}
+
+// SetTimeoutPeriod is a debug function that sets the frequency of the timeout goroutine's sleep cycle.
+// Defaults to 100ms. The only benefit of setting this lower is that the 1 background goroutine that manages
+// timeouts may exit slightly sooner after all the timeouts have expired. See Github issue #63
+func SetTimeoutCheckPeriod(d time.Duration) {
+ clockPeriod = d
+}
+
+// StopTimeoutClock should only be used in unit tests to prevent the timeout clock goroutine
+// from appearing like a leaking goroutine
+func StopTimeoutClock() {
+ stopClock()
+}
+
+// String returns the source text used to compile the regular expression.
+func (re *Regexp) String() string {
+ return re.pattern
+}
+
+func quote(s string) string {
+ if strconv.CanBackquote(s) {
+ return "`" + s + "`"
+ }
+ return strconv.Quote(s)
+}
+
+// RegexOptions impact the runtime and parsing behavior
+// for each specific regex. They are setable in code as well
+// as in the regex pattern itself.
+type RegexOptions int32
+
+const (
+ None RegexOptions = 0x0
+ IgnoreCase = 0x0001 // "i"
+ Multiline = 0x0002 // "m"
+ ExplicitCapture = 0x0004 // "n"
+ Compiled = 0x0008 // "c"
+ Singleline = 0x0010 // "s"
+ IgnorePatternWhitespace = 0x0020 // "x"
+ RightToLeft = 0x0040 // "r"
+ Debug = 0x0080 // "d"
+ ECMAScript = 0x0100 // "e"
+ RE2 = 0x0200 // RE2 (regexp package) compatibility mode
+ Unicode = 0x0400 // "u"
+)
+
+func (re *Regexp) RightToLeft() bool {
+ return re.options&RightToLeft != 0
+}
+
+func (re *Regexp) Debug() bool {
+ return re.options&Debug != 0
+}
+
+// Replace searches the input string and replaces each match found with the replacement text.
+// Count will limit the number of matches attempted and startAt will allow
+// us to skip past possible matches at the start of the input (left or right depending on RightToLeft option).
+// Set startAt and count to -1 to go through the whole string
+func (re *Regexp) Replace(input, replacement string, startAt, count int) (string, error) {
+ data, err := syntax.NewReplacerData(replacement, re.caps, re.capsize, re.capnames, syntax.RegexOptions(re.options))
+ if err != nil {
+ return "", err
+ }
+ //TODO: cache ReplacerData
+
+ return replace(re, data, nil, input, startAt, count)
+}
+
+// ReplaceFunc searches the input string and replaces each match found using the string from the evaluator
+// Count will limit the number of matches attempted and startAt will allow
+// us to skip past possible matches at the start of the input (left or right depending on RightToLeft option).
+// Set startAt and count to -1 to go through the whole string.
+func (re *Regexp) ReplaceFunc(input string, evaluator MatchEvaluator, startAt, count int) (string, error) {
+ return replace(re, nil, evaluator, input, startAt, count)
+}
+
+// FindStringMatch searches the input string for a Regexp match
+func (re *Regexp) FindStringMatch(s string) (*Match, error) {
+ // convert string to runes
+ return re.run(false, -1, getRunes(s))
+}
+
+// FindRunesMatch searches the input rune slice for a Regexp match
+func (re *Regexp) FindRunesMatch(r []rune) (*Match, error) {
+ return re.run(false, -1, r)
+}
+
+// FindStringMatchStartingAt searches the input string for a Regexp match starting at the startAt index
+func (re *Regexp) FindStringMatchStartingAt(s string, startAt int) (*Match, error) {
+ if startAt > len(s) {
+ return nil, errors.New("startAt must be less than the length of the input string")
+ }
+ r, startAt := re.getRunesAndStart(s, startAt)
+ if startAt == -1 {
+ // we didn't find our start index in the string -- that's a problem
+ return nil, errors.New("startAt must align to the start of a valid rune in the input string")
+ }
+
+ return re.run(false, startAt, r)
+}
+
+// FindRunesMatchStartingAt searches the input rune slice for a Regexp match starting at the startAt index
+func (re *Regexp) FindRunesMatchStartingAt(r []rune, startAt int) (*Match, error) {
+ return re.run(false, startAt, r)
+}
+
+// FindNextMatch returns the next match in the same input string as the match parameter.
+// Will return nil if there is no next match or if given a nil match.
+func (re *Regexp) FindNextMatch(m *Match) (*Match, error) {
+ if m == nil {
+ return nil, nil
+ }
+
+ // If previous match was empty, advance by one before matching to prevent
+ // infinite loop
+ startAt := m.textpos
+ if m.Length == 0 {
+ if m.textpos == len(m.text) {
+ return nil, nil
+ }
+
+ if re.RightToLeft() {
+ startAt--
+ } else {
+ startAt++
+ }
+ }
+ return re.run(false, startAt, m.text)
+}
+
+// MatchString return true if the string matches the regex
+// error will be set if a timeout occurs
+func (re *Regexp) MatchString(s string) (bool, error) {
+ m, err := re.run(true, -1, getRunes(s))
+ if err != nil {
+ return false, err
+ }
+ return m != nil, nil
+}
+
+func (re *Regexp) getRunesAndStart(s string, startAt int) ([]rune, int) {
+ if startAt < 0 {
+ if re.RightToLeft() {
+ r := getRunes(s)
+ return r, len(r)
+ }
+ return getRunes(s), 0
+ }
+ ret := make([]rune, len(s))
+ i := 0
+ runeIdx := -1
+ for strIdx, r := range s {
+ if strIdx == startAt {
+ runeIdx = i
+ }
+ ret[i] = r
+ i++
+ }
+ if startAt == len(s) {
+ runeIdx = i
+ }
+ return ret[:i], runeIdx
+}
+
+func getRunes(s string) []rune {
+ return []rune(s)
+}
+
+// MatchRunes return true if the runes matches the regex
+// error will be set if a timeout occurs
+func (re *Regexp) MatchRunes(r []rune) (bool, error) {
+ m, err := re.run(true, -1, r)
+ if err != nil {
+ return false, err
+ }
+ return m != nil, nil
+}
+
+// GetGroupNames Returns the set of strings used to name capturing groups in the expression.
+func (re *Regexp) GetGroupNames() []string {
+ var result []string
+
+ if re.capslist == nil {
+ result = make([]string, re.capsize)
+
+ for i := 0; i < len(result); i++ {
+ result[i] = strconv.Itoa(i)
+ }
+ } else {
+ result = make([]string, len(re.capslist))
+ copy(result, re.capslist)
+ }
+
+ return result
+}
+
+// GetGroupNumbers returns the integer group numbers corresponding to a group name.
+func (re *Regexp) GetGroupNumbers() []int {
+ var result []int
+
+ if re.caps == nil {
+ result = make([]int, re.capsize)
+
+ for i := 0; i < len(result); i++ {
+ result[i] = i
+ }
+ } else {
+ result = make([]int, len(re.caps))
+
+ for k, v := range re.caps {
+ result[v] = k
+ }
+ }
+
+ return result
+}
+
+// GroupNameFromNumber retrieves a group name that corresponds to a group number.
+// It will return "" for and unknown group number. Unnamed groups automatically
+// receive a name that is the decimal string equivalent of its number.
+func (re *Regexp) GroupNameFromNumber(i int) string {
+ if re.capslist == nil {
+ if i >= 0 && i < re.capsize {
+ return strconv.Itoa(i)
+ }
+
+ return ""
+ }
+
+ if re.caps != nil {
+ var ok bool
+ if i, ok = re.caps[i]; !ok {
+ return ""
+ }
+ }
+
+ if i >= 0 && i < len(re.capslist) {
+ return re.capslist[i]
+ }
+
+ return ""
+}
+
+// GroupNumberFromName returns a group number that corresponds to a group name.
+// Returns -1 if the name is not a recognized group name. Numbered groups
+// automatically get a group name that is the decimal string equivalent of its number.
+func (re *Regexp) GroupNumberFromName(name string) int {
+ // look up name if we have a hashtable of names
+ if re.capnames != nil {
+ if k, ok := re.capnames[name]; ok {
+ return k
+ }
+
+ return -1
+ }
+
+ // convert to an int if it looks like a number
+ result := 0
+ for i := 0; i < len(name); i++ {
+ ch := name[i]
+
+ if ch > '9' || ch < '0' {
+ return -1
+ }
+
+ result *= 10
+ result += int(ch - '0')
+ }
+
+ // return int if it's in range
+ if result >= 0 && result < re.capsize {
+ return result
+ }
+
+ return -1
+}
+
+// MarshalText implements [encoding.TextMarshaler]. The output
+// matches that of calling the [Regexp.String] method.
+func (re *Regexp) MarshalText() ([]byte, error) {
+ return []byte(re.String()), nil
+}
+
+// UnmarshalText implements [encoding.TextUnmarshaler] by calling
+// [Compile] on the encoded value.
+func (re *Regexp) UnmarshalText(text []byte) error {
+ newRE, err := Compile(string(text), DefaultUnmarshalOptions)
+ if err != nil {
+ return err
+ }
+ *re = *newRE
+ return nil
+}
diff --git a/vendor/github.com/dlclark/regexp2/replace.go b/vendor/github.com/dlclark/regexp2/replace.go
new file mode 100644
index 00000000..0376bd9d
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/replace.go
@@ -0,0 +1,177 @@
+package regexp2
+
+import (
+ "bytes"
+ "errors"
+
+ "github.com/dlclark/regexp2/syntax"
+)
+
+const (
+ replaceSpecials = 4
+ replaceLeftPortion = -1
+ replaceRightPortion = -2
+ replaceLastGroup = -3
+ replaceWholeString = -4
+)
+
+// MatchEvaluator is a function that takes a match and returns a replacement string to be used
+type MatchEvaluator func(Match) string
+
+// Three very similar algorithms appear below: replace (pattern),
+// replace (evaluator), and split.
+
+// Replace Replaces all occurrences of the regex in the string with the
+// replacement pattern.
+//
+// Note that the special case of no matches is handled on its own:
+// with no matches, the input string is returned unchanged.
+// The right-to-left case is split out because StringBuilder
+// doesn't handle right-to-left string building directly very well.
+func replace(regex *Regexp, data *syntax.ReplacerData, evaluator MatchEvaluator, input string, startAt, count int) (string, error) {
+ if count < -1 {
+ return "", errors.New("Count too small")
+ }
+ if count == 0 {
+ return "", nil
+ }
+
+ m, err := regex.FindStringMatchStartingAt(input, startAt)
+
+ if err != nil {
+ return "", err
+ }
+ if m == nil {
+ return input, nil
+ }
+
+ buf := &bytes.Buffer{}
+ text := m.text
+
+ if !regex.RightToLeft() {
+ prevat := 0
+ for m != nil {
+ if m.Index != prevat {
+ buf.WriteString(string(text[prevat:m.Index]))
+ }
+ prevat = m.Index + m.Length
+ if evaluator == nil {
+ replacementImpl(data, buf, m)
+ } else {
+ buf.WriteString(evaluator(*m))
+ }
+
+ count--
+ if count == 0 {
+ break
+ }
+ m, err = regex.FindNextMatch(m)
+ if err != nil {
+ return "", nil
+ }
+ }
+
+ if prevat < len(text) {
+ buf.WriteString(string(text[prevat:]))
+ }
+ } else {
+ prevat := len(text)
+ var al []string
+
+ for m != nil {
+ if m.Index+m.Length != prevat {
+ al = append(al, string(text[m.Index+m.Length:prevat]))
+ }
+ prevat = m.Index
+ if evaluator == nil {
+ replacementImplRTL(data, &al, m)
+ } else {
+ al = append(al, evaluator(*m))
+ }
+
+ count--
+ if count == 0 {
+ break
+ }
+ m, err = regex.FindNextMatch(m)
+ if err != nil {
+ return "", nil
+ }
+ }
+
+ if prevat > 0 {
+ buf.WriteString(string(text[:prevat]))
+ }
+
+ for i := len(al) - 1; i >= 0; i-- {
+ buf.WriteString(al[i])
+ }
+ }
+
+ return buf.String(), nil
+}
+
+// Given a Match, emits into the StringBuilder the evaluated
+// substitution pattern.
+func replacementImpl(data *syntax.ReplacerData, buf *bytes.Buffer, m *Match) {
+ for _, r := range data.Rules {
+
+ if r >= 0 { // string lookup
+ buf.WriteString(data.Strings[r])
+ } else if r < -replaceSpecials { // group lookup
+ m.groupValueAppendToBuf(-replaceSpecials-1-r, buf)
+ } else {
+ switch -replaceSpecials - 1 - r { // special insertion patterns
+ case replaceLeftPortion:
+ for i := 0; i < m.Index; i++ {
+ buf.WriteRune(m.text[i])
+ }
+ case replaceRightPortion:
+ for i := m.Index + m.Length; i < len(m.text); i++ {
+ buf.WriteRune(m.text[i])
+ }
+ case replaceLastGroup:
+ m.groupValueAppendToBuf(m.GroupCount()-1, buf)
+ case replaceWholeString:
+ for i := 0; i < len(m.text); i++ {
+ buf.WriteRune(m.text[i])
+ }
+ }
+ }
+ }
+}
+
+func replacementImplRTL(data *syntax.ReplacerData, al *[]string, m *Match) {
+ l := *al
+ buf := &bytes.Buffer{}
+
+ for _, r := range data.Rules {
+ buf.Reset()
+ if r >= 0 { // string lookup
+ l = append(l, data.Strings[r])
+ } else if r < -replaceSpecials { // group lookup
+ m.groupValueAppendToBuf(-replaceSpecials-1-r, buf)
+ l = append(l, buf.String())
+ } else {
+ switch -replaceSpecials - 1 - r { // special insertion patterns
+ case replaceLeftPortion:
+ for i := 0; i < m.Index; i++ {
+ buf.WriteRune(m.text[i])
+ }
+ case replaceRightPortion:
+ for i := m.Index + m.Length; i < len(m.text); i++ {
+ buf.WriteRune(m.text[i])
+ }
+ case replaceLastGroup:
+ m.groupValueAppendToBuf(m.GroupCount()-1, buf)
+ case replaceWholeString:
+ for i := 0; i < len(m.text); i++ {
+ buf.WriteRune(m.text[i])
+ }
+ }
+ l = append(l, buf.String())
+ }
+ }
+
+ *al = l
+}
diff --git a/vendor/github.com/dlclark/regexp2/runner.go b/vendor/github.com/dlclark/regexp2/runner.go
new file mode 100644
index 00000000..56759f14
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/runner.go
@@ -0,0 +1,1613 @@
+package regexp2
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+ "time"
+ "unicode"
+
+ "github.com/dlclark/regexp2/syntax"
+)
+
+type runner struct {
+ re *Regexp
+ code *syntax.Code
+
+ runtextstart int // starting point for search
+
+ runtext []rune // text to search
+ runtextpos int // current position in text
+ runtextend int
+
+ // The backtracking stack. Opcodes use this to store data regarding
+ // what they have matched and where to backtrack to. Each "frame" on
+ // the stack takes the form of [CodePosition Data1 Data2...], where
+ // CodePosition is the position of the current opcode and
+ // the data values are all optional. The CodePosition can be negative, and
+ // these values (also called "back2") are used by the BranchMark family of opcodes
+ // to indicate whether they are backtracking after a successful or failed
+ // match.
+ // When we backtrack, we pop the CodePosition off the stack, set the current
+ // instruction pointer to that code position, and mark the opcode
+ // with a backtracking flag ("Back"). Each opcode then knows how to
+ // handle its own data.
+ runtrack []int
+ runtrackpos int
+
+ // This stack is used to track text positions across different opcodes.
+ // For example, in /(a*b)+/, the parentheses result in a SetMark/CaptureMark
+ // pair. SetMark records the text position before we match a*b. Then
+ // CaptureMark uses that position to figure out where the capture starts.
+ // Opcodes which push onto this stack are always paired with other opcodes
+ // which will pop the value from it later. A successful match should mean
+ // that this stack is empty.
+ runstack []int
+ runstackpos int
+
+ // The crawl stack is used to keep track of captures. Every time a group
+ // has a capture, we push its group number onto the runcrawl stack. In
+ // the case of a balanced match, we push BOTH groups onto the stack.
+ runcrawl []int
+ runcrawlpos int
+
+ runtrackcount int // count of states that may do backtracking
+
+ runmatch *Match // result object
+
+ ignoreTimeout bool
+ timeout time.Duration // timeout in milliseconds (needed for actual)
+ deadline fasttime
+
+ operator syntax.InstOp
+ codepos int
+ rightToLeft bool
+ caseInsensitive bool
+}
+
+// run searches for matches and can continue from the previous match
+//
+// quick is usually false, but can be true to not return matches, just put it in caches
+// textstart is -1 to start at the "beginning" (depending on Right-To-Left), otherwise an index in input
+// input is the string to search for our regex pattern
+func (re *Regexp) run(quick bool, textstart int, input []rune) (*Match, error) {
+
+ // get a cached runner
+ runner := re.getRunner()
+ defer re.putRunner(runner)
+
+ if textstart < 0 {
+ if re.RightToLeft() {
+ textstart = len(input)
+ } else {
+ textstart = 0
+ }
+ }
+
+ return runner.scan(input, textstart, quick, re.MatchTimeout)
+}
+
+// Scans the string to find the first match. Uses the Match object
+// both to feed text in and as a place to store matches that come out.
+//
+// All the action is in the Go() method. Our
+// responsibility is to load up the class members before
+// calling Go.
+//
+// The optimizer can compute a set of candidate starting characters,
+// and we could use a separate method Skip() that will quickly scan past
+// any characters that we know can't match.
+func (r *runner) scan(rt []rune, textstart int, quick bool, timeout time.Duration) (*Match, error) {
+ r.timeout = timeout
+ r.ignoreTimeout = (time.Duration(math.MaxInt64) == timeout)
+ r.runtextstart = textstart
+ r.runtext = rt
+ r.runtextend = len(rt)
+
+ stoppos := r.runtextend
+ bump := 1
+
+ if r.re.RightToLeft() {
+ bump = -1
+ stoppos = 0
+ }
+
+ r.runtextpos = textstart
+ initted := false
+
+ r.startTimeoutWatch()
+ for {
+ if r.re.Debug() {
+ //fmt.Printf("\nSearch content: %v\n", string(r.runtext))
+ fmt.Printf("\nSearch range: from 0 to %v\n", r.runtextend)
+ fmt.Printf("Firstchar search starting at %v stopping at %v\n", r.runtextpos, stoppos)
+ }
+
+ if r.findFirstChar() {
+ if err := r.checkTimeout(); err != nil {
+ return nil, err
+ }
+
+ if !initted {
+ r.initMatch()
+ initted = true
+ }
+
+ if r.re.Debug() {
+ fmt.Printf("Executing engine starting at %v\n\n", r.runtextpos)
+ }
+
+ if err := r.execute(); err != nil {
+ return nil, err
+ }
+
+ if r.runmatch.matchcount[0] > 0 {
+ // We'll return a match even if it touches a previous empty match
+ return r.tidyMatch(quick), nil
+ }
+
+ // reset state for another go
+ r.runtrackpos = len(r.runtrack)
+ r.runstackpos = len(r.runstack)
+ r.runcrawlpos = len(r.runcrawl)
+ }
+
+ // failure!
+
+ if r.runtextpos == stoppos {
+ r.tidyMatch(true)
+ return nil, nil
+ }
+
+ // Recognize leading []* and various anchors, and bump on failure accordingly
+
+ // r.bump by one and start again
+
+ r.runtextpos += bump
+ }
+ // We never get here
+}
+
+func (r *runner) execute() error {
+
+ r.goTo(0)
+
+ for {
+
+ if r.re.Debug() {
+ r.dumpState()
+ }
+
+ if err := r.checkTimeout(); err != nil {
+ return err
+ }
+
+ switch r.operator {
+ case syntax.Stop:
+ return nil
+
+ case syntax.Nothing:
+ break
+
+ case syntax.Goto:
+ r.goTo(r.operand(0))
+ continue
+
+ case syntax.Testref:
+ if !r.runmatch.isMatched(r.operand(0)) {
+ break
+ }
+ r.advance(1)
+ continue
+
+ case syntax.Lazybranch:
+ r.trackPush1(r.textPos())
+ r.advance(1)
+ continue
+
+ case syntax.Lazybranch | syntax.Back:
+ r.trackPop()
+ r.textto(r.trackPeek())
+ r.goTo(r.operand(0))
+ continue
+
+ case syntax.Setmark:
+ r.stackPush(r.textPos())
+ r.trackPush()
+ r.advance(0)
+ continue
+
+ case syntax.Nullmark:
+ r.stackPush(-1)
+ r.trackPush()
+ r.advance(0)
+ continue
+
+ case syntax.Setmark | syntax.Back, syntax.Nullmark | syntax.Back:
+ r.stackPop()
+ break
+
+ case syntax.Getmark:
+ r.stackPop()
+ r.trackPush1(r.stackPeek())
+ r.textto(r.stackPeek())
+ r.advance(0)
+ continue
+
+ case syntax.Getmark | syntax.Back:
+ r.trackPop()
+ r.stackPush(r.trackPeek())
+ break
+
+ case syntax.Capturemark:
+ if r.operand(1) != -1 && !r.runmatch.isMatched(r.operand(1)) {
+ break
+ }
+ r.stackPop()
+ if r.operand(1) != -1 {
+ r.transferCapture(r.operand(0), r.operand(1), r.stackPeek(), r.textPos())
+ } else {
+ r.capture(r.operand(0), r.stackPeek(), r.textPos())
+ }
+ r.trackPush1(r.stackPeek())
+
+ r.advance(2)
+
+ continue
+
+ case syntax.Capturemark | syntax.Back:
+ r.trackPop()
+ r.stackPush(r.trackPeek())
+ r.uncapture()
+ if r.operand(0) != -1 && r.operand(1) != -1 {
+ r.uncapture()
+ }
+
+ break
+
+ case syntax.Branchmark:
+ r.stackPop()
+
+ matched := r.textPos() - r.stackPeek()
+
+ if matched != 0 { // Nonempty match -> loop now
+ r.trackPush2(r.stackPeek(), r.textPos()) // Save old mark, textpos
+ r.stackPush(r.textPos()) // Make new mark
+ r.goTo(r.operand(0)) // Loop
+ } else { // Empty match -> straight now
+ r.trackPushNeg1(r.stackPeek()) // Save old mark
+ r.advance(1) // Straight
+ }
+ continue
+
+ case syntax.Branchmark | syntax.Back:
+ r.trackPopN(2)
+ r.stackPop()
+ r.textto(r.trackPeekN(1)) // Recall position
+ r.trackPushNeg1(r.trackPeek()) // Save old mark
+ r.advance(1) // Straight
+ continue
+
+ case syntax.Branchmark | syntax.Back2:
+ r.trackPop()
+ r.stackPush(r.trackPeek()) // Recall old mark
+ break // Backtrack
+
+ case syntax.Lazybranchmark:
+ {
+ // We hit this the first time through a lazy loop and after each
+ // successful match of the inner expression. It simply continues
+ // on and doesn't loop.
+ r.stackPop()
+
+ oldMarkPos := r.stackPeek()
+
+ if r.textPos() != oldMarkPos { // Nonempty match -> try to loop again by going to 'back' state
+ if oldMarkPos != -1 {
+ r.trackPush2(oldMarkPos, r.textPos()) // Save old mark, textpos
+ } else {
+ r.trackPush2(r.textPos(), r.textPos())
+ }
+ } else {
+ // The inner expression found an empty match, so we'll go directly to 'back2' if we
+ // backtrack. In this case, we need to push something on the stack, since back2 pops.
+ // However, in the case of ()+? or similar, this empty match may be legitimate, so push the text
+ // position associated with that empty match.
+ r.stackPush(oldMarkPos)
+
+ r.trackPushNeg1(r.stackPeek()) // Save old mark
+ }
+ r.advance(1)
+ continue
+ }
+
+ case syntax.Lazybranchmark | syntax.Back:
+
+ // After the first time, Lazybranchmark | syntax.Back occurs
+ // with each iteration of the loop, and therefore with every attempted
+ // match of the inner expression. We'll try to match the inner expression,
+ // then go back to Lazybranchmark if successful. If the inner expression
+ // fails, we go to Lazybranchmark | syntax.Back2
+
+ r.trackPopN(2)
+ pos := r.trackPeekN(1)
+ r.trackPushNeg1(r.trackPeek()) // Save old mark
+ r.stackPush(pos) // Make new mark
+ r.textto(pos) // Recall position
+ r.goTo(r.operand(0)) // Loop
+ continue
+
+ case syntax.Lazybranchmark | syntax.Back2:
+ // The lazy loop has failed. We'll do a true backtrack and
+ // start over before the lazy loop.
+ r.stackPop()
+ r.trackPop()
+ r.stackPush(r.trackPeek()) // Recall old mark
+ break
+
+ case syntax.Setcount:
+ r.stackPush2(r.textPos(), r.operand(0))
+ r.trackPush()
+ r.advance(1)
+ continue
+
+ case syntax.Nullcount:
+ r.stackPush2(-1, r.operand(0))
+ r.trackPush()
+ r.advance(1)
+ continue
+
+ case syntax.Setcount | syntax.Back:
+ r.stackPopN(2)
+ break
+
+ case syntax.Nullcount | syntax.Back:
+ r.stackPopN(2)
+ break
+
+ case syntax.Branchcount:
+ // r.stackPush:
+ // 0: Mark
+ // 1: Count
+
+ r.stackPopN(2)
+ mark := r.stackPeek()
+ count := r.stackPeekN(1)
+ matched := r.textPos() - mark
+
+ if count >= r.operand(1) || (matched == 0 && count >= 0) { // Max loops or empty match -> straight now
+ r.trackPushNeg2(mark, count) // Save old mark, count
+ r.advance(2) // Straight
+ } else { // Nonempty match -> count+loop now
+ r.trackPush1(mark) // remember mark
+ r.stackPush2(r.textPos(), count+1) // Make new mark, incr count
+ r.goTo(r.operand(0)) // Loop
+ }
+ continue
+
+ case syntax.Branchcount | syntax.Back:
+ // r.trackPush:
+ // 0: Previous mark
+ // r.stackPush:
+ // 0: Mark (= current pos, discarded)
+ // 1: Count
+ r.trackPop()
+ r.stackPopN(2)
+ if r.stackPeekN(1) > 0 { // Positive -> can go straight
+ r.textto(r.stackPeek()) // Zap to mark
+ r.trackPushNeg2(r.trackPeek(), r.stackPeekN(1)-1) // Save old mark, old count
+ r.advance(2) // Straight
+ continue
+ }
+ r.stackPush2(r.trackPeek(), r.stackPeekN(1)-1) // recall old mark, old count
+ break
+
+ case syntax.Branchcount | syntax.Back2:
+ // r.trackPush:
+ // 0: Previous mark
+ // 1: Previous count
+ r.trackPopN(2)
+ r.stackPush2(r.trackPeek(), r.trackPeekN(1)) // Recall old mark, old count
+ break // Backtrack
+
+ case syntax.Lazybranchcount:
+ // r.stackPush:
+ // 0: Mark
+ // 1: Count
+
+ r.stackPopN(2)
+ mark := r.stackPeek()
+ count := r.stackPeekN(1)
+
+ if count < 0 { // Negative count -> loop now
+ r.trackPushNeg1(mark) // Save old mark
+ r.stackPush2(r.textPos(), count+1) // Make new mark, incr count
+ r.goTo(r.operand(0)) // Loop
+ } else { // Nonneg count -> straight now
+ r.trackPush3(mark, count, r.textPos()) // Save mark, count, position
+ r.advance(2) // Straight
+ }
+ continue
+
+ case syntax.Lazybranchcount | syntax.Back:
+ // r.trackPush:
+ // 0: Mark
+ // 1: Count
+ // 2: r.textPos
+
+ r.trackPopN(3)
+ mark := r.trackPeek()
+ textpos := r.trackPeekN(2)
+
+ if r.trackPeekN(1) < r.operand(1) && textpos != mark { // Under limit and not empty match -> loop
+ r.textto(textpos) // Recall position
+ r.stackPush2(textpos, r.trackPeekN(1)+1) // Make new mark, incr count
+ r.trackPushNeg1(mark) // Save old mark
+ r.goTo(r.operand(0)) // Loop
+ continue
+ } else { // Max loops or empty match -> backtrack
+ r.stackPush2(r.trackPeek(), r.trackPeekN(1)) // Recall old mark, count
+ break // backtrack
+ }
+
+ case syntax.Lazybranchcount | syntax.Back2:
+ // r.trackPush:
+ // 0: Previous mark
+ // r.stackPush:
+ // 0: Mark (== current pos, discarded)
+ // 1: Count
+ r.trackPop()
+ r.stackPopN(2)
+ r.stackPush2(r.trackPeek(), r.stackPeekN(1)-1) // Recall old mark, count
+ break // Backtrack
+
+ case syntax.Setjump:
+ r.stackPush2(r.trackpos(), r.crawlpos())
+ r.trackPush()
+ r.advance(0)
+ continue
+
+ case syntax.Setjump | syntax.Back:
+ r.stackPopN(2)
+ break
+
+ case syntax.Backjump:
+ // r.stackPush:
+ // 0: Saved trackpos
+ // 1: r.crawlpos
+ r.stackPopN(2)
+ r.trackto(r.stackPeek())
+
+ for r.crawlpos() != r.stackPeekN(1) {
+ r.uncapture()
+ }
+
+ break
+
+ case syntax.Forejump:
+ // r.stackPush:
+ // 0: Saved trackpos
+ // 1: r.crawlpos
+ r.stackPopN(2)
+ r.trackto(r.stackPeek())
+ r.trackPush1(r.stackPeekN(1))
+ r.advance(0)
+ continue
+
+ case syntax.Forejump | syntax.Back:
+ // r.trackPush:
+ // 0: r.crawlpos
+ r.trackPop()
+
+ for r.crawlpos() != r.trackPeek() {
+ r.uncapture()
+ }
+
+ break
+
+ case syntax.Bol:
+ if r.leftchars() > 0 && r.charAt(r.textPos()-1) != '\n' {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.Eol:
+ if r.rightchars() > 0 && r.charAt(r.textPos()) != '\n' {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.Boundary:
+ if !r.isBoundary(r.textPos(), 0, r.runtextend) {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.Nonboundary:
+ if r.isBoundary(r.textPos(), 0, r.runtextend) {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.ECMABoundary:
+ if !r.isECMABoundary(r.textPos(), 0, r.runtextend) {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.NonECMABoundary:
+ if r.isECMABoundary(r.textPos(), 0, r.runtextend) {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.Beginning:
+ if r.leftchars() > 0 {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.Start:
+ if r.textPos() != r.textstart() {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.EndZ:
+ rchars := r.rightchars()
+ if rchars > 1 {
+ break
+ }
+ // RE2 and EcmaScript define $ as "asserts position at the end of the string"
+ // PCRE/.NET adds "or before the line terminator right at the end of the string (if any)"
+ if (r.re.options & (RE2 | ECMAScript)) != 0 {
+ // RE2/Ecmascript mode
+ if rchars > 0 {
+ break
+ }
+ } else if rchars == 1 && r.charAt(r.textPos()) != '\n' {
+ // "regular" mode
+ break
+ }
+
+ r.advance(0)
+ continue
+
+ case syntax.End:
+ if r.rightchars() > 0 {
+ break
+ }
+ r.advance(0)
+ continue
+
+ case syntax.One:
+ if r.forwardchars() < 1 || r.forwardcharnext() != rune(r.operand(0)) {
+ break
+ }
+
+ r.advance(1)
+ continue
+
+ case syntax.Notone:
+ if r.forwardchars() < 1 || r.forwardcharnext() == rune(r.operand(0)) {
+ break
+ }
+
+ r.advance(1)
+ continue
+
+ case syntax.Set:
+
+ if r.forwardchars() < 1 || !r.code.Sets[r.operand(0)].CharIn(r.forwardcharnext()) {
+ break
+ }
+
+ r.advance(1)
+ continue
+
+ case syntax.Multi:
+ if !r.runematch(r.code.Strings[r.operand(0)]) {
+ break
+ }
+
+ r.advance(1)
+ continue
+
+ case syntax.Ref:
+
+ capnum := r.operand(0)
+
+ if r.runmatch.isMatched(capnum) {
+ if !r.refmatch(r.runmatch.matchIndex(capnum), r.runmatch.matchLength(capnum)) {
+ break
+ }
+ } else {
+ if (r.re.options & ECMAScript) == 0 {
+ break
+ }
+ }
+
+ r.advance(1)
+ continue
+
+ case syntax.Onerep:
+
+ c := r.operand(1)
+
+ if r.forwardchars() < c {
+ break
+ }
+
+ ch := rune(r.operand(0))
+
+ for c > 0 {
+ if r.forwardcharnext() != ch {
+ goto BreakBackward
+ }
+ c--
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Notonerep:
+
+ c := r.operand(1)
+
+ if r.forwardchars() < c {
+ break
+ }
+ ch := rune(r.operand(0))
+
+ for c > 0 {
+ if r.forwardcharnext() == ch {
+ goto BreakBackward
+ }
+ c--
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Setrep:
+
+ c := r.operand(1)
+
+ if r.forwardchars() < c {
+ break
+ }
+
+ set := r.code.Sets[r.operand(0)]
+
+ for c > 0 {
+ if !set.CharIn(r.forwardcharnext()) {
+ goto BreakBackward
+ }
+ c--
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Oneloop:
+
+ c := r.operand(1)
+
+ if c > r.forwardchars() {
+ c = r.forwardchars()
+ }
+
+ ch := rune(r.operand(0))
+ i := c
+
+ for ; i > 0; i-- {
+ if r.forwardcharnext() != ch {
+ r.backwardnext()
+ break
+ }
+ }
+
+ if c > i {
+ r.trackPush2(c-i-1, r.textPos()-r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Notoneloop:
+
+ c := r.operand(1)
+
+ if c > r.forwardchars() {
+ c = r.forwardchars()
+ }
+
+ ch := rune(r.operand(0))
+ i := c
+
+ for ; i > 0; i-- {
+ if r.forwardcharnext() == ch {
+ r.backwardnext()
+ break
+ }
+ }
+
+ if c > i {
+ r.trackPush2(c-i-1, r.textPos()-r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Setloop:
+
+ c := r.operand(1)
+
+ if c > r.forwardchars() {
+ c = r.forwardchars()
+ }
+
+ set := r.code.Sets[r.operand(0)]
+ i := c
+
+ for ; i > 0; i-- {
+ if !set.CharIn(r.forwardcharnext()) {
+ r.backwardnext()
+ break
+ }
+ }
+
+ if c > i {
+ r.trackPush2(c-i-1, r.textPos()-r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Oneloop | syntax.Back, syntax.Notoneloop | syntax.Back:
+
+ r.trackPopN(2)
+ i := r.trackPeek()
+ pos := r.trackPeekN(1)
+
+ r.textto(pos)
+
+ if i > 0 {
+ r.trackPush2(i-1, pos-r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Setloop | syntax.Back:
+
+ r.trackPopN(2)
+ i := r.trackPeek()
+ pos := r.trackPeekN(1)
+
+ r.textto(pos)
+
+ if i > 0 {
+ r.trackPush2(i-1, pos-r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Onelazy, syntax.Notonelazy:
+
+ c := r.operand(1)
+
+ if c > r.forwardchars() {
+ c = r.forwardchars()
+ }
+
+ if c > 0 {
+ r.trackPush2(c-1, r.textPos())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Setlazy:
+
+ c := r.operand(1)
+
+ if c > r.forwardchars() {
+ c = r.forwardchars()
+ }
+
+ if c > 0 {
+ r.trackPush2(c-1, r.textPos())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Onelazy | syntax.Back:
+
+ r.trackPopN(2)
+ pos := r.trackPeekN(1)
+ r.textto(pos)
+
+ if r.forwardcharnext() != rune(r.operand(0)) {
+ break
+ }
+
+ i := r.trackPeek()
+
+ if i > 0 {
+ r.trackPush2(i-1, pos+r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Notonelazy | syntax.Back:
+
+ r.trackPopN(2)
+ pos := r.trackPeekN(1)
+ r.textto(pos)
+
+ if r.forwardcharnext() == rune(r.operand(0)) {
+ break
+ }
+
+ i := r.trackPeek()
+
+ if i > 0 {
+ r.trackPush2(i-1, pos+r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ case syntax.Setlazy | syntax.Back:
+
+ r.trackPopN(2)
+ pos := r.trackPeekN(1)
+ r.textto(pos)
+
+ if !r.code.Sets[r.operand(0)].CharIn(r.forwardcharnext()) {
+ break
+ }
+
+ i := r.trackPeek()
+
+ if i > 0 {
+ r.trackPush2(i-1, pos+r.bump())
+ }
+
+ r.advance(2)
+ continue
+
+ default:
+ return errors.New("unknown state in regex runner")
+ }
+
+ BreakBackward:
+ ;
+
+ // "break Backward" comes here:
+ r.backtrack()
+ }
+}
+
+// increase the size of stack and track storage
+func (r *runner) ensureStorage() {
+ if r.runstackpos < r.runtrackcount*4 {
+ doubleIntSlice(&r.runstack, &r.runstackpos)
+ }
+ if r.runtrackpos < r.runtrackcount*4 {
+ doubleIntSlice(&r.runtrack, &r.runtrackpos)
+ }
+}
+
+func doubleIntSlice(s *[]int, pos *int) {
+ oldLen := len(*s)
+ newS := make([]int, oldLen*2)
+
+ copy(newS[oldLen:], *s)
+ *pos += oldLen
+ *s = newS
+}
+
+// Save a number on the longjump unrolling stack
+func (r *runner) crawl(i int) {
+ if r.runcrawlpos == 0 {
+ doubleIntSlice(&r.runcrawl, &r.runcrawlpos)
+ }
+ r.runcrawlpos--
+ r.runcrawl[r.runcrawlpos] = i
+}
+
+// Remove a number from the longjump unrolling stack
+func (r *runner) popcrawl() int {
+ val := r.runcrawl[r.runcrawlpos]
+ r.runcrawlpos++
+ return val
+}
+
+// Get the height of the stack
+func (r *runner) crawlpos() int {
+ return len(r.runcrawl) - r.runcrawlpos
+}
+
+func (r *runner) advance(i int) {
+ r.codepos += (i + 1)
+ r.setOperator(r.code.Codes[r.codepos])
+}
+
+func (r *runner) goTo(newpos int) {
+ // when branching backward or in place, ensure storage
+ if newpos <= r.codepos {
+ r.ensureStorage()
+ }
+
+ r.setOperator(r.code.Codes[newpos])
+ r.codepos = newpos
+}
+
+func (r *runner) textto(newpos int) {
+ r.runtextpos = newpos
+}
+
+func (r *runner) trackto(newpos int) {
+ r.runtrackpos = len(r.runtrack) - newpos
+}
+
+func (r *runner) textstart() int {
+ return r.runtextstart
+}
+
+func (r *runner) textPos() int {
+ return r.runtextpos
+}
+
+// push onto the backtracking stack
+func (r *runner) trackpos() int {
+ return len(r.runtrack) - r.runtrackpos
+}
+
+func (r *runner) trackPush() {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = r.codepos
+}
+
+func (r *runner) trackPush1(I1 int) {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I1
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = r.codepos
+}
+
+func (r *runner) trackPush2(I1, I2 int) {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I1
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I2
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = r.codepos
+}
+
+func (r *runner) trackPush3(I1, I2, I3 int) {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I1
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I2
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I3
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = r.codepos
+}
+
+func (r *runner) trackPushNeg1(I1 int) {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I1
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = -r.codepos
+}
+
+func (r *runner) trackPushNeg2(I1, I2 int) {
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I1
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = I2
+ r.runtrackpos--
+ r.runtrack[r.runtrackpos] = -r.codepos
+}
+
+func (r *runner) backtrack() {
+ newpos := r.runtrack[r.runtrackpos]
+ r.runtrackpos++
+
+ if r.re.Debug() {
+ if newpos < 0 {
+ fmt.Printf(" Backtracking (back2) to code position %v\n", -newpos)
+ } else {
+ fmt.Printf(" Backtracking to code position %v\n", newpos)
+ }
+ }
+
+ if newpos < 0 {
+ newpos = -newpos
+ r.setOperator(r.code.Codes[newpos] | syntax.Back2)
+ } else {
+ r.setOperator(r.code.Codes[newpos] | syntax.Back)
+ }
+
+ // When branching backward, ensure storage
+ if newpos < r.codepos {
+ r.ensureStorage()
+ }
+
+ r.codepos = newpos
+}
+
+func (r *runner) setOperator(op int) {
+ r.caseInsensitive = (0 != (op & syntax.Ci))
+ r.rightToLeft = (0 != (op & syntax.Rtl))
+ r.operator = syntax.InstOp(op & ^(syntax.Rtl | syntax.Ci))
+}
+
+func (r *runner) trackPop() {
+ r.runtrackpos++
+}
+
+// pop framesize items from the backtracking stack
+func (r *runner) trackPopN(framesize int) {
+ r.runtrackpos += framesize
+}
+
+// Technically we are actually peeking at items already popped. So if you want to
+// get and pop the top item from the stack, you do
+// r.trackPop();
+// r.trackPeek();
+func (r *runner) trackPeek() int {
+ return r.runtrack[r.runtrackpos-1]
+}
+
+// get the ith element down on the backtracking stack
+func (r *runner) trackPeekN(i int) int {
+ return r.runtrack[r.runtrackpos-i-1]
+}
+
+// Push onto the grouping stack
+func (r *runner) stackPush(I1 int) {
+ r.runstackpos--
+ r.runstack[r.runstackpos] = I1
+}
+
+func (r *runner) stackPush2(I1, I2 int) {
+ r.runstackpos--
+ r.runstack[r.runstackpos] = I1
+ r.runstackpos--
+ r.runstack[r.runstackpos] = I2
+}
+
+func (r *runner) stackPop() {
+ r.runstackpos++
+}
+
+// pop framesize items from the grouping stack
+func (r *runner) stackPopN(framesize int) {
+ r.runstackpos += framesize
+}
+
+// Technically we are actually peeking at items already popped. So if you want to
+// get and pop the top item from the stack, you do
+// r.stackPop();
+// r.stackPeek();
+func (r *runner) stackPeek() int {
+ return r.runstack[r.runstackpos-1]
+}
+
+// get the ith element down on the grouping stack
+func (r *runner) stackPeekN(i int) int {
+ return r.runstack[r.runstackpos-i-1]
+}
+
+func (r *runner) operand(i int) int {
+ return r.code.Codes[r.codepos+i+1]
+}
+
+func (r *runner) leftchars() int {
+ return r.runtextpos
+}
+
+func (r *runner) rightchars() int {
+ return r.runtextend - r.runtextpos
+}
+
+func (r *runner) bump() int {
+ if r.rightToLeft {
+ return -1
+ }
+ return 1
+}
+
+func (r *runner) forwardchars() int {
+ if r.rightToLeft {
+ return r.runtextpos
+ }
+ return r.runtextend - r.runtextpos
+}
+
+func (r *runner) forwardcharnext() rune {
+ var ch rune
+ if r.rightToLeft {
+ r.runtextpos--
+ ch = r.runtext[r.runtextpos]
+ } else {
+ ch = r.runtext[r.runtextpos]
+ r.runtextpos++
+ }
+
+ if r.caseInsensitive {
+ return unicode.ToLower(ch)
+ }
+ return ch
+}
+
+func (r *runner) runematch(str []rune) bool {
+ var pos int
+
+ c := len(str)
+ if !r.rightToLeft {
+ if r.runtextend-r.runtextpos < c {
+ return false
+ }
+
+ pos = r.runtextpos + c
+ } else {
+ if r.runtextpos-0 < c {
+ return false
+ }
+
+ pos = r.runtextpos
+ }
+
+ if !r.caseInsensitive {
+ for c != 0 {
+ c--
+ pos--
+ if str[c] != r.runtext[pos] {
+ return false
+ }
+ }
+ } else {
+ for c != 0 {
+ c--
+ pos--
+ if str[c] != unicode.ToLower(r.runtext[pos]) {
+ return false
+ }
+ }
+ }
+
+ if !r.rightToLeft {
+ pos += len(str)
+ }
+
+ r.runtextpos = pos
+
+ return true
+}
+
+func (r *runner) refmatch(index, len int) bool {
+ var c, pos, cmpos int
+
+ if !r.rightToLeft {
+ if r.runtextend-r.runtextpos < len {
+ return false
+ }
+
+ pos = r.runtextpos + len
+ } else {
+ if r.runtextpos-0 < len {
+ return false
+ }
+
+ pos = r.runtextpos
+ }
+ cmpos = index + len
+
+ c = len
+
+ if !r.caseInsensitive {
+ for c != 0 {
+ c--
+ cmpos--
+ pos--
+ if r.runtext[cmpos] != r.runtext[pos] {
+ return false
+ }
+
+ }
+ } else {
+ for c != 0 {
+ c--
+ cmpos--
+ pos--
+
+ if unicode.ToLower(r.runtext[cmpos]) != unicode.ToLower(r.runtext[pos]) {
+ return false
+ }
+ }
+ }
+
+ if !r.rightToLeft {
+ pos += len
+ }
+
+ r.runtextpos = pos
+
+ return true
+}
+
+func (r *runner) backwardnext() {
+ if r.rightToLeft {
+ r.runtextpos++
+ } else {
+ r.runtextpos--
+ }
+}
+
+func (r *runner) charAt(j int) rune {
+ return r.runtext[j]
+}
+
+func (r *runner) findFirstChar() bool {
+
+ if 0 != (r.code.Anchors & (syntax.AnchorBeginning | syntax.AnchorStart | syntax.AnchorEndZ | syntax.AnchorEnd)) {
+ if !r.code.RightToLeft {
+ if (0 != (r.code.Anchors&syntax.AnchorBeginning) && r.runtextpos > 0) ||
+ (0 != (r.code.Anchors&syntax.AnchorStart) && r.runtextpos > r.runtextstart) {
+ r.runtextpos = r.runtextend
+ return false
+ }
+ if 0 != (r.code.Anchors&syntax.AnchorEndZ) && r.runtextpos < r.runtextend-1 {
+ r.runtextpos = r.runtextend - 1
+ } else if 0 != (r.code.Anchors&syntax.AnchorEnd) && r.runtextpos < r.runtextend {
+ r.runtextpos = r.runtextend
+ }
+ } else {
+ if (0 != (r.code.Anchors&syntax.AnchorEnd) && r.runtextpos < r.runtextend) ||
+ (0 != (r.code.Anchors&syntax.AnchorEndZ) && (r.runtextpos < r.runtextend-1 ||
+ (r.runtextpos == r.runtextend-1 && r.charAt(r.runtextpos) != '\n'))) ||
+ (0 != (r.code.Anchors&syntax.AnchorStart) && r.runtextpos < r.runtextstart) {
+ r.runtextpos = 0
+ return false
+ }
+ if 0 != (r.code.Anchors&syntax.AnchorBeginning) && r.runtextpos > 0 {
+ r.runtextpos = 0
+ }
+ }
+
+ if r.code.BmPrefix != nil {
+ return r.code.BmPrefix.IsMatch(r.runtext, r.runtextpos, 0, r.runtextend)
+ }
+
+ return true // found a valid start or end anchor
+ } else if r.code.BmPrefix != nil {
+ r.runtextpos = r.code.BmPrefix.Scan(r.runtext, r.runtextpos, 0, r.runtextend)
+
+ if r.runtextpos == -1 {
+ if r.code.RightToLeft {
+ r.runtextpos = 0
+ } else {
+ r.runtextpos = r.runtextend
+ }
+ return false
+ }
+
+ return true
+ } else if r.code.FcPrefix == nil {
+ return true
+ }
+
+ r.rightToLeft = r.code.RightToLeft
+ r.caseInsensitive = r.code.FcPrefix.CaseInsensitive
+
+ set := r.code.FcPrefix.PrefixSet
+ if set.IsSingleton() {
+ ch := set.SingletonChar()
+ for i := r.forwardchars(); i > 0; i-- {
+ if ch == r.forwardcharnext() {
+ r.backwardnext()
+ return true
+ }
+ }
+ } else {
+ for i := r.forwardchars(); i > 0; i-- {
+ n := r.forwardcharnext()
+ //fmt.Printf("%v in %v: %v\n", string(n), set.String(), set.CharIn(n))
+ if set.CharIn(n) {
+ r.backwardnext()
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+func (r *runner) initMatch() {
+ // Use a hashtable'ed Match object if the capture numbers are sparse
+
+ if r.runmatch == nil {
+ if r.re.caps != nil {
+ r.runmatch = newMatchSparse(r.re, r.re.caps, r.re.capsize, r.runtext, r.runtextstart)
+ } else {
+ r.runmatch = newMatch(r.re, r.re.capsize, r.runtext, r.runtextstart)
+ }
+ } else {
+ r.runmatch.reset(r.runtext, r.runtextstart)
+ }
+
+ // note we test runcrawl, because it is the last one to be allocated
+ // If there is an alloc failure in the middle of the three allocations,
+ // we may still return to reuse this instance, and we want to behave
+ // as if the allocations didn't occur. (we used to test _trackcount != 0)
+
+ if r.runcrawl != nil {
+ r.runtrackpos = len(r.runtrack)
+ r.runstackpos = len(r.runstack)
+ r.runcrawlpos = len(r.runcrawl)
+ return
+ }
+
+ r.initTrackCount()
+
+ tracksize := r.runtrackcount * 8
+ stacksize := r.runtrackcount * 8
+
+ if tracksize < 32 {
+ tracksize = 32
+ }
+ if stacksize < 16 {
+ stacksize = 16
+ }
+
+ r.runtrack = make([]int, tracksize)
+ r.runtrackpos = tracksize
+
+ r.runstack = make([]int, stacksize)
+ r.runstackpos = stacksize
+
+ r.runcrawl = make([]int, 32)
+ r.runcrawlpos = 32
+}
+
+func (r *runner) tidyMatch(quick bool) *Match {
+ if !quick {
+ match := r.runmatch
+
+ r.runmatch = nil
+
+ match.tidy(r.runtextpos)
+ return match
+ } else {
+ // send back our match -- it's not leaving the package, so it's safe to not clean it up
+ // this reduces allocs for frequent calls to the "IsMatch" bool-only functions
+ return r.runmatch
+ }
+}
+
+// capture captures a subexpression. Note that the
+// capnum used here has already been mapped to a non-sparse
+// index (by the code generator RegexWriter).
+func (r *runner) capture(capnum, start, end int) {
+ if end < start {
+ T := end
+ end = start
+ start = T
+ }
+
+ r.crawl(capnum)
+ r.runmatch.addMatch(capnum, start, end-start)
+}
+
+// transferCapture captures a subexpression. Note that the
+// capnum used here has already been mapped to a non-sparse
+// index (by the code generator RegexWriter).
+func (r *runner) transferCapture(capnum, uncapnum, start, end int) {
+ var start2, end2 int
+
+ // these are the two intervals that are cancelling each other
+
+ if end < start {
+ T := end
+ end = start
+ start = T
+ }
+
+ start2 = r.runmatch.matchIndex(uncapnum)
+ end2 = start2 + r.runmatch.matchLength(uncapnum)
+
+ // The new capture gets the innermost defined interval
+
+ if start >= end2 {
+ end = start
+ start = end2
+ } else if end <= start2 {
+ start = start2
+ } else {
+ if end > end2 {
+ end = end2
+ }
+ if start2 > start {
+ start = start2
+ }
+ }
+
+ r.crawl(uncapnum)
+ r.runmatch.balanceMatch(uncapnum)
+
+ if capnum != -1 {
+ r.crawl(capnum)
+ r.runmatch.addMatch(capnum, start, end-start)
+ }
+}
+
+// revert the last capture
+func (r *runner) uncapture() {
+ capnum := r.popcrawl()
+ r.runmatch.removeMatch(capnum)
+}
+
+//debug
+
+func (r *runner) dumpState() {
+ back := ""
+ if r.operator&syntax.Back != 0 {
+ back = " Back"
+ }
+ if r.operator&syntax.Back2 != 0 {
+ back += " Back2"
+ }
+ fmt.Printf("Text: %v\nTrack: %v\nStack: %v\n %s%s\n\n",
+ r.textposDescription(),
+ r.stackDescription(r.runtrack, r.runtrackpos),
+ r.stackDescription(r.runstack, r.runstackpos),
+ r.code.OpcodeDescription(r.codepos),
+ back)
+}
+
+func (r *runner) stackDescription(a []int, index int) string {
+ buf := &bytes.Buffer{}
+
+ fmt.Fprintf(buf, "%v/%v", len(a)-index, len(a))
+ if buf.Len() < 8 {
+ buf.WriteString(strings.Repeat(" ", 8-buf.Len()))
+ }
+
+ buf.WriteRune('(')
+ for i := index; i < len(a); i++ {
+ if i > index {
+ buf.WriteRune(' ')
+ }
+
+ buf.WriteString(strconv.Itoa(a[i]))
+ }
+
+ buf.WriteRune(')')
+
+ return buf.String()
+}
+
+func (r *runner) textposDescription() string {
+ buf := &bytes.Buffer{}
+
+ buf.WriteString(strconv.Itoa(r.runtextpos))
+
+ if buf.Len() < 8 {
+ buf.WriteString(strings.Repeat(" ", 8-buf.Len()))
+ }
+
+ if r.runtextpos > 0 {
+ buf.WriteString(syntax.CharDescription(r.runtext[r.runtextpos-1]))
+ } else {
+ buf.WriteRune('^')
+ }
+
+ buf.WriteRune('>')
+
+ for i := r.runtextpos; i < r.runtextend; i++ {
+ buf.WriteString(syntax.CharDescription(r.runtext[i]))
+ }
+ if buf.Len() >= 64 {
+ buf.Truncate(61)
+ buf.WriteString("...")
+ } else {
+ buf.WriteRune('$')
+ }
+
+ return buf.String()
+}
+
+// decide whether the pos
+// at the specified index is a boundary or not. It's just not worth
+// emitting inline code for this logic.
+func (r *runner) isBoundary(index, startpos, endpos int) bool {
+ return (index > startpos && syntax.IsWordChar(r.runtext[index-1])) !=
+ (index < endpos && syntax.IsWordChar(r.runtext[index]))
+}
+
+func (r *runner) isECMABoundary(index, startpos, endpos int) bool {
+ return (index > startpos && syntax.IsECMAWordChar(r.runtext[index-1])) !=
+ (index < endpos && syntax.IsECMAWordChar(r.runtext[index]))
+}
+
+func (r *runner) startTimeoutWatch() {
+ if r.ignoreTimeout {
+ return
+ }
+ r.deadline = makeDeadline(r.timeout)
+}
+
+func (r *runner) checkTimeout() error {
+ if r.ignoreTimeout || !r.deadline.reached() {
+ return nil
+ }
+
+ if r.re.Debug() {
+ //Debug.WriteLine("")
+ //Debug.WriteLine("RegEx match timeout occurred!")
+ //Debug.WriteLine("Specified timeout: " + TimeSpan.FromMilliseconds(_timeout).ToString())
+ //Debug.WriteLine("Timeout check frequency: " + TimeoutCheckFrequency)
+ //Debug.WriteLine("Search pattern: " + _runregex._pattern)
+ //Debug.WriteLine("Input: " + r.runtext)
+ //Debug.WriteLine("About to throw RegexMatchTimeoutException.")
+ }
+
+ return fmt.Errorf("match timeout after %v on input `%v`", r.timeout, string(r.runtext))
+}
+
+func (r *runner) initTrackCount() {
+ r.runtrackcount = r.code.TrackCount
+}
+
+// getRunner returns a run to use for matching re.
+// It uses the re's runner cache if possible, to avoid
+// unnecessary allocation.
+func (re *Regexp) getRunner() *runner {
+ re.muRun.Lock()
+ if n := len(re.runner); n > 0 {
+ z := re.runner[n-1]
+ re.runner = re.runner[:n-1]
+ re.muRun.Unlock()
+ return z
+ }
+ re.muRun.Unlock()
+ z := &runner{
+ re: re,
+ code: re.code,
+ }
+ return z
+}
+
+// putRunner returns a runner to the re's cache.
+// There is no attempt to limit the size of the cache, so it will
+// grow to the maximum number of simultaneous matches
+// run using re. (The cache empties when re gets garbage collected.)
+func (re *Regexp) putRunner(r *runner) {
+ re.muRun.Lock()
+ r.runtext = nil
+ if r.runmatch != nil {
+ r.runmatch.text = nil
+ }
+ re.runner = append(re.runner, r)
+ re.muRun.Unlock()
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/charclass.go b/vendor/github.com/dlclark/regexp2/syntax/charclass.go
new file mode 100644
index 00000000..6881a0e2
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/charclass.go
@@ -0,0 +1,865 @@
+package syntax
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "sort"
+ "unicode"
+ "unicode/utf8"
+)
+
+// CharSet combines start-end rune ranges and unicode categories representing a set of characters
+type CharSet struct {
+ ranges []singleRange
+ categories []category
+ sub *CharSet //optional subtractor
+ negate bool
+ anything bool
+}
+
+type category struct {
+ negate bool
+ cat string
+}
+
+type singleRange struct {
+ first rune
+ last rune
+}
+
+const (
+ spaceCategoryText = " "
+ wordCategoryText = "W"
+)
+
+var (
+ ecmaSpace = []rune{0x0009, 0x000e, 0x0020, 0x0021, 0x00a0, 0x00a1, 0x1680, 0x1681, 0x2000, 0x200b, 0x2028, 0x202a, 0x202f, 0x2030, 0x205f, 0x2060, 0x3000, 0x3001, 0xfeff, 0xff00}
+ ecmaWord = []rune{0x0030, 0x003a, 0x0041, 0x005b, 0x005f, 0x0060, 0x0061, 0x007b}
+ ecmaDigit = []rune{0x0030, 0x003a}
+
+ re2Space = []rune{0x0009, 0x000b, 0x000c, 0x000e, 0x0020, 0x0021}
+)
+
+var (
+ AnyClass = getCharSetFromOldString([]rune{0}, false)
+ ECMAAnyClass = getCharSetFromOldString([]rune{0, 0x000a, 0x000b, 0x000d, 0x000e}, false)
+ NoneClass = getCharSetFromOldString(nil, false)
+ ECMAWordClass = getCharSetFromOldString(ecmaWord, false)
+ NotECMAWordClass = getCharSetFromOldString(ecmaWord, true)
+ ECMASpaceClass = getCharSetFromOldString(ecmaSpace, false)
+ NotECMASpaceClass = getCharSetFromOldString(ecmaSpace, true)
+ ECMADigitClass = getCharSetFromOldString(ecmaDigit, false)
+ NotECMADigitClass = getCharSetFromOldString(ecmaDigit, true)
+
+ WordClass = getCharSetFromCategoryString(false, false, wordCategoryText)
+ NotWordClass = getCharSetFromCategoryString(true, false, wordCategoryText)
+ SpaceClass = getCharSetFromCategoryString(false, false, spaceCategoryText)
+ NotSpaceClass = getCharSetFromCategoryString(true, false, spaceCategoryText)
+ DigitClass = getCharSetFromCategoryString(false, false, "Nd")
+ NotDigitClass = getCharSetFromCategoryString(false, true, "Nd")
+
+ RE2SpaceClass = getCharSetFromOldString(re2Space, false)
+ NotRE2SpaceClass = getCharSetFromOldString(re2Space, true)
+)
+
+var unicodeCategories = func() map[string]*unicode.RangeTable {
+ retVal := make(map[string]*unicode.RangeTable)
+ for k, v := range unicode.Scripts {
+ retVal[k] = v
+ }
+ for k, v := range unicode.Categories {
+ retVal[k] = v
+ }
+ for k, v := range unicode.Properties {
+ retVal[k] = v
+ }
+ return retVal
+}()
+
+func getCharSetFromCategoryString(negateSet bool, negateCat bool, cats ...string) func() *CharSet {
+ if negateCat && negateSet {
+ panic("BUG! You should only negate the set OR the category in a constant setup, but not both")
+ }
+
+ c := CharSet{negate: negateSet}
+
+ c.categories = make([]category, len(cats))
+ for i, cat := range cats {
+ c.categories[i] = category{cat: cat, negate: negateCat}
+ }
+ return func() *CharSet {
+ //make a copy each time
+ local := c
+ //return that address
+ return &local
+ }
+}
+
+func getCharSetFromOldString(setText []rune, negate bool) func() *CharSet {
+ c := CharSet{}
+ if len(setText) > 0 {
+ fillFirst := false
+ l := len(setText)
+ if negate {
+ if setText[0] == 0 {
+ setText = setText[1:]
+ } else {
+ l++
+ fillFirst = true
+ }
+ }
+
+ if l%2 == 0 {
+ c.ranges = make([]singleRange, l/2)
+ } else {
+ c.ranges = make([]singleRange, l/2+1)
+ }
+
+ first := true
+ if fillFirst {
+ c.ranges[0] = singleRange{first: 0}
+ first = false
+ }
+
+ i := 0
+ for _, r := range setText {
+ if first {
+ // lower bound in a new range
+ c.ranges[i] = singleRange{first: r}
+ first = false
+ } else {
+ c.ranges[i].last = r - 1
+ i++
+ first = true
+ }
+ }
+ if !first {
+ c.ranges[i].last = utf8.MaxRune
+ }
+ }
+
+ return func() *CharSet {
+ local := c
+ return &local
+ }
+}
+
+// Copy makes a deep copy to prevent accidental mutation of a set
+func (c CharSet) Copy() CharSet {
+ ret := CharSet{
+ anything: c.anything,
+ negate: c.negate,
+ }
+
+ ret.ranges = append(ret.ranges, c.ranges...)
+ ret.categories = append(ret.categories, c.categories...)
+
+ if c.sub != nil {
+ sub := c.sub.Copy()
+ ret.sub = &sub
+ }
+
+ return ret
+}
+
+// gets a human-readable description for a set string
+func (c CharSet) String() string {
+ buf := &bytes.Buffer{}
+ buf.WriteRune('[')
+
+ if c.IsNegated() {
+ buf.WriteRune('^')
+ }
+
+ for _, r := range c.ranges {
+
+ buf.WriteString(CharDescription(r.first))
+ if r.first != r.last {
+ if r.last-r.first != 1 {
+ //groups that are 1 char apart skip the dash
+ buf.WriteRune('-')
+ }
+ buf.WriteString(CharDescription(r.last))
+ }
+ }
+
+ for _, c := range c.categories {
+ buf.WriteString(c.String())
+ }
+
+ if c.sub != nil {
+ buf.WriteRune('-')
+ buf.WriteString(c.sub.String())
+ }
+
+ buf.WriteRune(']')
+
+ return buf.String()
+}
+
+// mapHashFill converts a charset into a buffer for use in maps
+func (c CharSet) mapHashFill(buf *bytes.Buffer) {
+ if c.negate {
+ buf.WriteByte(0)
+ } else {
+ buf.WriteByte(1)
+ }
+
+ binary.Write(buf, binary.LittleEndian, len(c.ranges))
+ binary.Write(buf, binary.LittleEndian, len(c.categories))
+ for _, r := range c.ranges {
+ buf.WriteRune(r.first)
+ buf.WriteRune(r.last)
+ }
+ for _, ct := range c.categories {
+ buf.WriteString(ct.cat)
+ if ct.negate {
+ buf.WriteByte(1)
+ } else {
+ buf.WriteByte(0)
+ }
+ }
+
+ if c.sub != nil {
+ c.sub.mapHashFill(buf)
+ }
+}
+
+// CharIn returns true if the rune is in our character set (either ranges or categories).
+// It handles negations and subtracted sub-charsets.
+func (c CharSet) CharIn(ch rune) bool {
+ val := false
+ // in s && !s.subtracted
+
+ //check ranges
+ for _, r := range c.ranges {
+ if ch < r.first {
+ continue
+ }
+ if ch <= r.last {
+ val = true
+ break
+ }
+ }
+
+ //check categories if we haven't already found a range
+ if !val && len(c.categories) > 0 {
+ for _, ct := range c.categories {
+ // special categories...then unicode
+ if ct.cat == spaceCategoryText {
+ if unicode.IsSpace(ch) {
+ // we found a space so we're done
+ // negate means this is a "bad" thing
+ val = !ct.negate
+ break
+ } else if ct.negate {
+ val = true
+ break
+ }
+ } else if ct.cat == wordCategoryText {
+ if IsWordChar(ch) {
+ val = !ct.negate
+ break
+ } else if ct.negate {
+ val = true
+ break
+ }
+ } else if unicode.Is(unicodeCategories[ct.cat], ch) {
+ // if we're in this unicode category then we're done
+ // if negate=true on this category then we "failed" our test
+ // otherwise we're good that we found it
+ val = !ct.negate
+ break
+ } else if ct.negate {
+ val = true
+ break
+ }
+ }
+ }
+
+ // negate the whole char set
+ if c.negate {
+ val = !val
+ }
+
+ // get subtracted recurse
+ if val && c.sub != nil {
+ val = !c.sub.CharIn(ch)
+ }
+
+ //log.Printf("Char '%v' in %v == %v", string(ch), c.String(), val)
+ return val
+}
+
+func (c category) String() string {
+ switch c.cat {
+ case spaceCategoryText:
+ if c.negate {
+ return "\\S"
+ }
+ return "\\s"
+ case wordCategoryText:
+ if c.negate {
+ return "\\W"
+ }
+ return "\\w"
+ }
+ if _, ok := unicodeCategories[c.cat]; ok {
+
+ if c.negate {
+ return "\\P{" + c.cat + "}"
+ }
+ return "\\p{" + c.cat + "}"
+ }
+ return "Unknown category: " + c.cat
+}
+
+// CharDescription Produces a human-readable description for a single character.
+func CharDescription(ch rune) string {
+ /*if ch == '\\' {
+ return "\\\\"
+ }
+
+ if ch > ' ' && ch <= '~' {
+ return string(ch)
+ } else if ch == '\n' {
+ return "\\n"
+ } else if ch == ' ' {
+ return "\\ "
+ }*/
+
+ b := &bytes.Buffer{}
+ escape(b, ch, false) //fmt.Sprintf("%U", ch)
+ return b.String()
+}
+
+// According to UTS#18 Unicode Regular Expressions (http://www.unicode.org/reports/tr18/)
+// RL 1.4 Simple Word Boundaries The class of includes all Alphabetic
+// values from the Unicode character database, from UnicodeData.txt [UData], plus the U+200C
+// ZERO WIDTH NON-JOINER and U+200D ZERO WIDTH JOINER.
+func IsWordChar(r rune) bool {
+ //"L", "Mn", "Nd", "Pc"
+ return unicode.In(r,
+ unicode.Categories["L"], unicode.Categories["Mn"],
+ unicode.Categories["Nd"], unicode.Categories["Pc"]) || r == '\u200D' || r == '\u200C'
+ //return 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' || '0' <= r && r <= '9' || r == '_'
+}
+
+func IsECMAWordChar(r rune) bool {
+ return unicode.In(r,
+ unicode.Categories["L"], unicode.Categories["Mn"],
+ unicode.Categories["Nd"], unicode.Categories["Pc"])
+
+ //return 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' || '0' <= r && r <= '9' || r == '_'
+}
+
+// SingletonChar will return the char from the first range without validation.
+// It assumes you have checked for IsSingleton or IsSingletonInverse and will panic given bad input
+func (c CharSet) SingletonChar() rune {
+ return c.ranges[0].first
+}
+
+func (c CharSet) IsSingleton() bool {
+ return !c.negate && //negated is multiple chars
+ len(c.categories) == 0 && len(c.ranges) == 1 && // multiple ranges and unicode classes represent multiple chars
+ c.sub == nil && // subtraction means we've got multiple chars
+ c.ranges[0].first == c.ranges[0].last // first and last equal means we're just 1 char
+}
+
+func (c CharSet) IsSingletonInverse() bool {
+ return c.negate && //same as above, but requires negated
+ len(c.categories) == 0 && len(c.ranges) == 1 && // multiple ranges and unicode classes represent multiple chars
+ c.sub == nil && // subtraction means we've got multiple chars
+ c.ranges[0].first == c.ranges[0].last // first and last equal means we're just 1 char
+}
+
+func (c CharSet) IsMergeable() bool {
+ return !c.IsNegated() && !c.HasSubtraction()
+}
+
+func (c CharSet) IsNegated() bool {
+ return c.negate
+}
+
+func (c CharSet) HasSubtraction() bool {
+ return c.sub != nil
+}
+
+func (c CharSet) IsEmpty() bool {
+ return len(c.ranges) == 0 && len(c.categories) == 0 && c.sub == nil
+}
+
+func (c *CharSet) addDigit(ecma, negate bool, pattern string) {
+ if ecma {
+ if negate {
+ c.addRanges(NotECMADigitClass().ranges)
+ } else {
+ c.addRanges(ECMADigitClass().ranges)
+ }
+ } else {
+ c.addCategories(category{cat: "Nd", negate: negate})
+ }
+}
+
+func (c *CharSet) addChar(ch rune) {
+ c.addRange(ch, ch)
+}
+
+func (c *CharSet) addSpace(ecma, re2, negate bool) {
+ if ecma {
+ if negate {
+ c.addRanges(NotECMASpaceClass().ranges)
+ } else {
+ c.addRanges(ECMASpaceClass().ranges)
+ }
+ } else if re2 {
+ if negate {
+ c.addRanges(NotRE2SpaceClass().ranges)
+ } else {
+ c.addRanges(RE2SpaceClass().ranges)
+ }
+ } else {
+ c.addCategories(category{cat: spaceCategoryText, negate: negate})
+ }
+}
+
+func (c *CharSet) addWord(ecma, negate bool) {
+ if ecma {
+ if negate {
+ c.addRanges(NotECMAWordClass().ranges)
+ } else {
+ c.addRanges(ECMAWordClass().ranges)
+ }
+ } else {
+ c.addCategories(category{cat: wordCategoryText, negate: negate})
+ }
+}
+
+// Add set ranges and categories into ours -- no deduping or anything
+func (c *CharSet) addSet(set CharSet) {
+ if c.anything {
+ return
+ }
+ if set.anything {
+ c.makeAnything()
+ return
+ }
+ // just append here to prevent double-canon
+ c.ranges = append(c.ranges, set.ranges...)
+ c.addCategories(set.categories...)
+ c.canonicalize()
+}
+
+func (c *CharSet) makeAnything() {
+ c.anything = true
+ c.categories = []category{}
+ c.ranges = AnyClass().ranges
+}
+
+func (c *CharSet) addCategories(cats ...category) {
+ // don't add dupes and remove positive+negative
+ if c.anything {
+ // if we've had a previous positive+negative group then
+ // just return, we're as broad as we can get
+ return
+ }
+
+ for _, ct := range cats {
+ found := false
+ for _, ct2 := range c.categories {
+ if ct.cat == ct2.cat {
+ if ct.negate != ct2.negate {
+ // oposite negations...this mean we just
+ // take us as anything and move on
+ c.makeAnything()
+ return
+ }
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ c.categories = append(c.categories, ct)
+ }
+ }
+}
+
+// Merges new ranges to our own
+func (c *CharSet) addRanges(ranges []singleRange) {
+ if c.anything {
+ return
+ }
+ c.ranges = append(c.ranges, ranges...)
+ c.canonicalize()
+}
+
+// Merges everything but the new ranges into our own
+func (c *CharSet) addNegativeRanges(ranges []singleRange) {
+ if c.anything {
+ return
+ }
+
+ var hi rune
+
+ // convert incoming ranges into opposites, assume they are in order
+ for _, r := range ranges {
+ if hi < r.first {
+ c.ranges = append(c.ranges, singleRange{hi, r.first - 1})
+ }
+ hi = r.last + 1
+ }
+
+ if hi < utf8.MaxRune {
+ c.ranges = append(c.ranges, singleRange{hi, utf8.MaxRune})
+ }
+
+ c.canonicalize()
+}
+
+func isValidUnicodeCat(catName string) bool {
+ _, ok := unicodeCategories[catName]
+ return ok
+}
+
+func (c *CharSet) addCategory(categoryName string, negate, caseInsensitive bool, pattern string) {
+ if !isValidUnicodeCat(categoryName) {
+ // unknown unicode category, script, or property "blah"
+ panic(fmt.Errorf("Unknown unicode category, script, or property '%v'", categoryName))
+
+ }
+
+ if caseInsensitive && (categoryName == "Ll" || categoryName == "Lu" || categoryName == "Lt") {
+ // when RegexOptions.IgnoreCase is specified then {Ll} {Lu} and {Lt} cases should all match
+ c.addCategories(
+ category{cat: "Ll", negate: negate},
+ category{cat: "Lu", negate: negate},
+ category{cat: "Lt", negate: negate})
+ }
+ c.addCategories(category{cat: categoryName, negate: negate})
+}
+
+func (c *CharSet) addSubtraction(sub *CharSet) {
+ c.sub = sub
+}
+
+func (c *CharSet) addRange(chMin, chMax rune) {
+ c.ranges = append(c.ranges, singleRange{first: chMin, last: chMax})
+ c.canonicalize()
+}
+
+func (c *CharSet) addNamedASCII(name string, negate bool) bool {
+ var rs []singleRange
+
+ switch name {
+ case "alnum":
+ rs = []singleRange{singleRange{'0', '9'}, singleRange{'A', 'Z'}, singleRange{'a', 'z'}}
+ case "alpha":
+ rs = []singleRange{singleRange{'A', 'Z'}, singleRange{'a', 'z'}}
+ case "ascii":
+ rs = []singleRange{singleRange{0, 0x7f}}
+ case "blank":
+ rs = []singleRange{singleRange{'\t', '\t'}, singleRange{' ', ' '}}
+ case "cntrl":
+ rs = []singleRange{singleRange{0, 0x1f}, singleRange{0x7f, 0x7f}}
+ case "digit":
+ c.addDigit(false, negate, "")
+ case "graph":
+ rs = []singleRange{singleRange{'!', '~'}}
+ case "lower":
+ rs = []singleRange{singleRange{'a', 'z'}}
+ case "print":
+ rs = []singleRange{singleRange{' ', '~'}}
+ case "punct": //[!-/:-@[-`{-~]
+ rs = []singleRange{singleRange{'!', '/'}, singleRange{':', '@'}, singleRange{'[', '`'}, singleRange{'{', '~'}}
+ case "space":
+ c.addSpace(true, false, negate)
+ case "upper":
+ rs = []singleRange{singleRange{'A', 'Z'}}
+ case "word":
+ c.addWord(true, negate)
+ case "xdigit":
+ rs = []singleRange{singleRange{'0', '9'}, singleRange{'A', 'F'}, singleRange{'a', 'f'}}
+ default:
+ return false
+ }
+
+ if len(rs) > 0 {
+ if negate {
+ c.addNegativeRanges(rs)
+ } else {
+ c.addRanges(rs)
+ }
+ }
+
+ return true
+}
+
+type singleRangeSorter []singleRange
+
+func (p singleRangeSorter) Len() int { return len(p) }
+func (p singleRangeSorter) Less(i, j int) bool { return p[i].first < p[j].first }
+func (p singleRangeSorter) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+// Logic to reduce a character class to a unique, sorted form.
+func (c *CharSet) canonicalize() {
+ var i, j int
+ var last rune
+
+ //
+ // Find and eliminate overlapping or abutting ranges
+ //
+
+ if len(c.ranges) > 1 {
+ sort.Sort(singleRangeSorter(c.ranges))
+
+ done := false
+
+ for i, j = 1, 0; ; i++ {
+ for last = c.ranges[j].last; ; i++ {
+ if i == len(c.ranges) || last == utf8.MaxRune {
+ done = true
+ break
+ }
+
+ CurrentRange := c.ranges[i]
+ if CurrentRange.first > last+1 {
+ break
+ }
+
+ if last < CurrentRange.last {
+ last = CurrentRange.last
+ }
+ }
+
+ c.ranges[j] = singleRange{first: c.ranges[j].first, last: last}
+
+ j++
+
+ if done {
+ break
+ }
+
+ if j < i {
+ c.ranges[j] = c.ranges[i]
+ }
+ }
+
+ c.ranges = append(c.ranges[:j], c.ranges[len(c.ranges):]...)
+ }
+}
+
+// Adds to the class any lowercase versions of characters already
+// in the class. Used for case-insensitivity.
+func (c *CharSet) addLowercase() {
+ if c.anything {
+ return
+ }
+ toAdd := []singleRange{}
+ for i := 0; i < len(c.ranges); i++ {
+ r := c.ranges[i]
+ if r.first == r.last {
+ lower := unicode.ToLower(r.first)
+ c.ranges[i] = singleRange{first: lower, last: lower}
+ } else {
+ toAdd = append(toAdd, r)
+ }
+ }
+
+ for _, r := range toAdd {
+ c.addLowercaseRange(r.first, r.last)
+ }
+ c.canonicalize()
+}
+
+/**************************************************************************
+ Let U be the set of Unicode character values and let L be the lowercase
+ function, mapping from U to U. To perform case insensitive matching of
+ character sets, we need to be able to map an interval I in U, say
+
+ I = [chMin, chMax] = { ch : chMin <= ch <= chMax }
+
+ to a set A such that A contains L(I) and A is contained in the union of
+ I and L(I).
+
+ The table below partitions U into intervals on which L is non-decreasing.
+ Thus, for any interval J = [a, b] contained in one of these intervals,
+ L(J) is contained in [L(a), L(b)].
+
+ It is also true that for any such J, [L(a), L(b)] is contained in the
+ union of J and L(J). This does not follow from L being non-decreasing on
+ these intervals. It follows from the nature of the L on each interval.
+ On each interval, L has one of the following forms:
+
+ (1) L(ch) = constant (LowercaseSet)
+ (2) L(ch) = ch + offset (LowercaseAdd)
+ (3) L(ch) = ch | 1 (LowercaseBor)
+ (4) L(ch) = ch + (ch & 1) (LowercaseBad)
+
+ It is easy to verify that for any of these forms [L(a), L(b)] is
+ contained in the union of [a, b] and L([a, b]).
+***************************************************************************/
+
+const (
+ LowercaseSet = 0 // Set to arg.
+ LowercaseAdd = 1 // Add arg.
+ LowercaseBor = 2 // Bitwise or with 1.
+ LowercaseBad = 3 // Bitwise and with 1 and add original.
+)
+
+type lcMap struct {
+ chMin, chMax rune
+ op, data int32
+}
+
+var lcTable = []lcMap{
+ lcMap{'\u0041', '\u005A', LowercaseAdd, 32},
+ lcMap{'\u00C0', '\u00DE', LowercaseAdd, 32},
+ lcMap{'\u0100', '\u012E', LowercaseBor, 0},
+ lcMap{'\u0130', '\u0130', LowercaseSet, 0x0069},
+ lcMap{'\u0132', '\u0136', LowercaseBor, 0},
+ lcMap{'\u0139', '\u0147', LowercaseBad, 0},
+ lcMap{'\u014A', '\u0176', LowercaseBor, 0},
+ lcMap{'\u0178', '\u0178', LowercaseSet, 0x00FF},
+ lcMap{'\u0179', '\u017D', LowercaseBad, 0},
+ lcMap{'\u0181', '\u0181', LowercaseSet, 0x0253},
+ lcMap{'\u0182', '\u0184', LowercaseBor, 0},
+ lcMap{'\u0186', '\u0186', LowercaseSet, 0x0254},
+ lcMap{'\u0187', '\u0187', LowercaseSet, 0x0188},
+ lcMap{'\u0189', '\u018A', LowercaseAdd, 205},
+ lcMap{'\u018B', '\u018B', LowercaseSet, 0x018C},
+ lcMap{'\u018E', '\u018E', LowercaseSet, 0x01DD},
+ lcMap{'\u018F', '\u018F', LowercaseSet, 0x0259},
+ lcMap{'\u0190', '\u0190', LowercaseSet, 0x025B},
+ lcMap{'\u0191', '\u0191', LowercaseSet, 0x0192},
+ lcMap{'\u0193', '\u0193', LowercaseSet, 0x0260},
+ lcMap{'\u0194', '\u0194', LowercaseSet, 0x0263},
+ lcMap{'\u0196', '\u0196', LowercaseSet, 0x0269},
+ lcMap{'\u0197', '\u0197', LowercaseSet, 0x0268},
+ lcMap{'\u0198', '\u0198', LowercaseSet, 0x0199},
+ lcMap{'\u019C', '\u019C', LowercaseSet, 0x026F},
+ lcMap{'\u019D', '\u019D', LowercaseSet, 0x0272},
+ lcMap{'\u019F', '\u019F', LowercaseSet, 0x0275},
+ lcMap{'\u01A0', '\u01A4', LowercaseBor, 0},
+ lcMap{'\u01A7', '\u01A7', LowercaseSet, 0x01A8},
+ lcMap{'\u01A9', '\u01A9', LowercaseSet, 0x0283},
+ lcMap{'\u01AC', '\u01AC', LowercaseSet, 0x01AD},
+ lcMap{'\u01AE', '\u01AE', LowercaseSet, 0x0288},
+ lcMap{'\u01AF', '\u01AF', LowercaseSet, 0x01B0},
+ lcMap{'\u01B1', '\u01B2', LowercaseAdd, 217},
+ lcMap{'\u01B3', '\u01B5', LowercaseBad, 0},
+ lcMap{'\u01B7', '\u01B7', LowercaseSet, 0x0292},
+ lcMap{'\u01B8', '\u01B8', LowercaseSet, 0x01B9},
+ lcMap{'\u01BC', '\u01BC', LowercaseSet, 0x01BD},
+ lcMap{'\u01C4', '\u01C5', LowercaseSet, 0x01C6},
+ lcMap{'\u01C7', '\u01C8', LowercaseSet, 0x01C9},
+ lcMap{'\u01CA', '\u01CB', LowercaseSet, 0x01CC},
+ lcMap{'\u01CD', '\u01DB', LowercaseBad, 0},
+ lcMap{'\u01DE', '\u01EE', LowercaseBor, 0},
+ lcMap{'\u01F1', '\u01F2', LowercaseSet, 0x01F3},
+ lcMap{'\u01F4', '\u01F4', LowercaseSet, 0x01F5},
+ lcMap{'\u01FA', '\u0216', LowercaseBor, 0},
+ lcMap{'\u0386', '\u0386', LowercaseSet, 0x03AC},
+ lcMap{'\u0388', '\u038A', LowercaseAdd, 37},
+ lcMap{'\u038C', '\u038C', LowercaseSet, 0x03CC},
+ lcMap{'\u038E', '\u038F', LowercaseAdd, 63},
+ lcMap{'\u0391', '\u03AB', LowercaseAdd, 32},
+ lcMap{'\u03E2', '\u03EE', LowercaseBor, 0},
+ lcMap{'\u0401', '\u040F', LowercaseAdd, 80},
+ lcMap{'\u0410', '\u042F', LowercaseAdd, 32},
+ lcMap{'\u0460', '\u0480', LowercaseBor, 0},
+ lcMap{'\u0490', '\u04BE', LowercaseBor, 0},
+ lcMap{'\u04C1', '\u04C3', LowercaseBad, 0},
+ lcMap{'\u04C7', '\u04C7', LowercaseSet, 0x04C8},
+ lcMap{'\u04CB', '\u04CB', LowercaseSet, 0x04CC},
+ lcMap{'\u04D0', '\u04EA', LowercaseBor, 0},
+ lcMap{'\u04EE', '\u04F4', LowercaseBor, 0},
+ lcMap{'\u04F8', '\u04F8', LowercaseSet, 0x04F9},
+ lcMap{'\u0531', '\u0556', LowercaseAdd, 48},
+ lcMap{'\u10A0', '\u10C5', LowercaseAdd, 48},
+ lcMap{'\u1E00', '\u1EF8', LowercaseBor, 0},
+ lcMap{'\u1F08', '\u1F0F', LowercaseAdd, -8},
+ lcMap{'\u1F18', '\u1F1F', LowercaseAdd, -8},
+ lcMap{'\u1F28', '\u1F2F', LowercaseAdd, -8},
+ lcMap{'\u1F38', '\u1F3F', LowercaseAdd, -8},
+ lcMap{'\u1F48', '\u1F4D', LowercaseAdd, -8},
+ lcMap{'\u1F59', '\u1F59', LowercaseSet, 0x1F51},
+ lcMap{'\u1F5B', '\u1F5B', LowercaseSet, 0x1F53},
+ lcMap{'\u1F5D', '\u1F5D', LowercaseSet, 0x1F55},
+ lcMap{'\u1F5F', '\u1F5F', LowercaseSet, 0x1F57},
+ lcMap{'\u1F68', '\u1F6F', LowercaseAdd, -8},
+ lcMap{'\u1F88', '\u1F8F', LowercaseAdd, -8},
+ lcMap{'\u1F98', '\u1F9F', LowercaseAdd, -8},
+ lcMap{'\u1FA8', '\u1FAF', LowercaseAdd, -8},
+ lcMap{'\u1FB8', '\u1FB9', LowercaseAdd, -8},
+ lcMap{'\u1FBA', '\u1FBB', LowercaseAdd, -74},
+ lcMap{'\u1FBC', '\u1FBC', LowercaseSet, 0x1FB3},
+ lcMap{'\u1FC8', '\u1FCB', LowercaseAdd, -86},
+ lcMap{'\u1FCC', '\u1FCC', LowercaseSet, 0x1FC3},
+ lcMap{'\u1FD8', '\u1FD9', LowercaseAdd, -8},
+ lcMap{'\u1FDA', '\u1FDB', LowercaseAdd, -100},
+ lcMap{'\u1FE8', '\u1FE9', LowercaseAdd, -8},
+ lcMap{'\u1FEA', '\u1FEB', LowercaseAdd, -112},
+ lcMap{'\u1FEC', '\u1FEC', LowercaseSet, 0x1FE5},
+ lcMap{'\u1FF8', '\u1FF9', LowercaseAdd, -128},
+ lcMap{'\u1FFA', '\u1FFB', LowercaseAdd, -126},
+ lcMap{'\u1FFC', '\u1FFC', LowercaseSet, 0x1FF3},
+ lcMap{'\u2160', '\u216F', LowercaseAdd, 16},
+ lcMap{'\u24B6', '\u24D0', LowercaseAdd, 26},
+ lcMap{'\uFF21', '\uFF3A', LowercaseAdd, 32},
+}
+
+func (c *CharSet) addLowercaseRange(chMin, chMax rune) {
+ var i, iMax, iMid int
+ var chMinT, chMaxT rune
+ var lc lcMap
+
+ for i, iMax = 0, len(lcTable); i < iMax; {
+ iMid = (i + iMax) / 2
+ if lcTable[iMid].chMax < chMin {
+ i = iMid + 1
+ } else {
+ iMax = iMid
+ }
+ }
+
+ for ; i < len(lcTable); i++ {
+ lc = lcTable[i]
+ if lc.chMin > chMax {
+ return
+ }
+ chMinT = lc.chMin
+ if chMinT < chMin {
+ chMinT = chMin
+ }
+
+ chMaxT = lc.chMax
+ if chMaxT > chMax {
+ chMaxT = chMax
+ }
+
+ switch lc.op {
+ case LowercaseSet:
+ chMinT = rune(lc.data)
+ chMaxT = rune(lc.data)
+ break
+ case LowercaseAdd:
+ chMinT += lc.data
+ chMaxT += lc.data
+ break
+ case LowercaseBor:
+ chMinT |= 1
+ chMaxT |= 1
+ break
+ case LowercaseBad:
+ chMinT += (chMinT & 1)
+ chMaxT += (chMaxT & 1)
+ break
+ }
+
+ if chMinT < chMin || chMaxT > chMax {
+ c.addRange(chMinT, chMaxT)
+ }
+ }
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/code.go b/vendor/github.com/dlclark/regexp2/syntax/code.go
new file mode 100644
index 00000000..686e822a
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/code.go
@@ -0,0 +1,274 @@
+package syntax
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+)
+
+// similar to prog.go in the go regex package...also with comment 'may not belong in this package'
+
+// File provides operator constants for use by the Builder and the Machine.
+
+// Implementation notes:
+//
+// Regexps are built into RegexCodes, which contain an operation array,
+// a string table, and some constants.
+//
+// Each operation is one of the codes below, followed by the integer
+// operands specified for each op.
+//
+// Strings and sets are indices into a string table.
+
+type InstOp int
+
+const (
+ // lef/back operands description
+
+ Onerep InstOp = 0 // lef,back char,min,max a {n}
+ Notonerep = 1 // lef,back char,min,max .{n}
+ Setrep = 2 // lef,back set,min,max [\d]{n}
+
+ Oneloop = 3 // lef,back char,min,max a {,n}
+ Notoneloop = 4 // lef,back char,min,max .{,n}
+ Setloop = 5 // lef,back set,min,max [\d]{,n}
+
+ Onelazy = 6 // lef,back char,min,max a {,n}?
+ Notonelazy = 7 // lef,back char,min,max .{,n}?
+ Setlazy = 8 // lef,back set,min,max [\d]{,n}?
+
+ One = 9 // lef char a
+ Notone = 10 // lef char [^a]
+ Set = 11 // lef set [a-z\s] \w \s \d
+
+ Multi = 12 // lef string abcd
+ Ref = 13 // lef group \#
+
+ Bol = 14 // ^
+ Eol = 15 // $
+ Boundary = 16 // \b
+ Nonboundary = 17 // \B
+ Beginning = 18 // \A
+ Start = 19 // \G
+ EndZ = 20 // \Z
+ End = 21 // \Z
+
+ Nothing = 22 // Reject!
+
+ // Primitive control structures
+
+ Lazybranch = 23 // back jump straight first
+ Branchmark = 24 // back jump branch first for loop
+ Lazybranchmark = 25 // back jump straight first for loop
+ Nullcount = 26 // back val set counter, null mark
+ Setcount = 27 // back val set counter, make mark
+ Branchcount = 28 // back jump,limit branch++ if zero<=c impl group slots
+ Capsize int // number of impl group slots
+ FcPrefix *Prefix // the set of candidate first characters (may be null)
+ BmPrefix *BmPrefix // the fixed prefix string as a Boyer-Moore machine (may be null)
+ Anchors AnchorLoc // the set of zero-length start anchors (RegexFCD.Bol, etc)
+ RightToLeft bool // true if right to left
+}
+
+func opcodeBacktracks(op InstOp) bool {
+ op &= Mask
+
+ switch op {
+ case Oneloop, Notoneloop, Setloop, Onelazy, Notonelazy, Setlazy, Lazybranch, Branchmark, Lazybranchmark,
+ Nullcount, Setcount, Branchcount, Lazybranchcount, Setmark, Capturemark, Getmark, Setjump, Backjump,
+ Forejump, Goto:
+ return true
+
+ default:
+ return false
+ }
+}
+
+func opcodeSize(op InstOp) int {
+ op &= Mask
+
+ switch op {
+ case Nothing, Bol, Eol, Boundary, Nonboundary, ECMABoundary, NonECMABoundary, Beginning, Start, EndZ,
+ End, Nullmark, Setmark, Getmark, Setjump, Backjump, Forejump, Stop:
+ return 1
+
+ case One, Notone, Multi, Ref, Testref, Goto, Nullcount, Setcount, Lazybranch, Branchmark, Lazybranchmark,
+ Prune, Set:
+ return 2
+
+ case Capturemark, Branchcount, Lazybranchcount, Onerep, Notonerep, Oneloop, Notoneloop, Onelazy, Notonelazy,
+ Setlazy, Setrep, Setloop:
+ return 3
+
+ default:
+ panic(fmt.Errorf("Unexpected op code: %v", op))
+ }
+}
+
+var codeStr = []string{
+ "Onerep", "Notonerep", "Setrep",
+ "Oneloop", "Notoneloop", "Setloop",
+ "Onelazy", "Notonelazy", "Setlazy",
+ "One", "Notone", "Set",
+ "Multi", "Ref",
+ "Bol", "Eol", "Boundary", "Nonboundary", "Beginning", "Start", "EndZ", "End",
+ "Nothing",
+ "Lazybranch", "Branchmark", "Lazybranchmark",
+ "Nullcount", "Setcount", "Branchcount", "Lazybranchcount",
+ "Nullmark", "Setmark", "Capturemark", "Getmark",
+ "Setjump", "Backjump", "Forejump", "Testref", "Goto",
+ "Prune", "Stop",
+ "ECMABoundary", "NonECMABoundary",
+}
+
+func operatorDescription(op InstOp) string {
+ desc := codeStr[op&Mask]
+ if (op & Ci) != 0 {
+ desc += "-Ci"
+ }
+ if (op & Rtl) != 0 {
+ desc += "-Rtl"
+ }
+ if (op & Back) != 0 {
+ desc += "-Back"
+ }
+ if (op & Back2) != 0 {
+ desc += "-Back2"
+ }
+
+ return desc
+}
+
+// OpcodeDescription is a humman readable string of the specific offset
+func (c *Code) OpcodeDescription(offset int) string {
+ buf := &bytes.Buffer{}
+
+ op := InstOp(c.Codes[offset])
+ fmt.Fprintf(buf, "%06d ", offset)
+
+ if opcodeBacktracks(op & Mask) {
+ buf.WriteString("*")
+ } else {
+ buf.WriteString(" ")
+ }
+ buf.WriteString(operatorDescription(op))
+ buf.WriteString("(")
+ op &= Mask
+
+ switch op {
+ case One, Notone, Onerep, Notonerep, Oneloop, Notoneloop, Onelazy, Notonelazy:
+ buf.WriteString("Ch = ")
+ buf.WriteString(CharDescription(rune(c.Codes[offset+1])))
+
+ case Set, Setrep, Setloop, Setlazy:
+ buf.WriteString("Set = ")
+ buf.WriteString(c.Sets[c.Codes[offset+1]].String())
+
+ case Multi:
+ fmt.Fprintf(buf, "String = %s", string(c.Strings[c.Codes[offset+1]]))
+
+ case Ref, Testref:
+ fmt.Fprintf(buf, "Index = %d", c.Codes[offset+1])
+
+ case Capturemark:
+ fmt.Fprintf(buf, "Index = %d", c.Codes[offset+1])
+ if c.Codes[offset+2] != -1 {
+ fmt.Fprintf(buf, ", Unindex = %d", c.Codes[offset+2])
+ }
+
+ case Nullcount, Setcount:
+ fmt.Fprintf(buf, "Value = %d", c.Codes[offset+1])
+
+ case Goto, Lazybranch, Branchmark, Lazybranchmark, Branchcount, Lazybranchcount:
+ fmt.Fprintf(buf, "Addr = %d", c.Codes[offset+1])
+ }
+
+ switch op {
+ case Onerep, Notonerep, Oneloop, Notoneloop, Onelazy, Notonelazy, Setrep, Setloop, Setlazy:
+ buf.WriteString(", Rep = ")
+ if c.Codes[offset+2] == math.MaxInt32 {
+ buf.WriteString("inf")
+ } else {
+ fmt.Fprintf(buf, "%d", c.Codes[offset+2])
+ }
+
+ case Branchcount, Lazybranchcount:
+ buf.WriteString(", Limit = ")
+ if c.Codes[offset+2] == math.MaxInt32 {
+ buf.WriteString("inf")
+ } else {
+ fmt.Fprintf(buf, "%d", c.Codes[offset+2])
+ }
+
+ }
+
+ buf.WriteString(")")
+
+ return buf.String()
+}
+
+func (c *Code) Dump() string {
+ buf := &bytes.Buffer{}
+
+ if c.RightToLeft {
+ fmt.Fprintln(buf, "Direction: right-to-left")
+ } else {
+ fmt.Fprintln(buf, "Direction: left-to-right")
+ }
+ if c.FcPrefix == nil {
+ fmt.Fprintln(buf, "Firstchars: n/a")
+ } else {
+ fmt.Fprintf(buf, "Firstchars: %v\n", c.FcPrefix.PrefixSet.String())
+ }
+
+ if c.BmPrefix == nil {
+ fmt.Fprintln(buf, "Prefix: n/a")
+ } else {
+ fmt.Fprintf(buf, "Prefix: %v\n", Escape(c.BmPrefix.String()))
+ }
+
+ fmt.Fprintf(buf, "Anchors: %v\n", c.Anchors)
+ fmt.Fprintln(buf)
+
+ if c.BmPrefix != nil {
+ fmt.Fprintln(buf, "BoyerMoore:")
+ fmt.Fprintln(buf, c.BmPrefix.Dump(" "))
+ }
+ for i := 0; i < len(c.Codes); i += opcodeSize(InstOp(c.Codes[i])) {
+ fmt.Fprintln(buf, c.OpcodeDescription(i))
+ }
+
+ return buf.String()
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/escape.go b/vendor/github.com/dlclark/regexp2/syntax/escape.go
new file mode 100644
index 00000000..609df107
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/escape.go
@@ -0,0 +1,94 @@
+package syntax
+
+import (
+ "bytes"
+ "strconv"
+ "strings"
+ "unicode"
+)
+
+func Escape(input string) string {
+ b := &bytes.Buffer{}
+ for _, r := range input {
+ escape(b, r, false)
+ }
+ return b.String()
+}
+
+const meta = `\.+*?()|[]{}^$# `
+
+func escape(b *bytes.Buffer, r rune, force bool) {
+ if unicode.IsPrint(r) {
+ if strings.IndexRune(meta, r) >= 0 || force {
+ b.WriteRune('\\')
+ }
+ b.WriteRune(r)
+ return
+ }
+
+ switch r {
+ case '\a':
+ b.WriteString(`\a`)
+ case '\f':
+ b.WriteString(`\f`)
+ case '\n':
+ b.WriteString(`\n`)
+ case '\r':
+ b.WriteString(`\r`)
+ case '\t':
+ b.WriteString(`\t`)
+ case '\v':
+ b.WriteString(`\v`)
+ default:
+ if r < 0x100 {
+ b.WriteString(`\x`)
+ s := strconv.FormatInt(int64(r), 16)
+ if len(s) == 1 {
+ b.WriteRune('0')
+ }
+ b.WriteString(s)
+ break
+ }
+ b.WriteString(`\u`)
+ b.WriteString(strconv.FormatInt(int64(r), 16))
+ }
+}
+
+func Unescape(input string) (string, error) {
+ idx := strings.IndexRune(input, '\\')
+ // no slashes means no unescape needed
+ if idx == -1 {
+ return input, nil
+ }
+
+ buf := bytes.NewBufferString(input[:idx])
+ // get the runes for the rest of the string -- we're going full parser scan on this
+
+ p := parser{}
+ p.setPattern(input[idx+1:])
+ for {
+ if p.rightMost() {
+ return "", p.getErr(ErrIllegalEndEscape)
+ }
+ r, err := p.scanCharEscape()
+ if err != nil {
+ return "", err
+ }
+ buf.WriteRune(r)
+ // are we done?
+ if p.rightMost() {
+ return buf.String(), nil
+ }
+
+ r = p.moveRightGetChar()
+ for r != '\\' {
+ buf.WriteRune(r)
+ if p.rightMost() {
+ // we're done, no more slashes
+ return buf.String(), nil
+ }
+ // keep scanning until we get another slash
+ r = p.moveRightGetChar()
+ }
+ }
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/fuzz.go b/vendor/github.com/dlclark/regexp2/syntax/fuzz.go
new file mode 100644
index 00000000..ee863866
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/fuzz.go
@@ -0,0 +1,20 @@
+// +build gofuzz
+
+package syntax
+
+// Fuzz is the input point for go-fuzz
+func Fuzz(data []byte) int {
+ sdata := string(data)
+ tree, err := Parse(sdata, RegexOptions(0))
+ if err != nil {
+ return 0
+ }
+
+ // translate it to code
+ _, err = Write(tree)
+ if err != nil {
+ panic(err)
+ }
+
+ return 1
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/parser.go b/vendor/github.com/dlclark/regexp2/syntax/parser.go
new file mode 100644
index 00000000..4ff0aaa8
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/parser.go
@@ -0,0 +1,2262 @@
+package syntax
+
+import (
+ "fmt"
+ "math"
+ "os"
+ "sort"
+ "strconv"
+ "unicode"
+)
+
+type RegexOptions int32
+
+const (
+ IgnoreCase RegexOptions = 0x0001 // "i"
+ Multiline = 0x0002 // "m"
+ ExplicitCapture = 0x0004 // "n"
+ Compiled = 0x0008 // "c"
+ Singleline = 0x0010 // "s"
+ IgnorePatternWhitespace = 0x0020 // "x"
+ RightToLeft = 0x0040 // "r"
+ Debug = 0x0080 // "d"
+ ECMAScript = 0x0100 // "e"
+ RE2 = 0x0200 // RE2 compat mode
+ Unicode = 0x0400 // "u"
+)
+
+func optionFromCode(ch rune) RegexOptions {
+ // case-insensitive
+ switch ch {
+ case 'i', 'I':
+ return IgnoreCase
+ case 'r', 'R':
+ return RightToLeft
+ case 'm', 'M':
+ return Multiline
+ case 'n', 'N':
+ return ExplicitCapture
+ case 's', 'S':
+ return Singleline
+ case 'x', 'X':
+ return IgnorePatternWhitespace
+ case 'd', 'D':
+ return Debug
+ case 'e', 'E':
+ return ECMAScript
+ case 'u', 'U':
+ return Unicode
+ default:
+ return 0
+ }
+}
+
+// An Error describes a failure to parse a regular expression
+// and gives the offending expression.
+type Error struct {
+ Code ErrorCode
+ Expr string
+ Args []interface{}
+}
+
+func (e *Error) Error() string {
+ if len(e.Args) == 0 {
+ return "error parsing regexp: " + e.Code.String() + " in `" + e.Expr + "`"
+ }
+ return "error parsing regexp: " + fmt.Sprintf(e.Code.String(), e.Args...) + " in `" + e.Expr + "`"
+}
+
+// An ErrorCode describes a failure to parse a regular expression.
+type ErrorCode string
+
+const (
+ // internal issue
+ ErrInternalError ErrorCode = "regexp/syntax: internal error"
+ // Parser errors
+ ErrUnterminatedComment = "unterminated comment"
+ ErrInvalidCharRange = "invalid character class range"
+ ErrInvalidRepeatSize = "invalid repeat count"
+ ErrInvalidUTF8 = "invalid UTF-8"
+ ErrCaptureGroupOutOfRange = "capture group number out of range"
+ ErrUnexpectedParen = "unexpected )"
+ ErrMissingParen = "missing closing )"
+ ErrMissingBrace = "missing closing }"
+ ErrInvalidRepeatOp = "invalid nested repetition operator"
+ ErrMissingRepeatArgument = "missing argument to repetition operator"
+ ErrConditionalExpression = "illegal conditional (?(...)) expression"
+ ErrTooManyAlternates = "too many | in (?()|)"
+ ErrUnrecognizedGrouping = "unrecognized grouping construct: (%v"
+ ErrInvalidGroupName = "invalid group name: group names must begin with a word character and have a matching terminator"
+ ErrCapNumNotZero = "capture number cannot be zero"
+ ErrUndefinedBackRef = "reference to undefined group number %v"
+ ErrUndefinedNameRef = "reference to undefined group name %v"
+ ErrAlternationCantCapture = "alternation conditions do not capture and cannot be named"
+ ErrAlternationCantHaveComment = "alternation conditions cannot be comments"
+ ErrMalformedReference = "(?(%v) ) malformed"
+ ErrUndefinedReference = "(?(%v) ) reference to undefined group"
+ ErrIllegalEndEscape = "illegal \\ at end of pattern"
+ ErrMalformedSlashP = "malformed \\p{X} character escape"
+ ErrIncompleteSlashP = "incomplete \\p{X} character escape"
+ ErrUnknownSlashP = "unknown unicode category, script, or property '%v'"
+ ErrUnrecognizedEscape = "unrecognized escape sequence \\%v"
+ ErrMissingControl = "missing control character"
+ ErrUnrecognizedControl = "unrecognized control character"
+ ErrTooFewHex = "insufficient hexadecimal digits"
+ ErrInvalidHex = "hex values may not be larger than 0x10FFFF"
+ ErrMalformedNameRef = "malformed \\k<...> named back reference"
+ ErrBadClassInCharRange = "cannot include class \\%v in character range"
+ ErrUnterminatedBracket = "unterminated [] set"
+ ErrSubtractionMustBeLast = "a subtraction must be the last element in a character class"
+ ErrReversedCharRange = "[%c-%c] range in reverse order"
+)
+
+func (e ErrorCode) String() string {
+ return string(e)
+}
+
+type parser struct {
+ stack *regexNode
+ group *regexNode
+ alternation *regexNode
+ concatenation *regexNode
+ unit *regexNode
+
+ patternRaw string
+ pattern []rune
+
+ currentPos int
+ specialCase *unicode.SpecialCase
+
+ autocap int
+ capcount int
+ captop int
+ capsize int
+
+ caps map[int]int
+ capnames map[string]int
+
+ capnumlist []int
+ capnamelist []string
+
+ options RegexOptions
+ optionsStack []RegexOptions
+ ignoreNextParen bool
+}
+
+const (
+ maxValueDiv10 int = math.MaxInt32 / 10
+ maxValueMod10 = math.MaxInt32 % 10
+)
+
+// Parse converts a regex string into a parse tree
+func Parse(re string, op RegexOptions) (*RegexTree, error) {
+ p := parser{
+ options: op,
+ caps: make(map[int]int),
+ }
+ p.setPattern(re)
+
+ if err := p.countCaptures(); err != nil {
+ return nil, err
+ }
+
+ p.reset(op)
+ root, err := p.scanRegex()
+
+ if err != nil {
+ return nil, err
+ }
+ tree := &RegexTree{
+ root: root,
+ caps: p.caps,
+ capnumlist: p.capnumlist,
+ captop: p.captop,
+ Capnames: p.capnames,
+ Caplist: p.capnamelist,
+ options: op,
+ }
+
+ if tree.options&Debug > 0 {
+ os.Stdout.WriteString(tree.Dump())
+ }
+
+ return tree, nil
+}
+
+func (p *parser) setPattern(pattern string) {
+ p.patternRaw = pattern
+ p.pattern = make([]rune, 0, len(pattern))
+
+ //populate our rune array to handle utf8 encoding
+ for _, r := range pattern {
+ p.pattern = append(p.pattern, r)
+ }
+}
+func (p *parser) getErr(code ErrorCode, args ...interface{}) error {
+ return &Error{Code: code, Expr: p.patternRaw, Args: args}
+}
+
+func (p *parser) noteCaptureSlot(i, pos int) {
+ if _, ok := p.caps[i]; !ok {
+ // the rhs of the hashtable isn't used in the parser
+ p.caps[i] = pos
+ p.capcount++
+
+ if p.captop <= i {
+ if i == math.MaxInt32 {
+ p.captop = i
+ } else {
+ p.captop = i + 1
+ }
+ }
+ }
+}
+
+func (p *parser) noteCaptureName(name string, pos int) {
+ if p.capnames == nil {
+ p.capnames = make(map[string]int)
+ }
+
+ if _, ok := p.capnames[name]; !ok {
+ p.capnames[name] = pos
+ p.capnamelist = append(p.capnamelist, name)
+ }
+}
+
+func (p *parser) assignNameSlots() {
+ if p.capnames != nil {
+ for _, name := range p.capnamelist {
+ for p.isCaptureSlot(p.autocap) {
+ p.autocap++
+ }
+ pos := p.capnames[name]
+ p.capnames[name] = p.autocap
+ p.noteCaptureSlot(p.autocap, pos)
+
+ p.autocap++
+ }
+ }
+
+ // if the caps array has at least one gap, construct the list of used slots
+ if p.capcount < p.captop {
+ p.capnumlist = make([]int, p.capcount)
+ i := 0
+
+ for k := range p.caps {
+ p.capnumlist[i] = k
+ i++
+ }
+
+ sort.Ints(p.capnumlist)
+ }
+
+ // merge capsnumlist into capnamelist
+ if p.capnames != nil || p.capnumlist != nil {
+ var oldcapnamelist []string
+ var next int
+ var k int
+
+ if p.capnames == nil {
+ oldcapnamelist = nil
+ p.capnames = make(map[string]int)
+ p.capnamelist = []string{}
+ next = -1
+ } else {
+ oldcapnamelist = p.capnamelist
+ p.capnamelist = []string{}
+ next = p.capnames[oldcapnamelist[0]]
+ }
+
+ for i := 0; i < p.capcount; i++ {
+ j := i
+ if p.capnumlist != nil {
+ j = p.capnumlist[i]
+ }
+
+ if next == j {
+ p.capnamelist = append(p.capnamelist, oldcapnamelist[k])
+ k++
+
+ if k == len(oldcapnamelist) {
+ next = -1
+ } else {
+ next = p.capnames[oldcapnamelist[k]]
+ }
+
+ } else {
+ //feature: culture?
+ str := strconv.Itoa(j)
+ p.capnamelist = append(p.capnamelist, str)
+ p.capnames[str] = j
+ }
+ }
+ }
+}
+
+func (p *parser) consumeAutocap() int {
+ r := p.autocap
+ p.autocap++
+ return r
+}
+
+// CountCaptures is a prescanner for deducing the slots used for
+// captures by doing a partial tokenization of the pattern.
+func (p *parser) countCaptures() error {
+ var ch rune
+
+ p.noteCaptureSlot(0, 0)
+
+ p.autocap = 1
+
+ for p.charsRight() > 0 {
+ pos := p.textpos()
+ ch = p.moveRightGetChar()
+ switch ch {
+ case '\\':
+ if p.charsRight() > 0 {
+ p.scanBackslash(true)
+ }
+
+ case '#':
+ if p.useOptionX() {
+ p.moveLeft()
+ p.scanBlank()
+ }
+
+ case '[':
+ p.scanCharSet(false, true)
+
+ case ')':
+ if !p.emptyOptionsStack() {
+ p.popOptions()
+ }
+
+ case '(':
+ if p.charsRight() >= 2 && p.rightChar(1) == '#' && p.rightChar(0) == '?' {
+ p.moveLeft()
+ p.scanBlank()
+ } else {
+ p.pushOptions()
+ if p.charsRight() > 0 && p.rightChar(0) == '?' {
+ // we have (?...
+ p.moveRight(1)
+
+ if p.charsRight() > 1 && (p.rightChar(0) == '<' || p.rightChar(0) == '\'') {
+ // named group: (?<... or (?'...
+
+ p.moveRight(1)
+ ch = p.rightChar(0)
+
+ if ch != '0' && IsWordChar(ch) {
+ if ch >= '1' && ch <= '9' {
+ dec, err := p.scanDecimal()
+ if err != nil {
+ return err
+ }
+ p.noteCaptureSlot(dec, pos)
+ } else {
+ p.noteCaptureName(p.scanCapname(), pos)
+ }
+ }
+ } else if p.useRE2() && p.charsRight() > 2 && (p.rightChar(0) == 'P' && p.rightChar(1) == '<') {
+ // RE2-compat (?P<)
+ p.moveRight(2)
+ ch = p.rightChar(0)
+ if IsWordChar(ch) {
+ p.noteCaptureName(p.scanCapname(), pos)
+ }
+
+ } else {
+ // (?...
+
+ // get the options if it's an option construct (?cimsx-cimsx...)
+ p.scanOptions()
+
+ if p.charsRight() > 0 {
+ if p.rightChar(0) == ')' {
+ // (?cimsx-cimsx)
+ p.moveRight(1)
+ p.popKeepOptions()
+ } else if p.rightChar(0) == '(' {
+ // alternation construct: (?(foo)yes|no)
+ // ignore the next paren so we don't capture the condition
+ p.ignoreNextParen = true
+
+ // break from here so we don't reset ignoreNextParen
+ continue
+ }
+ }
+ }
+ } else {
+ if !p.useOptionN() && !p.ignoreNextParen {
+ p.noteCaptureSlot(p.consumeAutocap(), pos)
+ }
+ }
+ }
+
+ p.ignoreNextParen = false
+
+ }
+ }
+
+ p.assignNameSlots()
+ return nil
+}
+
+func (p *parser) reset(topopts RegexOptions) {
+ p.currentPos = 0
+ p.autocap = 1
+ p.ignoreNextParen = false
+
+ if len(p.optionsStack) > 0 {
+ p.optionsStack = p.optionsStack[:0]
+ }
+
+ p.options = topopts
+ p.stack = nil
+}
+
+func (p *parser) scanRegex() (*regexNode, error) {
+ ch := '@' // nonspecial ch, means at beginning
+ isQuant := false
+
+ p.startGroup(newRegexNodeMN(ntCapture, p.options, 0, -1))
+
+ for p.charsRight() > 0 {
+ wasPrevQuantifier := isQuant
+ isQuant = false
+
+ if err := p.scanBlank(); err != nil {
+ return nil, err
+ }
+
+ startpos := p.textpos()
+
+ // move past all of the normal characters. We'll stop when we hit some kind of control character,
+ // or if IgnorePatternWhiteSpace is on, we'll stop when we see some whitespace.
+ if p.useOptionX() {
+ for p.charsRight() > 0 {
+ ch = p.rightChar(0)
+ //UGLY: clean up, this is ugly
+ if !(!isStopperX(ch) || (ch == '{' && !p.isTrueQuantifier())) {
+ break
+ }
+ p.moveRight(1)
+ }
+ } else {
+ for p.charsRight() > 0 {
+ ch = p.rightChar(0)
+ if !(!isSpecial(ch) || ch == '{' && !p.isTrueQuantifier()) {
+ break
+ }
+ p.moveRight(1)
+ }
+ }
+
+ endpos := p.textpos()
+
+ p.scanBlank()
+
+ if p.charsRight() == 0 {
+ ch = '!' // nonspecial, means at end
+ } else if ch = p.rightChar(0); isSpecial(ch) {
+ isQuant = isQuantifier(ch)
+ p.moveRight(1)
+ } else {
+ ch = ' ' // nonspecial, means at ordinary char
+ }
+
+ if startpos < endpos {
+ cchUnquantified := endpos - startpos
+ if isQuant {
+ cchUnquantified--
+ }
+ wasPrevQuantifier = false
+
+ if cchUnquantified > 0 {
+ p.addToConcatenate(startpos, cchUnquantified, false)
+ }
+
+ if isQuant {
+ p.addUnitOne(p.charAt(endpos - 1))
+ }
+ }
+
+ switch ch {
+ case '!':
+ goto BreakOuterScan
+
+ case ' ':
+ goto ContinueOuterScan
+
+ case '[':
+ cc, err := p.scanCharSet(p.useOptionI(), false)
+ if err != nil {
+ return nil, err
+ }
+ p.addUnitSet(cc)
+
+ case '(':
+ p.pushOptions()
+
+ if grouper, err := p.scanGroupOpen(); err != nil {
+ return nil, err
+ } else if grouper == nil {
+ p.popKeepOptions()
+ } else {
+ p.pushGroup()
+ p.startGroup(grouper)
+ }
+
+ continue
+
+ case '|':
+ p.addAlternate()
+ goto ContinueOuterScan
+
+ case ')':
+ if p.emptyStack() {
+ return nil, p.getErr(ErrUnexpectedParen)
+ }
+
+ if err := p.addGroup(); err != nil {
+ return nil, err
+ }
+ if err := p.popGroup(); err != nil {
+ return nil, err
+ }
+ p.popOptions()
+
+ if p.unit == nil {
+ goto ContinueOuterScan
+ }
+
+ case '\\':
+ n, err := p.scanBackslash(false)
+ if err != nil {
+ return nil, err
+ }
+ p.addUnitNode(n)
+
+ case '^':
+ if p.useOptionM() {
+ p.addUnitType(ntBol)
+ } else {
+ p.addUnitType(ntBeginning)
+ }
+
+ case '$':
+ if p.useOptionM() {
+ p.addUnitType(ntEol)
+ } else {
+ p.addUnitType(ntEndZ)
+ }
+
+ case '.':
+ if p.useOptionS() {
+ p.addUnitSet(AnyClass())
+ } else if p.useOptionE() {
+ p.addUnitSet(ECMAAnyClass())
+ } else {
+ p.addUnitNotone('\n')
+ }
+
+ case '{', '*', '+', '?':
+ if p.unit == nil {
+ if wasPrevQuantifier {
+ return nil, p.getErr(ErrInvalidRepeatOp)
+ } else {
+ return nil, p.getErr(ErrMissingRepeatArgument)
+ }
+ }
+ p.moveLeft()
+
+ default:
+ return nil, p.getErr(ErrInternalError)
+ }
+
+ if err := p.scanBlank(); err != nil {
+ return nil, err
+ }
+
+ if p.charsRight() > 0 {
+ isQuant = p.isTrueQuantifier()
+ }
+ if p.charsRight() == 0 || !isQuant {
+ //maintain odd C# assignment order -- not sure if required, could clean up?
+ p.addConcatenate()
+ goto ContinueOuterScan
+ }
+
+ ch = p.moveRightGetChar()
+
+ // Handle quantifiers
+ for p.unit != nil {
+ var min, max int
+ var lazy bool
+
+ switch ch {
+ case '*':
+ min = 0
+ max = math.MaxInt32
+
+ case '?':
+ min = 0
+ max = 1
+
+ case '+':
+ min = 1
+ max = math.MaxInt32
+
+ case '{':
+ {
+ var err error
+ startpos = p.textpos()
+ if min, err = p.scanDecimal(); err != nil {
+ return nil, err
+ }
+ max = min
+ if startpos < p.textpos() {
+ if p.charsRight() > 0 && p.rightChar(0) == ',' {
+ p.moveRight(1)
+ if p.charsRight() == 0 || p.rightChar(0) == '}' {
+ max = math.MaxInt32
+ } else {
+ if max, err = p.scanDecimal(); err != nil {
+ return nil, err
+ }
+ }
+ }
+ }
+
+ if startpos == p.textpos() || p.charsRight() == 0 || p.moveRightGetChar() != '}' {
+ p.addConcatenate()
+ p.textto(startpos - 1)
+ goto ContinueOuterScan
+ }
+ }
+
+ default:
+ return nil, p.getErr(ErrInternalError)
+ }
+
+ if err := p.scanBlank(); err != nil {
+ return nil, err
+ }
+
+ if p.charsRight() == 0 || p.rightChar(0) != '?' {
+ lazy = false
+ } else {
+ p.moveRight(1)
+ lazy = true
+ }
+
+ if min > max {
+ return nil, p.getErr(ErrInvalidRepeatSize)
+ }
+
+ p.addConcatenate3(lazy, min, max)
+ }
+
+ ContinueOuterScan:
+ }
+
+BreakOuterScan:
+ ;
+
+ if !p.emptyStack() {
+ return nil, p.getErr(ErrMissingParen)
+ }
+
+ if err := p.addGroup(); err != nil {
+ return nil, err
+ }
+
+ return p.unit, nil
+
+}
+
+/*
+ * Simple parsing for replacement patterns
+ */
+func (p *parser) scanReplacement() (*regexNode, error) {
+ var c, startpos int
+
+ p.concatenation = newRegexNode(ntConcatenate, p.options)
+
+ for {
+ c = p.charsRight()
+ if c == 0 {
+ break
+ }
+
+ startpos = p.textpos()
+
+ for c > 0 && p.rightChar(0) != '$' {
+ p.moveRight(1)
+ c--
+ }
+
+ p.addToConcatenate(startpos, p.textpos()-startpos, true)
+
+ if c > 0 {
+ if p.moveRightGetChar() == '$' {
+ n, err := p.scanDollar()
+ if err != nil {
+ return nil, err
+ }
+ p.addUnitNode(n)
+ }
+ p.addConcatenate()
+ }
+ }
+
+ return p.concatenation, nil
+}
+
+/*
+ * Scans $ patterns recognized within replacement patterns
+ */
+func (p *parser) scanDollar() (*regexNode, error) {
+ if p.charsRight() == 0 {
+ return newRegexNodeCh(ntOne, p.options, '$'), nil
+ }
+
+ ch := p.rightChar(0)
+ angled := false
+ backpos := p.textpos()
+ lastEndPos := backpos
+
+ // Note angle
+
+ if ch == '{' && p.charsRight() > 1 {
+ angled = true
+ p.moveRight(1)
+ ch = p.rightChar(0)
+ }
+
+ // Try to parse backreference: \1 or \{1} or \{cap}
+
+ if ch >= '0' && ch <= '9' {
+ if !angled && p.useOptionE() {
+ capnum := -1
+ newcapnum := int(ch - '0')
+ p.moveRight(1)
+ if p.isCaptureSlot(newcapnum) {
+ capnum = newcapnum
+ lastEndPos = p.textpos()
+ }
+
+ for p.charsRight() > 0 {
+ ch = p.rightChar(0)
+ if ch < '0' || ch > '9' {
+ break
+ }
+ digit := int(ch - '0')
+ if newcapnum > maxValueDiv10 || (newcapnum == maxValueDiv10 && digit > maxValueMod10) {
+ return nil, p.getErr(ErrCaptureGroupOutOfRange)
+ }
+
+ newcapnum = newcapnum*10 + digit
+
+ p.moveRight(1)
+ if p.isCaptureSlot(newcapnum) {
+ capnum = newcapnum
+ lastEndPos = p.textpos()
+ }
+ }
+ p.textto(lastEndPos)
+ if capnum >= 0 {
+ return newRegexNodeM(ntRef, p.options, capnum), nil
+ }
+ } else {
+ capnum, err := p.scanDecimal()
+ if err != nil {
+ return nil, err
+ }
+ if !angled || p.charsRight() > 0 && p.moveRightGetChar() == '}' {
+ if p.isCaptureSlot(capnum) {
+ return newRegexNodeM(ntRef, p.options, capnum), nil
+ }
+ }
+ }
+ } else if angled && IsWordChar(ch) {
+ capname := p.scanCapname()
+
+ if p.charsRight() > 0 && p.moveRightGetChar() == '}' {
+ if p.isCaptureName(capname) {
+ return newRegexNodeM(ntRef, p.options, p.captureSlotFromName(capname)), nil
+ }
+ }
+ } else if !angled {
+ capnum := 1
+
+ switch ch {
+ case '$':
+ p.moveRight(1)
+ return newRegexNodeCh(ntOne, p.options, '$'), nil
+ case '&':
+ capnum = 0
+ case '`':
+ capnum = replaceLeftPortion
+ case '\'':
+ capnum = replaceRightPortion
+ case '+':
+ capnum = replaceLastGroup
+ case '_':
+ capnum = replaceWholeString
+ }
+
+ if capnum != 1 {
+ p.moveRight(1)
+ return newRegexNodeM(ntRef, p.options, capnum), nil
+ }
+ }
+
+ // unrecognized $: literalize
+
+ p.textto(backpos)
+ return newRegexNodeCh(ntOne, p.options, '$'), nil
+}
+
+// scanGroupOpen scans chars following a '(' (not counting the '('), and returns
+// a RegexNode for the type of group scanned, or nil if the group
+// simply changed options (?cimsx-cimsx) or was a comment (#...).
+func (p *parser) scanGroupOpen() (*regexNode, error) {
+ var ch rune
+ var nt nodeType
+ var err error
+ close := '>'
+ start := p.textpos()
+
+ // just return a RegexNode if we have:
+ // 1. "(" followed by nothing
+ // 2. "(x" where x != ?
+ // 3. "(?)"
+ if p.charsRight() == 0 || p.rightChar(0) != '?' || (p.rightChar(0) == '?' && (p.charsRight() > 1 && p.rightChar(1) == ')')) {
+ if p.useOptionN() || p.ignoreNextParen {
+ p.ignoreNextParen = false
+ return newRegexNode(ntGroup, p.options), nil
+ }
+ return newRegexNodeMN(ntCapture, p.options, p.consumeAutocap(), -1), nil
+ }
+
+ p.moveRight(1)
+
+ for {
+ if p.charsRight() == 0 {
+ break
+ }
+
+ switch ch = p.moveRightGetChar(); ch {
+ case ':':
+ nt = ntGroup
+
+ case '=':
+ p.options &= ^RightToLeft
+ nt = ntRequire
+
+ case '!':
+ p.options &= ^RightToLeft
+ nt = ntPrevent
+
+ case '>':
+ nt = ntGreedy
+
+ case '\'':
+ close = '\''
+ fallthrough
+
+ case '<':
+ if p.charsRight() == 0 {
+ goto BreakRecognize
+ }
+
+ switch ch = p.moveRightGetChar(); ch {
+ case '=':
+ if close == '\'' {
+ goto BreakRecognize
+ }
+
+ p.options |= RightToLeft
+ nt = ntRequire
+
+ case '!':
+ if close == '\'' {
+ goto BreakRecognize
+ }
+
+ p.options |= RightToLeft
+ nt = ntPrevent
+
+ default:
+ p.moveLeft()
+ capnum := -1
+ uncapnum := -1
+ proceed := false
+
+ // grab part before -
+
+ if ch >= '0' && ch <= '9' {
+ if capnum, err = p.scanDecimal(); err != nil {
+ return nil, err
+ }
+
+ if !p.isCaptureSlot(capnum) {
+ capnum = -1
+ }
+
+ // check if we have bogus characters after the number
+ if p.charsRight() > 0 && !(p.rightChar(0) == close || p.rightChar(0) == '-') {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ if capnum == 0 {
+ return nil, p.getErr(ErrCapNumNotZero)
+ }
+ } else if IsWordChar(ch) {
+ capname := p.scanCapname()
+
+ if p.isCaptureName(capname) {
+ capnum = p.captureSlotFromName(capname)
+ }
+
+ // check if we have bogus character after the name
+ if p.charsRight() > 0 && !(p.rightChar(0) == close || p.rightChar(0) == '-') {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ } else if ch == '-' {
+ proceed = true
+ } else {
+ // bad group name - starts with something other than a word character and isn't a number
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+
+ // grab part after - if any
+
+ if (capnum != -1 || proceed == true) && p.charsRight() > 0 && p.rightChar(0) == '-' {
+ p.moveRight(1)
+
+ //no more chars left, no closing char, etc
+ if p.charsRight() == 0 {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+
+ ch = p.rightChar(0)
+ if ch >= '0' && ch <= '9' {
+ if uncapnum, err = p.scanDecimal(); err != nil {
+ return nil, err
+ }
+
+ if !p.isCaptureSlot(uncapnum) {
+ return nil, p.getErr(ErrUndefinedBackRef, uncapnum)
+ }
+
+ // check if we have bogus characters after the number
+ if p.charsRight() > 0 && p.rightChar(0) != close {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ } else if IsWordChar(ch) {
+ uncapname := p.scanCapname()
+
+ if !p.isCaptureName(uncapname) {
+ return nil, p.getErr(ErrUndefinedNameRef, uncapname)
+ }
+ uncapnum = p.captureSlotFromName(uncapname)
+
+ // check if we have bogus character after the name
+ if p.charsRight() > 0 && p.rightChar(0) != close {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ } else {
+ // bad group name - starts with something other than a word character and isn't a number
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ }
+
+ // actually make the node
+
+ if (capnum != -1 || uncapnum != -1) && p.charsRight() > 0 && p.moveRightGetChar() == close {
+ return newRegexNodeMN(ntCapture, p.options, capnum, uncapnum), nil
+ }
+ goto BreakRecognize
+ }
+
+ case '(':
+ // alternation construct (?(...) | )
+
+ parenPos := p.textpos()
+ if p.charsRight() > 0 {
+ ch = p.rightChar(0)
+
+ // check if the alternation condition is a backref
+ if ch >= '0' && ch <= '9' {
+ var capnum int
+ if capnum, err = p.scanDecimal(); err != nil {
+ return nil, err
+ }
+ if p.charsRight() > 0 && p.moveRightGetChar() == ')' {
+ if p.isCaptureSlot(capnum) {
+ return newRegexNodeM(ntTestref, p.options, capnum), nil
+ }
+ return nil, p.getErr(ErrUndefinedReference, capnum)
+ }
+
+ return nil, p.getErr(ErrMalformedReference, capnum)
+
+ } else if IsWordChar(ch) {
+ capname := p.scanCapname()
+
+ if p.isCaptureName(capname) && p.charsRight() > 0 && p.moveRightGetChar() == ')' {
+ return newRegexNodeM(ntTestref, p.options, p.captureSlotFromName(capname)), nil
+ }
+ }
+ }
+ // not a backref
+ nt = ntTestgroup
+ p.textto(parenPos - 1) // jump to the start of the parentheses
+ p.ignoreNextParen = true // but make sure we don't try to capture the insides
+
+ charsRight := p.charsRight()
+ if charsRight >= 3 && p.rightChar(1) == '?' {
+ rightchar2 := p.rightChar(2)
+ // disallow comments in the condition
+ if rightchar2 == '#' {
+ return nil, p.getErr(ErrAlternationCantHaveComment)
+ }
+
+ // disallow named capture group (?<..>..) in the condition
+ if rightchar2 == '\'' {
+ return nil, p.getErr(ErrAlternationCantCapture)
+ }
+
+ if charsRight >= 4 && (rightchar2 == '<' && p.rightChar(3) != '!' && p.rightChar(3) != '=') {
+ return nil, p.getErr(ErrAlternationCantCapture)
+ }
+ }
+
+ case 'P':
+ if p.useRE2() {
+ // support for P syntax
+ if p.charsRight() < 3 {
+ goto BreakRecognize
+ }
+
+ ch = p.moveRightGetChar()
+ if ch != '<' {
+ goto BreakRecognize
+ }
+
+ ch = p.moveRightGetChar()
+ p.moveLeft()
+
+ if IsWordChar(ch) {
+ capnum := -1
+ capname := p.scanCapname()
+
+ if p.isCaptureName(capname) {
+ capnum = p.captureSlotFromName(capname)
+ }
+
+ // check if we have bogus character after the name
+ if p.charsRight() > 0 && p.rightChar(0) != '>' {
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+
+ // actually make the node
+
+ if capnum != -1 && p.charsRight() > 0 && p.moveRightGetChar() == '>' {
+ return newRegexNodeMN(ntCapture, p.options, capnum, -1), nil
+ }
+ goto BreakRecognize
+
+ } else {
+ // bad group name - starts with something other than a word character and isn't a number
+ return nil, p.getErr(ErrInvalidGroupName)
+ }
+ }
+ // if we're not using RE2 compat mode then
+ // we just behave like normal
+ fallthrough
+
+ default:
+ p.moveLeft()
+
+ nt = ntGroup
+ // disallow options in the children of a testgroup node
+ if p.group.t != ntTestgroup {
+ p.scanOptions()
+ }
+ if p.charsRight() == 0 {
+ goto BreakRecognize
+ }
+
+ if ch = p.moveRightGetChar(); ch == ')' {
+ return nil, nil
+ }
+
+ if ch != ':' {
+ goto BreakRecognize
+ }
+
+ }
+
+ return newRegexNode(nt, p.options), nil
+ }
+
+BreakRecognize:
+
+ // break Recognize comes here
+
+ return nil, p.getErr(ErrUnrecognizedGrouping, string(p.pattern[start:p.textpos()]))
+}
+
+// scans backslash specials and basics
+func (p *parser) scanBackslash(scanOnly bool) (*regexNode, error) {
+
+ if p.charsRight() == 0 {
+ return nil, p.getErr(ErrIllegalEndEscape)
+ }
+
+ switch ch := p.rightChar(0); ch {
+ case 'b', 'B', 'A', 'G', 'Z', 'z':
+ p.moveRight(1)
+ return newRegexNode(p.typeFromCode(ch), p.options), nil
+
+ case 'w':
+ p.moveRight(1)
+ if p.useOptionE() || p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, ECMAWordClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, WordClass()), nil
+
+ case 'W':
+ p.moveRight(1)
+ if p.useOptionE() || p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, NotECMAWordClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, NotWordClass()), nil
+
+ case 's':
+ p.moveRight(1)
+ if p.useOptionE() {
+ return newRegexNodeSet(ntSet, p.options, ECMASpaceClass()), nil
+ } else if p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, RE2SpaceClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, SpaceClass()), nil
+
+ case 'S':
+ p.moveRight(1)
+ if p.useOptionE() {
+ return newRegexNodeSet(ntSet, p.options, NotECMASpaceClass()), nil
+ } else if p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, NotRE2SpaceClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, NotSpaceClass()), nil
+
+ case 'd':
+ p.moveRight(1)
+ if p.useOptionE() || p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, ECMADigitClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, DigitClass()), nil
+
+ case 'D':
+ p.moveRight(1)
+ if p.useOptionE() || p.useRE2() {
+ return newRegexNodeSet(ntSet, p.options, NotECMADigitClass()), nil
+ }
+ return newRegexNodeSet(ntSet, p.options, NotDigitClass()), nil
+
+ case 'p', 'P':
+ p.moveRight(1)
+ prop, err := p.parseProperty()
+ if err != nil {
+ return nil, err
+ }
+ cc := &CharSet{}
+ cc.addCategory(prop, (ch != 'p'), p.useOptionI(), p.patternRaw)
+ if p.useOptionI() {
+ cc.addLowercase()
+ }
+
+ return newRegexNodeSet(ntSet, p.options, cc), nil
+
+ default:
+ return p.scanBasicBackslash(scanOnly)
+ }
+}
+
+// Scans \-style backreferences and character escapes
+func (p *parser) scanBasicBackslash(scanOnly bool) (*regexNode, error) {
+ if p.charsRight() == 0 {
+ return nil, p.getErr(ErrIllegalEndEscape)
+ }
+ angled := false
+ k := false
+ close := '\x00'
+
+ backpos := p.textpos()
+ ch := p.rightChar(0)
+
+ // Allow \k instead of \, which is now deprecated.
+
+ // According to ECMAScript specification, \k is only parsed as a named group reference if
+ // there is at least one group name in the regexp.
+ // See https://www.ecma-international.org/ecma-262/#sec-isvalidregularexpressionliteral, step 7.
+ // Note, during the first (scanOnly) run we may not have all group names scanned, but that's ok.
+ if ch == 'k' && (!p.useOptionE() || len(p.capnames) > 0) {
+ if p.charsRight() >= 2 {
+ p.moveRight(1)
+ ch = p.moveRightGetChar()
+
+ if ch == '<' || (!p.useOptionE() && ch == '\'') { // No support for \k'name' in ECMAScript
+ angled = true
+ if ch == '\'' {
+ close = '\''
+ } else {
+ close = '>'
+ }
+ }
+ }
+
+ if !angled || p.charsRight() <= 0 {
+ return nil, p.getErr(ErrMalformedNameRef)
+ }
+
+ ch = p.rightChar(0)
+ k = true
+
+ } else if !p.useOptionE() && (ch == '<' || ch == '\'') && p.charsRight() > 1 { // Note angle without \g
+ angled = true
+ if ch == '\'' {
+ close = '\''
+ } else {
+ close = '>'
+ }
+
+ p.moveRight(1)
+ ch = p.rightChar(0)
+ }
+
+ // Try to parse backreference: \<1> or \
+
+ if angled && ch >= '0' && ch <= '9' {
+ capnum, err := p.scanDecimal()
+ if err != nil {
+ return nil, err
+ }
+
+ if p.charsRight() > 0 && p.moveRightGetChar() == close {
+ if p.isCaptureSlot(capnum) {
+ return newRegexNodeM(ntRef, p.options, capnum), nil
+ }
+ return nil, p.getErr(ErrUndefinedBackRef, capnum)
+ }
+ } else if !angled && ch >= '1' && ch <= '9' { // Try to parse backreference or octal: \1
+ capnum, err := p.scanDecimal()
+ if err != nil {
+ return nil, err
+ }
+
+ if scanOnly {
+ return nil, nil
+ }
+
+ if p.isCaptureSlot(capnum) {
+ return newRegexNodeM(ntRef, p.options, capnum), nil
+ }
+ if capnum <= 9 && !p.useOptionE() {
+ return nil, p.getErr(ErrUndefinedBackRef, capnum)
+ }
+
+ } else if angled {
+ capname := p.scanCapname()
+
+ if capname != "" && p.charsRight() > 0 && p.moveRightGetChar() == close {
+
+ if scanOnly {
+ return nil, nil
+ }
+
+ if p.isCaptureName(capname) {
+ return newRegexNodeM(ntRef, p.options, p.captureSlotFromName(capname)), nil
+ }
+ return nil, p.getErr(ErrUndefinedNameRef, capname)
+ } else {
+ if k {
+ return nil, p.getErr(ErrMalformedNameRef)
+ }
+ }
+ }
+
+ // Not backreference: must be char code
+
+ p.textto(backpos)
+ ch, err := p.scanCharEscape()
+ if err != nil {
+ return nil, err
+ }
+
+ if scanOnly {
+ return nil, nil
+ }
+
+ if p.useOptionI() {
+ ch = unicode.ToLower(ch)
+ }
+
+ return newRegexNodeCh(ntOne, p.options, ch), nil
+}
+
+// Scans X for \p{X} or \P{X}
+func (p *parser) parseProperty() (string, error) {
+ // RE2 and PCRE supports \pX syntax (no {} and only 1 letter unicode cats supported)
+ // since this is purely additive syntax it's not behind a flag
+ if p.charsRight() >= 1 && p.rightChar(0) != '{' {
+ ch := string(p.moveRightGetChar())
+ // check if it's a valid cat
+ if !isValidUnicodeCat(ch) {
+ return "", p.getErr(ErrUnknownSlashP, ch)
+ }
+ return ch, nil
+ }
+
+ if p.charsRight() < 3 {
+ return "", p.getErr(ErrIncompleteSlashP)
+ }
+ ch := p.moveRightGetChar()
+ if ch != '{' {
+ return "", p.getErr(ErrMalformedSlashP)
+ }
+
+ startpos := p.textpos()
+ for p.charsRight() > 0 {
+ ch = p.moveRightGetChar()
+ if !(IsWordChar(ch) || ch == '-') {
+ p.moveLeft()
+ break
+ }
+ }
+ capname := string(p.pattern[startpos:p.textpos()])
+
+ if p.charsRight() == 0 || p.moveRightGetChar() != '}' {
+ return "", p.getErr(ErrIncompleteSlashP)
+ }
+
+ if !isValidUnicodeCat(capname) {
+ return "", p.getErr(ErrUnknownSlashP, capname)
+ }
+
+ return capname, nil
+}
+
+// Returns ReNode type for zero-length assertions with a \ code.
+func (p *parser) typeFromCode(ch rune) nodeType {
+ switch ch {
+ case 'b':
+ if p.useOptionE() {
+ return ntECMABoundary
+ }
+ return ntBoundary
+ case 'B':
+ if p.useOptionE() {
+ return ntNonECMABoundary
+ }
+ return ntNonboundary
+ case 'A':
+ return ntBeginning
+ case 'G':
+ return ntStart
+ case 'Z':
+ return ntEndZ
+ case 'z':
+ return ntEnd
+ default:
+ return ntNothing
+ }
+}
+
+// Scans whitespace or x-mode comments.
+func (p *parser) scanBlank() error {
+ if p.useOptionX() {
+ for {
+ for p.charsRight() > 0 && isSpace(p.rightChar(0)) {
+ p.moveRight(1)
+ }
+
+ if p.charsRight() == 0 {
+ break
+ }
+
+ if p.rightChar(0) == '#' {
+ for p.charsRight() > 0 && p.rightChar(0) != '\n' {
+ p.moveRight(1)
+ }
+ } else if p.charsRight() >= 3 && p.rightChar(2) == '#' &&
+ p.rightChar(1) == '?' && p.rightChar(0) == '(' {
+ for p.charsRight() > 0 && p.rightChar(0) != ')' {
+ p.moveRight(1)
+ }
+ if p.charsRight() == 0 {
+ return p.getErr(ErrUnterminatedComment)
+ }
+ p.moveRight(1)
+ } else {
+ break
+ }
+ }
+ } else {
+ for {
+ if p.charsRight() < 3 || p.rightChar(2) != '#' ||
+ p.rightChar(1) != '?' || p.rightChar(0) != '(' {
+ return nil
+ }
+
+ for p.charsRight() > 0 && p.rightChar(0) != ')' {
+ p.moveRight(1)
+ }
+ if p.charsRight() == 0 {
+ return p.getErr(ErrUnterminatedComment)
+ }
+ p.moveRight(1)
+ }
+ }
+ return nil
+}
+
+func (p *parser) scanCapname() string {
+ startpos := p.textpos()
+
+ for p.charsRight() > 0 {
+ if !IsWordChar(p.moveRightGetChar()) {
+ p.moveLeft()
+ break
+ }
+ }
+
+ return string(p.pattern[startpos:p.textpos()])
+}
+
+// Scans contents of [] (not including []'s), and converts to a set.
+func (p *parser) scanCharSet(caseInsensitive, scanOnly bool) (*CharSet, error) {
+ ch := '\x00'
+ chPrev := '\x00'
+ inRange := false
+ firstChar := true
+ closed := false
+
+ var cc *CharSet
+ if !scanOnly {
+ cc = &CharSet{}
+ }
+
+ if p.charsRight() > 0 && p.rightChar(0) == '^' {
+ p.moveRight(1)
+ if !scanOnly {
+ cc.negate = true
+ }
+ }
+
+ for ; p.charsRight() > 0; firstChar = false {
+ fTranslatedChar := false
+ ch = p.moveRightGetChar()
+ if ch == ']' {
+ if !firstChar {
+ closed = true
+ break
+ } else if p.useOptionE() {
+ if !scanOnly {
+ cc.addRanges(NoneClass().ranges)
+ }
+ closed = true
+ break
+ }
+
+ } else if ch == '\\' && p.charsRight() > 0 {
+ switch ch = p.moveRightGetChar(); ch {
+ case 'D', 'd':
+ if !scanOnly {
+ if inRange {
+ return nil, p.getErr(ErrBadClassInCharRange, ch)
+ }
+ cc.addDigit(p.useOptionE() || p.useRE2(), ch == 'D', p.patternRaw)
+ }
+ continue
+
+ case 'S', 's':
+ if !scanOnly {
+ if inRange {
+ return nil, p.getErr(ErrBadClassInCharRange, ch)
+ }
+ cc.addSpace(p.useOptionE(), p.useRE2(), ch == 'S')
+ }
+ continue
+
+ case 'W', 'w':
+ if !scanOnly {
+ if inRange {
+ return nil, p.getErr(ErrBadClassInCharRange, ch)
+ }
+
+ cc.addWord(p.useOptionE() || p.useRE2(), ch == 'W')
+ }
+ continue
+
+ case 'p', 'P':
+ if !scanOnly {
+ if inRange {
+ return nil, p.getErr(ErrBadClassInCharRange, ch)
+ }
+ prop, err := p.parseProperty()
+ if err != nil {
+ return nil, err
+ }
+ cc.addCategory(prop, (ch != 'p'), caseInsensitive, p.patternRaw)
+ } else {
+ p.parseProperty()
+ }
+
+ continue
+
+ case '-':
+ if !scanOnly {
+ cc.addRange(ch, ch)
+ }
+ continue
+
+ default:
+ p.moveLeft()
+ var err error
+ ch, err = p.scanCharEscape() // non-literal character
+ if err != nil {
+ return nil, err
+ }
+ fTranslatedChar = true
+ break // this break will only break out of the switch
+ }
+ } else if ch == '[' {
+ // This is code for Posix style properties - [:Ll:] or [:IsTibetan:].
+ // It currently doesn't do anything other than skip the whole thing!
+ if p.charsRight() > 0 && p.rightChar(0) == ':' && !inRange {
+ savePos := p.textpos()
+
+ p.moveRight(1)
+ negate := false
+ if p.charsRight() > 1 && p.rightChar(0) == '^' {
+ negate = true
+ p.moveRight(1)
+ }
+
+ nm := p.scanCapname() // snag the name
+ if !scanOnly && p.useRE2() {
+ // look up the name since these are valid for RE2
+ // add the group based on the name
+ if ok := cc.addNamedASCII(nm, negate); !ok {
+ return nil, p.getErr(ErrInvalidCharRange)
+ }
+ }
+ if p.charsRight() < 2 || p.moveRightGetChar() != ':' || p.moveRightGetChar() != ']' {
+ p.textto(savePos)
+ } else if p.useRE2() {
+ // move on
+ continue
+ }
+ }
+ }
+
+ if inRange {
+ inRange = false
+ if !scanOnly {
+ if ch == '[' && !fTranslatedChar && !firstChar {
+ // We thought we were in a range, but we're actually starting a subtraction.
+ // In that case, we'll add chPrev to our char class, skip the opening [, and
+ // scan the new character class recursively.
+ cc.addChar(chPrev)
+ sub, err := p.scanCharSet(caseInsensitive, false)
+ if err != nil {
+ return nil, err
+ }
+ cc.addSubtraction(sub)
+
+ if p.charsRight() > 0 && p.rightChar(0) != ']' {
+ return nil, p.getErr(ErrSubtractionMustBeLast)
+ }
+ } else {
+ // a regular range, like a-z
+ if chPrev > ch {
+ return nil, p.getErr(ErrReversedCharRange, chPrev, ch)
+ }
+ cc.addRange(chPrev, ch)
+ }
+ }
+ } else if p.charsRight() >= 2 && p.rightChar(0) == '-' && p.rightChar(1) != ']' {
+ // this could be the start of a range
+ chPrev = ch
+ inRange = true
+ p.moveRight(1)
+ } else if p.charsRight() >= 1 && ch == '-' && !fTranslatedChar && p.rightChar(0) == '[' && !firstChar {
+ // we aren't in a range, and now there is a subtraction. Usually this happens
+ // only when a subtraction follows a range, like [a-z-[b]]
+ if !scanOnly {
+ p.moveRight(1)
+ sub, err := p.scanCharSet(caseInsensitive, false)
+ if err != nil {
+ return nil, err
+ }
+ cc.addSubtraction(sub)
+
+ if p.charsRight() > 0 && p.rightChar(0) != ']' {
+ return nil, p.getErr(ErrSubtractionMustBeLast)
+ }
+ } else {
+ p.moveRight(1)
+ p.scanCharSet(caseInsensitive, true)
+ }
+ } else {
+ if !scanOnly {
+ cc.addRange(ch, ch)
+ }
+ }
+ }
+
+ if !closed {
+ return nil, p.getErr(ErrUnterminatedBracket)
+ }
+
+ if !scanOnly && caseInsensitive {
+ cc.addLowercase()
+ }
+
+ return cc, nil
+}
+
+// Scans any number of decimal digits (pegs value at 2^31-1 if too large)
+func (p *parser) scanDecimal() (int, error) {
+ i := 0
+ var d int
+
+ for p.charsRight() > 0 {
+ d = int(p.rightChar(0) - '0')
+ if d < 0 || d > 9 {
+ break
+ }
+ p.moveRight(1)
+
+ if i > maxValueDiv10 || (i == maxValueDiv10 && d > maxValueMod10) {
+ return 0, p.getErr(ErrCaptureGroupOutOfRange)
+ }
+
+ i *= 10
+ i += d
+ }
+
+ return int(i), nil
+}
+
+// Returns true for options allowed only at the top level
+func isOnlyTopOption(option RegexOptions) bool {
+ return option == RightToLeft || option == ECMAScript || option == RE2
+}
+
+// Scans cimsx-cimsx option string, stops at the first unrecognized char.
+func (p *parser) scanOptions() {
+
+ for off := false; p.charsRight() > 0; p.moveRight(1) {
+ ch := p.rightChar(0)
+
+ if ch == '-' {
+ off = true
+ } else if ch == '+' {
+ off = false
+ } else {
+ option := optionFromCode(ch)
+ if option == 0 || isOnlyTopOption(option) {
+ return
+ }
+
+ if off {
+ p.options &= ^option
+ } else {
+ p.options |= option
+ }
+ }
+ }
+}
+
+// Scans \ code for escape codes that map to single unicode chars.
+func (p *parser) scanCharEscape() (r rune, err error) {
+
+ ch := p.moveRightGetChar()
+
+ if ch >= '0' && ch <= '7' {
+ p.moveLeft()
+ return p.scanOctal(), nil
+ }
+
+ pos := p.textpos()
+
+ switch ch {
+ case 'x':
+ // support for \x{HEX} syntax from Perl and PCRE
+ if p.charsRight() > 0 && p.rightChar(0) == '{' {
+ if p.useOptionE() {
+ return ch, nil
+ }
+ p.moveRight(1)
+ return p.scanHexUntilBrace()
+ } else {
+ r, err = p.scanHex(2)
+ }
+ case 'u':
+ // ECMAscript suppot \u{HEX} only if `u` is also set
+ if p.useOptionE() && p.useOptionU() && p.charsRight() > 0 && p.rightChar(0) == '{' {
+ p.moveRight(1)
+ return p.scanHexUntilBrace()
+ } else {
+ r, err = p.scanHex(4)
+ }
+ case 'a':
+ return '\u0007', nil
+ case 'b':
+ return '\b', nil
+ case 'e':
+ return '\u001B', nil
+ case 'f':
+ return '\f', nil
+ case 'n':
+ return '\n', nil
+ case 'r':
+ return '\r', nil
+ case 't':
+ return '\t', nil
+ case 'v':
+ return '\u000B', nil
+ case 'c':
+ r, err = p.scanControl()
+ default:
+ if !p.useOptionE() && !p.useRE2() && IsWordChar(ch) {
+ return 0, p.getErr(ErrUnrecognizedEscape, string(ch))
+ }
+ return ch, nil
+ }
+ if err != nil && p.useOptionE() {
+ p.textto(pos)
+ return ch, nil
+ }
+ return
+}
+
+// Grabs and converts an ascii control character
+func (p *parser) scanControl() (rune, error) {
+ if p.charsRight() <= 0 {
+ return 0, p.getErr(ErrMissingControl)
+ }
+
+ ch := p.moveRightGetChar()
+
+ // \ca interpreted as \cA
+
+ if ch >= 'a' && ch <= 'z' {
+ ch = (ch - ('a' - 'A'))
+ }
+ ch = (ch - '@')
+ if ch >= 0 && ch < ' ' {
+ return ch, nil
+ }
+
+ return 0, p.getErr(ErrUnrecognizedControl)
+
+}
+
+// Scan hex digits until we hit a closing brace.
+// Non-hex digits, hex value too large for UTF-8, or running out of chars are errors
+func (p *parser) scanHexUntilBrace() (rune, error) {
+ // PCRE spec reads like unlimited hex digits are allowed, but unicode has a limit
+ // so we can enforce that
+ i := 0
+ hasContent := false
+
+ for p.charsRight() > 0 {
+ ch := p.moveRightGetChar()
+ if ch == '}' {
+ // hit our close brace, we're done here
+ // prevent \x{}
+ if !hasContent {
+ return 0, p.getErr(ErrTooFewHex)
+ }
+ return rune(i), nil
+ }
+ hasContent = true
+ // no brace needs to be hex digit
+ d := hexDigit(ch)
+ if d < 0 {
+ return 0, p.getErr(ErrMissingBrace)
+ }
+
+ i *= 0x10
+ i += d
+
+ if i > unicode.MaxRune {
+ return 0, p.getErr(ErrInvalidHex)
+ }
+ }
+
+ // we only make it here if we run out of digits without finding the brace
+ return 0, p.getErr(ErrMissingBrace)
+}
+
+// Scans exactly c hex digits (c=2 for \xFF, c=4 for \uFFFF)
+func (p *parser) scanHex(c int) (rune, error) {
+
+ i := 0
+
+ if p.charsRight() >= c {
+ for c > 0 {
+ d := hexDigit(p.moveRightGetChar())
+ if d < 0 {
+ break
+ }
+ i *= 0x10
+ i += d
+ c--
+ }
+ }
+
+ if c > 0 {
+ return 0, p.getErr(ErrTooFewHex)
+ }
+
+ return rune(i), nil
+}
+
+// Returns n <= 0xF for a hex digit.
+func hexDigit(ch rune) int {
+
+ if d := uint(ch - '0'); d <= 9 {
+ return int(d)
+ }
+
+ if d := uint(ch - 'a'); d <= 5 {
+ return int(d + 0xa)
+ }
+
+ if d := uint(ch - 'A'); d <= 5 {
+ return int(d + 0xa)
+ }
+
+ return -1
+}
+
+// Scans up to three octal digits (stops before exceeding 0377).
+func (p *parser) scanOctal() rune {
+ // Consume octal chars only up to 3 digits and value 0377
+
+ c := 3
+
+ if c > p.charsRight() {
+ c = p.charsRight()
+ }
+
+ //we know the first char is good because the caller had to check
+ i := 0
+ d := int(p.rightChar(0) - '0')
+ for c > 0 && d <= 7 && d >= 0 {
+ if i >= 0x20 && p.useOptionE() {
+ break
+ }
+ i *= 8
+ i += d
+ c--
+
+ p.moveRight(1)
+ if !p.rightMost() {
+ d = int(p.rightChar(0) - '0')
+ }
+ }
+
+ // Octal codes only go up to 255. Any larger and the behavior that Perl follows
+ // is simply to truncate the high bits.
+ i &= 0xFF
+
+ return rune(i)
+}
+
+// Returns the current parsing position.
+func (p *parser) textpos() int {
+ return p.currentPos
+}
+
+// Zaps to a specific parsing position.
+func (p *parser) textto(pos int) {
+ p.currentPos = pos
+}
+
+// Returns the char at the right of the current parsing position and advances to the right.
+func (p *parser) moveRightGetChar() rune {
+ ch := p.pattern[p.currentPos]
+ p.currentPos++
+ return ch
+}
+
+// Moves the current position to the right.
+func (p *parser) moveRight(i int) {
+ // default would be 1
+ p.currentPos += i
+}
+
+// Moves the current parsing position one to the left.
+func (p *parser) moveLeft() {
+ p.currentPos--
+}
+
+// Returns the char left of the current parsing position.
+func (p *parser) charAt(i int) rune {
+ return p.pattern[i]
+}
+
+// Returns the char i chars right of the current parsing position.
+func (p *parser) rightChar(i int) rune {
+ // default would be 0
+ return p.pattern[p.currentPos+i]
+}
+
+// Number of characters to the right of the current parsing position.
+func (p *parser) charsRight() int {
+ return len(p.pattern) - p.currentPos
+}
+
+func (p *parser) rightMost() bool {
+ return p.currentPos == len(p.pattern)
+}
+
+// Looks up the slot number for a given name
+func (p *parser) captureSlotFromName(capname string) int {
+ return p.capnames[capname]
+}
+
+// True if the capture slot was noted
+func (p *parser) isCaptureSlot(i int) bool {
+ if p.caps != nil {
+ _, ok := p.caps[i]
+ return ok
+ }
+
+ return (i >= 0 && i < p.capsize)
+}
+
+// Looks up the slot number for a given name
+func (p *parser) isCaptureName(capname string) bool {
+ if p.capnames == nil {
+ return false
+ }
+
+ _, ok := p.capnames[capname]
+ return ok
+}
+
+// option shortcuts
+
+// True if N option disabling '(' autocapture is on.
+func (p *parser) useOptionN() bool {
+ return (p.options & ExplicitCapture) != 0
+}
+
+// True if I option enabling case-insensitivity is on.
+func (p *parser) useOptionI() bool {
+ return (p.options & IgnoreCase) != 0
+}
+
+// True if M option altering meaning of $ and ^ is on.
+func (p *parser) useOptionM() bool {
+ return (p.options & Multiline) != 0
+}
+
+// True if S option altering meaning of . is on.
+func (p *parser) useOptionS() bool {
+ return (p.options & Singleline) != 0
+}
+
+// True if X option enabling whitespace/comment mode is on.
+func (p *parser) useOptionX() bool {
+ return (p.options & IgnorePatternWhitespace) != 0
+}
+
+// True if E option enabling ECMAScript behavior on.
+func (p *parser) useOptionE() bool {
+ return (p.options & ECMAScript) != 0
+}
+
+// true to use RE2 compatibility parsing behavior.
+func (p *parser) useRE2() bool {
+ return (p.options & RE2) != 0
+}
+
+// True if U option enabling ECMAScript's Unicode behavior on.
+func (p *parser) useOptionU() bool {
+ return (p.options & Unicode) != 0
+}
+
+// True if options stack is empty.
+func (p *parser) emptyOptionsStack() bool {
+ return len(p.optionsStack) == 0
+}
+
+// Finish the current quantifiable (when a quantifier is not found or is not possible)
+func (p *parser) addConcatenate() {
+ // The first (| inside a Testgroup group goes directly to the group
+ p.concatenation.addChild(p.unit)
+ p.unit = nil
+}
+
+// Finish the current quantifiable (when a quantifier is found)
+func (p *parser) addConcatenate3(lazy bool, min, max int) {
+ p.concatenation.addChild(p.unit.makeQuantifier(lazy, min, max))
+ p.unit = nil
+}
+
+// Sets the current unit to a single char node
+func (p *parser) addUnitOne(ch rune) {
+ if p.useOptionI() {
+ ch = unicode.ToLower(ch)
+ }
+
+ p.unit = newRegexNodeCh(ntOne, p.options, ch)
+}
+
+// Sets the current unit to a single inverse-char node
+func (p *parser) addUnitNotone(ch rune) {
+ if p.useOptionI() {
+ ch = unicode.ToLower(ch)
+ }
+
+ p.unit = newRegexNodeCh(ntNotone, p.options, ch)
+}
+
+// Sets the current unit to a single set node
+func (p *parser) addUnitSet(set *CharSet) {
+ p.unit = newRegexNodeSet(ntSet, p.options, set)
+}
+
+// Sets the current unit to a subtree
+func (p *parser) addUnitNode(node *regexNode) {
+ p.unit = node
+}
+
+// Sets the current unit to an assertion of the specified type
+func (p *parser) addUnitType(t nodeType) {
+ p.unit = newRegexNode(t, p.options)
+}
+
+// Finish the current group (in response to a ')' or end)
+func (p *parser) addGroup() error {
+ if p.group.t == ntTestgroup || p.group.t == ntTestref {
+ p.group.addChild(p.concatenation.reverseLeft())
+ if (p.group.t == ntTestref && len(p.group.children) > 2) || len(p.group.children) > 3 {
+ return p.getErr(ErrTooManyAlternates)
+ }
+ } else {
+ p.alternation.addChild(p.concatenation.reverseLeft())
+ p.group.addChild(p.alternation)
+ }
+
+ p.unit = p.group
+ return nil
+}
+
+// Pops the option stack, but keeps the current options unchanged.
+func (p *parser) popKeepOptions() {
+ lastIdx := len(p.optionsStack) - 1
+ p.optionsStack = p.optionsStack[:lastIdx]
+}
+
+// Recalls options from the stack.
+func (p *parser) popOptions() {
+ lastIdx := len(p.optionsStack) - 1
+ // get the last item on the stack and then remove it by reslicing
+ p.options = p.optionsStack[lastIdx]
+ p.optionsStack = p.optionsStack[:lastIdx]
+}
+
+// Saves options on a stack.
+func (p *parser) pushOptions() {
+ p.optionsStack = append(p.optionsStack, p.options)
+}
+
+// Add a string to the last concatenate.
+func (p *parser) addToConcatenate(pos, cch int, isReplacement bool) {
+ var node *regexNode
+
+ if cch == 0 {
+ return
+ }
+
+ if cch > 1 {
+ str := make([]rune, cch)
+ copy(str, p.pattern[pos:pos+cch])
+
+ if p.useOptionI() && !isReplacement {
+ // We do the ToLower character by character for consistency. With surrogate chars, doing
+ // a ToLower on the entire string could actually change the surrogate pair. This is more correct
+ // linguistically, but since Regex doesn't support surrogates, it's more important to be
+ // consistent.
+ for i := 0; i < len(str); i++ {
+ str[i] = unicode.ToLower(str[i])
+ }
+ }
+
+ node = newRegexNodeStr(ntMulti, p.options, str)
+ } else {
+ ch := p.charAt(pos)
+
+ if p.useOptionI() && !isReplacement {
+ ch = unicode.ToLower(ch)
+ }
+
+ node = newRegexNodeCh(ntOne, p.options, ch)
+ }
+
+ p.concatenation.addChild(node)
+}
+
+// Push the parser state (in response to an open paren)
+func (p *parser) pushGroup() {
+ p.group.next = p.stack
+ p.alternation.next = p.group
+ p.concatenation.next = p.alternation
+ p.stack = p.concatenation
+}
+
+// Remember the pushed state (in response to a ')')
+func (p *parser) popGroup() error {
+ p.concatenation = p.stack
+ p.alternation = p.concatenation.next
+ p.group = p.alternation.next
+ p.stack = p.group.next
+
+ // The first () inside a Testgroup group goes directly to the group
+ if p.group.t == ntTestgroup && len(p.group.children) == 0 {
+ if p.unit == nil {
+ return p.getErr(ErrConditionalExpression)
+ }
+
+ p.group.addChild(p.unit)
+ p.unit = nil
+ }
+ return nil
+}
+
+// True if the group stack is empty.
+func (p *parser) emptyStack() bool {
+ return p.stack == nil
+}
+
+// Start a new round for the parser state (in response to an open paren or string start)
+func (p *parser) startGroup(openGroup *regexNode) {
+ p.group = openGroup
+ p.alternation = newRegexNode(ntAlternate, p.options)
+ p.concatenation = newRegexNode(ntConcatenate, p.options)
+}
+
+// Finish the current concatenation (in response to a |)
+func (p *parser) addAlternate() {
+ // The | parts inside a Testgroup group go directly to the group
+
+ if p.group.t == ntTestgroup || p.group.t == ntTestref {
+ p.group.addChild(p.concatenation.reverseLeft())
+ } else {
+ p.alternation.addChild(p.concatenation.reverseLeft())
+ }
+
+ p.concatenation = newRegexNode(ntConcatenate, p.options)
+}
+
+// For categorizing ascii characters.
+
+const (
+ Q byte = 5 // quantifier
+ S = 4 // ordinary stopper
+ Z = 3 // ScanBlank stopper
+ X = 2 // whitespace
+ E = 1 // should be escaped
+)
+
+var _category = []byte{
+ //01 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, X, X, X, X, X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
+ X, 0, 0, Z, S, 0, 0, 0, S, S, Q, Q, 0, 0, S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Q,
+ //@A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, S, 0,
+ //'a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Q, S, 0, 0, 0,
+}
+
+func isSpace(ch rune) bool {
+ return (ch <= ' ' && _category[ch] == X)
+}
+
+// Returns true for those characters that terminate a string of ordinary chars.
+func isSpecial(ch rune) bool {
+ return (ch <= '|' && _category[ch] >= S)
+}
+
+// Returns true for those characters that terminate a string of ordinary chars.
+func isStopperX(ch rune) bool {
+ return (ch <= '|' && _category[ch] >= X)
+}
+
+// Returns true for those characters that begin a quantifier.
+func isQuantifier(ch rune) bool {
+ return (ch <= '{' && _category[ch] >= Q)
+}
+
+func (p *parser) isTrueQuantifier() bool {
+ nChars := p.charsRight()
+ if nChars == 0 {
+ return false
+ }
+
+ startpos := p.textpos()
+ ch := p.charAt(startpos)
+ if ch != '{' {
+ return ch <= '{' && _category[ch] >= Q
+ }
+
+ //UGLY: this is ugly -- the original code was ugly too
+ pos := startpos
+ for {
+ nChars--
+ if nChars <= 0 {
+ break
+ }
+ pos++
+ ch = p.charAt(pos)
+ if ch < '0' || ch > '9' {
+ break
+ }
+ }
+
+ if nChars == 0 || pos-startpos == 1 {
+ return false
+ }
+ if ch == '}' {
+ return true
+ }
+ if ch != ',' {
+ return false
+ }
+ for {
+ nChars--
+ if nChars <= 0 {
+ break
+ }
+ pos++
+ ch = p.charAt(pos)
+ if ch < '0' || ch > '9' {
+ break
+ }
+ }
+
+ return nChars > 0 && ch == '}'
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/prefix.go b/vendor/github.com/dlclark/regexp2/syntax/prefix.go
new file mode 100644
index 00000000..f6716886
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/prefix.go
@@ -0,0 +1,896 @@
+package syntax
+
+import (
+ "bytes"
+ "fmt"
+ "strconv"
+ "unicode"
+ "unicode/utf8"
+)
+
+type Prefix struct {
+ PrefixStr []rune
+ PrefixSet CharSet
+ CaseInsensitive bool
+}
+
+// It takes a RegexTree and computes the set of chars that can start it.
+func getFirstCharsPrefix(tree *RegexTree) *Prefix {
+ s := regexFcd{
+ fcStack: make([]regexFc, 32),
+ intStack: make([]int, 32),
+ }
+ fc := s.regexFCFromRegexTree(tree)
+
+ if fc == nil || fc.nullable || fc.cc.IsEmpty() {
+ return nil
+ }
+ fcSet := fc.getFirstChars()
+ return &Prefix{PrefixSet: fcSet, CaseInsensitive: fc.caseInsensitive}
+}
+
+type regexFcd struct {
+ intStack []int
+ intDepth int
+ fcStack []regexFc
+ fcDepth int
+ skipAllChildren bool // don't process any more children at the current level
+ skipchild bool // don't process the current child.
+ failed bool
+}
+
+/*
+ * The main FC computation. It does a shortcutted depth-first walk
+ * through the tree and calls CalculateFC to emits code before
+ * and after each child of an interior node, and at each leaf.
+ */
+func (s *regexFcd) regexFCFromRegexTree(tree *RegexTree) *regexFc {
+ curNode := tree.root
+ curChild := 0
+
+ for {
+ if len(curNode.children) == 0 {
+ // This is a leaf node
+ s.calculateFC(curNode.t, curNode, 0)
+ } else if curChild < len(curNode.children) && !s.skipAllChildren {
+ // This is an interior node, and we have more children to analyze
+ s.calculateFC(curNode.t|beforeChild, curNode, curChild)
+
+ if !s.skipchild {
+ curNode = curNode.children[curChild]
+ // this stack is how we get a depth first walk of the tree.
+ s.pushInt(curChild)
+ curChild = 0
+ } else {
+ curChild++
+ s.skipchild = false
+ }
+ continue
+ }
+
+ // This is an interior node where we've finished analyzing all the children, or
+ // the end of a leaf node.
+ s.skipAllChildren = false
+
+ if s.intIsEmpty() {
+ break
+ }
+
+ curChild = s.popInt()
+ curNode = curNode.next
+
+ s.calculateFC(curNode.t|afterChild, curNode, curChild)
+ if s.failed {
+ return nil
+ }
+
+ curChild++
+ }
+
+ if s.fcIsEmpty() {
+ return nil
+ }
+
+ return s.popFC()
+}
+
+// To avoid recursion, we use a simple integer stack.
+// This is the push.
+func (s *regexFcd) pushInt(I int) {
+ if s.intDepth >= len(s.intStack) {
+ expanded := make([]int, s.intDepth*2)
+ copy(expanded, s.intStack)
+ s.intStack = expanded
+ }
+
+ s.intStack[s.intDepth] = I
+ s.intDepth++
+}
+
+// True if the stack is empty.
+func (s *regexFcd) intIsEmpty() bool {
+ return s.intDepth == 0
+}
+
+// This is the pop.
+func (s *regexFcd) popInt() int {
+ s.intDepth--
+ return s.intStack[s.intDepth]
+}
+
+// We also use a stack of RegexFC objects.
+// This is the push.
+func (s *regexFcd) pushFC(fc regexFc) {
+ if s.fcDepth >= len(s.fcStack) {
+ expanded := make([]regexFc, s.fcDepth*2)
+ copy(expanded, s.fcStack)
+ s.fcStack = expanded
+ }
+
+ s.fcStack[s.fcDepth] = fc
+ s.fcDepth++
+}
+
+// True if the stack is empty.
+func (s *regexFcd) fcIsEmpty() bool {
+ return s.fcDepth == 0
+}
+
+// This is the pop.
+func (s *regexFcd) popFC() *regexFc {
+ s.fcDepth--
+ return &s.fcStack[s.fcDepth]
+}
+
+// This is the top.
+func (s *regexFcd) topFC() *regexFc {
+ return &s.fcStack[s.fcDepth-1]
+}
+
+// Called in Beforechild to prevent further processing of the current child
+func (s *regexFcd) skipChild() {
+ s.skipchild = true
+}
+
+// FC computation and shortcut cases for each node type
+func (s *regexFcd) calculateFC(nt nodeType, node *regexNode, CurIndex int) {
+ //fmt.Printf("NodeType: %v, CurIndex: %v, Desc: %v\n", nt, CurIndex, node.description())
+ ci := false
+ rtl := false
+
+ if nt <= ntRef {
+ if (node.options & IgnoreCase) != 0 {
+ ci = true
+ }
+ if (node.options & RightToLeft) != 0 {
+ rtl = true
+ }
+ }
+
+ switch nt {
+ case ntConcatenate | beforeChild, ntAlternate | beforeChild, ntTestref | beforeChild, ntLoop | beforeChild, ntLazyloop | beforeChild:
+ break
+
+ case ntTestgroup | beforeChild:
+ if CurIndex == 0 {
+ s.skipChild()
+ }
+ break
+
+ case ntEmpty:
+ s.pushFC(regexFc{nullable: true})
+ break
+
+ case ntConcatenate | afterChild:
+ if CurIndex != 0 {
+ child := s.popFC()
+ cumul := s.topFC()
+
+ s.failed = !cumul.addFC(*child, true)
+ }
+
+ fc := s.topFC()
+ if !fc.nullable {
+ s.skipAllChildren = true
+ }
+ break
+
+ case ntTestgroup | afterChild:
+ if CurIndex > 1 {
+ child := s.popFC()
+ cumul := s.topFC()
+
+ s.failed = !cumul.addFC(*child, false)
+ }
+ break
+
+ case ntAlternate | afterChild, ntTestref | afterChild:
+ if CurIndex != 0 {
+ child := s.popFC()
+ cumul := s.topFC()
+
+ s.failed = !cumul.addFC(*child, false)
+ }
+ break
+
+ case ntLoop | afterChild, ntLazyloop | afterChild:
+ if node.m == 0 {
+ fc := s.topFC()
+ fc.nullable = true
+ }
+ break
+
+ case ntGroup | beforeChild, ntGroup | afterChild, ntCapture | beforeChild, ntCapture | afterChild, ntGreedy | beforeChild, ntGreedy | afterChild:
+ break
+
+ case ntRequire | beforeChild, ntPrevent | beforeChild:
+ s.skipChild()
+ s.pushFC(regexFc{nullable: true})
+ break
+
+ case ntRequire | afterChild, ntPrevent | afterChild:
+ break
+
+ case ntOne, ntNotone:
+ s.pushFC(newRegexFc(node.ch, nt == ntNotone, false, ci))
+ break
+
+ case ntOneloop, ntOnelazy:
+ s.pushFC(newRegexFc(node.ch, false, node.m == 0, ci))
+ break
+
+ case ntNotoneloop, ntNotonelazy:
+ s.pushFC(newRegexFc(node.ch, true, node.m == 0, ci))
+ break
+
+ case ntMulti:
+ if len(node.str) == 0 {
+ s.pushFC(regexFc{nullable: true})
+ } else if !rtl {
+ s.pushFC(newRegexFc(node.str[0], false, false, ci))
+ } else {
+ s.pushFC(newRegexFc(node.str[len(node.str)-1], false, false, ci))
+ }
+ break
+
+ case ntSet:
+ s.pushFC(regexFc{cc: node.set.Copy(), nullable: false, caseInsensitive: ci})
+ break
+
+ case ntSetloop, ntSetlazy:
+ s.pushFC(regexFc{cc: node.set.Copy(), nullable: node.m == 0, caseInsensitive: ci})
+ break
+
+ case ntRef:
+ s.pushFC(regexFc{cc: *AnyClass(), nullable: true, caseInsensitive: false})
+ break
+
+ case ntNothing, ntBol, ntEol, ntBoundary, ntNonboundary, ntECMABoundary, ntNonECMABoundary, ntBeginning, ntStart, ntEndZ, ntEnd:
+ s.pushFC(regexFc{nullable: true})
+ break
+
+ default:
+ panic(fmt.Sprintf("unexpected op code: %v", nt))
+ }
+}
+
+type regexFc struct {
+ cc CharSet
+ nullable bool
+ caseInsensitive bool
+}
+
+func newRegexFc(ch rune, not, nullable, caseInsensitive bool) regexFc {
+ r := regexFc{
+ caseInsensitive: caseInsensitive,
+ nullable: nullable,
+ }
+ if not {
+ if ch > 0 {
+ r.cc.addRange('\x00', ch-1)
+ }
+ if ch < 0xFFFF {
+ r.cc.addRange(ch+1, utf8.MaxRune)
+ }
+ } else {
+ r.cc.addRange(ch, ch)
+ }
+ return r
+}
+
+func (r *regexFc) getFirstChars() CharSet {
+ if r.caseInsensitive {
+ r.cc.addLowercase()
+ }
+
+ return r.cc
+}
+
+func (r *regexFc) addFC(fc regexFc, concatenate bool) bool {
+ if !r.cc.IsMergeable() || !fc.cc.IsMergeable() {
+ return false
+ }
+
+ if concatenate {
+ if !r.nullable {
+ return true
+ }
+
+ if !fc.nullable {
+ r.nullable = false
+ }
+ } else {
+ if fc.nullable {
+ r.nullable = true
+ }
+ }
+
+ r.caseInsensitive = r.caseInsensitive || fc.caseInsensitive
+ r.cc.addSet(fc.cc)
+
+ return true
+}
+
+// This is a related computation: it takes a RegexTree and computes the
+// leading substring if it sees one. It's quite trivial and gives up easily.
+func getPrefix(tree *RegexTree) *Prefix {
+ var concatNode *regexNode
+ nextChild := 0
+
+ curNode := tree.root
+
+ for {
+ switch curNode.t {
+ case ntConcatenate:
+ if len(curNode.children) > 0 {
+ concatNode = curNode
+ nextChild = 0
+ }
+
+ case ntGreedy, ntCapture:
+ curNode = curNode.children[0]
+ concatNode = nil
+ continue
+
+ case ntOneloop, ntOnelazy:
+ if curNode.m > 0 {
+ return &Prefix{
+ PrefixStr: repeat(curNode.ch, curNode.m),
+ CaseInsensitive: (curNode.options & IgnoreCase) != 0,
+ }
+ }
+ return nil
+
+ case ntOne:
+ return &Prefix{
+ PrefixStr: []rune{curNode.ch},
+ CaseInsensitive: (curNode.options & IgnoreCase) != 0,
+ }
+
+ case ntMulti:
+ return &Prefix{
+ PrefixStr: curNode.str,
+ CaseInsensitive: (curNode.options & IgnoreCase) != 0,
+ }
+
+ case ntBol, ntEol, ntBoundary, ntECMABoundary, ntBeginning, ntStart,
+ ntEndZ, ntEnd, ntEmpty, ntRequire, ntPrevent:
+
+ default:
+ return nil
+ }
+
+ if concatNode == nil || nextChild >= len(concatNode.children) {
+ return nil
+ }
+
+ curNode = concatNode.children[nextChild]
+ nextChild++
+ }
+}
+
+// repeat the rune r, c times... up to the max of MaxPrefixSize
+func repeat(r rune, c int) []rune {
+ if c > MaxPrefixSize {
+ c = MaxPrefixSize
+ }
+
+ ret := make([]rune, c)
+
+ // binary growth using copy for speed
+ ret[0] = r
+ bp := 1
+ for bp < len(ret) {
+ copy(ret[bp:], ret[:bp])
+ bp *= 2
+ }
+
+ return ret
+}
+
+// BmPrefix precomputes the Boyer-Moore
+// tables for fast string scanning. These tables allow
+// you to scan for the first occurrence of a string within
+// a large body of text without examining every character.
+// The performance of the heuristic depends on the actual
+// string and the text being searched, but usually, the longer
+// the string that is being searched for, the fewer characters
+// need to be examined.
+type BmPrefix struct {
+ positive []int
+ negativeASCII []int
+ negativeUnicode [][]int
+ pattern []rune
+ lowASCII rune
+ highASCII rune
+ rightToLeft bool
+ caseInsensitive bool
+}
+
+func newBmPrefix(pattern []rune, caseInsensitive, rightToLeft bool) *BmPrefix {
+
+ b := &BmPrefix{
+ rightToLeft: rightToLeft,
+ caseInsensitive: caseInsensitive,
+ pattern: pattern,
+ }
+
+ if caseInsensitive {
+ for i := 0; i < len(b.pattern); i++ {
+ // We do the ToLower character by character for consistency. With surrogate chars, doing
+ // a ToLower on the entire string could actually change the surrogate pair. This is more correct
+ // linguistically, but since Regex doesn't support surrogates, it's more important to be
+ // consistent.
+
+ b.pattern[i] = unicode.ToLower(b.pattern[i])
+ }
+ }
+
+ var beforefirst, last, bump int
+ var scan, match int
+
+ if !rightToLeft {
+ beforefirst = -1
+ last = len(b.pattern) - 1
+ bump = 1
+ } else {
+ beforefirst = len(b.pattern)
+ last = 0
+ bump = -1
+ }
+
+ // PART I - the good-suffix shift table
+ //
+ // compute the positive requirement:
+ // if char "i" is the first one from the right that doesn't match,
+ // then we know the matcher can advance by _positive[i].
+ //
+ // This algorithm is a simplified variant of the standard
+ // Boyer-Moore good suffix calculation.
+
+ b.positive = make([]int, len(b.pattern))
+
+ examine := last
+ ch := b.pattern[examine]
+ b.positive[examine] = bump
+ examine -= bump
+
+Outerloop:
+ for {
+ // find an internal char (examine) that matches the tail
+
+ for {
+ if examine == beforefirst {
+ break Outerloop
+ }
+ if b.pattern[examine] == ch {
+ break
+ }
+ examine -= bump
+ }
+
+ match = last
+ scan = examine
+
+ // find the length of the match
+ for {
+ if scan == beforefirst || b.pattern[match] != b.pattern[scan] {
+ // at the end of the match, note the difference in _positive
+ // this is not the length of the match, but the distance from the internal match
+ // to the tail suffix.
+ if b.positive[match] == 0 {
+ b.positive[match] = match - scan
+ }
+
+ // System.Diagnostics.Debug.WriteLine("Set positive[" + match + "] to " + (match - scan));
+
+ break
+ }
+
+ scan -= bump
+ match -= bump
+ }
+
+ examine -= bump
+ }
+
+ match = last - bump
+
+ // scan for the chars for which there are no shifts that yield a different candidate
+
+ // The inside of the if statement used to say
+ // "_positive[match] = last - beforefirst;"
+ // This is slightly less aggressive in how much we skip, but at worst it
+ // should mean a little more work rather than skipping a potential match.
+ for match != beforefirst {
+ if b.positive[match] == 0 {
+ b.positive[match] = bump
+ }
+
+ match -= bump
+ }
+
+ // PART II - the bad-character shift table
+ //
+ // compute the negative requirement:
+ // if char "ch" is the reject character when testing position "i",
+ // we can slide up by _negative[ch];
+ // (_negative[ch] = str.Length - 1 - str.LastIndexOf(ch))
+ //
+ // the lookup table is divided into ASCII and Unicode portions;
+ // only those parts of the Unicode 16-bit code set that actually
+ // appear in the string are in the table. (Maximum size with
+ // Unicode is 65K; ASCII only case is 512 bytes.)
+
+ b.negativeASCII = make([]int, 128)
+
+ for i := 0; i < len(b.negativeASCII); i++ {
+ b.negativeASCII[i] = last - beforefirst
+ }
+
+ b.lowASCII = 127
+ b.highASCII = 0
+
+ for examine = last; examine != beforefirst; examine -= bump {
+ ch = b.pattern[examine]
+
+ switch {
+ case ch < 128:
+ if b.lowASCII > ch {
+ b.lowASCII = ch
+ }
+
+ if b.highASCII < ch {
+ b.highASCII = ch
+ }
+
+ if b.negativeASCII[ch] == last-beforefirst {
+ b.negativeASCII[ch] = last - examine
+ }
+ case ch <= 0xffff:
+ i, j := ch>>8, ch&0xFF
+
+ if b.negativeUnicode == nil {
+ b.negativeUnicode = make([][]int, 256)
+ }
+
+ if b.negativeUnicode[i] == nil {
+ newarray := make([]int, 256)
+
+ for k := 0; k < len(newarray); k++ {
+ newarray[k] = last - beforefirst
+ }
+
+ if i == 0 {
+ copy(newarray, b.negativeASCII)
+ //TODO: this line needed?
+ b.negativeASCII = newarray
+ }
+
+ b.negativeUnicode[i] = newarray
+ }
+
+ if b.negativeUnicode[i][j] == last-beforefirst {
+ b.negativeUnicode[i][j] = last - examine
+ }
+ default:
+ // we can't do the filter because this algo doesn't support
+ // unicode chars >0xffff
+ return nil
+ }
+ }
+
+ return b
+}
+
+func (b *BmPrefix) String() string {
+ return string(b.pattern)
+}
+
+// Dump returns the contents of the filter as a human readable string
+func (b *BmPrefix) Dump(indent string) string {
+ buf := &bytes.Buffer{}
+
+ fmt.Fprintf(buf, "%sBM Pattern: %s\n%sPositive: ", indent, string(b.pattern), indent)
+ for i := 0; i < len(b.positive); i++ {
+ buf.WriteString(strconv.Itoa(b.positive[i]))
+ buf.WriteRune(' ')
+ }
+ buf.WriteRune('\n')
+
+ if b.negativeASCII != nil {
+ buf.WriteString(indent)
+ buf.WriteString("Negative table\n")
+ for i := 0; i < len(b.negativeASCII); i++ {
+ if b.negativeASCII[i] != len(b.pattern) {
+ fmt.Fprintf(buf, "%s %s %s\n", indent, Escape(string(rune(i))), strconv.Itoa(b.negativeASCII[i]))
+ }
+ }
+ }
+
+ return buf.String()
+}
+
+// Scan uses the Boyer-Moore algorithm to find the first occurrence
+// of the specified string within text, beginning at index, and
+// constrained within beglimit and endlimit.
+//
+// The direction and case-sensitivity of the match is determined
+// by the arguments to the RegexBoyerMoore constructor.
+func (b *BmPrefix) Scan(text []rune, index, beglimit, endlimit int) int {
+ var (
+ defadv, test, test2 int
+ match, startmatch, endmatch int
+ bump, advance int
+ chTest rune
+ unicodeLookup []int
+ )
+
+ if !b.rightToLeft {
+ defadv = len(b.pattern)
+ startmatch = len(b.pattern) - 1
+ endmatch = 0
+ test = index + defadv - 1
+ bump = 1
+ } else {
+ defadv = -len(b.pattern)
+ startmatch = 0
+ endmatch = -defadv - 1
+ test = index + defadv
+ bump = -1
+ }
+
+ chMatch := b.pattern[startmatch]
+
+ for {
+ if test >= endlimit || test < beglimit {
+ return -1
+ }
+
+ chTest = text[test]
+
+ if b.caseInsensitive {
+ chTest = unicode.ToLower(chTest)
+ }
+
+ if chTest != chMatch {
+ if chTest < 128 {
+ advance = b.negativeASCII[chTest]
+ } else if chTest < 0xffff && len(b.negativeUnicode) > 0 {
+ unicodeLookup = b.negativeUnicode[chTest>>8]
+ if len(unicodeLookup) > 0 {
+ advance = unicodeLookup[chTest&0xFF]
+ } else {
+ advance = defadv
+ }
+ } else {
+ advance = defadv
+ }
+
+ test += advance
+ } else { // if (chTest == chMatch)
+ test2 = test
+ match = startmatch
+
+ for {
+ if match == endmatch {
+ if b.rightToLeft {
+ return test2 + 1
+ } else {
+ return test2
+ }
+ }
+
+ match -= bump
+ test2 -= bump
+
+ chTest = text[test2]
+
+ if b.caseInsensitive {
+ chTest = unicode.ToLower(chTest)
+ }
+
+ if chTest != b.pattern[match] {
+ advance = b.positive[match]
+ if chTest < 128 {
+ test2 = (match - startmatch) + b.negativeASCII[chTest]
+ } else if chTest < 0xffff && len(b.negativeUnicode) > 0 {
+ unicodeLookup = b.negativeUnicode[chTest>>8]
+ if len(unicodeLookup) > 0 {
+ test2 = (match - startmatch) + unicodeLookup[chTest&0xFF]
+ } else {
+ test += advance
+ break
+ }
+ } else {
+ test += advance
+ break
+ }
+
+ if b.rightToLeft {
+ if test2 < advance {
+ advance = test2
+ }
+ } else if test2 > advance {
+ advance = test2
+ }
+
+ test += advance
+ break
+ }
+ }
+ }
+ }
+}
+
+// When a regex is anchored, we can do a quick IsMatch test instead of a Scan
+func (b *BmPrefix) IsMatch(text []rune, index, beglimit, endlimit int) bool {
+ if !b.rightToLeft {
+ if index < beglimit || endlimit-index < len(b.pattern) {
+ return false
+ }
+
+ return b.matchPattern(text, index)
+ } else {
+ if index > endlimit || index-beglimit < len(b.pattern) {
+ return false
+ }
+
+ return b.matchPattern(text, index-len(b.pattern))
+ }
+}
+
+func (b *BmPrefix) matchPattern(text []rune, index int) bool {
+ if len(text)-index < len(b.pattern) {
+ return false
+ }
+
+ if b.caseInsensitive {
+ for i := 0; i < len(b.pattern); i++ {
+ //Debug.Assert(textinfo.ToLower(_pattern[i]) == _pattern[i], "pattern should be converted to lower case in constructor!");
+ if unicode.ToLower(text[index+i]) != b.pattern[i] {
+ return false
+ }
+ }
+ return true
+ } else {
+ for i := 0; i < len(b.pattern); i++ {
+ if text[index+i] != b.pattern[i] {
+ return false
+ }
+ }
+ return true
+ }
+}
+
+type AnchorLoc int16
+
+// where the regex can be pegged
+const (
+ AnchorBeginning AnchorLoc = 0x0001
+ AnchorBol = 0x0002
+ AnchorStart = 0x0004
+ AnchorEol = 0x0008
+ AnchorEndZ = 0x0010
+ AnchorEnd = 0x0020
+ AnchorBoundary = 0x0040
+ AnchorECMABoundary = 0x0080
+)
+
+func getAnchors(tree *RegexTree) AnchorLoc {
+
+ var concatNode *regexNode
+ nextChild, result := 0, AnchorLoc(0)
+
+ curNode := tree.root
+
+ for {
+ switch curNode.t {
+ case ntConcatenate:
+ if len(curNode.children) > 0 {
+ concatNode = curNode
+ nextChild = 0
+ }
+
+ case ntGreedy, ntCapture:
+ curNode = curNode.children[0]
+ concatNode = nil
+ continue
+
+ case ntBol, ntEol, ntBoundary, ntECMABoundary, ntBeginning,
+ ntStart, ntEndZ, ntEnd:
+ return result | anchorFromType(curNode.t)
+
+ case ntEmpty, ntRequire, ntPrevent:
+
+ default:
+ return result
+ }
+
+ if concatNode == nil || nextChild >= len(concatNode.children) {
+ return result
+ }
+
+ curNode = concatNode.children[nextChild]
+ nextChild++
+ }
+}
+
+func anchorFromType(t nodeType) AnchorLoc {
+ switch t {
+ case ntBol:
+ return AnchorBol
+ case ntEol:
+ return AnchorEol
+ case ntBoundary:
+ return AnchorBoundary
+ case ntECMABoundary:
+ return AnchorECMABoundary
+ case ntBeginning:
+ return AnchorBeginning
+ case ntStart:
+ return AnchorStart
+ case ntEndZ:
+ return AnchorEndZ
+ case ntEnd:
+ return AnchorEnd
+ default:
+ return 0
+ }
+}
+
+// anchorDescription returns a human-readable description of the anchors
+func (anchors AnchorLoc) String() string {
+ buf := &bytes.Buffer{}
+
+ if 0 != (anchors & AnchorBeginning) {
+ buf.WriteString(", Beginning")
+ }
+ if 0 != (anchors & AnchorStart) {
+ buf.WriteString(", Start")
+ }
+ if 0 != (anchors & AnchorBol) {
+ buf.WriteString(", Bol")
+ }
+ if 0 != (anchors & AnchorBoundary) {
+ buf.WriteString(", Boundary")
+ }
+ if 0 != (anchors & AnchorECMABoundary) {
+ buf.WriteString(", ECMABoundary")
+ }
+ if 0 != (anchors & AnchorEol) {
+ buf.WriteString(", Eol")
+ }
+ if 0 != (anchors & AnchorEnd) {
+ buf.WriteString(", End")
+ }
+ if 0 != (anchors & AnchorEndZ) {
+ buf.WriteString(", EndZ")
+ }
+
+ // trim off comma
+ if buf.Len() >= 2 {
+ return buf.String()[2:]
+ }
+ return "None"
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/replacerdata.go b/vendor/github.com/dlclark/regexp2/syntax/replacerdata.go
new file mode 100644
index 00000000..bcf4d3f2
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/replacerdata.go
@@ -0,0 +1,87 @@
+package syntax
+
+import (
+ "bytes"
+ "errors"
+)
+
+type ReplacerData struct {
+ Rep string
+ Strings []string
+ Rules []int
+}
+
+const (
+ replaceSpecials = 4
+ replaceLeftPortion = -1
+ replaceRightPortion = -2
+ replaceLastGroup = -3
+ replaceWholeString = -4
+)
+
+//ErrReplacementError is a general error during parsing the replacement text
+var ErrReplacementError = errors.New("Replacement pattern error.")
+
+// NewReplacerData will populate a reusable replacer data struct based on the given replacement string
+// and the capture group data from a regexp
+func NewReplacerData(rep string, caps map[int]int, capsize int, capnames map[string]int, op RegexOptions) (*ReplacerData, error) {
+ p := parser{
+ options: op,
+ caps: caps,
+ capsize: capsize,
+ capnames: capnames,
+ }
+ p.setPattern(rep)
+ concat, err := p.scanReplacement()
+ if err != nil {
+ return nil, err
+ }
+
+ if concat.t != ntConcatenate {
+ panic(ErrReplacementError)
+ }
+
+ sb := &bytes.Buffer{}
+ var (
+ strings []string
+ rules []int
+ )
+
+ for _, child := range concat.children {
+ switch child.t {
+ case ntMulti:
+ child.writeStrToBuf(sb)
+
+ case ntOne:
+ sb.WriteRune(child.ch)
+
+ case ntRef:
+ if sb.Len() > 0 {
+ rules = append(rules, len(strings))
+ strings = append(strings, sb.String())
+ sb.Reset()
+ }
+ slot := child.m
+
+ if len(caps) > 0 && slot >= 0 {
+ slot = caps[slot]
+ }
+
+ rules = append(rules, -replaceSpecials-1-slot)
+
+ default:
+ panic(ErrReplacementError)
+ }
+ }
+
+ if sb.Len() > 0 {
+ rules = append(rules, len(strings))
+ strings = append(strings, sb.String())
+ }
+
+ return &ReplacerData{
+ Rep: rep,
+ Strings: strings,
+ Rules: rules,
+ }, nil
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/tree.go b/vendor/github.com/dlclark/regexp2/syntax/tree.go
new file mode 100644
index 00000000..ea288293
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/tree.go
@@ -0,0 +1,654 @@
+package syntax
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+ "strconv"
+)
+
+type RegexTree struct {
+ root *regexNode
+ caps map[int]int
+ capnumlist []int
+ captop int
+ Capnames map[string]int
+ Caplist []string
+ options RegexOptions
+}
+
+// It is built into a parsed tree for a regular expression.
+
+// Implementation notes:
+//
+// Since the node tree is a temporary data structure only used
+// during compilation of the regexp to integer codes, it's
+// designed for clarity and convenience rather than
+// space efficiency.
+//
+// RegexNodes are built into a tree, linked by the n.children list.
+// Each node also has a n.parent and n.ichild member indicating
+// its parent and which child # it is in its parent's list.
+//
+// RegexNodes come in as many types as there are constructs in
+// a regular expression, for example, "concatenate", "alternate",
+// "one", "rept", "group". There are also node types for basic
+// peephole optimizations, e.g., "onerep", "notsetrep", etc.
+//
+// Because perl 5 allows "lookback" groups that scan backwards,
+// each node also gets a "direction". Normally the value of
+// boolean n.backward = false.
+//
+// During parsing, top-level nodes are also stacked onto a parse
+// stack (a stack of trees). For this purpose we have a n.next
+// pointer. [Note that to save a few bytes, we could overload the
+// n.parent pointer instead.]
+//
+// On the parse stack, each tree has a "role" - basically, the
+// nonterminal in the grammar that the parser has currently
+// assigned to the tree. That code is stored in n.role.
+//
+// Finally, some of the different kinds of nodes have data.
+// Two integers (for the looping constructs) are stored in
+// n.operands, an an object (either a string or a set)
+// is stored in n.data
+type regexNode struct {
+ t nodeType
+ children []*regexNode
+ str []rune
+ set *CharSet
+ ch rune
+ m int
+ n int
+ options RegexOptions
+ next *regexNode
+}
+
+type nodeType int32
+
+const (
+ // The following are leaves, and correspond to primitive operations
+
+ ntOnerep nodeType = 0 // lef,back char,min,max a {n}
+ ntNotonerep = 1 // lef,back char,min,max .{n}
+ ntSetrep = 2 // lef,back set,min,max [\d]{n}
+ ntOneloop = 3 // lef,back char,min,max a {,n}
+ ntNotoneloop = 4 // lef,back char,min,max .{,n}
+ ntSetloop = 5 // lef,back set,min,max [\d]{,n}
+ ntOnelazy = 6 // lef,back char,min,max a {,n}?
+ ntNotonelazy = 7 // lef,back char,min,max .{,n}?
+ ntSetlazy = 8 // lef,back set,min,max [\d]{,n}?
+ ntOne = 9 // lef char a
+ ntNotone = 10 // lef char [^a]
+ ntSet = 11 // lef set [a-z\s] \w \s \d
+ ntMulti = 12 // lef string abcd
+ ntRef = 13 // lef group \#
+ ntBol = 14 // ^
+ ntEol = 15 // $
+ ntBoundary = 16 // \b
+ ntNonboundary = 17 // \B
+ ntBeginning = 18 // \A
+ ntStart = 19 // \G
+ ntEndZ = 20 // \Z
+ ntEnd = 21 // \Z
+
+ // Interior nodes do not correspond to primitive operations, but
+ // control structures compositing other operations
+
+ // Concat and alternate take n children, and can run forward or backwards
+
+ ntNothing = 22 // []
+ ntEmpty = 23 // ()
+ ntAlternate = 24 // a|b
+ ntConcatenate = 25 // ab
+ ntLoop = 26 // m,x * + ? {,}
+ ntLazyloop = 27 // m,x *? +? ?? {,}?
+ ntCapture = 28 // n ()
+ ntGroup = 29 // (?:)
+ ntRequire = 30 // (?=) (?<=)
+ ntPrevent = 31 // (?!) (?) (?<)
+ ntTestref = 33 // (?(n) | )
+ ntTestgroup = 34 // (?(...) | )
+
+ ntECMABoundary = 41 // \b
+ ntNonECMABoundary = 42 // \B
+)
+
+func newRegexNode(t nodeType, opt RegexOptions) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ }
+}
+
+func newRegexNodeCh(t nodeType, opt RegexOptions, ch rune) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ ch: ch,
+ }
+}
+
+func newRegexNodeStr(t nodeType, opt RegexOptions, str []rune) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ str: str,
+ }
+}
+
+func newRegexNodeSet(t nodeType, opt RegexOptions, set *CharSet) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ set: set,
+ }
+}
+
+func newRegexNodeM(t nodeType, opt RegexOptions, m int) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ m: m,
+ }
+}
+func newRegexNodeMN(t nodeType, opt RegexOptions, m, n int) *regexNode {
+ return ®exNode{
+ t: t,
+ options: opt,
+ m: m,
+ n: n,
+ }
+}
+
+func (n *regexNode) writeStrToBuf(buf *bytes.Buffer) {
+ for i := 0; i < len(n.str); i++ {
+ buf.WriteRune(n.str[i])
+ }
+}
+
+func (n *regexNode) addChild(child *regexNode) {
+ reduced := child.reduce()
+ n.children = append(n.children, reduced)
+ reduced.next = n
+}
+
+func (n *regexNode) insertChildren(afterIndex int, nodes []*regexNode) {
+ newChildren := make([]*regexNode, 0, len(n.children)+len(nodes))
+ n.children = append(append(append(newChildren, n.children[:afterIndex]...), nodes...), n.children[afterIndex:]...)
+}
+
+// removes children including the start but not the end index
+func (n *regexNode) removeChildren(startIndex, endIndex int) {
+ n.children = append(n.children[:startIndex], n.children[endIndex:]...)
+}
+
+// Pass type as OneLazy or OneLoop
+func (n *regexNode) makeRep(t nodeType, min, max int) {
+ n.t += (t - ntOne)
+ n.m = min
+ n.n = max
+}
+
+func (n *regexNode) reduce() *regexNode {
+ switch n.t {
+ case ntAlternate:
+ return n.reduceAlternation()
+
+ case ntConcatenate:
+ return n.reduceConcatenation()
+
+ case ntLoop, ntLazyloop:
+ return n.reduceRep()
+
+ case ntGroup:
+ return n.reduceGroup()
+
+ case ntSet, ntSetloop:
+ return n.reduceSet()
+
+ default:
+ return n
+ }
+}
+
+// Basic optimization. Single-letter alternations can be replaced
+// by faster set specifications, and nested alternations with no
+// intervening operators can be flattened:
+//
+// a|b|c|def|g|h -> [a-c]|def|[gh]
+// apple|(?:orange|pear)|grape -> apple|orange|pear|grape
+func (n *regexNode) reduceAlternation() *regexNode {
+ if len(n.children) == 0 {
+ return newRegexNode(ntNothing, n.options)
+ }
+
+ wasLastSet := false
+ lastNodeCannotMerge := false
+ var optionsLast RegexOptions
+ var i, j int
+
+ for i, j = 0, 0; i < len(n.children); i, j = i+1, j+1 {
+ at := n.children[i]
+
+ if j < i {
+ n.children[j] = at
+ }
+
+ for {
+ if at.t == ntAlternate {
+ for k := 0; k < len(at.children); k++ {
+ at.children[k].next = n
+ }
+ n.insertChildren(i+1, at.children)
+
+ j--
+ } else if at.t == ntSet || at.t == ntOne {
+ // Cannot merge sets if L or I options differ, or if either are negated.
+ optionsAt := at.options & (RightToLeft | IgnoreCase)
+
+ if at.t == ntSet {
+ if !wasLastSet || optionsLast != optionsAt || lastNodeCannotMerge || !at.set.IsMergeable() {
+ wasLastSet = true
+ lastNodeCannotMerge = !at.set.IsMergeable()
+ optionsLast = optionsAt
+ break
+ }
+ } else if !wasLastSet || optionsLast != optionsAt || lastNodeCannotMerge {
+ wasLastSet = true
+ lastNodeCannotMerge = false
+ optionsLast = optionsAt
+ break
+ }
+
+ // The last node was a Set or a One, we're a Set or One and our options are the same.
+ // Merge the two nodes.
+ j--
+ prev := n.children[j]
+
+ var prevCharClass *CharSet
+ if prev.t == ntOne {
+ prevCharClass = &CharSet{}
+ prevCharClass.addChar(prev.ch)
+ } else {
+ prevCharClass = prev.set
+ }
+
+ if at.t == ntOne {
+ prevCharClass.addChar(at.ch)
+ } else {
+ prevCharClass.addSet(*at.set)
+ }
+
+ prev.t = ntSet
+ prev.set = prevCharClass
+ } else if at.t == ntNothing {
+ j--
+ } else {
+ wasLastSet = false
+ lastNodeCannotMerge = false
+ }
+ break
+ }
+ }
+
+ if j < i {
+ n.removeChildren(j, i)
+ }
+
+ return n.stripEnation(ntNothing)
+}
+
+// Basic optimization. Adjacent strings can be concatenated.
+//
+// (?:abc)(?:def) -> abcdef
+func (n *regexNode) reduceConcatenation() *regexNode {
+ // Eliminate empties and concat adjacent strings/chars
+
+ var optionsLast RegexOptions
+ var optionsAt RegexOptions
+ var i, j int
+
+ if len(n.children) == 0 {
+ return newRegexNode(ntEmpty, n.options)
+ }
+
+ wasLastString := false
+
+ for i, j = 0, 0; i < len(n.children); i, j = i+1, j+1 {
+ var at, prev *regexNode
+
+ at = n.children[i]
+
+ if j < i {
+ n.children[j] = at
+ }
+
+ if at.t == ntConcatenate &&
+ ((at.options & RightToLeft) == (n.options & RightToLeft)) {
+ for k := 0; k < len(at.children); k++ {
+ at.children[k].next = n
+ }
+
+ //insert at.children at i+1 index in n.children
+ n.insertChildren(i+1, at.children)
+
+ j--
+ } else if at.t == ntMulti || at.t == ntOne {
+ // Cannot merge strings if L or I options differ
+ optionsAt = at.options & (RightToLeft | IgnoreCase)
+
+ if !wasLastString || optionsLast != optionsAt {
+ wasLastString = true
+ optionsLast = optionsAt
+ continue
+ }
+
+ j--
+ prev = n.children[j]
+
+ if prev.t == ntOne {
+ prev.t = ntMulti
+ prev.str = []rune{prev.ch}
+ }
+
+ if (optionsAt & RightToLeft) == 0 {
+ if at.t == ntOne {
+ prev.str = append(prev.str, at.ch)
+ } else {
+ prev.str = append(prev.str, at.str...)
+ }
+ } else {
+ if at.t == ntOne {
+ // insert at the front by expanding our slice, copying the data over, and then setting the value
+ prev.str = append(prev.str, 0)
+ copy(prev.str[1:], prev.str)
+ prev.str[0] = at.ch
+ } else {
+ //insert at the front...this one we'll make a new slice and copy both into it
+ merge := make([]rune, len(prev.str)+len(at.str))
+ copy(merge, at.str)
+ copy(merge[len(at.str):], prev.str)
+ prev.str = merge
+ }
+ }
+ } else if at.t == ntEmpty {
+ j--
+ } else {
+ wasLastString = false
+ }
+ }
+
+ if j < i {
+ // remove indices j through i from the children
+ n.removeChildren(j, i)
+ }
+
+ return n.stripEnation(ntEmpty)
+}
+
+// Nested repeaters just get multiplied with each other if they're not
+// too lumpy
+func (n *regexNode) reduceRep() *regexNode {
+
+ u := n
+ t := n.t
+ min := n.m
+ max := n.n
+
+ for {
+ if len(u.children) == 0 {
+ break
+ }
+
+ child := u.children[0]
+
+ // multiply reps of the same type only
+ if child.t != t {
+ childType := child.t
+
+ if !(childType >= ntOneloop && childType <= ntSetloop && t == ntLoop ||
+ childType >= ntOnelazy && childType <= ntSetlazy && t == ntLazyloop) {
+ break
+ }
+ }
+
+ // child can be too lumpy to blur, e.g., (a {100,105}) {3} or (a {2,})?
+ // [but things like (a {2,})+ are not too lumpy...]
+ if u.m == 0 && child.m > 1 || child.n < child.m*2 {
+ break
+ }
+
+ u = child
+ if u.m > 0 {
+ if (math.MaxInt32-1)/u.m < min {
+ u.m = math.MaxInt32
+ } else {
+ u.m = u.m * min
+ }
+ }
+ if u.n > 0 {
+ if (math.MaxInt32-1)/u.n < max {
+ u.n = math.MaxInt32
+ } else {
+ u.n = u.n * max
+ }
+ }
+ }
+
+ if math.MaxInt32 == min {
+ return newRegexNode(ntNothing, n.options)
+ }
+ return u
+
+}
+
+// Simple optimization. If a concatenation or alternation has only
+// one child strip out the intermediate node. If it has zero children,
+// turn it into an empty.
+func (n *regexNode) stripEnation(emptyType nodeType) *regexNode {
+ switch len(n.children) {
+ case 0:
+ return newRegexNode(emptyType, n.options)
+ case 1:
+ return n.children[0]
+ default:
+ return n
+ }
+}
+
+func (n *regexNode) reduceGroup() *regexNode {
+ u := n
+
+ for u.t == ntGroup {
+ u = u.children[0]
+ }
+
+ return u
+}
+
+// Simple optimization. If a set is a singleton, an inverse singleton,
+// or empty, it's transformed accordingly.
+func (n *regexNode) reduceSet() *regexNode {
+ // Extract empty-set, one and not-one case as special
+
+ if n.set == nil {
+ n.t = ntNothing
+ } else if n.set.IsSingleton() {
+ n.ch = n.set.SingletonChar()
+ n.set = nil
+ n.t += (ntOne - ntSet)
+ } else if n.set.IsSingletonInverse() {
+ n.ch = n.set.SingletonChar()
+ n.set = nil
+ n.t += (ntNotone - ntSet)
+ }
+
+ return n
+}
+
+func (n *regexNode) reverseLeft() *regexNode {
+ if n.options&RightToLeft != 0 && n.t == ntConcatenate && len(n.children) > 0 {
+ //reverse children order
+ for left, right := 0, len(n.children)-1; left < right; left, right = left+1, right-1 {
+ n.children[left], n.children[right] = n.children[right], n.children[left]
+ }
+ }
+
+ return n
+}
+
+func (n *regexNode) makeQuantifier(lazy bool, min, max int) *regexNode {
+ if min == 0 && max == 0 {
+ return newRegexNode(ntEmpty, n.options)
+ }
+
+ if min == 1 && max == 1 {
+ return n
+ }
+
+ switch n.t {
+ case ntOne, ntNotone, ntSet:
+ if lazy {
+ n.makeRep(Onelazy, min, max)
+ } else {
+ n.makeRep(Oneloop, min, max)
+ }
+ return n
+
+ default:
+ var t nodeType
+ if lazy {
+ t = ntLazyloop
+ } else {
+ t = ntLoop
+ }
+ result := newRegexNodeMN(t, n.options, min, max)
+ result.addChild(n)
+ return result
+ }
+}
+
+// debug functions
+
+var typeStr = []string{
+ "Onerep", "Notonerep", "Setrep",
+ "Oneloop", "Notoneloop", "Setloop",
+ "Onelazy", "Notonelazy", "Setlazy",
+ "One", "Notone", "Set",
+ "Multi", "Ref",
+ "Bol", "Eol", "Boundary", "Nonboundary",
+ "Beginning", "Start", "EndZ", "End",
+ "Nothing", "Empty",
+ "Alternate", "Concatenate",
+ "Loop", "Lazyloop",
+ "Capture", "Group", "Require", "Prevent", "Greedy",
+ "Testref", "Testgroup",
+ "Unknown", "Unknown", "Unknown",
+ "Unknown", "Unknown", "Unknown",
+ "ECMABoundary", "NonECMABoundary",
+}
+
+func (n *regexNode) description() string {
+ buf := &bytes.Buffer{}
+
+ buf.WriteString(typeStr[n.t])
+
+ if (n.options & ExplicitCapture) != 0 {
+ buf.WriteString("-C")
+ }
+ if (n.options & IgnoreCase) != 0 {
+ buf.WriteString("-I")
+ }
+ if (n.options & RightToLeft) != 0 {
+ buf.WriteString("-L")
+ }
+ if (n.options & Multiline) != 0 {
+ buf.WriteString("-M")
+ }
+ if (n.options & Singleline) != 0 {
+ buf.WriteString("-S")
+ }
+ if (n.options & IgnorePatternWhitespace) != 0 {
+ buf.WriteString("-X")
+ }
+ if (n.options & ECMAScript) != 0 {
+ buf.WriteString("-E")
+ }
+
+ switch n.t {
+ case ntOneloop, ntNotoneloop, ntOnelazy, ntNotonelazy, ntOne, ntNotone:
+ buf.WriteString("(Ch = " + CharDescription(n.ch) + ")")
+ break
+ case ntCapture:
+ buf.WriteString("(index = " + strconv.Itoa(n.m) + ", unindex = " + strconv.Itoa(n.n) + ")")
+ break
+ case ntRef, ntTestref:
+ buf.WriteString("(index = " + strconv.Itoa(n.m) + ")")
+ break
+ case ntMulti:
+ fmt.Fprintf(buf, "(String = %s)", string(n.str))
+ break
+ case ntSet, ntSetloop, ntSetlazy:
+ buf.WriteString("(Set = " + n.set.String() + ")")
+ break
+ }
+
+ switch n.t {
+ case ntOneloop, ntNotoneloop, ntOnelazy, ntNotonelazy, ntSetloop, ntSetlazy, ntLoop, ntLazyloop:
+ buf.WriteString("(Min = ")
+ buf.WriteString(strconv.Itoa(n.m))
+ buf.WriteString(", Max = ")
+ if n.n == math.MaxInt32 {
+ buf.WriteString("inf")
+ } else {
+ buf.WriteString(strconv.Itoa(n.n))
+ }
+ buf.WriteString(")")
+
+ break
+ }
+
+ return buf.String()
+}
+
+var padSpace = []byte(" ")
+
+func (t *RegexTree) Dump() string {
+ return t.root.dump()
+}
+
+func (n *regexNode) dump() string {
+ var stack []int
+ CurNode := n
+ CurChild := 0
+
+ buf := bytes.NewBufferString(CurNode.description())
+ buf.WriteRune('\n')
+
+ for {
+ if CurNode.children != nil && CurChild < len(CurNode.children) {
+ stack = append(stack, CurChild+1)
+ CurNode = CurNode.children[CurChild]
+ CurChild = 0
+
+ Depth := len(stack)
+ if Depth > 32 {
+ Depth = 32
+ }
+ buf.Write(padSpace[:Depth])
+ buf.WriteString(CurNode.description())
+ buf.WriteRune('\n')
+ } else {
+ if len(stack) == 0 {
+ break
+ }
+
+ CurChild = stack[len(stack)-1]
+ stack = stack[:len(stack)-1]
+ CurNode = CurNode.next
+ }
+ }
+ return buf.String()
+}
diff --git a/vendor/github.com/dlclark/regexp2/syntax/writer.go b/vendor/github.com/dlclark/regexp2/syntax/writer.go
new file mode 100644
index 00000000..a5aa11ca
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/syntax/writer.go
@@ -0,0 +1,500 @@
+package syntax
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+ "os"
+)
+
+func Write(tree *RegexTree) (*Code, error) {
+ w := writer{
+ intStack: make([]int, 0, 32),
+ emitted: make([]int, 2),
+ stringhash: make(map[string]int),
+ sethash: make(map[string]int),
+ }
+
+ code, err := w.codeFromTree(tree)
+
+ if tree.options&Debug > 0 && code != nil {
+ os.Stdout.WriteString(code.Dump())
+ os.Stdout.WriteString("\n")
+ }
+
+ return code, err
+}
+
+type writer struct {
+ emitted []int
+
+ intStack []int
+ curpos int
+ stringhash map[string]int
+ stringtable [][]rune
+ sethash map[string]int
+ settable []*CharSet
+ counting bool
+ count int
+ trackcount int
+ caps map[int]int
+}
+
+const (
+ beforeChild nodeType = 64
+ afterChild = 128
+ //MaxPrefixSize is the largest number of runes we'll use for a BoyerMoyer prefix
+ MaxPrefixSize = 50
+)
+
+// The top level RegexCode generator. It does a depth-first walk
+// through the tree and calls EmitFragment to emits code before
+// and after each child of an interior node, and at each leaf.
+//
+// It runs two passes, first to count the size of the generated
+// code, and second to generate the code.
+//
+// We should time it against the alternative, which is
+// to just generate the code and grow the array as we go.
+func (w *writer) codeFromTree(tree *RegexTree) (*Code, error) {
+ var (
+ curNode *regexNode
+ curChild int
+ capsize int
+ )
+ // construct sparse capnum mapping if some numbers are unused
+
+ if tree.capnumlist == nil || tree.captop == len(tree.capnumlist) {
+ capsize = tree.captop
+ w.caps = nil
+ } else {
+ capsize = len(tree.capnumlist)
+ w.caps = tree.caps
+ for i := 0; i < len(tree.capnumlist); i++ {
+ w.caps[tree.capnumlist[i]] = i
+ }
+ }
+
+ w.counting = true
+
+ for {
+ if !w.counting {
+ w.emitted = make([]int, w.count)
+ }
+
+ curNode = tree.root
+ curChild = 0
+
+ w.emit1(Lazybranch, 0)
+
+ for {
+ if len(curNode.children) == 0 {
+ w.emitFragment(curNode.t, curNode, 0)
+ } else if curChild < len(curNode.children) {
+ w.emitFragment(curNode.t|beforeChild, curNode, curChild)
+
+ curNode = curNode.children[curChild]
+
+ w.pushInt(curChild)
+ curChild = 0
+ continue
+ }
+
+ if w.emptyStack() {
+ break
+ }
+
+ curChild = w.popInt()
+ curNode = curNode.next
+
+ w.emitFragment(curNode.t|afterChild, curNode, curChild)
+ curChild++
+ }
+
+ w.patchJump(0, w.curPos())
+ w.emit(Stop)
+
+ if !w.counting {
+ break
+ }
+
+ w.counting = false
+ }
+
+ fcPrefix := getFirstCharsPrefix(tree)
+ prefix := getPrefix(tree)
+ rtl := (tree.options & RightToLeft) != 0
+
+ var bmPrefix *BmPrefix
+ //TODO: benchmark string prefixes
+ if prefix != nil && len(prefix.PrefixStr) > 0 && MaxPrefixSize > 0 {
+ if len(prefix.PrefixStr) > MaxPrefixSize {
+ // limit prefix changes to 10k
+ prefix.PrefixStr = prefix.PrefixStr[:MaxPrefixSize]
+ }
+ bmPrefix = newBmPrefix(prefix.PrefixStr, prefix.CaseInsensitive, rtl)
+ } else {
+ bmPrefix = nil
+ }
+
+ return &Code{
+ Codes: w.emitted,
+ Strings: w.stringtable,
+ Sets: w.settable,
+ TrackCount: w.trackcount,
+ Caps: w.caps,
+ Capsize: capsize,
+ FcPrefix: fcPrefix,
+ BmPrefix: bmPrefix,
+ Anchors: getAnchors(tree),
+ RightToLeft: rtl,
+ }, nil
+}
+
+// The main RegexCode generator. It does a depth-first walk
+// through the tree and calls EmitFragment to emits code before
+// and after each child of an interior node, and at each leaf.
+func (w *writer) emitFragment(nodetype nodeType, node *regexNode, curIndex int) error {
+ bits := InstOp(0)
+
+ if nodetype <= ntRef {
+ if (node.options & RightToLeft) != 0 {
+ bits |= Rtl
+ }
+ if (node.options & IgnoreCase) != 0 {
+ bits |= Ci
+ }
+ }
+ ntBits := nodeType(bits)
+
+ switch nodetype {
+ case ntConcatenate | beforeChild, ntConcatenate | afterChild, ntEmpty:
+ break
+
+ case ntAlternate | beforeChild:
+ if curIndex < len(node.children)-1 {
+ w.pushInt(w.curPos())
+ w.emit1(Lazybranch, 0)
+ }
+
+ case ntAlternate | afterChild:
+ if curIndex < len(node.children)-1 {
+ lbPos := w.popInt()
+ w.pushInt(w.curPos())
+ w.emit1(Goto, 0)
+ w.patchJump(lbPos, w.curPos())
+ } else {
+ for i := 0; i < curIndex; i++ {
+ w.patchJump(w.popInt(), w.curPos())
+ }
+ }
+ break
+
+ case ntTestref | beforeChild:
+ if curIndex == 0 {
+ w.emit(Setjump)
+ w.pushInt(w.curPos())
+ w.emit1(Lazybranch, 0)
+ w.emit1(Testref, w.mapCapnum(node.m))
+ w.emit(Forejump)
+ }
+
+ case ntTestref | afterChild:
+ if curIndex == 0 {
+ branchpos := w.popInt()
+ w.pushInt(w.curPos())
+ w.emit1(Goto, 0)
+ w.patchJump(branchpos, w.curPos())
+ w.emit(Forejump)
+ if len(node.children) <= 1 {
+ w.patchJump(w.popInt(), w.curPos())
+ }
+ } else if curIndex == 1 {
+ w.patchJump(w.popInt(), w.curPos())
+ }
+
+ case ntTestgroup | beforeChild:
+ if curIndex == 0 {
+ w.emit(Setjump)
+ w.emit(Setmark)
+ w.pushInt(w.curPos())
+ w.emit1(Lazybranch, 0)
+ }
+
+ case ntTestgroup | afterChild:
+ if curIndex == 0 {
+ w.emit(Getmark)
+ w.emit(Forejump)
+ } else if curIndex == 1 {
+ Branchpos := w.popInt()
+ w.pushInt(w.curPos())
+ w.emit1(Goto, 0)
+ w.patchJump(Branchpos, w.curPos())
+ w.emit(Getmark)
+ w.emit(Forejump)
+ if len(node.children) <= 2 {
+ w.patchJump(w.popInt(), w.curPos())
+ }
+ } else if curIndex == 2 {
+ w.patchJump(w.popInt(), w.curPos())
+ }
+
+ case ntLoop | beforeChild, ntLazyloop | beforeChild:
+
+ if node.n < math.MaxInt32 || node.m > 1 {
+ if node.m == 0 {
+ w.emit1(Nullcount, 0)
+ } else {
+ w.emit1(Setcount, 1-node.m)
+ }
+ } else if node.m == 0 {
+ w.emit(Nullmark)
+ } else {
+ w.emit(Setmark)
+ }
+
+ if node.m == 0 {
+ w.pushInt(w.curPos())
+ w.emit1(Goto, 0)
+ }
+ w.pushInt(w.curPos())
+
+ case ntLoop | afterChild, ntLazyloop | afterChild:
+
+ startJumpPos := w.curPos()
+ lazy := (nodetype - (ntLoop | afterChild))
+
+ if node.n < math.MaxInt32 || node.m > 1 {
+ if node.n == math.MaxInt32 {
+ w.emit2(InstOp(Branchcount+lazy), w.popInt(), math.MaxInt32)
+ } else {
+ w.emit2(InstOp(Branchcount+lazy), w.popInt(), node.n-node.m)
+ }
+ } else {
+ w.emit1(InstOp(Branchmark+lazy), w.popInt())
+ }
+
+ if node.m == 0 {
+ w.patchJump(w.popInt(), startJumpPos)
+ }
+
+ case ntGroup | beforeChild, ntGroup | afterChild:
+
+ case ntCapture | beforeChild:
+ w.emit(Setmark)
+
+ case ntCapture | afterChild:
+ w.emit2(Capturemark, w.mapCapnum(node.m), w.mapCapnum(node.n))
+
+ case ntRequire | beforeChild:
+ // NOTE: the following line causes lookahead/lookbehind to be
+ // NON-BACKTRACKING. It can be commented out with (*)
+ w.emit(Setjump)
+
+ w.emit(Setmark)
+
+ case ntRequire | afterChild:
+ w.emit(Getmark)
+
+ // NOTE: the following line causes lookahead/lookbehind to be
+ // NON-BACKTRACKING. It can be commented out with (*)
+ w.emit(Forejump)
+
+ case ntPrevent | beforeChild:
+ w.emit(Setjump)
+ w.pushInt(w.curPos())
+ w.emit1(Lazybranch, 0)
+
+ case ntPrevent | afterChild:
+ w.emit(Backjump)
+ w.patchJump(w.popInt(), w.curPos())
+ w.emit(Forejump)
+
+ case ntGreedy | beforeChild:
+ w.emit(Setjump)
+
+ case ntGreedy | afterChild:
+ w.emit(Forejump)
+
+ case ntOne, ntNotone:
+ w.emit1(InstOp(node.t|ntBits), int(node.ch))
+
+ case ntNotoneloop, ntNotonelazy, ntOneloop, ntOnelazy:
+ if node.m > 0 {
+ if node.t == ntOneloop || node.t == ntOnelazy {
+ w.emit2(Onerep|bits, int(node.ch), node.m)
+ } else {
+ w.emit2(Notonerep|bits, int(node.ch), node.m)
+ }
+ }
+ if node.n > node.m {
+ if node.n == math.MaxInt32 {
+ w.emit2(InstOp(node.t|ntBits), int(node.ch), math.MaxInt32)
+ } else {
+ w.emit2(InstOp(node.t|ntBits), int(node.ch), node.n-node.m)
+ }
+ }
+
+ case ntSetloop, ntSetlazy:
+ if node.m > 0 {
+ w.emit2(Setrep|bits, w.setCode(node.set), node.m)
+ }
+ if node.n > node.m {
+ if node.n == math.MaxInt32 {
+ w.emit2(InstOp(node.t|ntBits), w.setCode(node.set), math.MaxInt32)
+ } else {
+ w.emit2(InstOp(node.t|ntBits), w.setCode(node.set), node.n-node.m)
+ }
+ }
+
+ case ntMulti:
+ w.emit1(InstOp(node.t|ntBits), w.stringCode(node.str))
+
+ case ntSet:
+ w.emit1(InstOp(node.t|ntBits), w.setCode(node.set))
+
+ case ntRef:
+ w.emit1(InstOp(node.t|ntBits), w.mapCapnum(node.m))
+
+ case ntNothing, ntBol, ntEol, ntBoundary, ntNonboundary, ntECMABoundary, ntNonECMABoundary, ntBeginning, ntStart, ntEndZ, ntEnd:
+ w.emit(InstOp(node.t))
+
+ default:
+ return fmt.Errorf("unexpected opcode in regular expression generation: %v", nodetype)
+ }
+
+ return nil
+}
+
+// To avoid recursion, we use a simple integer stack.
+// This is the push.
+func (w *writer) pushInt(i int) {
+ w.intStack = append(w.intStack, i)
+}
+
+// Returns true if the stack is empty.
+func (w *writer) emptyStack() bool {
+ return len(w.intStack) == 0
+}
+
+// This is the pop.
+func (w *writer) popInt() int {
+ //get our item
+ idx := len(w.intStack) - 1
+ i := w.intStack[idx]
+ //trim our slice
+ w.intStack = w.intStack[:idx]
+ return i
+}
+
+// Returns the current position in the emitted code.
+func (w *writer) curPos() int {
+ return w.curpos
+}
+
+// Fixes up a jump instruction at the specified offset
+// so that it jumps to the specified jumpDest.
+func (w *writer) patchJump(offset, jumpDest int) {
+ w.emitted[offset+1] = jumpDest
+}
+
+// Returns an index in the set table for a charset
+// uses a map to eliminate duplicates.
+func (w *writer) setCode(set *CharSet) int {
+ if w.counting {
+ return 0
+ }
+
+ buf := &bytes.Buffer{}
+
+ set.mapHashFill(buf)
+ hash := buf.String()
+ i, ok := w.sethash[hash]
+ if !ok {
+ i = len(w.sethash)
+ w.sethash[hash] = i
+ w.settable = append(w.settable, set)
+ }
+ return i
+}
+
+// Returns an index in the string table for a string.
+// uses a map to eliminate duplicates.
+func (w *writer) stringCode(str []rune) int {
+ if w.counting {
+ return 0
+ }
+
+ hash := string(str)
+ i, ok := w.stringhash[hash]
+ if !ok {
+ i = len(w.stringhash)
+ w.stringhash[hash] = i
+ w.stringtable = append(w.stringtable, str)
+ }
+
+ return i
+}
+
+// When generating code on a regex that uses a sparse set
+// of capture slots, we hash them to a dense set of indices
+// for an array of capture slots. Instead of doing the hash
+// at match time, it's done at compile time, here.
+func (w *writer) mapCapnum(capnum int) int {
+ if capnum == -1 {
+ return -1
+ }
+
+ if w.caps != nil {
+ return w.caps[capnum]
+ }
+
+ return capnum
+}
+
+// Emits a zero-argument operation. Note that the emit
+// functions all run in two modes: they can emit code, or
+// they can just count the size of the code.
+func (w *writer) emit(op InstOp) {
+ if w.counting {
+ w.count++
+ if opcodeBacktracks(op) {
+ w.trackcount++
+ }
+ return
+ }
+ w.emitted[w.curpos] = int(op)
+ w.curpos++
+}
+
+// Emits a one-argument operation.
+func (w *writer) emit1(op InstOp, opd1 int) {
+ if w.counting {
+ w.count += 2
+ if opcodeBacktracks(op) {
+ w.trackcount++
+ }
+ return
+ }
+ w.emitted[w.curpos] = int(op)
+ w.curpos++
+ w.emitted[w.curpos] = opd1
+ w.curpos++
+}
+
+// Emits a two-argument operation.
+func (w *writer) emit2(op InstOp, opd1, opd2 int) {
+ if w.counting {
+ w.count += 3
+ if opcodeBacktracks(op) {
+ w.trackcount++
+ }
+ return
+ }
+ w.emitted[w.curpos] = int(op)
+ w.curpos++
+ w.emitted[w.curpos] = opd1
+ w.curpos++
+ w.emitted[w.curpos] = opd2
+ w.curpos++
+}
diff --git a/vendor/github.com/dlclark/regexp2/testoutput1 b/vendor/github.com/dlclark/regexp2/testoutput1
new file mode 100644
index 00000000..fbf63fdf
--- /dev/null
+++ b/vendor/github.com/dlclark/regexp2/testoutput1
@@ -0,0 +1,7061 @@
+# This set of tests is for features that are compatible with all versions of
+# Perl >= 5.10, in non-UTF mode. It should run clean for the 8-bit, 16-bit, and
+# 32-bit PCRE libraries, and also using the perltest.pl script.
+
+#forbid_utf
+#newline_default lf any anycrlf
+#perltest
+
+/the quick brown fox/
+ the quick brown fox
+ 0: the quick brown fox
+ What do you know about the quick brown fox?
+ 0: the quick brown fox
+\= Expect no match
+ The quick brown FOX
+No match
+ What do you know about THE QUICK BROWN FOX?
+No match
+
+/The quick brown fox/i
+ the quick brown fox
+ 0: the quick brown fox
+ The quick brown FOX
+ 0: The quick brown FOX
+ What do you know about the quick brown fox?
+ 0: the quick brown fox
+ What do you know about THE QUICK BROWN FOX?
+ 0: THE QUICK BROWN FOX
+
+/abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/
+ abcd\t\n\r\f\a\e9;\$\\?caxyz
+ 0: abcd\x09\x0a\x0d\x0c\x07\x1b9;$\?caxyz
+
+/a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/
+ abxyzpqrrrabbxyyyypqAzz
+ 0: abxyzpqrrrabbxyyyypqAzz
+ abxyzpqrrrabbxyyyypqAzz
+ 0: abxyzpqrrrabbxyyyypqAzz
+ aabxyzpqrrrabbxyyyypqAzz
+ 0: aabxyzpqrrrabbxyyyypqAzz
+ aaabxyzpqrrrabbxyyyypqAzz
+ 0: aaabxyzpqrrrabbxyyyypqAzz
+ aaaabxyzpqrrrabbxyyyypqAzz
+ 0: aaaabxyzpqrrrabbxyyyypqAzz
+ abcxyzpqrrrabbxyyyypqAzz
+ 0: abcxyzpqrrrabbxyyyypqAzz
+ aabcxyzpqrrrabbxyyyypqAzz
+ 0: aabcxyzpqrrrabbxyyyypqAzz
+ aaabcxyzpqrrrabbxyyyypAzz
+ 0: aaabcxyzpqrrrabbxyyyypAzz
+ aaabcxyzpqrrrabbxyyyypqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqAzz
+ aaabcxyzpqrrrabbxyyyypqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqAzz
+ aaabcxyzpqrrrabbxyyyypqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqAzz
+ aaabcxyzpqrrrabbxyyyypqqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqqAzz
+ aaabcxyzpqrrrabbxyyyypqqqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqqqAzz
+ aaabcxyzpqrrrabbxyyyypqqqqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqqqqAzz
+ aaaabcxyzpqrrrabbxyyyypqAzz
+ 0: aaaabcxyzpqrrrabbxyyyypqAzz
+ abxyzzpqrrrabbxyyyypqAzz
+ 0: abxyzzpqrrrabbxyyyypqAzz
+ aabxyzzzpqrrrabbxyyyypqAzz
+ 0: aabxyzzzpqrrrabbxyyyypqAzz
+ aaabxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaabxyzzzzpqrrrabbxyyyypqAzz
+ aaaabxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaaabxyzzzzpqrrrabbxyyyypqAzz
+ abcxyzzpqrrrabbxyyyypqAzz
+ 0: abcxyzzpqrrrabbxyyyypqAzz
+ aabcxyzzzpqrrrabbxyyyypqAzz
+ 0: aabcxyzzzpqrrrabbxyyyypqAzz
+ aaabcxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaabcxyzzzzpqrrrabbxyyyypqAzz
+ aaaabcxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaaabcxyzzzzpqrrrabbxyyyypqAzz
+ aaaabcxyzzzzpqrrrabbbxyyyypqAzz
+ 0: aaaabcxyzzzzpqrrrabbbxyyyypqAzz
+ aaaabcxyzzzzpqrrrabbbxyyyyypqAzz
+ 0: aaaabcxyzzzzpqrrrabbbxyyyyypqAzz
+ aaabcxyzpqrrrabbxyyyypABzz
+ 0: aaabcxyzpqrrrabbxyyyypABzz
+ aaabcxyzpqrrrabbxyyyypABBzz
+ 0: aaabcxyzpqrrrabbxyyyypABBzz
+ >>>aaabxyzpqrrrabbxyyyypqAzz
+ 0: aaabxyzpqrrrabbxyyyypqAzz
+ >aaaabxyzpqrrrabbxyyyypqAzz
+ 0: aaaabxyzpqrrrabbxyyyypqAzz
+ >>>>abcxyzpqrrrabbxyyyypqAzz
+ 0: abcxyzpqrrrabbxyyyypqAzz
+\= Expect no match
+ abxyzpqrrabbxyyyypqAzz
+No match
+ abxyzpqrrrrabbxyyyypqAzz
+No match
+ abxyzpqrrrabxyyyypqAzz
+No match
+ aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz
+No match
+ aaaabcxyzzzzpqrrrabbbxyyypqAzz
+No match
+ aaabcxyzpqrrrabbxyyyypqqqqqqqAzz
+No match
+
+/^(abc){1,2}zz/
+ abczz
+ 0: abczz
+ 1: abc
+ abcabczz
+ 0: abcabczz
+ 1: abc
+\= Expect no match
+ zz
+No match
+ abcabcabczz
+No match
+ >>abczz
+No match
+
+/^(b+?|a){1,2}?c/
+ bc
+ 0: bc
+ 1: b
+ bbc
+ 0: bbc
+ 1: b
+ bbbc
+ 0: bbbc
+ 1: bb
+ bac
+ 0: bac
+ 1: a
+ bbac
+ 0: bbac
+ 1: a
+ aac
+ 0: aac
+ 1: a
+ abbbbbbbbbbbc
+ 0: abbbbbbbbbbbc
+ 1: bbbbbbbbbbb
+ bbbbbbbbbbbac
+ 0: bbbbbbbbbbbac
+ 1: a
+\= Expect no match
+ aaac
+No match
+ abbbbbbbbbbbac
+No match
+
+/^(b+|a){1,2}c/
+ bc
+ 0: bc
+ 1: b
+ bbc
+ 0: bbc
+ 1: bb
+ bbbc
+ 0: bbbc
+ 1: bbb
+ bac
+ 0: bac
+ 1: a
+ bbac
+ 0: bbac
+ 1: a
+ aac
+ 0: aac
+ 1: a
+ abbbbbbbbbbbc
+ 0: abbbbbbbbbbbc
+ 1: bbbbbbbbbbb
+ bbbbbbbbbbbac
+ 0: bbbbbbbbbbbac
+ 1: a
+\= Expect no match
+ aaac
+No match
+ abbbbbbbbbbbac
+No match
+
+/^(b+|a){1,2}?bc/
+ bbc
+ 0: bbc
+ 1: b
+
+/^(b*|ba){1,2}?bc/
+ babc
+ 0: babc
+ 1: ba
+ bbabc
+ 0: bbabc
+ 1: ba
+ bababc
+ 0: bababc
+ 1: ba
+\= Expect no match
+ bababbc
+No match
+ babababc
+No match
+
+/^(ba|b*){1,2}?bc/
+ babc
+ 0: babc
+ 1: ba
+ bbabc
+ 0: bbabc
+ 1: ba
+ bababc
+ 0: bababc
+ 1: ba
+\= Expect no match
+ bababbc
+No match
+ babababc
+No match
+
+#/^\ca\cA\c[;\c:/
+# \x01\x01\e;z
+# 0: \x01\x01\x1b;z
+
+/^[ab\]cde]/
+ athing
+ 0: a
+ bthing
+ 0: b
+ ]thing
+ 0: ]
+ cthing
+ 0: c
+ dthing
+ 0: d
+ ething
+ 0: e
+\= Expect no match
+ fthing
+No match
+ [thing
+No match
+ \\thing
+No match
+
+/^[]cde]/
+ ]thing
+ 0: ]
+ cthing
+ 0: c
+ dthing
+ 0: d
+ ething
+ 0: e
+\= Expect no match
+ athing
+No match
+ fthing
+No match
+
+/^[^ab\]cde]/
+ fthing
+ 0: f
+ [thing
+ 0: [
+ \\thing
+ 0: \
+\= Expect no match
+ athing
+No match
+ bthing
+No match
+ ]thing
+No match
+ cthing
+No match
+ dthing
+No match
+ ething
+No match
+
+/^[^]cde]/
+ athing
+ 0: a
+ fthing
+ 0: f
+\= Expect no match
+ ]thing
+No match
+ cthing
+No match
+ dthing
+No match
+ ething
+No match
+
+# DLC - I don't get this one
+#/^\/
+#
+# 0: \x81
+
+#updated to handle 16-bits utf8
+/^ÿ/
+ ÿ
+ 0: \xc3\xbf
+
+/^[0-9]+$/
+ 0
+ 0: 0
+ 1
+ 0: 1
+ 2
+ 0: 2
+ 3
+ 0: 3
+ 4
+ 0: 4
+ 5
+ 0: 5
+ 6
+ 0: 6
+ 7
+ 0: 7
+ 8
+ 0: 8
+ 9
+ 0: 9
+ 10
+ 0: 10
+ 100
+ 0: 100
+\= Expect no match
+ abc
+No match
+
+/^.*nter/
+ enter
+ 0: enter
+ inter
+ 0: inter
+ uponter
+ 0: uponter
+
+/^xxx[0-9]+$/
+ xxx0
+ 0: xxx0
+ xxx1234
+ 0: xxx1234
+\= Expect no match
+ xxx
+No match
+
+/^.+[0-9][0-9][0-9]$/
+ x123
+ 0: x123
+ x1234
+ 0: x1234
+ xx123
+ 0: xx123
+ 123456
+ 0: 123456
+\= Expect no match
+ 123
+No match
+
+/^.+?[0-9][0-9][0-9]$/
+ x123
+ 0: x123
+ x1234
+ 0: x1234
+ xx123
+ 0: xx123
+ 123456
+ 0: 123456
+\= Expect no match
+ 123
+No match
+
+/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/
+ abc!pqr=apquxz.ixr.zzz.ac.uk
+ 0: abc!pqr=apquxz.ixr.zzz.ac.uk
+ 1: abc
+ 2: pqr
+\= Expect no match
+ !pqr=apquxz.ixr.zzz.ac.uk
+No match
+ abc!=apquxz.ixr.zzz.ac.uk
+No match
+ abc!pqr=apquxz:ixr.zzz.ac.uk
+No match
+ abc!pqr=apquxz.ixr.zzz.ac.ukk
+No match
+
+/:/
+ Well, we need a colon: somewhere
+ 0: :
+\= Expect no match
+ Fail without a colon
+No match
+
+/([\da-f:]+)$/i
+ 0abc
+ 0: 0abc
+ 1: 0abc
+ abc
+ 0: abc
+ 1: abc
+ fed
+ 0: fed
+ 1: fed
+ E
+ 0: E
+ 1: E
+ ::
+ 0: ::
+ 1: ::
+ 5f03:12C0::932e
+ 0: 5f03:12C0::932e
+ 1: 5f03:12C0::932e
+ fed def
+ 0: def
+ 1: def
+ Any old stuff
+ 0: ff
+ 1: ff
+\= Expect no match
+ 0zzz
+No match
+ gzzz
+No match
+ fed\x20
+No match
+ Any old rubbish
+No match
+
+/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
+ .1.2.3
+ 0: .1.2.3
+ 1: 1
+ 2: 2
+ 3: 3
+ A.12.123.0
+ 0: A.12.123.0
+ 1: 12
+ 2: 123
+ 3: 0
+\= Expect no match
+ .1.2.3333
+No match
+ 1.2.3
+No match
+ 1234.2.3
+No match
+
+/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/
+ 1 IN SOA non-sp1 non-sp2(
+ 0: 1 IN SOA non-sp1 non-sp2(
+ 1: 1
+ 2: non-sp1
+ 3: non-sp2
+ 1 IN SOA non-sp1 non-sp2 (
+ 0: 1 IN SOA non-sp1 non-sp2 (
+ 1: 1
+ 2: non-sp1
+ 3: non-sp2
+\= Expect no match
+ 1IN SOA non-sp1 non-sp2(
+No match
+
+/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/
+ a.
+ 0: a.
+ Z.
+ 0: Z.
+ 2.
+ 0: 2.
+ ab-c.pq-r.
+ 0: ab-c.pq-r.
+ 1: .pq-r
+ sxk.zzz.ac.uk.
+ 0: sxk.zzz.ac.uk.
+ 1: .uk
+ x-.y-.
+ 0: x-.y-.
+ 1: .y-
+\= Expect no match
+ -abc.peq.
+No match
+
+/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/
+ *.a
+ 0: *.a
+ *.b0-a
+ 0: *.b0-a
+ 1: 0-a
+ *.c3-b.c
+ 0: *.c3-b.c
+ 1: 3-b
+ 2: .c
+ *.c-a.b-c
+ 0: *.c-a.b-c
+ 1: -a
+ 2: .b-c
+ 3: -c
+\= Expect no match
+ *.0
+No match
+ *.a-
+No match
+ *.a-b.c-
+No match
+ *.c-a.0-c
+No match
+
+/^(?=ab(de))(abd)(e)/
+ abde
+ 0: abde
+ 1: de
+ 2: abd
+ 3: e
+
+/^(?!(ab)de|x)(abd)(f)/
+ abdf
+ 0: abdf
+ 1:
+ 2: abd
+ 3: f
+
+/^(?=(ab(cd)))(ab)/
+ abcd
+ 0: ab
+ 1: abcd
+ 2: cd
+ 3: ab
+
+/^[\da-f](\.[\da-f])*$/i
+ a.b.c.d
+ 0: a.b.c.d
+ 1: .d
+ A.B.C.D
+ 0: A.B.C.D
+ 1: .D
+ a.b.c.1.2.3.C
+ 0: a.b.c.1.2.3.C
+ 1: .C
+
+/^\".*\"\s*(;.*)?$/
+ \"1234\"
+ 0: "1234"
+ \"abcd\" ;
+ 0: "abcd" ;
+ 1: ;
+ \"\" ; rhubarb
+ 0: "" ; rhubarb
+ 1: ; rhubarb
+\= Expect no match
+ \"1234\" : things
+No match
+
+/^$/
+ \
+ 0:
+\= Expect no match
+ A non-empty line
+No match
+
+/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x
+ ab c
+ 0: ab c
+\= Expect no match
+ abc
+No match
+ ab cde
+No match
+
+/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/
+ ab c
+ 0: ab c
+\= Expect no match
+ abc
+No match
+ ab cde
+No match
+
+/^ a\ b[c ]d $/x
+ a bcd
+ 0: a bcd
+ a b d
+ 0: a b d
+\= Expect no match
+ abcd
+No match
+ ab d
+No match
+
+/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/
+ abcdefhijklm
+ 0: abcdefhijklm
+ 1: abc
+ 2: bc
+ 3: c
+ 4: def
+ 5: ef
+ 6: f
+ 7: hij
+ 8: ij
+ 9: j
+10: klm
+11: lm
+12: m
+
+/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/
+ abcdefhijklm
+ 0: abcdefhijklm
+ 1: bc
+ 2: c
+ 3: ef
+ 4: f
+ 5: ij
+ 6: j
+ 7: lm
+ 8: m
+
+#/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/
+# a+ Z0+\x08\n\x1d\x12
+# 0: a+ Z0+\x08\x0a\x1d\x12
+
+/^[.^$|()*+?{,}]+/
+ .^\$(*+)|{?,?}
+ 0: .^$(*+)|{?,?}
+
+/^a*\w/
+ z
+ 0: z
+ az
+ 0: az
+ aaaz
+ 0: aaaz
+ a
+ 0: a
+ aa
+ 0: aa
+ aaaa
+ 0: aaaa
+ a+
+ 0: a
+ aa+
+ 0: aa
+
+/^a*?\w/
+ z
+ 0: z
+ az
+ 0: a
+ aaaz
+ 0: a
+ a
+ 0: a
+ aa
+ 0: a
+ aaaa
+ 0: a
+ a+
+ 0: a
+ aa+
+ 0: a
+
+/^a+\w/
+ az
+ 0: az
+ aaaz
+ 0: aaaz
+ aa
+ 0: aa
+ aaaa
+ 0: aaaa
+ aa+
+ 0: aa
+
+/^a+?\w/
+ az
+ 0: az
+ aaaz
+ 0: aa
+ aa
+ 0: aa
+ aaaa
+ 0: aa
+ aa+
+ 0: aa
+
+/^\d{8}\w{2,}/
+ 1234567890
+ 0: 1234567890
+ 12345678ab
+ 0: 12345678ab
+ 12345678__
+ 0: 12345678__
+\= Expect no match
+ 1234567
+No match
+
+/^[aeiou\d]{4,5}$/
+ uoie
+ 0: uoie
+ 1234
+ 0: 1234
+ 12345
+ 0: 12345
+ aaaaa
+ 0: aaaaa
+\= Expect no match
+ 123456
+No match
+
+/^[aeiou\d]{4,5}?/
+ uoie
+ 0: uoie
+ 1234
+ 0: 1234
+ 12345
+ 0: 1234
+ aaaaa
+ 0: aaaa
+ 123456
+ 0: 1234
+
+/\A(abc|def)=(\1){2,3}\Z/
+ abc=abcabc
+ 0: abc=abcabc
+ 1: abc
+ 2: abc
+ def=defdefdef
+ 0: def=defdefdef
+ 1: def
+ 2: def
+\= Expect no match
+ abc=defdef
+No match
+
+/^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/
+ abcdefghijkcda2
+ 0: abcdefghijkcda2
+ 1: a
+ 2: b
+ 3: c
+ 4: d
+ 5: e
+ 6: f
+ 7: g
+ 8: h
+ 9: i
+10: j
+11: k
+12: cd
+ abcdefghijkkkkcda2
+ 0: abcdefghijkkkkcda2
+ 1: a
+ 2: b
+ 3: c
+ 4: d
+ 5: e
+ 6: f
+ 7: g
+ 8: h
+ 9: i
+10: j
+11: k
+12: cd
+
+/(cat(a(ract|tonic)|erpillar)) \1()2(3)/
+ cataract cataract23
+ 0: cataract cataract23
+ 1: cataract
+ 2: aract
+ 3: ract
+ 4:
+ 5: 3
+ catatonic catatonic23
+ 0: catatonic catatonic23
+ 1: catatonic
+ 2: atonic
+ 3: tonic
+ 4:
+ 5: 3
+ caterpillar caterpillar23
+ 0: caterpillar caterpillar23
+ 1: caterpillar
+ 2: erpillar
+ 3:
+ 4:
+ 5: 3
+
+
+/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/
+ From abcd Mon Sep 01 12:33:02 1997
+ 0: From abcd Mon Sep 01 12:33
+ 1: abcd
+
+/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/
+ From abcd Mon Sep 01 12:33:02 1997
+ 0: From abcd Mon Sep 01 12:33
+ 1: Sep
+ From abcd Mon Sep 1 12:33:02 1997
+ 0: From abcd Mon Sep 1 12:33
+ 1: Sep
+\= Expect no match
+ From abcd Sep 01 12:33:02 1997
+No match
+
+/^12.34/s
+ 12\n34
+ 0: 12\x0a34
+ 12\r34
+ 0: 12\x0d34
+
+/\w+(?=\t)/
+ the quick brown\t fox
+ 0: brown
+
+/foo(?!bar)(.*)/
+ foobar is foolish see?
+ 0: foolish see?
+ 1: lish see?
+
+/(?:(?!foo)...|^.{0,2})bar(.*)/
+ foobar crowbar etc
+ 0: rowbar etc
+ 1: etc
+ barrel
+ 0: barrel
+ 1: rel
+ 2barrel
+ 0: 2barrel
+ 1: rel
+ A barrel
+ 0: A barrel
+ 1: rel
+
+/^(\D*)(?=\d)(?!123)/
+ abc456
+ 0: abc
+ 1: abc
+\= Expect no match
+ abc123
+No match
+
+/^1234(?# test newlines
+ inside)/
+ 1234
+ 0: 1234
+
+/^1234 #comment in extended re
+ /x
+ 1234
+ 0: 1234
+
+/#rhubarb
+ abcd/x
+ abcd
+ 0: abcd
+
+/^abcd#rhubarb/x
+ abcd
+ 0: abcd
+
+/^(a)\1{2,3}(.)/
+ aaab
+ 0: aaab
+ 1: a
+ 2: b
+ aaaab
+ 0: aaaab
+ 1: a
+ 2: b
+ aaaaab
+ 0: aaaaa
+ 1: a
+ 2: a
+ aaaaaab
+ 0: aaaaa
+ 1: a
+ 2: a
+
+/(?!^)abc/
+ the abc
+ 0: abc
+\= Expect no match
+ abc
+No match
+
+/(?=^)abc/
+ abc
+ 0: abc
+\= Expect no match
+ the abc
+No match
+
+/^[ab]{1,3}(ab*|b)/
+ aabbbbb
+ 0: aabb
+ 1: b
+
+/^[ab]{1,3}?(ab*|b)/
+ aabbbbb
+ 0: aabbbbb
+ 1: abbbbb
+
+/^[ab]{1,3}?(ab*?|b)/
+ aabbbbb
+ 0: aa
+ 1: a
+
+/^[ab]{1,3}(ab*?|b)/
+ aabbbbb
+ 0: aabb
+ 1: b
+
+/ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional leading comment
+(?: (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address
+| # or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # one word, optionally followed by....
+(?:
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or...
+\(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) | # comments, or...
+
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+# quoted strings
+)*
+< (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # leading <
+(?: @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* , (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+)* # further okay, if led by comma
+: # closing colon
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* )? # optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address spec
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* > # trailing >
+# name and address
+) (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional trailing comment
+/x
+ Alan Other
+ 0: Alan Other
+
+ 0: user@dom.ain
+ user\@dom.ain
+ 0: user@dom.ain
+ \"A. Other\" (a comment)
+ 0: "A. Other" (a comment)
+ A. Other (a comment)
+ 0: Other (a comment)
+ \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay
+ 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay
+ A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+| # or
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+# Quoted string
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+| # or
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+# Quoted string
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# additional words
+)*
+@
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+)*
+# address
+| # or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+| # or
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+# Quoted string
+)
+# leading word
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces
+(?:
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+|
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+) # "special" comment or quoted string
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal"
+)*
+<
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# <
+(?:
+@
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+)*
+(?: ,
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+@
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+)*
+)* # additional domains
+:
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+)? # optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+| # or
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+# Quoted string
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+| # or
+" # "
+[^\\\x80-\xff\n\015"] * # normal
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )*
+" # "
+# Quoted string
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# additional words
+)*
+@
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+)
+[\040\t]* # Nab whitespace.
+(?:
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: # (
+(?: \\ [^\x80-\xff] |
+\( # (
+[^\\\x80-\xff\n\015()] * # normal*
+(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)*
+\) # )
+) # special
+[^\\\x80-\xff\n\015()] * # normal*
+)* # )*
+\) # )
+[\040\t]* )* # If comment found, allow more spaces.
+# optional trailing comments
+)*
+# address spec
+> # >
+# name and address
+)
+/x
+ Alan Other
+ 0: Alan Other
+
+ 0: user@dom.ain
+ user\@dom.ain
+ 0: user@dom.ain
+ \"A. Other\" (a comment)
+ 0: "A. Other"
+ A. Other (a comment)
+ 0: Other
+ \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay
+ 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay
+ A missing angle ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f
+
+/P[^*]TAIRE[^*]{1,6}?LL/
+ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx
+ 0: PSTAIREISLL
+
+/P[^*]TAIRE[^*]{1,}?LL/
+ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx
+ 0: PSTAIREISLL
+
+/(\.\d\d[1-9]?)\d+/
+ 1.230003938
+ 0: .230003938
+ 1: .23
+ 1.875000282
+ 0: .875000282
+ 1: .875
+ 1.235
+ 0: .235
+ 1: .23
+
+/(\.\d\d((?=0)|\d(?=\d)))/
+ 1.230003938
+ 0: .23
+ 1: .23
+ 2:
+ 1.875000282
+ 0: .875
+ 1: .875
+ 2: 5
+\= Expect no match
+ 1.235
+No match
+
+/\b(foo)\s+(\w+)/i
+ Food is on the foo table
+ 0: foo table
+ 1: foo
+ 2: table
+
+/foo(.*)bar/
+ The food is under the bar in the barn.
+ 0: food is under the bar in the bar
+ 1: d is under the bar in the
+
+/foo(.*?)bar/
+ The food is under the bar in the barn.
+ 0: food is under the bar
+ 1: d is under the
+
+/(.*)(\d*)/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 53147
+ 2:
+
+/(.*)(\d+)/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 5314
+ 2: 7
+
+/(.*?)(\d*)/
+ I have 2 numbers: 53147
+ 0:
+ 1:
+ 2:
+
+/(.*?)(\d+)/
+ I have 2 numbers: 53147
+ 0: I have 2
+ 1: I have
+ 2: 2
+
+/(.*)(\d+)$/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 5314
+ 2: 7
+
+/(.*?)(\d+)$/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers:
+ 2: 53147
+
+/(.*)\b(\d+)$/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers:
+ 2: 53147
+
+/(.*\D)(\d+)$/
+ I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers:
+ 2: 53147
+
+/^\D*(?!123)/
+ ABC123
+ 0: AB
+
+/^(\D*)(?=\d)(?!123)/
+ ABC445
+ 0: ABC
+ 1: ABC
+\= Expect no match
+ ABC123
+No match
+
+/^[W-]46]/
+ W46]789
+ 0: W46]
+ -46]789
+ 0: -46]
+\= Expect no match
+ Wall
+No match
+ Zebra
+No match
+ 42
+No match
+ [abcd]
+No match
+ ]abcd[
+No match
+
+/^[W-\]46]/
+ W46]789
+ 0: W
+ Wall
+ 0: W
+ Zebra
+ 0: Z
+ Xylophone
+ 0: X
+ 42
+ 0: 4
+ [abcd]
+ 0: [
+ ]abcd[
+ 0: ]
+ \\backslash
+ 0: \
+\= Expect no match
+ -46]789
+No match
+ well
+No match
+
+/\d\d\/\d\d\/\d\d\d\d/
+ 01/01/2000
+ 0: 01/01/2000
+
+/word (?:[a-zA-Z0-9]+ ){0,10}otherword/
+ word cat dog elephant mussel cow horse canary baboon snake shark otherword
+ 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword
+\= Expect no match
+ word cat dog elephant mussel cow horse canary baboon snake shark
+No match
+
+/word (?:[a-zA-Z0-9]+ ){0,300}otherword/
+\= Expect no match
+ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope
+No match
+
+/^(a){0,0}/
+ bcd
+ 0:
+ abc
+ 0:
+ aab
+ 0:
+
+/^(a){0,1}/
+ bcd
+ 0:
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: a
+ 1: a
+
+/^(a){0,2}/
+ bcd
+ 0:
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+
+/^(a){0,3}/
+ bcd
+ 0:
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+ aaa
+ 0: aaa
+ 1: a
+
+/^(a){0,}/
+ bcd
+ 0:
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+ aaa
+ 0: aaa
+ 1: a
+ aaaaaaaa
+ 0: aaaaaaaa
+ 1: a
+
+/^(a){1,1}/
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: a
+ 1: a
+\= Expect no match
+ bcd
+No match
+
+/^(a){1,2}/
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+\= Expect no match
+ bcd
+No match
+
+/^(a){1,3}/
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+ aaa
+ 0: aaa
+ 1: a
+\= Expect no match
+ bcd
+No match
+
+/^(a){1,}/
+ abc
+ 0: a
+ 1: a
+ aab
+ 0: aa
+ 1: a
+ aaa
+ 0: aaa
+ 1: a
+ aaaaaaaa
+ 0: aaaaaaaa
+ 1: a
+\= Expect no match
+ bcd
+No match
+
+/.*\.gif/
+ borfle\nbib.gif\nno
+ 0: bib.gif
+
+/.{0,}\.gif/
+ borfle\nbib.gif\nno
+ 0: bib.gif
+
+/.*\.gif/m
+ borfle\nbib.gif\nno
+ 0: bib.gif
+
+/.*\.gif/s
+ borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif
+
+/.*\.gif/ms
+ borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif
+
+/.*$/
+ borfle\nbib.gif\nno
+ 0: no
+
+/.*$/m
+ borfle\nbib.gif\nno
+ 0: borfle
+
+/.*$/s
+ borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif\x0ano
+
+/.*$/ms
+ borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif\x0ano
+
+/.*$/
+ borfle\nbib.gif\nno\n
+ 0: no
+
+/.*$/m
+ borfle\nbib.gif\nno\n
+ 0: borfle
+
+/.*$/s
+ borfle\nbib.gif\nno\n
+ 0: borfle\x0abib.gif\x0ano\x0a
+
+/.*$/ms
+ borfle\nbib.gif\nno\n
+ 0: borfle\x0abib.gif\x0ano\x0a
+
+/(.*X|^B)/
+ abcde\n1234Xyz
+ 0: 1234X
+ 1: 1234X
+ BarFoo
+ 0: B
+ 1: B
+\= Expect no match
+ abcde\nBar
+No match
+
+/(.*X|^B)/m
+ abcde\n1234Xyz
+ 0: 1234X
+ 1: 1234X
+ BarFoo
+ 0: B
+ 1: B
+ abcde\nBar
+ 0: B
+ 1: B
+
+/(.*X|^B)/s
+ abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ 1: abcde\x0a1234X
+ BarFoo
+ 0: B
+ 1: B
+\= Expect no match
+ abcde\nBar
+No match
+
+/(.*X|^B)/ms
+ abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ 1: abcde\x0a1234X
+ BarFoo
+ 0: B
+ 1: B
+ abcde\nBar
+ 0: B
+ 1: B
+
+/(?s)(.*X|^B)/
+ abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ 1: abcde\x0a1234X
+ BarFoo
+ 0: B
+ 1: B
+\= Expect no match
+ abcde\nBar
+No match
+
+/(?s:.*X|^B)/
+ abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ BarFoo
+ 0: B
+\= Expect no match
+ abcde\nBar
+No match
+
+/^.*B/
+\= Expect no match
+ abc\nB
+No match
+
+/(?s)^.*B/
+ abc\nB
+ 0: abc\x0aB
+
+/(?m)^.*B/
+ abc\nB
+ 0: B
+
+/(?ms)^.*B/
+ abc\nB
+ 0: abc\x0aB
+
+/(?ms)^B/
+ abc\nB
+ 0: B
+
+/(?s)B$/
+ B\n
+ 0: B
+
+/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/
+ 123456654321
+ 0: 123456654321
+
+/^\d\d\d\d\d\d\d\d\d\d\d\d/
+ 123456654321
+ 0: 123456654321
+
+/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/
+ 123456654321
+ 0: 123456654321
+
+/^[abc]{12}/
+ abcabcabcabc
+ 0: abcabcabcabc
+
+/^[a-c]{12}/
+ abcabcabcabc
+ 0: abcabcabcabc
+
+/^(a|b|c){12}/
+ abcabcabcabc
+ 0: abcabcabcabc
+ 1: c
+
+/^[abcdefghijklmnopqrstuvwxy0123456789]/
+ n
+ 0: n
+\= Expect no match
+ z
+No match
+
+/abcde{0,0}/
+ abcd
+ 0: abcd
+\= Expect no match
+ abce
+No match
+
+/ab[cd]{0,0}e/
+ abe
+ 0: abe
+\= Expect no match
+ abcde
+No match
+
+/ab(c){0,0}d/
+ abd
+ 0: abd
+\= Expect no match
+ abcd
+No match
+
+/a(b*)/
+ a
+ 0: a
+ 1:
+ ab
+ 0: ab
+ 1: b
+ abbbb
+ 0: abbbb
+ 1: bbbb
+\= Expect no match
+ bbbbb
+No match
+
+/ab\d{0}e/
+ abe
+ 0: abe
+\= Expect no match
+ ab1e
+No match
+
+/"([^\\"]+|\\.)*"/
+ the \"quick\" brown fox
+ 0: "quick"
+ 1: quick
+ \"the \\\"quick\\\" brown fox\"
+ 0: "the \"quick\" brown fox"
+ 1: brown fox
+
+/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD> ]{0,})>([\w\W\s\d][^<>]{0,})<\/TD> ]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is
+ 43.Word Processor
(N-1286) Lega lstaff.com CA - Statewide
+ 0: 43.Word Processor
(N-1286) Lega lstaff.com CA - Statewide
+ 1: BGCOLOR='#DBE9E9'
+ 2: align=left valign=top
+ 3: 43.
+ 4: Word Processor
(N-1286)
+ 5:
+ 6:
+ 7:
+ 8: align=left valign=top
+ 9: Lega lstaff.com
+10: align=left valign=top
+11: CA - Statewide
+
+/a[^a]b/
+ acb
+ 0: acb
+ a\nb
+ 0: a\x0ab
+
+/a.b/
+ acb
+ 0: acb
+\= Expect no match
+ a\nb
+No match
+
+/a[^a]b/s
+ acb
+ 0: acb
+ a\nb
+ 0: a\x0ab
+
+/a.b/s
+ acb
+ 0: acb
+ a\nb
+ 0: a\x0ab
+
+/^(b+?|a){1,2}?c/
+ bac
+ 0: bac
+ 1: a
+ bbac
+ 0: bbac
+ 1: a
+ bbbac
+ 0: bbbac
+ 1: a
+ bbbbac
+ 0: bbbbac
+ 1: a
+ bbbbbac
+ 0: bbbbbac
+ 1: a
+
+/^(b+|a){1,2}?c/
+ bac
+ 0: bac
+ 1: a
+ bbac
+ 0: bbac
+ 1: a
+ bbbac
+ 0: bbbac
+ 1: a
+ bbbbac
+ 0: bbbbac
+ 1: a
+ bbbbbac
+ 0: bbbbbac
+ 1: a
+
+/(?!\A)x/m
+ a\bx\n
+ 0: x
+ a\nx\n
+ 0: x
+\= Expect no match
+ x\nb\n
+No match
+
+/(A|B)*?CD/
+ CD
+ 0: CD
+
+/(A|B)*CD/
+ CD
+ 0: CD
+
+/(AB)*?\1/
+ ABABAB
+ 0: ABAB
+ 1: AB
+
+/(AB)*\1/
+ ABABAB
+ 0: ABABAB
+ 1: AB
+
+/(?.*/)foo"
+ /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo
+ 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo
+\= Expect no match
+ /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/
+No match
+
+/(?>(\.\d\d[1-9]?))\d+/
+ 1.230003938
+ 0: .230003938
+ 1: .23
+ 1.875000282
+ 0: .875000282
+ 1: .875
+\= Expect no match
+ 1.235
+No match
+
+/^((?>\w+)|(?>\s+))*$/
+ now is the time for all good men to come to the aid of the party
+ 0: now is the time for all good men to come to the aid of the party
+ 1: party
+\= Expect no match
+ this is not a line with only words and spaces!
+No match
+
+/(\d+)(\w)/
+ 12345a
+ 0: 12345a
+ 1: 12345
+ 2: a
+ 12345+
+ 0: 12345
+ 1: 1234
+ 2: 5
+
+/((?>\d+))(\w)/
+ 12345a
+ 0: 12345a
+ 1: 12345
+ 2: a
+\= Expect no match
+ 12345+
+No match
+
+/(?>a+)b/
+ aaab
+ 0: aaab
+
+/((?>a+)b)/
+ aaab
+ 0: aaab
+ 1: aaab
+
+/(?>(a+))b/
+ aaab
+ 0: aaab
+ 1: aaa
+
+/(?>b)+/
+ aaabbbccc
+ 0: bbb
+
+/(?>a+|b+|c+)*c/
+ aaabbbbccccd
+ 0: aaabbbbc
+
+/((?>[^()]+)|\([^()]*\))+/
+ ((abc(ade)ufh()()x
+ 0: abc(ade)ufh()()x
+ 1: x
+
+/\(((?>[^()]+)|\([^()]+\))+\)/
+ (abc)
+ 0: (abc)
+ 1: abc
+ (abc(def)xyz)
+ 0: (abc(def)xyz)
+ 1: xyz
+\= Expect no match
+ ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+No match
+
+/a(?-i)b/i
+ ab
+ 0: ab
+ Ab
+ 0: Ab
+\= Expect no match
+ aB
+No match
+ AB
+No match
+
+/(a (?x)b c)d e/
+ a bcd e
+ 0: a bcd e
+ 1: a bc
+\= Expect no match
+ a b cd e
+No match
+ abcd e
+No match
+ a bcde
+No match
+
+/(a b(?x)c d (?-x)e f)/
+ a bcde f
+ 0: a bcde f
+ 1: a bcde f
+\= Expect no match
+ abcdef
+No match
+
+/(a(?i)b)c/
+ abc
+ 0: abc
+ 1: ab
+ aBc
+ 0: aBc
+ 1: aB
+\= Expect no match
+ abC
+No match
+ aBC
+No match
+ Abc
+No match
+ ABc
+No match
+ ABC
+No match
+ AbC
+No match
+
+/a(?i:b)c/
+ abc
+ 0: abc
+ aBc
+ 0: aBc
+\= Expect no match
+ ABC
+No match
+ abC
+No match
+ aBC
+No match
+
+/a(?i:b)*c/
+ aBc
+ 0: aBc
+ aBBc
+ 0: aBBc
+\= Expect no match
+ aBC
+No match
+ aBBC
+No match
+
+/a(?=b(?i)c)\w\wd/
+ abcd
+ 0: abcd
+ abCd
+ 0: abCd
+\= Expect no match
+ aBCd
+No match
+ abcD
+No match
+
+/(?s-i:more.*than).*million/i
+ more than million
+ 0: more than million
+ more than MILLION
+ 0: more than MILLION
+ more \n than Million
+ 0: more \x0a than Million
+\= Expect no match
+ MORE THAN MILLION
+No match
+ more \n than \n million
+No match
+
+/(?:(?s-i)more.*than).*million/i
+ more than million
+ 0: more than million
+ more than MILLION
+ 0: more than MILLION
+ more \n than Million
+ 0: more \x0a than Million
+\= Expect no match
+ MORE THAN MILLION
+No match
+ more \n than \n million
+No match
+
+/(?>a(?i)b+)+c/
+ abc
+ 0: abc
+ aBbc
+ 0: aBbc
+ aBBc
+ 0: aBBc
+\= Expect no match
+ Abc
+No match
+ abAb
+No match
+ abbC
+No match
+
+/(?=a(?i)b)\w\wc/
+ abc
+ 0: abc
+ aBc
+ 0: aBc
+\= Expect no match
+ Ab
+No match
+ abC
+No match
+ aBC
+No match
+
+/(?<=a(?i)b)(\w\w)c/
+ abxxc
+ 0: xxc
+ 1: xx
+ aBxxc
+ 0: xxc
+ 1: xx
+\= Expect no match
+ Abxxc
+No match
+ ABxxc
+No match
+ abxxC
+No match
+
+/(?:(a)|b)(?(1)A|B)/
+ aA
+ 0: aA
+ 1: a
+ bB
+ 0: bB
+\= Expect no match
+ aB
+No match
+ bA
+No match
+
+/^(a)?(?(1)a|b)+$/
+ aa
+ 0: aa
+ 1: a
+ b
+ 0: b
+ bb
+ 0: bb
+\= Expect no match
+ ab
+No match
+
+# Perl gets this next one wrong if the pattern ends with $; in that case it
+# fails to match "12".
+
+/^(?(?=abc)\w{3}:|\d\d)/
+ abc:
+ 0: abc:
+ 12
+ 0: 12
+ 123
+ 0: 12
+\= Expect no match
+ xyz
+No match
+
+/^(?(?!abc)\d\d|\w{3}:)$/
+ abc:
+ 0: abc:
+ 12
+ 0: 12
+\= Expect no match
+ 123
+No match
+ xyz
+No match
+
+/(?(?<=foo)bar|cat)/
+ foobar
+ 0: bar
+ cat
+ 0: cat
+ fcat
+ 0: cat
+ focat
+ 0: cat
+\= Expect no match
+ foocat
+No match
+
+/(?(?a*)*/
+ a
+ 0: a
+ aa
+ 0: aa
+ aaaa
+ 0: aaaa
+
+/(abc|)+/
+ abc
+ 0: abc
+ 1:
+ abcabc
+ 0: abcabc
+ 1:
+ abcabcabc
+ 0: abcabcabc
+ 1:
+ xyz
+ 0:
+ 1:
+
+/([a]*)*/
+ a
+ 0: a
+ 1:
+ aaaaa
+ 0: aaaaa
+ 1:
+
+/([ab]*)*/
+ a
+ 0: a
+ 1:
+ b
+ 0: b
+ 1:
+ ababab
+ 0: ababab
+ 1:
+ aaaabcde
+ 0: aaaab
+ 1:
+ bbbb
+ 0: bbbb
+ 1:
+
+/([^a]*)*/
+ b
+ 0: b
+ 1:
+ bbbb
+ 0: bbbb
+ 1:
+ aaa
+ 0:
+ 1:
+
+/([^ab]*)*/
+ cccc
+ 0: cccc
+ 1:
+ abab
+ 0:
+ 1:
+
+/([a]*?)*/
+ a
+ 0:
+ 1:
+ aaaa
+ 0:
+ 1:
+
+/([ab]*?)*/
+ a
+ 0:
+ 1:
+ b
+ 0:
+ 1:
+ abab
+ 0:
+ 1:
+ baba
+ 0:
+ 1:
+
+/([^a]*?)*/
+ b
+ 0:
+ 1:
+ bbbb
+ 0:
+ 1:
+ aaa
+ 0:
+ 1:
+
+/([^ab]*?)*/
+ c
+ 0:
+ 1:
+ cccc
+ 0:
+ 1:
+ baba
+ 0:
+ 1:
+
+/(?>a*)*/
+ a
+ 0: a
+ aaabcde
+ 0: aaa
+
+/((?>a*))*/
+ aaaaa
+ 0: aaaaa
+ 1:
+ aabbaa
+ 0: aa
+ 1:
+
+/((?>a*?))*/
+ aaaaa
+ 0:
+ 1:
+ aabbaa
+ 0:
+ 1:
+
+/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x
+ 12-sep-98
+ 0: 12-sep-98
+ 12-09-98
+ 0: 12-09-98
+\= Expect no match
+ sep-12-98
+No match
+
+/(?<=(foo))bar\1/
+ foobarfoo
+ 0: barfoo
+ 1: foo
+ foobarfootling
+ 0: barfoo
+ 1: foo
+\= Expect no match
+ foobar
+No match
+ barfoo
+No match
+
+/(?i:saturday|sunday)/
+ saturday
+ 0: saturday
+ sunday
+ 0: sunday
+ Saturday
+ 0: Saturday
+ Sunday
+ 0: Sunday
+ SATURDAY
+ 0: SATURDAY
+ SUNDAY
+ 0: SUNDAY
+ SunDay
+ 0: SunDay
+
+/(a(?i)bc|BB)x/
+ abcx
+ 0: abcx
+ 1: abc
+ aBCx
+ 0: aBCx
+ 1: aBC
+ bbx
+ 0: bbx
+ 1: bb
+ BBx
+ 0: BBx
+ 1: BB
+\= Expect no match
+ abcX
+No match
+ aBCX
+No match
+ bbX
+No match
+ BBX
+No match
+
+/^([ab](?i)[cd]|[ef])/
+ ac
+ 0: ac
+ 1: ac
+ aC
+ 0: aC
+ 1: aC
+ bD
+ 0: bD
+ 1: bD
+ elephant
+ 0: e
+ 1: e
+ Europe
+ 0: E
+ 1: E
+ frog
+ 0: f
+ 1: f
+ France
+ 0: F
+ 1: F
+\= Expect no match
+ Africa
+No match
+
+/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/
+ ab
+ 0: ab
+ 1: ab
+ aBd
+ 0: aBd
+ 1: aBd
+ xy
+ 0: xy
+ 1: xy
+ xY
+ 0: xY
+ 1: xY
+ zebra
+ 0: z
+ 1: z
+ Zambesi
+ 0: Z
+ 1: Z
+\= Expect no match
+ aCD
+No match
+ XY
+No match
+
+/(?<=foo\n)^bar/m
+ foo\nbar
+ 0: bar
+\= Expect no match
+ bar
+No match
+ baz\nbar
+No match
+
+/(?<=(?]&/
+ <&OUT
+ 0: <&
+
+/^(a\1?){4}$/
+ aaaaaaaaaa
+ 0: aaaaaaaaaa
+ 1: aaaa
+\= Expect no match
+ AB
+No match
+ aaaaaaaaa
+No match
+ aaaaaaaaaaa
+No match
+
+/^(a(?(1)\1)){4}$/
+ aaaaaaaaaa
+ 0: aaaaaaaaaa
+ 1: aaaa
+\= Expect no match
+ aaaaaaaaa
+No match
+ aaaaaaaaaaa
+No match
+
+/(?:(f)(o)(o)|(b)(a)(r))*/
+ foobar
+ 0: foobar
+ 1: f
+ 2: o
+ 3: o
+ 4: b
+ 5: a
+ 6: r
+
+/(?<=a)b/
+ ab
+ 0: b
+\= Expect no match
+ cb
+No match
+ b
+No match
+
+/(?
+ 2: abcd
+ xy:z:::abcd
+ 0: xy:z:::abcd
+ 1: xy:z:::
+ 2: abcd
+
+/^[^bcd]*(c+)/
+ aexycd
+ 0: aexyc
+ 1: c
+
+/(a*)b+/
+ caab
+ 0: aab
+ 1: aa
+
+/([\w:]+::)?(\w+)$/
+ abcd
+ 0: abcd
+ 1:
+ 2: abcd
+ xy:z:::abcd
+ 0: xy:z:::abcd
+ 1: xy:z:::
+ 2: abcd
+\= Expect no match
+ abcd:
+No match
+ abcd:
+No match
+
+/^[^bcd]*(c+)/
+ aexycd
+ 0: aexyc
+ 1: c
+
+/(>a+)ab/
+
+/(?>a+)b/
+ aaab
+ 0: aaab
+
+/([[:]+)/
+ a:[b]:
+ 0: :[
+ 1: :[
+
+/([[=]+)/
+ a=[b]=
+ 0: =[
+ 1: =[
+
+/([[.]+)/
+ a.[b].
+ 0: .[
+ 1: .[
+
+/((?>a+)b)/
+ aaab
+ 0: aaab
+ 1: aaab
+
+/(?>(a+))b/
+ aaab
+ 0: aaab
+ 1: aaa
+
+/((?>[^()]+)|\([^()]*\))+/
+ ((abc(ade)ufh()()x
+ 0: abc(ade)ufh()()x
+ 1: x
+
+/a\Z/
+\= Expect no match
+ aaab
+No match
+ a\nb\n
+No match
+
+/b\Z/
+ a\nb\n
+ 0: b
+
+/b\z/
+
+/b\Z/
+ a\nb
+ 0: b
+
+/b\z/
+ a\nb
+ 0: b
+
+/^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/
+ a
+ 0: a
+ 1:
+ abc
+ 0: abc
+ 1:
+ a-b
+ 0: a-b
+ 1:
+ 0-9
+ 0: 0-9
+ 1:
+ a.b
+ 0: a.b
+ 1:
+ 5.6.7
+ 0: 5.6.7
+ 1:
+ the.quick.brown.fox
+ 0: the.quick.brown.fox
+ 1:
+ a100.b200.300c
+ 0: a100.b200.300c
+ 1:
+ 12-ab.1245
+ 0: 12-ab.1245
+ 1:
+\= Expect no match
+ \
+No match
+ .a
+No match
+ -a
+No match
+ a-
+No match
+ a.
+No match
+ a_b
+No match
+ a.-
+No match
+ a..
+No match
+ ab..bc
+No match
+ the.quick.brown.fox-
+No match
+ the.quick.brown.fox.
+No match
+ the.quick.brown.fox_
+No match
+ the.quick.brown.fox+
+No match
+
+/(?>.*)(?<=(abcd|wxyz))/
+ alphabetabcd
+ 0: alphabetabcd
+ 1: abcd
+ endingwxyz
+ 0: endingwxyz
+ 1: wxyz
+\= Expect no match
+ a rather long string that doesn't end with one of them
+No match
+
+/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/
+ word cat dog elephant mussel cow horse canary baboon snake shark otherword
+ 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword
+\= Expect no match
+ word cat dog elephant mussel cow horse canary baboon snake shark
+No match
+
+/word (?>[a-zA-Z0-9]+ ){0,30}otherword/
+\= Expect no match
+ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope
+No match
+
+/(?<=\d{3}(?!999))foo/
+ 999foo
+ 0: foo
+ 123999foo
+ 0: foo
+\= Expect no match
+ 123abcfoo
+No match
+
+/(?<=(?!...999)\d{3})foo/
+ 999foo
+ 0: foo
+ 123999foo
+ 0: foo
+\= Expect no match
+ 123abcfoo
+No match
+
+/(?<=\d{3}(?!999)...)foo/
+ 123abcfoo
+ 0: foo
+ 123456foo
+ 0: foo
+\= Expect no match
+ 123999foo
+No match
+
+/(?<=\d{3}...)(?
+ 2:
+ 3: abcd
+
+ 2:
+ 3: abcd
+ \s*)=(?>\s*) # find
+ 2:
+ 3: abcd
+ Z)+|A)*/
+ ZABCDEFG
+ 0: ZA
+ 1: A
+
+/((?>)+|A)*/
+ ZABCDEFG
+ 0:
+ 1:
+
+/^[\d-a]/
+ abcde
+ 0: a
+ -things
+ 0: -
+ 0digit
+ 0: 0
+\= Expect no match
+ bcdef
+No match
+
+/[\s]+/
+ > \x09\x0a\x0c\x0d\x0b<
+ 0: \x09\x0a\x0c\x0d\x0b
+
+/\s+/
+ > \x09\x0a\x0c\x0d\x0b<
+ 0: \x09\x0a\x0c\x0d\x0b
+
+/ab/x
+ ab
+ 0: ab
+
+/(?!\A)x/m
+ a\nxb\n
+ 0: x
+
+/(?!^)x/m
+\= Expect no match
+ a\nxb\n
+No match
+
+#/abc\Qabc\Eabc/
+# abcabcabc
+# 0: abcabcabc
+
+#/abc\Q(*+|\Eabc/
+# abc(*+|abc
+# 0: abc(*+|abc
+
+#/ abc\Q abc\Eabc/x
+# abc abcabc
+# 0: abc abcabc
+#\= Expect no match
+# abcabcabc
+#No match
+
+#/abc#comment
+# \Q#not comment
+# literal\E/x
+# abc#not comment\n literal
+# 0: abc#not comment\x0a literal
+
+#/abc#comment
+# \Q#not comment
+# literal/x
+# abc#not comment\n literal
+# 0: abc#not comment\x0a literal
+
+#/abc#comment
+# \Q#not comment
+# literal\E #more comment
+# /x
+# abc#not comment\n literal
+# 0: abc#not comment\x0a literal
+
+#/abc#comment
+# \Q#not comment
+# literal\E #more comment/x
+# abc#not comment\n literal
+# 0: abc#not comment\x0a literal
+
+#/\Qabc\$xyz\E/
+# abc\\\$xyz
+# 0: abc\$xyz
+
+#/\Qabc\E\$\Qxyz\E/
+# abc\$xyz
+# 0: abc$xyz
+
+/\Gabc/
+ abc
+ 0: abc
+\= Expect no match
+ xyzabc
+No match
+
+/a(?x: b c )d/
+ XabcdY
+ 0: abcd
+\= Expect no match
+ Xa b c d Y
+No match
+
+/((?x)x y z | a b c)/
+ XabcY
+ 0: abc
+ 1: abc
+ AxyzB
+ 0: xyz
+ 1: xyz
+
+/(?i)AB(?-i)C/
+ XabCY
+ 0: abC
+\= Expect no match
+ XabcY
+No match
+
+/((?i)AB(?-i)C|D)E/
+ abCE
+ 0: abCE
+ 1: abC
+ DE
+ 0: DE
+ 1: D
+\= Expect no match
+ abcE
+No match
+ abCe
+No match
+ dE
+No match
+ De
+No match
+
+/(.*)\d+\1/
+ abc123abc
+ 0: abc123abc
+ 1: abc
+ abc123bc
+ 0: bc123bc
+ 1: bc
+
+/(.*)\d+\1/s
+ abc123abc
+ 0: abc123abc
+ 1: abc
+ abc123bc
+ 0: bc123bc
+ 1: bc
+
+/((.*))\d+\1/
+ abc123abc
+ 0: abc123abc
+ 1: abc
+ 2: abc
+ abc123bc
+ 0: bc123bc
+ 1: bc
+ 2: bc
+
+# This tests for an IPv6 address in the form where it can have up to
+# eight components, one and only one of which is empty. This must be
+# an internal component.
+
+/^(?!:) # colon disallowed at start
+ (?: # start of item
+ (?: [0-9a-f]{1,4} | # 1-4 hex digits or
+ (?(1)0 | () ) ) # if null previously matched, fail; else null
+ : # followed by colon
+ ){1,7} # end item; 1-7 of them required
+ [0-9a-f]{1,4} $ # final hex number at end of string
+ (?(1)|.) # check that there was an empty component
+ /ix
+ a123::a123
+ 0: a123::a123
+ 1:
+ a123:b342::abcd
+ 0: a123:b342::abcd
+ 1:
+ a123:b342::324e:abcd
+ 0: a123:b342::324e:abcd
+ 1:
+ a123:ddde:b342::324e:abcd
+ 0: a123:ddde:b342::324e:abcd
+ 1:
+ a123:ddde:b342::324e:dcba:abcd
+ 0: a123:ddde:b342::324e:dcba:abcd
+ 1:
+ a123:ddde:9999:b342::324e:dcba:abcd
+ 0: a123:ddde:9999:b342::324e:dcba:abcd
+ 1:
+\= Expect no match
+ 1:2:3:4:5:6:7:8
+No match
+ a123:bce:ddde:9999:b342::324e:dcba:abcd
+No match
+ a123::9999:b342::324e:dcba:abcd
+No match
+ abcde:2:3:4:5:6:7:8
+No match
+ ::1
+No match
+ abcd:fee0:123::
+No match
+ :1
+No match
+ 1:
+No match
+
+#/[z\Qa-d]\E]/
+# z
+# 0: z
+# a
+# 0: a
+# -
+# 0: -
+# d
+# 0: d
+# ]
+# 0: ]
+#\= Expect no match
+# b
+#No match
+
+#TODO: PCRE has an optimization to make this workable, .NET does not
+#/(a+)*b/
+#\= Expect no match
+# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+#No match
+
+# All these had to be updated because we understand unicode
+# and this looks like it's expecting single byte matches
+
+# .NET generates \xe4...not sure what's up, might just be different code pages
+/(?i)reg(?:ul(?:[aä]|ae)r|ex)/
+ REGular
+ 0: REGular
+ regulaer
+ 0: regulaer
+ Regex
+ 0: Regex
+ regulär
+ 0: regul\xc3\xa4r
+
+#/Åæåä[à-ÿÀ-ß]+/
+# Åæåäà
+# 0: \xc5\xe6\xe5\xe4\xe0
+# Åæåäÿ
+# 0: \xc5\xe6\xe5\xe4\xff
+# ÅæåäÀ
+# 0: \xc5\xe6\xe5\xe4\xc0
+# Åæåäß
+# 0: \xc5\xe6\xe5\xe4\xdf
+
+/(?<=Z)X./
+ \x84XAZXB
+ 0: XB
+
+/ab cd (?x) de fg/
+ ab cd defg
+ 0: ab cd defg
+
+/ab cd(?x) de fg/
+ ab cddefg
+ 0: ab cddefg
+\= Expect no match
+ abcddefg
+No match
+
+/(?
+ 2:
+ D
+ 0: D
+ 1:
+ 2:
+
+# this is really long with debug -- removing for now
+#/(a|)*\d/
+# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+# 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+# 1:
+#\= Expect no match
+# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+#No match
+
+/(?>a|)*\d/
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+ 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+\= Expect no match
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+No match
+
+/(?:a|)*\d/
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+ 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
+\= Expect no match
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+No match
+
+/^(?s)(?>.*)(?
+ 2: a
+
+/(?>(a))b|(a)c/
+ ac
+ 0: ac
+ 1:
+ 2: a
+
+/(?=(a))ab|(a)c/
+ ac
+ 0: ac
+ 1:
+ 2: a
+
+/((?>(a))b|(a)c)/
+ ac
+ 0: ac
+ 1: ac
+ 2:
+ 3: a
+
+/(?=(?>(a))b|(a)c)(..)/
+ ac
+ 0: ac
+ 1:
+ 2: a
+ 3: ac
+
+/(?>(?>(a))b|(a)c)/
+ ac
+ 0: ac
+ 1:
+ 2: a
+
+/((?>(a+)b)+(aabab))/
+ aaaabaaabaabab
+ 0: aaaabaaabaabab
+ 1: aaaabaaabaabab
+ 2: aaa
+ 3: aabab
+
+/(?>a+|ab)+?c/
+\= Expect no match
+ aabc
+No match
+
+/(?>a+|ab)+c/
+\= Expect no match
+ aabc
+No match
+
+/(?:a+|ab)+c/
+ aabc
+ 0: aabc
+
+/^(?:a|ab)+c/
+ aaaabc
+ 0: aaaabc
+
+/(?=abc){0}xyz/
+ xyz
+ 0: xyz
+
+/(?=abc){1}xyz/
+\= Expect no match
+ xyz
+No match
+
+/(?=(a))?./
+ ab
+ 0: a
+ 1: a
+ bc
+ 0: b
+
+/(?=(a))??./
+ ab
+ 0: a
+ bc
+ 0: b
+
+/^(?!a){0}\w+/
+ aaaaa
+ 0: aaaaa
+
+/(?<=(abc))?xyz/
+ abcxyz
+ 0: xyz
+ 1: abc
+ pqrxyz
+ 0: xyz
+
+/^[g]+/
+ ggg<<>>
+ 0: ggg<<>>
+\= Expect no match
+ \\ga
+No match
+
+/^[ga]+/
+ gggagagaxyz
+ 0: gggagaga
+
+/[:a]xxx[b:]/
+ :xxx:
+ 0: :xxx:
+
+/(?<=a{2})b/i
+ xaabc
+ 0: b
+\= Expect no match
+ xabc
+No match
+
+/(?
+# 4:
+# 5: c
+# 6: d
+# 7: Y
+
+#/^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/
+# XYabcdY
+# 0: XYabcdY
+# 1: a
+# 2: b
+# 3:
+# 4:
+# 5: c
+# 6: d
+# 7: Y
+
+/(?'abc'\w+):\k{2}/
+ a:aaxyz
+ 0: a:aa
+ 1: a
+ ab:ababxyz
+ 0: ab:abab
+ 1: ab
+\= Expect no match
+ a:axyz
+No match
+ ab:abxyz
+No match
+
+/^(?a)? (?(ab)b|c) (?(ab)d|e)/x
+ abd
+ 0: abd
+ 1: a
+ ce
+ 0: ce
+
+# .NET has more consistent grouping numbers with these dupe groups for the two options
+/(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?(quote)[a-z]+|[0-9]+)/x,dupnames
+ a\"aaaaa
+ 0: a"aaaaa
+ 1: "
+ 2:
+ 3: "
+ b\"aaaaa
+ 0: b"aaaaa
+ 1: "
+ 2:
+ 3: "
+\= Expect no match
+ b\"11111
+No match
+
+#/(?P(?P0)(?P>L1)|(?P>L2))/
+# 0
+# 0: 0
+# 1: 0
+# 00
+# 0: 00
+# 1: 00
+# 2: 0
+# 0000
+# 0: 0000
+# 1: 0000
+# 2: 0
+
+#/(?P(?P0)|(?P>L2)(?P>L1))/
+# 0
+# 0: 0
+# 1: 0
+# 2: 0
+# 00
+# 0: 0
+# 1: 0
+# 2: 0
+# 0000
+# 0: 0
+# 1: 0
+# 2: 0
+
+# Check the use of names for failure
+
+# Check opening parens in comment when seeking forward reference.
+
+#/(?P(?P=abn)xxx|)+/
+# xxx
+# 0:
+# 1:
+
+#Posses
+/^(a)?(\w)/
+ aaaaX
+ 0: aa
+ 1: a
+ 2: a
+ YZ
+ 0: Y
+ 1:
+ 2: Y
+
+#Posses
+/^(?:a)?(\w)/
+ aaaaX
+ 0: aa
+ 1: a
+ YZ
+ 0: Y
+ 1: Y
+
+/\A.*?(a|bc)/
+ ba
+ 0: ba
+ 1: a
+
+/\A.*?(?:a|bc|d)/
+ ba
+ 0: ba
+
+# --------------------------
+
+/(another)?(\1?)test/
+ hello world test
+ 0: test
+ 1:
+ 2:
+
+/(another)?(\1+)test/
+\= Expect no match
+ hello world test
+No match
+
+/((?:a?)*)*c/
+ aac
+ 0: aac
+ 1:
+
+/((?>a?)*)*c/
+ aac
+ 0: aac
+ 1:
+
+/(?>.*?a)(?<=ba)/
+ aba
+ 0: ba
+
+/(?:.*?a)(?<=ba)/
+ aba
+ 0: aba
+
+/(?>.*?a)b/s
+ aab
+ 0: ab
+
+/(?>.*?a)b/
+ aab
+ 0: ab
+
+/(?>^a)b/s
+\= Expect no match
+ aab
+No match
+
+/(?>.*?)(?<=(abcd)|(wxyz))/
+ alphabetabcd
+ 0:
+ 1: abcd
+ endingwxyz
+ 0:
+ 1:
+ 2: wxyz
+
+/(?>.*)(?<=(abcd)|(wxyz))/
+ alphabetabcd
+ 0: alphabetabcd
+ 1: abcd
+ endingwxyz
+ 0: endingwxyz
+ 1:
+ 2: wxyz
+
+"(?>.*)foo"
+\= Expect no match
+ abcdfooxyz
+No match
+
+"(?>.*?)foo"
+ abcdfooxyz
+ 0: foo
+
+# Tests that try to figure out how Perl works. My hypothesis is that the first
+# verb that is backtracked onto is the one that acts. This seems to be the case
+# almost all the time, but there is one exception that is perhaps a bug.
+
+/a(?=bc).|abd/
+ abd
+ 0: abd
+ abc
+ 0: ab
+
+/a(?>bc)d|abd/
+ abceabd
+ 0: abd
+
+# These tests were formerly in test 2, but changes in PCRE and Perl have
+# made them compatible.
+
+/^(a)?(?(1)a|b)+$/
+\= Expect no match
+ a
+No match
+
+# ----
+
+/^\d*\w{4}/
+ 1234
+ 0: 1234
+\= Expect no match
+ 123
+No match
+
+/^[^b]*\w{4}/
+ aaaa
+ 0: aaaa
+\= Expect no match
+ aaa
+No match
+
+/^[^b]*\w{4}/i
+ aaaa
+ 0: aaaa
+\= Expect no match
+ aaa
+No match
+
+/^a*\w{4}/
+ aaaa
+ 0: aaaa
+\= Expect no match
+ aaa
+No match
+
+/^a*\w{4}/i
+ aaaa
+ 0: aaaa
+\= Expect no match
+ aaa
+No match
+
+/(?:(?foo)|(?bar))\k/dupnames
+ foofoo
+ 0: foofoo
+ 1: foo
+ barbar
+ 0: barbar
+ 1: bar
+
+# A notable difference between PCRE and .NET. According to
+# the PCRE docs:
+# If you make a subroutine call to a non-unique named
+# subpattern, the one that corresponds to the first
+# occurrence of the name is used. In the absence of
+# duplicate numbers (see the previous section) this is
+# the one with the lowest number.
+# .NET takes the most recently captured number according to MSDN:
+# A backreference refers to the most recent definition of
+# a group (the definition most immediately to the left,
+# when matching left to right). When a group makes multiple
+# captures, a backreference refers to the most recent capture.
+
+#/(?A)(?:(?foo)|(?bar))\k/dupnames
+# AfooA
+# 0: AfooA
+# 1: A
+# 2: foo
+# AbarA
+# 0: AbarA
+# 1: A
+# 2:
+# 3: bar
+#\= Expect no match
+# Afoofoo
+#No match
+# Abarbar
+#No match
+
+/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/
+ 1 IN SOA non-sp1 non-sp2(
+ 0: 1 IN SOA non-sp1 non-sp2(
+ 1: 1
+ 2: non-sp1
+ 3: non-sp2
+
+# TODO: .NET's group number ordering here in the second example is a bit odd
+/^ (?:(?A)|(?'B'B)(?A)) (?(A)x) (?(B)y)$/x,dupnames
+ Ax
+ 0: Ax
+ 1: A
+ BAxy
+ 0: BAxy
+ 1: A
+ 2: B
+
+/ ^ a + b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ a + #comment
+ b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ a + #comment
+ #comment
+ b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ (?> a + ) b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ ( a + ) + \w $ /x
+ aaaab
+ 0: aaaab
+ 1: aaaa
+
+/(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc/
+\= Expect no match
+ acb
+No match
+
+#Posses
+#/\A(?:[^\"]+|\"(?:[^\"]*|\"\")*\")+/
+# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+# 0: NON QUOTED "QUOT""ED" AFTER
+
+#Posses
+#/\A(?:[^\"]+|\"(?:[^\"]+|\"\")*\")+/
+# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+# 0: NON QUOTED "QUOT""ED" AFTER
+
+#Posses
+#/\A(?:[^\"]+|\"(?:[^\"]+|\"\")+\")+/
+# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+# 0: NON QUOTED "QUOT""ED" AFTER
+
+#Posses
+#/\A([^\"1]+|[\"2]([^\"3]*|[\"4][\"5])*[\"6])+/
+# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+# 0: NON QUOTED "QUOT""ED" AFTER
+# 1: AFTER
+# 2:
+
+/^\w+(?>\s*)(?<=\w)/
+ test test
+ 0: tes
+
+#/(?Pa)?(?Pb)?(?()c|d)*l/
+# acl
+# 0: acl
+# 1: a
+# bdl
+# 0: bdl
+# 1:
+# 2: b
+# adl
+# 0: dl
+# bcl
+# 0: l
+
+/\sabc/
+ \x0babc
+ 0: \x0babc
+
+#/[\Qa]\E]+/
+# aa]]
+# 0: aa]]
+
+#/[\Q]a\E]+/
+# aa]]
+# 0: aa]]
+
+/A((((((((a))))))))\8B/
+ AaaB
+ 0: AaaB
+ 1: a
+ 2: a
+ 3: a
+ 4: a
+ 5: a
+ 6: a
+ 7: a
+ 8: a
+
+/A(((((((((a)))))))))\9B/
+ AaaB
+ 0: AaaB
+ 1: a
+ 2: a
+ 3: a
+ 4: a
+ 5: a
+ 6: a
+ 7: a
+ 8: a
+ 9: a
+
+/(|ab)*?d/
+ abd
+ 0: abd
+ 1: ab
+ xyd
+ 0: d
+
+/(\2|a)(\1)/
+ aaa
+ 0: aa
+ 1: a
+ 2: a
+
+/(\2)(\1)/
+
+"Z*(|d*){216}"
+
+/((((((((((((x))))))))))))\12/
+ xx
+ 0: xx
+ 1: x
+ 2: x
+ 3: x
+ 4: x
+ 5: x
+ 6: x
+ 7: x
+ 8: x
+ 9: x
+10: x
+11: x
+12: x
+
+#"(?|(\k'Pm')|(?'Pm'))"
+# abcd
+# 0:
+# 1:
+
+#/(?|(aaa)|(b))\g{1}/
+# aaaaaa
+# 0: aaaaaa
+# 1: aaa
+# bb
+# 0: bb
+# 1: b
+
+#/(?|(aaa)|(b))(?1)/
+# aaaaaa
+# 0: aaaaaa
+# 1: aaa
+# baaa
+# 0: baaa
+# 1: b
+#\= Expect no match
+# bb
+#No match
+
+#/(?|(aaa)|(b))/
+# xaaa
+# 0: aaa
+# 1: aaa
+# xbc
+# 0: b
+# 1: b
+
+#/(?|(?'a'aaa)|(?'a'b))\k'a'/
+# aaaaaa
+# 0: aaaaaa
+# 1: aaa
+# bb
+# 0: bb
+# 1: b
+
+#/(?|(?'a'aaa)|(?'a'b))(?'a'cccc)\k'a'/dupnames
+# aaaccccaaa
+# 0: aaaccccaaa
+# 1: aaa
+# 2: cccc
+# bccccb
+# 0: bccccb
+# 1: b
+# 2: cccc
+
+# End of testinput1
diff --git a/vendor/github.com/firefart/nonamedreturns/analyzer/analyzer.go b/vendor/github.com/firefart/nonamedreturns/analyzer/analyzer.go
index ecd4915a..a61899f0 100644
--- a/vendor/github.com/firefart/nonamedreturns/analyzer/analyzer.go
+++ b/vendor/github.com/firefart/nonamedreturns/analyzer/analyzer.go
@@ -1,6 +1,7 @@
package analyzer
import (
+ "errors"
"flag"
"go/ast"
"go/types"
@@ -30,7 +31,10 @@ func run(pass *analysis.Pass) (interface{}, error) {
reportErrorInDefer := pass.Analyzer.Flags.Lookup(FlagReportErrorInDefer).Value.String() == "true"
errorType := types.Universe.Lookup("error").Type()
- inspector := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+ inspector, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+ if !ok {
+ return nil, errors.New("failed to get inspector")
+ }
// only filter function defintions
nodeFilter := []ast.Node{
@@ -87,7 +91,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
})
- return nil, nil
+ return nil, nil // nolint:nilnil
}
func findDeferWithVariableAssignment(body *ast.BlockStmt, info *types.Info, variable types.Object) bool {
diff --git a/vendor/github.com/ghostiam/protogetter/flake.lock b/vendor/github.com/ghostiam/protogetter/flake.lock
new file mode 100644
index 00000000..46930d25
--- /dev/null
+++ b/vendor/github.com/ghostiam/protogetter/flake.lock
@@ -0,0 +1,61 @@
+{
+ "nodes": {
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1741513245,
+ "narHash": "sha256-7rTAMNTY1xoBwz0h7ZMtEcd8LELk9R5TzBPoHuhNSCk=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "e3e32b642a31e6714ec1b712de8c91a3352ce7e1",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "flake-utils": "flake-utils",
+ "nixpkgs": "nixpkgs"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/vendor/github.com/ghostiam/protogetter/flake.nix b/vendor/github.com/ghostiam/protogetter/flake.nix
new file mode 100644
index 00000000..3e2a6ce6
--- /dev/null
+++ b/vendor/github.com/ghostiam/protogetter/flake.nix
@@ -0,0 +1,69 @@
+{
+ description = "A flake that builds a repo";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ flake-utils.url = "github:numtide/flake-utils";
+ };
+
+ outputs =
+ inputs@{
+ nixpkgs,
+ flake-utils,
+ ...
+ }:
+ flake-utils.lib.eachDefaultSystem (
+ system:
+ let
+ pkgs = import nixpkgs { inherit system; };
+ buildInputs = with pkgs; [
+ go
+ coreutils
+ curl
+ xmlstarlet
+
+ # Protobuf + gRPC
+ protobuf
+ protoc-gen-go
+ protoc-gen-go-grpc
+ grpc
+ ];
+
+ defaultShellHook = ''
+ export SHELL="${pkgs.bashInteractive}/bin/bash"
+
+ export FLAKE_ROOT="$(nix flake metadata | grep 'Resolved URL' | awk '{print $3}' | sed 's/^path://' | sed 's/^git+file:\/\///')"
+ export HISTFILE="$FLAKE_ROOT/.nix_bash_history"
+
+ export GOROOT="${pkgs.go}/share/go"
+ '';
+ in
+ {
+ # run: `nix develop`
+ devShells = {
+ default = pkgs.mkShell {
+ inherit buildInputs;
+ shellHook = defaultShellHook;
+ };
+
+ # Update IDEA paths. Use only if nix installed in whole system.
+ # run: `nix develop .#idea`
+ idea = pkgs.mkShell {
+ inherit buildInputs;
+
+ shellHook = pkgs.lib.concatLines [
+ defaultShellHook
+ ''
+ cd "$FLAKE_ROOT"
+
+ echo "Replace GOPATH"
+ xmlstarlet ed -L -u '//project/component[@name="GOROOT"]/@url' -v 'file://${pkgs.go}/share/go' .idea/workspace.xml
+
+ exit 0
+ ''
+ ];
+ };
+ };
+ }
+ );
+}
diff --git a/vendor/github.com/ghostiam/protogetter/processor.go b/vendor/github.com/ghostiam/protogetter/processor.go
index 44f346e8..aaa4ab3c 100644
--- a/vendor/github.com/ghostiam/protogetter/processor.go
+++ b/vendor/github.com/ghostiam/protogetter/processor.go
@@ -33,12 +33,21 @@ func (c *processor) process(n ast.Node) (*Result, error) {
switch x := n.(type) {
case *ast.AssignStmt:
// Skip any assignment to the field.
- for _, s := range x.Lhs {
+ for i, s := range x.Lhs {
c.filter.AddPos(s.Pos())
if se, ok := s.(*ast.StarExpr); ok {
c.filter.AddPos(se.X.Pos())
}
+
+ if len(x.Rhs) > i {
+ value := x.Rhs[i]
+ if se, ok := value.(*ast.SelectorExpr); ok {
+ if hasPointerKeyWithoutPointerGetter(c.info, s, se) {
+ c.filter.AddPos(se.Sel.Pos())
+ }
+ }
+ }
}
case *ast.IncDecStmt:
@@ -52,6 +61,13 @@ func (c *processor) process(n ast.Node) (*Result, error) {
c.filter.AddPos(x.X.Pos())
}
+ case *ast.KeyValueExpr:
+ if se, ok := x.Value.(*ast.SelectorExpr); ok {
+ if hasPointerKeyWithoutPointerGetter(c.info, x.Key, se) {
+ c.filter.AddPos(se.Sel.Pos())
+ }
+ }
+
case *ast.CallExpr:
if !c.cfg.ReplaceFirstArgInAppend && len(x.Args) > 0 {
if v, ok := x.Fun.(*ast.Ident); ok && v.Name == "append" {
@@ -61,17 +77,61 @@ func (c *processor) process(n ast.Node) (*Result, error) {
}
}
- f, ok := x.Fun.(*ast.SelectorExpr)
- if !ok {
- return &Result{}, nil
- }
+ switch fun := x.Fun.(type) {
+ case *ast.Ident:
+ // Allow passing optional parameters to the function without getter.
- if !isProtoMessage(c.info, f.X) {
+ if len(x.Args) == 0 {
+ return &Result{}, nil
+ }
+
+ if fun.Obj == nil || fun.Obj.Kind != ast.Fun {
+ return &Result{}, nil
+ }
+
+ decl, ok := fun.Obj.Decl.(*ast.FuncDecl)
+ if !ok || decl.Type == nil {
+ return &Result{}, nil
+ }
+
+ for _, arg := range x.Args {
+ a, ok := arg.(*ast.SelectorExpr)
+ if !ok {
+ continue
+ }
+
+ if !isProtoMessage(c.info, a.X) {
+ continue
+ }
+
+ // If the argument is not a pointer,
+ // then we should not skip the check for using the getter.
+ _, isPtrArg := c.info.TypeOf(a).Underlying().(*types.Pointer)
+ if !isPtrArg {
+ continue
+ }
+
+ // If the getter also have a pointer,
+ // then we should not skip the check for using the getter.
+ getterHasPointer, _ := getterResultHasPointer(c.info, a.X, a.Sel.Name)
+ if getterHasPointer {
+ continue
+ }
+
+ c.filter.AddPos(a.Sel.Pos())
+ }
+
+ case *ast.SelectorExpr:
+ if !isProtoMessage(c.info, fun.X) {
+ return &Result{}, nil
+ }
+
+ c.processInner(x)
+
+ default:
return &Result{}, nil
}
- c.processInner(x)
-
case *ast.SelectorExpr:
if !isProtoMessage(c.info, x.X) {
// If the selector is not on a proto message, skip it.
@@ -176,8 +236,11 @@ func (c *processor) processInner(expr ast.Expr) {
c.processInner(x.X)
c.write(".")
+ // Skip if the field is filtered.
+ isFiltered := c.filter.IsFiltered(x.Sel.Pos())
+
// If getter exists, use it.
- if methodIsExists(c.info, x.X, "Get"+x.Sel.Name) {
+ if methodIsExists(c.info, x.X, "Get"+x.Sel.Name) && !isFiltered {
c.writeFrom(x.Sel.Name)
c.writeTo("Get" + x.Sel.Name + "()")
return
@@ -218,7 +281,7 @@ func (c *processor) processInner(expr ast.Expr) {
c.write("*")
c.processInner(x.X)
- case *ast.CompositeLit, *ast.TypeAssertExpr, *ast.ArrayType, *ast.FuncLit, *ast.SliceExpr:
+ case *ast.CompositeLit, *ast.TypeAssertExpr, *ast.ArrayType, *ast.FuncLit, *ast.SliceExpr, *ast.MapType:
// Process the node as is.
c.write(formatNode(x))
@@ -349,3 +412,17 @@ func getterResultHasPointer(info *types.Info, x ast.Expr, name string) (hasPoint
return false, false
}
+
+func hasPointerKeyWithoutPointerGetter(info *types.Info, key ast.Expr, value *ast.SelectorExpr) bool {
+ _, isPtr := info.TypeOf(key).(*types.Pointer)
+ if !isPtr {
+ return false
+ }
+
+ getterHasPointer, ok := getterResultHasPointer(info, value.X, value.Sel.Name)
+ if !ok {
+ return false
+ }
+
+ return !getterHasPointer
+}
diff --git a/vendor/github.com/ghostiam/protogetter/protogetter.go b/vendor/github.com/ghostiam/protogetter/protogetter.go
index c1c42c75..0dbcf31c 100644
--- a/vendor/github.com/ghostiam/protogetter/protogetter.go
+++ b/vendor/github.com/ghostiam/protogetter/protogetter.go
@@ -96,6 +96,7 @@ func Run(pass *analysis.Pass, cfg *Config) error {
(*ast.StarExpr)(nil),
(*ast.IncDecStmt)(nil),
(*ast.UnaryExpr)(nil),
+ (*ast.KeyValueExpr)(nil),
}
// Skip filtered files.
diff --git a/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go b/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go
index 8595b795..788355d7 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go
@@ -93,6 +93,10 @@ func (c *commentedOutCodeChecker) VisitLocalComment(cg *ast.CommentGroup) {
return
}
+ if c.isExampleOutputComment(s) {
+ return
+ }
+
stmt := strparse.Stmt(s)
if c.isPermittedStmt(stmt) {
@@ -109,11 +113,6 @@ func (c *commentedOutCodeChecker) VisitLocalComment(cg *ast.CommentGroup) {
return
}
- // Some attempts to avoid false positives.
- if c.skipBlock(s) {
- return
- }
-
// Add braces to make block statement from
// multiple statements.
stmt = strparse.Stmt(fmt.Sprintf("{ %s }", s))
@@ -123,15 +122,18 @@ func (c *commentedOutCodeChecker) VisitLocalComment(cg *ast.CommentGroup) {
}
}
-func (c *commentedOutCodeChecker) skipBlock(s string) bool {
- lines := strings.Split(s, "\n") // There is at least 1 line, that's invariant
-
- // Special example test block.
- if isExampleTestFunc(c.fn) && strings.Contains(lines[0], "Output:") {
- return true
- }
-
- return false
+// An example output comment can be one of the following:
+//
+// Output: some output
+//
+// or
+//
+// Output:
+// some output
+//
+// See https://go.dev/blog/examples
+func (c *commentedOutCodeChecker) isExampleOutputComment(s string) bool {
+ return isExampleTestFunc(c.fn) && strings.Contains(s, "Output:")
}
func (c *commentedOutCodeChecker) isPermittedStmt(stmt ast.Stmt) bool {
diff --git a/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go b/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go
index 4ab31076..ace418d4 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go
@@ -1391,48 +1391,53 @@ var PrecompiledRules = &ir.File{
Line: 384,
SyntaxPatterns: []ir.PatternString{
{Line: 384, Value: "copy($x, $x)"},
- {Line: 385, Value: "math.Max($x, $x)"},
- {Line: 386, Value: "math.Min($x, $x)"},
- {Line: 387, Value: "reflect.Copy($x, $x)"},
- {Line: 388, Value: "reflect.DeepEqual($x, $x)"},
- {Line: 389, Value: "strings.Contains($x, $x)"},
- {Line: 390, Value: "strings.Compare($x, $x)"},
- {Line: 391, Value: "strings.EqualFold($x, $x)"},
- {Line: 392, Value: "strings.HasPrefix($x, $x)"},
- {Line: 393, Value: "strings.HasSuffix($x, $x)"},
- {Line: 394, Value: "strings.Index($x, $x)"},
- {Line: 395, Value: "strings.LastIndex($x, $x)"},
- {Line: 396, Value: "strings.Split($x, $x)"},
- {Line: 397, Value: "strings.SplitAfter($x, $x)"},
- {Line: 398, Value: "strings.SplitAfterN($x, $x, $_)"},
- {Line: 399, Value: "strings.SplitN($x, $x, $_)"},
- {Line: 400, Value: "strings.Replace($_, $x, $x, $_)"},
- {Line: 401, Value: "strings.ReplaceAll($_, $x, $x)"},
- {Line: 402, Value: "bytes.Contains($x, $x)"},
- {Line: 403, Value: "bytes.Compare($x, $x)"},
- {Line: 404, Value: "bytes.Equal($x, $x)"},
- {Line: 405, Value: "bytes.EqualFold($x, $x)"},
- {Line: 406, Value: "bytes.HasPrefix($x, $x)"},
- {Line: 407, Value: "bytes.HasSuffix($x, $x)"},
- {Line: 408, Value: "bytes.Index($x, $x)"},
- {Line: 409, Value: "bytes.LastIndex($x, $x)"},
- {Line: 410, Value: "bytes.Split($x, $x)"},
- {Line: 411, Value: "bytes.SplitAfter($x, $x)"},
- {Line: 412, Value: "bytes.SplitAfterN($x, $x, $_)"},
- {Line: 413, Value: "bytes.SplitN($x, $x, $_)"},
- {Line: 414, Value: "bytes.Replace($_, $x, $x, $_)"},
- {Line: 415, Value: "bytes.ReplaceAll($_, $x, $x)"},
- {Line: 416, Value: "types.Identical($x, $x)"},
- {Line: 417, Value: "types.IdenticalIgnoreTags($x, $x)"},
- {Line: 418, Value: "draw.Draw($x, $_, $x, $_, $_)"},
+ {Line: 385, Value: "cmp.Compare($x, $x)"},
+ {Line: 386, Value: "maps.Equal($x, $x)"},
+ {Line: 387, Value: "math.Dim($x, $x)"},
+ {Line: 388, Value: "math.Max($x, $x)"},
+ {Line: 389, Value: "math.Min($x, $x)"},
+ {Line: 390, Value: "reflect.Copy($x, $x)"},
+ {Line: 391, Value: "reflect.DeepEqual($x, $x)"},
+ {Line: 392, Value: "slices.Compare($x, $x)"},
+ {Line: 393, Value: "slices.Equal($x, $x)"},
+ {Line: 394, Value: "strings.Contains($x, $x)"},
+ {Line: 395, Value: "strings.Compare($x, $x)"},
+ {Line: 396, Value: "strings.EqualFold($x, $x)"},
+ {Line: 397, Value: "strings.HasPrefix($x, $x)"},
+ {Line: 398, Value: "strings.HasSuffix($x, $x)"},
+ {Line: 399, Value: "strings.Index($x, $x)"},
+ {Line: 400, Value: "strings.LastIndex($x, $x)"},
+ {Line: 401, Value: "strings.Split($x, $x)"},
+ {Line: 402, Value: "strings.SplitAfter($x, $x)"},
+ {Line: 403, Value: "strings.SplitAfterN($x, $x, $_)"},
+ {Line: 404, Value: "strings.SplitN($x, $x, $_)"},
+ {Line: 405, Value: "strings.Replace($_, $x, $x, $_)"},
+ {Line: 406, Value: "strings.ReplaceAll($_, $x, $x)"},
+ {Line: 407, Value: "bytes.Contains($x, $x)"},
+ {Line: 408, Value: "bytes.Compare($x, $x)"},
+ {Line: 409, Value: "bytes.Equal($x, $x)"},
+ {Line: 410, Value: "bytes.EqualFold($x, $x)"},
+ {Line: 411, Value: "bytes.HasPrefix($x, $x)"},
+ {Line: 412, Value: "bytes.HasSuffix($x, $x)"},
+ {Line: 413, Value: "bytes.Index($x, $x)"},
+ {Line: 414, Value: "bytes.LastIndex($x, $x)"},
+ {Line: 415, Value: "bytes.Split($x, $x)"},
+ {Line: 416, Value: "bytes.SplitAfter($x, $x)"},
+ {Line: 417, Value: "bytes.SplitAfterN($x, $x, $_)"},
+ {Line: 418, Value: "bytes.SplitN($x, $x, $_)"},
+ {Line: 419, Value: "bytes.Replace($_, $x, $x, $_)"},
+ {Line: 420, Value: "bytes.ReplaceAll($_, $x, $x)"},
+ {Line: 421, Value: "types.Identical($x, $x)"},
+ {Line: 422, Value: "types.IdenticalIgnoreTags($x, $x)"},
+ {Line: 423, Value: "draw.Draw($x, $_, $x, $_, $_)"},
},
ReportTemplate: "suspicious duplicated args in $$",
- WhereExpr: ir.FilterExpr{Line: 419, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
+ WhereExpr: ir.FilterExpr{Line: 424, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
},
},
},
{
- Line: 427,
+ Line: 432,
Name: "returnAfterHttpError",
MatcherName: "m",
DocTags: []string{"diagnostic", "experimental"},
@@ -1440,14 +1445,14 @@ var PrecompiledRules = &ir.File{
DocBefore: "if err != nil { http.Error(...); }",
DocAfter: "if err != nil { http.Error(...); return; }",
Rules: []ir.Rule{{
- Line: 428,
- SyntaxPatterns: []ir.PatternString{{Line: 428, Value: "if $_ { $*_; http.Error($w, $err, $code) }"}},
+ Line: 433,
+ SyntaxPatterns: []ir.PatternString{{Line: 433, Value: "if $_ { $*_; http.Error($w, $err, $code) }"}},
ReportTemplate: "Possibly return is missed after the http.Error call",
LocationVar: "w",
}},
},
{
- Line: 437,
+ Line: 442,
Name: "preferFilepathJoin",
MatcherName: "m",
DocTags: []string{"style", "experimental"},
@@ -1455,35 +1460,35 @@ var PrecompiledRules = &ir.File{
DocBefore: "x + string(os.PathSeparator) + y",
DocAfter: "filepath.Join(x, y)",
Rules: []ir.Rule{{
- Line: 438,
- SyntaxPatterns: []ir.PatternString{{Line: 438, Value: "$x + string(os.PathSeparator) + $y"}},
+ Line: 443,
+ SyntaxPatterns: []ir.PatternString{{Line: 443, Value: "$x + string(os.PathSeparator) + $y"}},
ReportTemplate: "filepath.Join($x, $y) should be preferred to the $$",
SuggestTemplate: "filepath.Join($x, $y)",
WhereExpr: ir.FilterExpr{
- Line: 439,
+ Line: 444,
Op: ir.FilterAndOp,
Src: "m[\"x\"].Type.Is(`string`) && m[\"y\"].Type.Is(`string`)",
Args: []ir.FilterExpr{
{
- Line: 439,
+ Line: 444,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"x\"].Type.Is(`string`)",
Value: "x",
- Args: []ir.FilterExpr{{Line: 439, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}},
+ Args: []ir.FilterExpr{{Line: 444, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}},
},
{
- Line: 439,
+ Line: 444,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"y\"].Type.Is(`string`)",
Value: "y",
- Args: []ir.FilterExpr{{Line: 439, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}},
+ Args: []ir.FilterExpr{{Line: 444, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}},
},
},
},
}},
},
{
- Line: 448,
+ Line: 453,
Name: "preferStringWriter",
MatcherName: "m",
DocTags: []string{"performance", "experimental"},
@@ -1492,35 +1497,35 @@ var PrecompiledRules = &ir.File{
DocAfter: "w.WriteString(\"foo\")",
Rules: []ir.Rule{
{
- Line: 449,
- SyntaxPatterns: []ir.PatternString{{Line: 449, Value: "$w.Write([]byte($s))"}},
+ Line: 454,
+ SyntaxPatterns: []ir.PatternString{{Line: 454, Value: "$w.Write([]byte($s))"}},
ReportTemplate: "$w.WriteString($s) should be preferred to the $$",
SuggestTemplate: "$w.WriteString($s)",
WhereExpr: ir.FilterExpr{
- Line: 450,
+ Line: 455,
Op: ir.FilterVarTypeImplementsOp,
Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")",
Value: "w",
- Args: []ir.FilterExpr{{Line: 450, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}},
+ Args: []ir.FilterExpr{{Line: 455, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}},
},
},
{
- Line: 454,
- SyntaxPatterns: []ir.PatternString{{Line: 454, Value: "io.WriteString($w, $s)"}},
+ Line: 459,
+ SyntaxPatterns: []ir.PatternString{{Line: 459, Value: "io.WriteString($w, $s)"}},
ReportTemplate: "$w.WriteString($s) should be preferred to the $$",
SuggestTemplate: "$w.WriteString($s)",
WhereExpr: ir.FilterExpr{
- Line: 455,
+ Line: 460,
Op: ir.FilterVarTypeImplementsOp,
Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")",
Value: "w",
- Args: []ir.FilterExpr{{Line: 455, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}},
+ Args: []ir.FilterExpr{{Line: 460, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}},
},
},
},
},
{
- Line: 464,
+ Line: 469,
Name: "sliceClear",
MatcherName: "m",
DocTags: []string{"performance", "experimental"},
@@ -1528,22 +1533,22 @@ var PrecompiledRules = &ir.File{
DocBefore: "for i := 0; i < len(buf); i++ { buf[i] = 0 }",
DocAfter: "for i := range buf { buf[i] = 0 }",
Rules: []ir.Rule{{
- Line: 465,
- SyntaxPatterns: []ir.PatternString{{Line: 465, Value: "for $i := 0; $i < len($xs); $i++ { $xs[$i] = $zero }"}},
+ Line: 470,
+ SyntaxPatterns: []ir.PatternString{{Line: 470, Value: "for $i := 0; $i < len($xs); $i++ { $xs[$i] = $zero }"}},
ReportTemplate: "rewrite as for-range so compiler can recognize this pattern",
WhereExpr: ir.FilterExpr{
- Line: 466,
+ Line: 471,
Op: ir.FilterEqOp,
Src: "m[\"zero\"].Value.Int() == 0",
Args: []ir.FilterExpr{
{
- Line: 466,
+ Line: 471,
Op: ir.FilterVarValueIntOp,
Src: "m[\"zero\"].Value.Int()",
Value: "zero",
},
{
- Line: 466,
+ Line: 471,
Op: ir.FilterIntOp,
Src: "0",
Value: int64(0),
@@ -1553,7 +1558,7 @@ var PrecompiledRules = &ir.File{
}},
},
{
- Line: 474,
+ Line: 479,
Name: "syncMapLoadAndDelete",
MatcherName: "m",
DocTags: []string{"diagnostic", "experimental"},
@@ -1561,33 +1566,33 @@ var PrecompiledRules = &ir.File{
DocBefore: "v, ok := m.Load(k); if ok { m.Delete($k); f(v); }",
DocAfter: "v, deleted := m.LoadAndDelete(k); if deleted { f(v) }",
Rules: []ir.Rule{{
- Line: 475,
- SyntaxPatterns: []ir.PatternString{{Line: 475, Value: "$_, $ok := $m.Load($k); if $ok { $m.Delete($k); $*_ }"}},
+ Line: 480,
+ SyntaxPatterns: []ir.PatternString{{Line: 480, Value: "$_, $ok := $m.Load($k); if $ok { $m.Delete($k); $*_ }"}},
ReportTemplate: "use $m.LoadAndDelete to perform load+delete operations atomically",
WhereExpr: ir.FilterExpr{
- Line: 476,
+ Line: 481,
Op: ir.FilterAndOp,
Src: "m.GoVersion().GreaterEqThan(\"1.15\") &&\n\tm[\"m\"].Type.Is(`*sync.Map`)",
Args: []ir.FilterExpr{
{
- Line: 476,
+ Line: 481,
Op: ir.FilterGoVersionGreaterEqThanOp,
Src: "m.GoVersion().GreaterEqThan(\"1.15\")",
Value: "1.15",
},
{
- Line: 477,
+ Line: 482,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"m\"].Type.Is(`*sync.Map`)",
Value: "m",
- Args: []ir.FilterExpr{{Line: 477, Op: ir.FilterStringOp, Src: "`*sync.Map`", Value: "*sync.Map"}},
+ Args: []ir.FilterExpr{{Line: 482, Op: ir.FilterStringOp, Src: "`*sync.Map`", Value: "*sync.Map"}},
},
},
},
}},
},
{
- Line: 485,
+ Line: 490,
Name: "sprintfQuotedString",
MatcherName: "m",
DocTags: []string{"diagnostic", "experimental"},
@@ -1595,34 +1600,34 @@ var PrecompiledRules = &ir.File{
DocBefore: "fmt.Sprintf(`\"%s\"`, s)",
DocAfter: "fmt.Sprintf(`%q`, s)",
Rules: []ir.Rule{{
- Line: 486,
- SyntaxPatterns: []ir.PatternString{{Line: 486, Value: "fmt.Sprintf($s, $*_)"}},
+ Line: 491,
+ SyntaxPatterns: []ir.PatternString{{Line: 491, Value: "fmt.Sprintf($s, $*_)"}},
ReportTemplate: "use %q instead of \"%s\" for quoted strings",
WhereExpr: ir.FilterExpr{
- Line: 487,
+ Line: 492,
Op: ir.FilterOrOp,
Src: "m[\"s\"].Text.Matches(\"^`.*\\\"%s\\\".*`$\") ||\n\tm[\"s\"].Text.Matches(`^\".*\\\\\"%s\\\\\".*\"$`)",
Args: []ir.FilterExpr{
{
- Line: 487,
+ Line: 492,
Op: ir.FilterVarTextMatchesOp,
Src: "m[\"s\"].Text.Matches(\"^`.*\\\"%s\\\".*`$\")",
Value: "s",
- Args: []ir.FilterExpr{{Line: 487, Op: ir.FilterStringOp, Src: "\"^`.*\\\"%s\\\".*`$\"", Value: "^`.*\"%s\".*`$"}},
+ Args: []ir.FilterExpr{{Line: 492, Op: ir.FilterStringOp, Src: "\"^`.*\\\"%s\\\".*`$\"", Value: "^`.*\"%s\".*`$"}},
},
{
- Line: 488,
+ Line: 493,
Op: ir.FilterVarTextMatchesOp,
Src: "m[\"s\"].Text.Matches(`^\".*\\\\\"%s\\\\\".*\"$`)",
Value: "s",
- Args: []ir.FilterExpr{{Line: 488, Op: ir.FilterStringOp, Src: "`^\".*\\\\\"%s\\\\\".*\"$`", Value: "^\".*\\\\\"%s\\\\\".*\"$"}},
+ Args: []ir.FilterExpr{{Line: 493, Op: ir.FilterStringOp, Src: "`^\".*\\\\\"%s\\\\\".*\"$`", Value: "^\".*\\\\\"%s\\\\\".*\"$"}},
},
},
},
}},
},
{
- Line: 496,
+ Line: 501,
Name: "offBy1",
MatcherName: "m",
DocTags: []string{"diagnostic"},
@@ -1631,80 +1636,80 @@ var PrecompiledRules = &ir.File{
DocAfter: "xs[len(xs)-1]",
Rules: []ir.Rule{
{
- Line: 497,
- SyntaxPatterns: []ir.PatternString{{Line: 497, Value: "$x[len($x)]"}},
+ Line: 502,
+ SyntaxPatterns: []ir.PatternString{{Line: 502, Value: "$x[len($x)]"}},
ReportTemplate: "index expr always panics; maybe you wanted $x[len($x)-1]?",
SuggestTemplate: "$x[len($x)-1]",
WhereExpr: ir.FilterExpr{
- Line: 498,
+ Line: 503,
Op: ir.FilterAndOp,
Src: "m[\"x\"].Pure && m[\"x\"].Type.Is(`[]$_`)",
Args: []ir.FilterExpr{
- {Line: 498, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
+ {Line: 503, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
{
- Line: 498,
+ Line: 503,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"x\"].Type.Is(`[]$_`)",
Value: "x",
- Args: []ir.FilterExpr{{Line: 498, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}},
+ Args: []ir.FilterExpr{{Line: 503, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}},
},
},
},
},
{
- Line: 505,
+ Line: 510,
SyntaxPatterns: []ir.PatternString{
- {Line: 506, Value: "$i := strings.Index($s, $_); $_ := $slicing[$i:]"},
- {Line: 507, Value: "$i := strings.Index($s, $_); $_ = $slicing[$i:]"},
- {Line: 508, Value: "$i := bytes.Index($s, $_); $_ := $slicing[$i:]"},
- {Line: 509, Value: "$i := bytes.Index($s, $_); $_ = $slicing[$i:]"},
+ {Line: 511, Value: "$i := strings.Index($s, $_); $_ := $slicing[$i:]"},
+ {Line: 512, Value: "$i := strings.Index($s, $_); $_ = $slicing[$i:]"},
+ {Line: 513, Value: "$i := bytes.Index($s, $_); $_ := $slicing[$i:]"},
+ {Line: 514, Value: "$i := bytes.Index($s, $_); $_ = $slicing[$i:]"},
},
ReportTemplate: "Index() can return -1; maybe you wanted to do $s[$i+1:]",
WhereExpr: ir.FilterExpr{
- Line: 510,
+ Line: 515,
Op: ir.FilterEqOp,
Src: "m[\"s\"].Text == m[\"slicing\"].Text",
Args: []ir.FilterExpr{
- {Line: 510, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"},
- {Line: 510, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"},
+ {Line: 515, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"},
+ {Line: 515, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"},
},
},
LocationVar: "slicing",
},
{
- Line: 514,
+ Line: 519,
SyntaxPatterns: []ir.PatternString{
- {Line: 515, Value: "$i := strings.Index($s, $_); $_ := $slicing[:$i]"},
- {Line: 516, Value: "$i := strings.Index($s, $_); $_ = $slicing[:$i]"},
- {Line: 517, Value: "$i := bytes.Index($s, $_); $_ := $slicing[:$i]"},
- {Line: 518, Value: "$i := bytes.Index($s, $_); $_ = $slicing[:$i]"},
+ {Line: 520, Value: "$i := strings.Index($s, $_); $_ := $slicing[:$i]"},
+ {Line: 521, Value: "$i := strings.Index($s, $_); $_ = $slicing[:$i]"},
+ {Line: 522, Value: "$i := bytes.Index($s, $_); $_ := $slicing[:$i]"},
+ {Line: 523, Value: "$i := bytes.Index($s, $_); $_ = $slicing[:$i]"},
},
ReportTemplate: "Index() can return -1; maybe you wanted to do $s[:$i+1]",
WhereExpr: ir.FilterExpr{
- Line: 519,
+ Line: 524,
Op: ir.FilterEqOp,
Src: "m[\"s\"].Text == m[\"slicing\"].Text",
Args: []ir.FilterExpr{
- {Line: 519, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"},
- {Line: 519, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"},
+ {Line: 524, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"},
+ {Line: 524, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"},
},
},
LocationVar: "slicing",
},
{
- Line: 523,
+ Line: 528,
SyntaxPatterns: []ir.PatternString{
- {Line: 524, Value: "$s[strings.Index($s, $_):]"},
- {Line: 525, Value: "$s[:strings.Index($s, $_)]"},
- {Line: 526, Value: "$s[bytes.Index($s, $_):]"},
- {Line: 527, Value: "$s[:bytes.Index($s, $_)]"},
+ {Line: 529, Value: "$s[strings.Index($s, $_):]"},
+ {Line: 530, Value: "$s[:strings.Index($s, $_)]"},
+ {Line: 531, Value: "$s[bytes.Index($s, $_):]"},
+ {Line: 532, Value: "$s[:bytes.Index($s, $_)]"},
},
ReportTemplate: "Index() can return -1; maybe you wanted to do Index()+1",
},
},
},
{
- Line: 535,
+ Line: 540,
Name: "unslice",
MatcherName: "m",
DocTags: []string{"style"},
@@ -1712,35 +1717,35 @@ var PrecompiledRules = &ir.File{
DocBefore: "copy(b[:], values...)",
DocAfter: "copy(b, values...)",
Rules: []ir.Rule{{
- Line: 536,
- SyntaxPatterns: []ir.PatternString{{Line: 536, Value: "$s[:]"}},
+ Line: 541,
+ SyntaxPatterns: []ir.PatternString{{Line: 541, Value: "$s[:]"}},
ReportTemplate: "could simplify $$ to $s",
SuggestTemplate: "$s",
WhereExpr: ir.FilterExpr{
- Line: 537,
+ Line: 542,
Op: ir.FilterOrOp,
Src: "m[\"s\"].Type.Is(`string`) || m[\"s\"].Type.Is(`[]$_`)",
Args: []ir.FilterExpr{
{
- Line: 537,
+ Line: 542,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"s\"].Type.Is(`string`)",
Value: "s",
- Args: []ir.FilterExpr{{Line: 537, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}},
+ Args: []ir.FilterExpr{{Line: 542, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}},
},
{
- Line: 537,
+ Line: 542,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"s\"].Type.Is(`[]$_`)",
Value: "s",
- Args: []ir.FilterExpr{{Line: 537, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}},
+ Args: []ir.FilterExpr{{Line: 542, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}},
},
},
},
}},
},
{
- Line: 546,
+ Line: 551,
Name: "yodaStyleExpr",
MatcherName: "m",
DocTags: []string{"style", "experimental"},
@@ -1749,105 +1754,105 @@ var PrecompiledRules = &ir.File{
DocAfter: "return ptr != nil",
Rules: []ir.Rule{
{
- Line: 547,
- SyntaxPatterns: []ir.PatternString{{Line: 547, Value: "$constval != $x"}},
+ Line: 552,
+ SyntaxPatterns: []ir.PatternString{{Line: 552, Value: "$constval != $x"}},
ReportTemplate: "consider to change order in expression to $x != $constval",
WhereExpr: ir.FilterExpr{
- Line: 547,
+ Line: 552,
Op: ir.FilterAndOp,
Src: "m[\"constval\"].Node.Is(`BasicLit`) && !m[\"x\"].Node.Is(`BasicLit`)",
Args: []ir.FilterExpr{
{
- Line: 547,
+ Line: 552,
Op: ir.FilterVarNodeIsOp,
Src: "m[\"constval\"].Node.Is(`BasicLit`)",
Value: "constval",
- Args: []ir.FilterExpr{{Line: 547, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
+ Args: []ir.FilterExpr{{Line: 552, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
},
{
- Line: 547,
+ Line: 552,
Op: ir.FilterNotOp,
Src: "!m[\"x\"].Node.Is(`BasicLit`)",
Args: []ir.FilterExpr{{
- Line: 547,
+ Line: 552,
Op: ir.FilterVarNodeIsOp,
Src: "m[\"x\"].Node.Is(`BasicLit`)",
Value: "x",
- Args: []ir.FilterExpr{{Line: 547, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
+ Args: []ir.FilterExpr{{Line: 552, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
}},
},
},
},
},
{
- Line: 549,
- SyntaxPatterns: []ir.PatternString{{Line: 549, Value: "$constval == $x"}},
+ Line: 554,
+ SyntaxPatterns: []ir.PatternString{{Line: 554, Value: "$constval == $x"}},
ReportTemplate: "consider to change order in expression to $x == $constval",
WhereExpr: ir.FilterExpr{
- Line: 549,
+ Line: 554,
Op: ir.FilterAndOp,
Src: "m[\"constval\"].Node.Is(`BasicLit`) && !m[\"x\"].Node.Is(`BasicLit`)",
Args: []ir.FilterExpr{
{
- Line: 549,
+ Line: 554,
Op: ir.FilterVarNodeIsOp,
Src: "m[\"constval\"].Node.Is(`BasicLit`)",
Value: "constval",
- Args: []ir.FilterExpr{{Line: 549, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
+ Args: []ir.FilterExpr{{Line: 554, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
},
{
- Line: 549,
+ Line: 554,
Op: ir.FilterNotOp,
Src: "!m[\"x\"].Node.Is(`BasicLit`)",
Args: []ir.FilterExpr{{
- Line: 549,
+ Line: 554,
Op: ir.FilterVarNodeIsOp,
Src: "m[\"x\"].Node.Is(`BasicLit`)",
Value: "x",
- Args: []ir.FilterExpr{{Line: 549, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
+ Args: []ir.FilterExpr{{Line: 554, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
}},
},
},
},
},
{
- Line: 552,
- SyntaxPatterns: []ir.PatternString{{Line: 552, Value: "nil != $x"}},
+ Line: 557,
+ SyntaxPatterns: []ir.PatternString{{Line: 557, Value: "nil != $x"}},
ReportTemplate: "consider to change order in expression to $x != nil",
WhereExpr: ir.FilterExpr{
- Line: 552,
+ Line: 557,
Op: ir.FilterNotOp,
Src: "!m[\"x\"].Node.Is(`BasicLit`)",
Args: []ir.FilterExpr{{
- Line: 552,
+ Line: 557,
Op: ir.FilterVarNodeIsOp,
Src: "m[\"x\"].Node.Is(`BasicLit`)",
Value: "x",
- Args: []ir.FilterExpr{{Line: 552, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
+ Args: []ir.FilterExpr{{Line: 557, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
}},
},
},
{
- Line: 554,
- SyntaxPatterns: []ir.PatternString{{Line: 554, Value: "nil == $x"}},
+ Line: 559,
+ SyntaxPatterns: []ir.PatternString{{Line: 559, Value: "nil == $x"}},
ReportTemplate: "consider to change order in expression to $x == nil",
WhereExpr: ir.FilterExpr{
- Line: 554,
+ Line: 559,
Op: ir.FilterNotOp,
Src: "!m[\"x\"].Node.Is(`BasicLit`)",
Args: []ir.FilterExpr{{
- Line: 554,
+ Line: 559,
Op: ir.FilterVarNodeIsOp,
Src: "m[\"x\"].Node.Is(`BasicLit`)",
Value: "x",
- Args: []ir.FilterExpr{{Line: 554, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
+ Args: []ir.FilterExpr{{Line: 559, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}},
}},
},
},
},
},
{
- Line: 562,
+ Line: 567,
Name: "equalFold",
MatcherName: "m",
DocTags: []string{"performance", "experimental"},
@@ -1856,114 +1861,114 @@ var PrecompiledRules = &ir.File{
DocAfter: "strings.EqualFold(x, y)",
Rules: []ir.Rule{
{
- Line: 571,
+ Line: 576,
SyntaxPatterns: []ir.PatternString{
- {Line: 572, Value: "strings.ToLower($x) == $y"},
- {Line: 573, Value: "strings.ToLower($x) == strings.ToLower($y)"},
- {Line: 574, Value: "$x == strings.ToLower($y)"},
- {Line: 575, Value: "strings.ToUpper($x) == $y"},
- {Line: 576, Value: "strings.ToUpper($x) == strings.ToUpper($y)"},
- {Line: 577, Value: "$x == strings.ToUpper($y)"},
+ {Line: 577, Value: "strings.ToLower($x) == $y"},
+ {Line: 578, Value: "strings.ToLower($x) == strings.ToLower($y)"},
+ {Line: 579, Value: "$x == strings.ToLower($y)"},
+ {Line: 580, Value: "strings.ToUpper($x) == $y"},
+ {Line: 581, Value: "strings.ToUpper($x) == strings.ToUpper($y)"},
+ {Line: 582, Value: "$x == strings.ToUpper($y)"},
},
ReportTemplate: "consider replacing with strings.EqualFold($x, $y)",
SuggestTemplate: "strings.EqualFold($x, $y)",
WhereExpr: ir.FilterExpr{
- Line: 578,
+ Line: 583,
Op: ir.FilterAndOp,
Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text",
Args: []ir.FilterExpr{
{
- Line: 578,
+ Line: 583,
Op: ir.FilterAndOp,
Src: "m[\"x\"].Pure && m[\"y\"].Pure",
Args: []ir.FilterExpr{
- {Line: 578, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
- {Line: 578, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"},
+ {Line: 583, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
+ {Line: 583, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"},
},
},
{
- Line: 578,
+ Line: 583,
Op: ir.FilterNeqOp,
Src: "m[\"x\"].Text != m[\"y\"].Text",
Args: []ir.FilterExpr{
- {Line: 578, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"},
- {Line: 578, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"},
+ {Line: 583, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"},
+ {Line: 583, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"},
},
},
},
},
},
{
- Line: 583,
+ Line: 588,
SyntaxPatterns: []ir.PatternString{
- {Line: 584, Value: "strings.ToLower($x) != $y"},
- {Line: 585, Value: "strings.ToLower($x) != strings.ToLower($y)"},
- {Line: 586, Value: "$x != strings.ToLower($y)"},
- {Line: 587, Value: "strings.ToUpper($x) != $y"},
- {Line: 588, Value: "strings.ToUpper($x) != strings.ToUpper($y)"},
- {Line: 589, Value: "$x != strings.ToUpper($y)"},
+ {Line: 589, Value: "strings.ToLower($x) != $y"},
+ {Line: 590, Value: "strings.ToLower($x) != strings.ToLower($y)"},
+ {Line: 591, Value: "$x != strings.ToLower($y)"},
+ {Line: 592, Value: "strings.ToUpper($x) != $y"},
+ {Line: 593, Value: "strings.ToUpper($x) != strings.ToUpper($y)"},
+ {Line: 594, Value: "$x != strings.ToUpper($y)"},
},
ReportTemplate: "consider replacing with !strings.EqualFold($x, $y)",
SuggestTemplate: "!strings.EqualFold($x, $y)",
WhereExpr: ir.FilterExpr{
- Line: 590,
+ Line: 595,
Op: ir.FilterAndOp,
Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text",
Args: []ir.FilterExpr{
{
- Line: 590,
+ Line: 595,
Op: ir.FilterAndOp,
Src: "m[\"x\"].Pure && m[\"y\"].Pure",
Args: []ir.FilterExpr{
- {Line: 590, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
- {Line: 590, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"},
+ {Line: 595, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
+ {Line: 595, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"},
},
},
{
- Line: 590,
+ Line: 595,
Op: ir.FilterNeqOp,
Src: "m[\"x\"].Text != m[\"y\"].Text",
Args: []ir.FilterExpr{
- {Line: 590, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"},
- {Line: 590, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"},
+ {Line: 595, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"},
+ {Line: 595, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"},
},
},
},
},
},
{
- Line: 595,
+ Line: 600,
SyntaxPatterns: []ir.PatternString{
- {Line: 596, Value: "bytes.Equal(bytes.ToLower($x), $y)"},
- {Line: 597, Value: "bytes.Equal(bytes.ToLower($x), bytes.ToLower($y))"},
- {Line: 598, Value: "bytes.Equal($x, bytes.ToLower($y))"},
- {Line: 599, Value: "bytes.Equal(bytes.ToUpper($x), $y)"},
- {Line: 600, Value: "bytes.Equal(bytes.ToUpper($x), bytes.ToUpper($y))"},
- {Line: 601, Value: "bytes.Equal($x, bytes.ToUpper($y))"},
+ {Line: 601, Value: "bytes.Equal(bytes.ToLower($x), $y)"},
+ {Line: 602, Value: "bytes.Equal(bytes.ToLower($x), bytes.ToLower($y))"},
+ {Line: 603, Value: "bytes.Equal($x, bytes.ToLower($y))"},
+ {Line: 604, Value: "bytes.Equal(bytes.ToUpper($x), $y)"},
+ {Line: 605, Value: "bytes.Equal(bytes.ToUpper($x), bytes.ToUpper($y))"},
+ {Line: 606, Value: "bytes.Equal($x, bytes.ToUpper($y))"},
},
ReportTemplate: "consider replacing with bytes.EqualFold($x, $y)",
SuggestTemplate: "bytes.EqualFold($x, $y)",
WhereExpr: ir.FilterExpr{
- Line: 602,
+ Line: 607,
Op: ir.FilterAndOp,
Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text",
Args: []ir.FilterExpr{
{
- Line: 602,
+ Line: 607,
Op: ir.FilterAndOp,
Src: "m[\"x\"].Pure && m[\"y\"].Pure",
Args: []ir.FilterExpr{
- {Line: 602, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
- {Line: 602, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"},
+ {Line: 607, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"},
+ {Line: 607, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"},
},
},
{
- Line: 602,
+ Line: 607,
Op: ir.FilterNeqOp,
Src: "m[\"x\"].Text != m[\"y\"].Text",
Args: []ir.FilterExpr{
- {Line: 602, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"},
- {Line: 602, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"},
+ {Line: 607, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"},
+ {Line: 607, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"},
},
},
},
@@ -1972,7 +1977,7 @@ var PrecompiledRules = &ir.File{
},
},
{
- Line: 611,
+ Line: 616,
Name: "argOrder",
MatcherName: "m",
DocTags: []string{"diagnostic"},
@@ -1980,45 +1985,45 @@ var PrecompiledRules = &ir.File{
DocBefore: "strings.HasPrefix(\"#\", userpass)",
DocAfter: "strings.HasPrefix(userpass, \"#\")",
Rules: []ir.Rule{{
- Line: 612,
+ Line: 617,
SyntaxPatterns: []ir.PatternString{
- {Line: 613, Value: "strings.HasPrefix($lit, $s)"},
- {Line: 614, Value: "bytes.HasPrefix($lit, $s)"},
- {Line: 615, Value: "strings.HasSuffix($lit, $s)"},
- {Line: 616, Value: "bytes.HasSuffix($lit, $s)"},
- {Line: 617, Value: "strings.Contains($lit, $s)"},
- {Line: 618, Value: "bytes.Contains($lit, $s)"},
- {Line: 619, Value: "strings.TrimPrefix($lit, $s)"},
- {Line: 620, Value: "bytes.TrimPrefix($lit, $s)"},
- {Line: 621, Value: "strings.TrimSuffix($lit, $s)"},
- {Line: 622, Value: "bytes.TrimSuffix($lit, $s)"},
- {Line: 623, Value: "strings.Split($lit, $s)"},
- {Line: 624, Value: "bytes.Split($lit, $s)"},
+ {Line: 618, Value: "strings.HasPrefix($lit, $s)"},
+ {Line: 619, Value: "bytes.HasPrefix($lit, $s)"},
+ {Line: 620, Value: "strings.HasSuffix($lit, $s)"},
+ {Line: 621, Value: "bytes.HasSuffix($lit, $s)"},
+ {Line: 622, Value: "strings.Contains($lit, $s)"},
+ {Line: 623, Value: "bytes.Contains($lit, $s)"},
+ {Line: 624, Value: "strings.TrimPrefix($lit, $s)"},
+ {Line: 625, Value: "bytes.TrimPrefix($lit, $s)"},
+ {Line: 626, Value: "strings.TrimSuffix($lit, $s)"},
+ {Line: 627, Value: "bytes.TrimSuffix($lit, $s)"},
+ {Line: 628, Value: "strings.Split($lit, $s)"},
+ {Line: 629, Value: "bytes.Split($lit, $s)"},
},
ReportTemplate: "$lit and $s arguments order looks reversed",
WhereExpr: ir.FilterExpr{
- Line: 625,
+ Line: 630,
Op: ir.FilterAndOp,
Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice) &&\n\t!(m[\"s\"].Const || m[\"s\"].ConstSlice) &&\n\t!m[\"lit\"].Node.Is(`Ident`)",
Args: []ir.FilterExpr{
{
- Line: 625,
+ Line: 630,
Op: ir.FilterAndOp,
Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice) &&\n\t!(m[\"s\"].Const || m[\"s\"].ConstSlice)",
Args: []ir.FilterExpr{
{
- Line: 625,
+ Line: 630,
Op: ir.FilterOrOp,
Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice)",
Args: []ir.FilterExpr{
{
- Line: 625,
+ Line: 630,
Op: ir.FilterVarConstOp,
Src: "m[\"lit\"].Const",
Value: "lit",
},
{
- Line: 625,
+ Line: 630,
Op: ir.FilterVarConstSliceOp,
Src: "m[\"lit\"].ConstSlice",
Value: "lit",
@@ -2026,22 +2031,22 @@ var PrecompiledRules = &ir.File{
},
},
{
- Line: 626,
+ Line: 631,
Op: ir.FilterNotOp,
Src: "!(m[\"s\"].Const || m[\"s\"].ConstSlice)",
Args: []ir.FilterExpr{{
- Line: 626,
+ Line: 631,
Op: ir.FilterOrOp,
Src: "(m[\"s\"].Const || m[\"s\"].ConstSlice)",
Args: []ir.FilterExpr{
{
- Line: 626,
+ Line: 631,
Op: ir.FilterVarConstOp,
Src: "m[\"s\"].Const",
Value: "s",
},
{
- Line: 626,
+ Line: 631,
Op: ir.FilterVarConstSliceOp,
Src: "m[\"s\"].ConstSlice",
Value: "s",
@@ -2052,15 +2057,15 @@ var PrecompiledRules = &ir.File{
},
},
{
- Line: 627,
+ Line: 632,
Op: ir.FilterNotOp,
Src: "!m[\"lit\"].Node.Is(`Ident`)",
Args: []ir.FilterExpr{{
- Line: 627,
+ Line: 632,
Op: ir.FilterVarNodeIsOp,
Src: "m[\"lit\"].Node.Is(`Ident`)",
Value: "lit",
- Args: []ir.FilterExpr{{Line: 627, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"}},
+ Args: []ir.FilterExpr{{Line: 632, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"}},
}},
},
},
@@ -2068,7 +2073,7 @@ var PrecompiledRules = &ir.File{
}},
},
{
- Line: 635,
+ Line: 640,
Name: "stringConcatSimplify",
MatcherName: "m",
DocTags: []string{"style", "experimental"},
@@ -2077,27 +2082,27 @@ var PrecompiledRules = &ir.File{
DocAfter: "x + \"_\" + y",
Rules: []ir.Rule{
{
- Line: 636,
- SyntaxPatterns: []ir.PatternString{{Line: 636, Value: "strings.Join([]string{$x, $y}, \"\")"}},
+ Line: 641,
+ SyntaxPatterns: []ir.PatternString{{Line: 641, Value: "strings.Join([]string{$x, $y}, \"\")"}},
ReportTemplate: "suggestion: $x + $y",
SuggestTemplate: "$x + $y",
},
{
- Line: 637,
- SyntaxPatterns: []ir.PatternString{{Line: 637, Value: "strings.Join([]string{$x, $y, $z}, \"\")"}},
+ Line: 642,
+ SyntaxPatterns: []ir.PatternString{{Line: 642, Value: "strings.Join([]string{$x, $y, $z}, \"\")"}},
ReportTemplate: "suggestion: $x + $y + $z",
SuggestTemplate: "$x + $y + $z",
},
{
- Line: 638,
- SyntaxPatterns: []ir.PatternString{{Line: 638, Value: "strings.Join([]string{$x, $y}, $glue)"}},
+ Line: 643,
+ SyntaxPatterns: []ir.PatternString{{Line: 643, Value: "strings.Join([]string{$x, $y}, $glue)"}},
ReportTemplate: "suggestion: $x + $glue + $y",
SuggestTemplate: "$x + $glue + $y",
},
},
},
{
- Line: 645,
+ Line: 650,
Name: "timeExprSimplify",
MatcherName: "m",
DocTags: []string{"style", "experimental"},
@@ -2106,39 +2111,39 @@ var PrecompiledRules = &ir.File{
DocAfter: "t.UnixMilli()",
Rules: []ir.Rule{
{
- Line: 650,
- SyntaxPatterns: []ir.PatternString{{Line: 650, Value: "$t.Unix() / 1000"}},
+ Line: 655,
+ SyntaxPatterns: []ir.PatternString{{Line: 655, Value: "$t.Unix() / 1000"}},
ReportTemplate: "use $t.UnixMilli() instead of $$",
SuggestTemplate: "$t.UnixMilli()",
WhereExpr: ir.FilterExpr{
- Line: 651,
+ Line: 656,
Op: ir.FilterAndOp,
Src: "m.GoVersion().GreaterEqThan(\"1.17\") && isTime(m[\"t\"])",
Args: []ir.FilterExpr{
{
- Line: 651,
+ Line: 656,
Op: ir.FilterGoVersionGreaterEqThanOp,
Src: "m.GoVersion().GreaterEqThan(\"1.17\")",
Value: "1.17",
},
{
- Line: 651,
+ Line: 656,
Op: ir.FilterOrOp,
Src: "isTime(m[\"t\"])",
Args: []ir.FilterExpr{
{
- Line: 651,
+ Line: 656,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"t\"].Type.Is(`time.Time`)",
Value: "t",
- Args: []ir.FilterExpr{{Line: 647, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}},
+ Args: []ir.FilterExpr{{Line: 652, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}},
},
{
- Line: 651,
+ Line: 656,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"t\"].Type.Is(`*time.Time`)",
Value: "t",
- Args: []ir.FilterExpr{{Line: 647, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}},
+ Args: []ir.FilterExpr{{Line: 652, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}},
},
},
},
@@ -2146,39 +2151,39 @@ var PrecompiledRules = &ir.File{
},
},
{
- Line: 655,
- SyntaxPatterns: []ir.PatternString{{Line: 655, Value: "$t.UnixNano() * 1000"}},
+ Line: 660,
+ SyntaxPatterns: []ir.PatternString{{Line: 660, Value: "$t.UnixNano() * 1000"}},
ReportTemplate: "use $t.UnixMicro() instead of $$",
SuggestTemplate: "$t.UnixMicro()",
WhereExpr: ir.FilterExpr{
- Line: 656,
+ Line: 661,
Op: ir.FilterAndOp,
Src: "m.GoVersion().GreaterEqThan(\"1.17\") && isTime(m[\"t\"])",
Args: []ir.FilterExpr{
{
- Line: 656,
+ Line: 661,
Op: ir.FilterGoVersionGreaterEqThanOp,
Src: "m.GoVersion().GreaterEqThan(\"1.17\")",
Value: "1.17",
},
{
- Line: 656,
+ Line: 661,
Op: ir.FilterOrOp,
Src: "isTime(m[\"t\"])",
Args: []ir.FilterExpr{
{
- Line: 656,
+ Line: 661,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"t\"].Type.Is(`time.Time`)",
Value: "t",
- Args: []ir.FilterExpr{{Line: 647, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}},
+ Args: []ir.FilterExpr{{Line: 652, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}},
},
{
- Line: 656,
+ Line: 661,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"t\"].Type.Is(`*time.Time`)",
Value: "t",
- Args: []ir.FilterExpr{{Line: 647, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}},
+ Args: []ir.FilterExpr{{Line: 652, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}},
},
},
},
@@ -2188,7 +2193,7 @@ var PrecompiledRules = &ir.File{
},
},
{
- Line: 665,
+ Line: 670,
Name: "exposedSyncMutex",
MatcherName: "m",
DocTags: []string{"style", "experimental"},
@@ -2197,57 +2202,57 @@ var PrecompiledRules = &ir.File{
DocAfter: "type Foo struct{ ...; mu sync.Mutex; ... }",
Rules: []ir.Rule{
{
- Line: 670,
- SyntaxPatterns: []ir.PatternString{{Line: 670, Value: "type $x struct { $*_; sync.Mutex; $*_ }"}},
+ Line: 675,
+ SyntaxPatterns: []ir.PatternString{{Line: 675, Value: "type $x struct { $*_; sync.Mutex; $*_ }"}},
ReportTemplate: "don't embed sync.Mutex",
WhereExpr: ir.FilterExpr{
- Line: 671,
+ Line: 676,
Op: ir.FilterVarTextMatchesOp,
Src: "isExported(m[\"x\"])",
Value: "x",
- Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}},
+ Args: []ir.FilterExpr{{Line: 672, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}},
},
},
{
- Line: 674,
- SyntaxPatterns: []ir.PatternString{{Line: 674, Value: "type $x struct { $*_; *sync.Mutex; $*_ }"}},
+ Line: 679,
+ SyntaxPatterns: []ir.PatternString{{Line: 679, Value: "type $x struct { $*_; *sync.Mutex; $*_ }"}},
ReportTemplate: "don't embed *sync.Mutex",
WhereExpr: ir.FilterExpr{
- Line: 675,
+ Line: 680,
Op: ir.FilterVarTextMatchesOp,
Src: "isExported(m[\"x\"])",
Value: "x",
- Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}},
+ Args: []ir.FilterExpr{{Line: 672, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}},
},
},
{
- Line: 678,
- SyntaxPatterns: []ir.PatternString{{Line: 678, Value: "type $x struct { $*_; sync.RWMutex; $*_ }"}},
+ Line: 683,
+ SyntaxPatterns: []ir.PatternString{{Line: 683, Value: "type $x struct { $*_; sync.RWMutex; $*_ }"}},
ReportTemplate: "don't embed sync.RWMutex",
WhereExpr: ir.FilterExpr{
- Line: 679,
+ Line: 684,
Op: ir.FilterVarTextMatchesOp,
Src: "isExported(m[\"x\"])",
Value: "x",
- Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}},
+ Args: []ir.FilterExpr{{Line: 672, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}},
},
},
{
- Line: 682,
- SyntaxPatterns: []ir.PatternString{{Line: 682, Value: "type $x struct { $*_; *sync.RWMutex; $*_ }"}},
+ Line: 687,
+ SyntaxPatterns: []ir.PatternString{{Line: 687, Value: "type $x struct { $*_; *sync.RWMutex; $*_ }"}},
ReportTemplate: "don't embed *sync.RWMutex",
WhereExpr: ir.FilterExpr{
- Line: 683,
+ Line: 688,
Op: ir.FilterVarTextMatchesOp,
Src: "isExported(m[\"x\"])",
Value: "x",
- Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}},
+ Args: []ir.FilterExpr{{Line: 672, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}},
},
},
},
},
{
- Line: 691,
+ Line: 696,
Name: "badSorting",
MatcherName: "m",
DocTags: []string{"diagnostic", "experimental"},
@@ -2256,48 +2261,48 @@ var PrecompiledRules = &ir.File{
DocAfter: "sort.Strings(xs)",
Rules: []ir.Rule{
{
- Line: 692,
- SyntaxPatterns: []ir.PatternString{{Line: 692, Value: "$x = sort.IntSlice($x)"}},
+ Line: 697,
+ SyntaxPatterns: []ir.PatternString{{Line: 697, Value: "$x = sort.IntSlice($x)"}},
ReportTemplate: "suspicious sort.IntSlice usage, maybe sort.Ints was intended?",
SuggestTemplate: "sort.Ints($x)",
WhereExpr: ir.FilterExpr{
- Line: 693,
+ Line: 698,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"x\"].Type.Is(`[]int`)",
Value: "x",
- Args: []ir.FilterExpr{{Line: 693, Op: ir.FilterStringOp, Src: "`[]int`", Value: "[]int"}},
+ Args: []ir.FilterExpr{{Line: 698, Op: ir.FilterStringOp, Src: "`[]int`", Value: "[]int"}},
},
},
{
- Line: 697,
- SyntaxPatterns: []ir.PatternString{{Line: 697, Value: "$x = sort.Float64Slice($x)"}},
+ Line: 702,
+ SyntaxPatterns: []ir.PatternString{{Line: 702, Value: "$x = sort.Float64Slice($x)"}},
ReportTemplate: "suspicious sort.Float64s usage, maybe sort.Float64s was intended?",
SuggestTemplate: "sort.Float64s($x)",
WhereExpr: ir.FilterExpr{
- Line: 698,
+ Line: 703,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"x\"].Type.Is(`[]float64`)",
Value: "x",
- Args: []ir.FilterExpr{{Line: 698, Op: ir.FilterStringOp, Src: "`[]float64`", Value: "[]float64"}},
+ Args: []ir.FilterExpr{{Line: 703, Op: ir.FilterStringOp, Src: "`[]float64`", Value: "[]float64"}},
},
},
{
- Line: 702,
- SyntaxPatterns: []ir.PatternString{{Line: 702, Value: "$x = sort.StringSlice($x)"}},
+ Line: 707,
+ SyntaxPatterns: []ir.PatternString{{Line: 707, Value: "$x = sort.StringSlice($x)"}},
ReportTemplate: "suspicious sort.StringSlice usage, maybe sort.Strings was intended?",
SuggestTemplate: "sort.Strings($x)",
WhereExpr: ir.FilterExpr{
- Line: 703,
+ Line: 708,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"x\"].Type.Is(`[]string`)",
Value: "x",
- Args: []ir.FilterExpr{{Line: 703, Op: ir.FilterStringOp, Src: "`[]string`", Value: "[]string"}},
+ Args: []ir.FilterExpr{{Line: 708, Op: ir.FilterStringOp, Src: "`[]string`", Value: "[]string"}},
},
},
},
},
{
- Line: 712,
+ Line: 717,
Name: "externalErrorReassign",
MatcherName: "m",
DocTags: []string{"diagnostic", "experimental"},
@@ -2305,34 +2310,34 @@ var PrecompiledRules = &ir.File{
DocBefore: "io.EOF = nil",
DocAfter: "/* don't do it */",
Rules: []ir.Rule{{
- Line: 713,
- SyntaxPatterns: []ir.PatternString{{Line: 713, Value: "$pkg.$err = $x"}},
+ Line: 718,
+ SyntaxPatterns: []ir.PatternString{{Line: 718, Value: "$pkg.$err = $x"}},
ReportTemplate: "suspicious reassignment of error from another package",
WhereExpr: ir.FilterExpr{
- Line: 714,
+ Line: 719,
Op: ir.FilterAndOp,
Src: "m[\"err\"].Type.Is(`error`) && m[\"pkg\"].Object.Is(`PkgName`)",
Args: []ir.FilterExpr{
{
- Line: 714,
+ Line: 719,
Op: ir.FilterVarTypeIsOp,
Src: "m[\"err\"].Type.Is(`error`)",
Value: "err",
- Args: []ir.FilterExpr{{Line: 714, Op: ir.FilterStringOp, Src: "`error`", Value: "error"}},
+ Args: []ir.FilterExpr{{Line: 719, Op: ir.FilterStringOp, Src: "`error`", Value: "error"}},
},
{
- Line: 714,
+ Line: 719,
Op: ir.FilterVarObjectIsOp,
Src: "m[\"pkg\"].Object.Is(`PkgName`)",
Value: "pkg",
- Args: []ir.FilterExpr{{Line: 714, Op: ir.FilterStringOp, Src: "`PkgName`", Value: "PkgName"}},
+ Args: []ir.FilterExpr{{Line: 719, Op: ir.FilterStringOp, Src: "`PkgName`", Value: "PkgName"}},
},
},
},
}},
},
{
- Line: 722,
+ Line: 727,
Name: "emptyDecl",
MatcherName: "m",
DocTags: []string{"diagnostic", "experimental"},
@@ -2341,42 +2346,42 @@ var PrecompiledRules = &ir.File{
DocAfter: "/* nothing */",
Rules: []ir.Rule{
{
- Line: 723,
- SyntaxPatterns: []ir.PatternString{{Line: 723, Value: "var()"}},
+ Line: 728,
+ SyntaxPatterns: []ir.PatternString{{Line: 728, Value: "var()"}},
ReportTemplate: "empty var() block",
},
{
- Line: 724,
- SyntaxPatterns: []ir.PatternString{{Line: 724, Value: "const()"}},
+ Line: 729,
+ SyntaxPatterns: []ir.PatternString{{Line: 729, Value: "const()"}},
ReportTemplate: "empty const() block",
},
{
- Line: 725,
- SyntaxPatterns: []ir.PatternString{{Line: 725, Value: "type()"}},
+ Line: 730,
+ SyntaxPatterns: []ir.PatternString{{Line: 730, Value: "type()"}},
ReportTemplate: "empty type() block",
},
},
},
{
- Line: 732,
+ Line: 737,
Name: "dynamicFmtString",
MatcherName: "m",
DocTags: []string{"diagnostic", "experimental"},
DocSummary: "Detects suspicious formatting strings usage",
DocBefore: "fmt.Errorf(msg)",
- DocAfter: "fmt.Errorf(\"%s\", msg)",
+ DocAfter: "errors.New(msg) or fmt.Errorf(\"%s\", msg)",
Rules: []ir.Rule{
{
- Line: 733,
- SyntaxPatterns: []ir.PatternString{{Line: 733, Value: "fmt.Errorf($f)"}},
+ Line: 738,
+ SyntaxPatterns: []ir.PatternString{{Line: 738, Value: "fmt.Errorf($f)"}},
ReportTemplate: "use errors.New($f) or fmt.Errorf(\"%s\", $f) instead",
SuggestTemplate: "errors.New($f)",
WhereExpr: ir.FilterExpr{
- Line: 734,
+ Line: 739,
Op: ir.FilterNotOp,
Src: "!m[\"f\"].Const",
Args: []ir.FilterExpr{{
- Line: 734,
+ Line: 739,
Op: ir.FilterVarConstOp,
Src: "m[\"f\"].Const",
Value: "f",
@@ -2384,15 +2389,15 @@ var PrecompiledRules = &ir.File{
},
},
{
- Line: 738,
- SyntaxPatterns: []ir.PatternString{{Line: 738, Value: "fmt.Errorf($f($*args))"}},
+ Line: 743,
+ SyntaxPatterns: []ir.PatternString{{Line: 743, Value: "fmt.Errorf($f($*args))"}},
ReportTemplate: "use errors.New($f($*args)) or fmt.Errorf(\"%s\", $f($*args)) instead",
SuggestTemplate: "errors.New($f($*args))",
},
},
},
{
- Line: 747,
+ Line: 752,
Name: "stringsCompare",
MatcherName: "m",
DocTags: []string{"style", "experimental"},
@@ -2401,25 +2406,25 @@ var PrecompiledRules = &ir.File{
DocAfter: "x < y",
Rules: []ir.Rule{
{
- Line: 748,
- SyntaxPatterns: []ir.PatternString{{Line: 748, Value: "strings.Compare($s1, $s2) == 0"}},
+ Line: 753,
+ SyntaxPatterns: []ir.PatternString{{Line: 753, Value: "strings.Compare($s1, $s2) == 0"}},
ReportTemplate: "suggestion: $s1 == $s2",
SuggestTemplate: "$s1 == $s2",
},
{
- Line: 751,
+ Line: 756,
SyntaxPatterns: []ir.PatternString{
- {Line: 751, Value: "strings.Compare($s1, $s2) == -1"},
- {Line: 752, Value: "strings.Compare($s1, $s2) < 0"},
+ {Line: 756, Value: "strings.Compare($s1, $s2) == -1"},
+ {Line: 757, Value: "strings.Compare($s1, $s2) < 0"},
},
ReportTemplate: "suggestion: $s1 < $s2",
SuggestTemplate: "$s1 < $s2",
},
{
- Line: 755,
+ Line: 760,
SyntaxPatterns: []ir.PatternString{
- {Line: 755, Value: "strings.Compare($s1, $s2) == 1"},
- {Line: 756, Value: "strings.Compare($s1, $s2) > 0"},
+ {Line: 760, Value: "strings.Compare($s1, $s2) == 1"},
+ {Line: 761, Value: "strings.Compare($s1, $s2) > 0"},
},
ReportTemplate: "suggestion: $s1 > $s2",
SuggestTemplate: "$s1 > $s2",
@@ -2427,7 +2432,7 @@ var PrecompiledRules = &ir.File{
},
},
{
- Line: 764,
+ Line: 769,
Name: "uncheckedInlineErr",
MatcherName: "m",
DocTags: []string{"diagnostic", "experimental"},
@@ -2435,47 +2440,47 @@ var PrecompiledRules = &ir.File{
DocBefore: "if err := expr(); err2 != nil { /*...*/ }",
DocAfter: "if err := expr(); err != nil { /*...*/ }",
Rules: []ir.Rule{{
- Line: 765,
+ Line: 770,
SyntaxPatterns: []ir.PatternString{
- {Line: 766, Value: "if $err := $_($*_); $err2 != nil { $*_ }"},
- {Line: 767, Value: "if $err = $_($*_); $err2 != nil { $*_ }"},
- {Line: 768, Value: "if $*_, $err := $_($*_); $err2 != nil { $*_ }"},
- {Line: 769, Value: "if $*_, $err = $_($*_); $err2 != nil { $*_ }"},
+ {Line: 771, Value: "if $err := $_($*_); $err2 != nil { $*_ }"},
+ {Line: 772, Value: "if $err = $_($*_); $err2 != nil { $*_ }"},
+ {Line: 773, Value: "if $*_, $err := $_($*_); $err2 != nil { $*_ }"},
+ {Line: 774, Value: "if $*_, $err = $_($*_); $err2 != nil { $*_ }"},
},
ReportTemplate: "$err error is unchecked, maybe intended to check it instead of $err2",
WhereExpr: ir.FilterExpr{
- Line: 770,
+ Line: 775,
Op: ir.FilterAndOp,
Src: "m[\"err\"].Type.Implements(\"error\") && m[\"err2\"].Type.Implements(\"error\") &&\n\tm[\"err\"].Text != m[\"err2\"].Text",
Args: []ir.FilterExpr{
{
- Line: 770,
+ Line: 775,
Op: ir.FilterAndOp,
Src: "m[\"err\"].Type.Implements(\"error\") && m[\"err2\"].Type.Implements(\"error\")",
Args: []ir.FilterExpr{
{
- Line: 770,
+ Line: 775,
Op: ir.FilterVarTypeImplementsOp,
Src: "m[\"err\"].Type.Implements(\"error\")",
Value: "err",
- Args: []ir.FilterExpr{{Line: 770, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
+ Args: []ir.FilterExpr{{Line: 775, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
},
{
- Line: 770,
+ Line: 775,
Op: ir.FilterVarTypeImplementsOp,
Src: "m[\"err2\"].Type.Implements(\"error\")",
Value: "err2",
- Args: []ir.FilterExpr{{Line: 770, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
+ Args: []ir.FilterExpr{{Line: 775, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
},
},
},
{
- Line: 771,
+ Line: 776,
Op: ir.FilterNeqOp,
Src: "m[\"err\"].Text != m[\"err2\"].Text",
Args: []ir.FilterExpr{
- {Line: 771, Op: ir.FilterVarTextOp, Src: "m[\"err\"].Text", Value: "err"},
- {Line: 771, Op: ir.FilterVarTextOp, Src: "m[\"err2\"].Text", Value: "err2"},
+ {Line: 776, Op: ir.FilterVarTextOp, Src: "m[\"err\"].Text", Value: "err"},
+ {Line: 776, Op: ir.FilterVarTextOp, Src: "m[\"err2\"].Text", Value: "err2"},
},
},
},
@@ -2484,7 +2489,7 @@ var PrecompiledRules = &ir.File{
}},
},
{
- Line: 780,
+ Line: 785,
Name: "badSyncOnceFunc",
MatcherName: "m",
DocTags: []string{"diagnostic", "experimental"},
@@ -2493,22 +2498,22 @@ var PrecompiledRules = &ir.File{
DocAfter: "fooOnce := sync.OnceFunc(foo); ...; fooOnce()",
Rules: []ir.Rule{
{
- Line: 781,
- SyntaxPatterns: []ir.PatternString{{Line: 781, Value: "$*_; sync.OnceFunc($x); $*_;"}},
+ Line: 786,
+ SyntaxPatterns: []ir.PatternString{{Line: 786, Value: "$*_; sync.OnceFunc($x); $*_;"}},
ReportTemplate: "possible sync.OnceFunc misuse, sync.OnceFunc($x) result is not used",
WhereExpr: ir.FilterExpr{
- Line: 783,
+ Line: 788,
Op: ir.FilterGoVersionGreaterEqThanOp,
Src: "m.GoVersion().GreaterEqThan(\"1.21\")",
Value: "1.21",
},
},
{
- Line: 785,
- SyntaxPatterns: []ir.PatternString{{Line: 785, Value: "sync.OnceFunc($x)()"}},
+ Line: 790,
+ SyntaxPatterns: []ir.PatternString{{Line: 790, Value: "sync.OnceFunc($x)()"}},
ReportTemplate: "possible sync.OnceFunc misuse, consider to assign sync.OnceFunc($x) to a variable",
WhereExpr: ir.FilterExpr{
- Line: 787,
+ Line: 792,
Op: ir.FilterGoVersionGreaterEqThanOp,
Src: "m.GoVersion().GreaterEqThan(\"1.21\")",
Value: "1.21",
diff --git a/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go b/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go
index 8a132b58..02a2370d 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go
@@ -125,6 +125,13 @@ func (c *sqlQueryChecker) typeHasExecMethod(typ types.Type) bool {
return true
}
}
+ case *types.Alias:
+ switch typ := typ.Underlying().(type) {
+ case *types.Interface:
+ return c.typeHasExecMethod(typ)
+ default:
+ // TODO(cristaloleg): is there something else to handle?
+ }
case *types.Interface:
for i := 0; i < typ.NumMethods(); i++ {
if c.funcIsExec(typ.Method(i)) {
diff --git a/vendor/github.com/go-critic/go-critic/checkers/utils.go b/vendor/github.com/go-critic/go-critic/checkers/utils.go
index 6e12cf9b..5740f0d4 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/utils.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/utils.go
@@ -9,183 +9,183 @@ import (
)
// goStdlib contains `go list std` command output list.
+// `internal` and `vendor` packages are excluded.
// Used to detect packages that belong to standard Go packages distribution.
var goStdlib = map[string]bool{
- "archive/tar": true,
- "archive/zip": true,
- "bufio": true,
- "bytes": true,
- "compress/bzip2": true,
- "compress/flate": true,
- "compress/gzip": true,
- "compress/lzw": true,
- "compress/zlib": true,
- "container/heap": true,
- "container/list": true,
- "container/ring": true,
- "context": true,
- "crypto": true,
- "crypto/aes": true,
- "crypto/cipher": true,
- "crypto/des": true,
- "crypto/dsa": true,
- "crypto/ecdsa": true,
- "crypto/elliptic": true,
- "crypto/hmac": true,
- "crypto/internal/randutil": true,
- "crypto/internal/subtle": true,
- "crypto/md5": true,
- "crypto/rand": true,
- "crypto/rc4": true,
- "crypto/rsa": true,
- "crypto/sha1": true,
- "crypto/sha256": true,
- "crypto/sha512": true,
- "crypto/subtle": true,
- "crypto/tls": true,
- "crypto/x509": true,
- "crypto/x509/pkix": true,
- "database/sql": true,
- "database/sql/driver": true,
- "debug/dwarf": true,
- "debug/elf": true,
- "debug/gosym": true,
- "debug/macho": true,
- "debug/pe": true,
- "debug/plan9obj": true,
- "encoding": true,
- "encoding/ascii85": true,
- "encoding/asn1": true,
- "encoding/base32": true,
- "encoding/base64": true,
- "encoding/binary": true,
- "encoding/csv": true,
- "encoding/gob": true,
- "encoding/hex": true,
- "encoding/json": true,
- "encoding/pem": true,
- "encoding/xml": true,
- "errors": true,
- "expvar": true,
- "flag": true,
- "fmt": true,
- "go/ast": true,
- "go/build": true,
- "go/constant": true,
- "go/doc": true,
- "go/format": true,
- "go/importer": true,
- "go/internal/gccgoimporter": true,
- "go/internal/gcimporter": true,
- "go/internal/srcimporter": true,
- "go/parser": true,
- "go/printer": true,
- "go/scanner": true,
- "go/token": true,
- "go/types": true,
- "hash": true,
- "hash/adler32": true,
- "hash/crc32": true,
- "hash/crc64": true,
- "hash/fnv": true,
- "html": true,
- "html/template": true,
- "image": true,
- "image/color": true,
- "image/color/palette": true,
- "image/draw": true,
- "image/gif": true,
- "image/internal/imageutil": true,
- "image/jpeg": true,
- "image/png": true,
- "index/suffixarray": true,
- "internal/bytealg": true,
- "internal/cpu": true,
- "internal/nettrace": true,
- "internal/poll": true,
- "internal/race": true,
- "internal/singleflight": true,
- "internal/syscall/unix": true,
- "internal/syscall/windows": true,
- "internal/syscall/windows/registry": true,
- "internal/syscall/windows/sysdll": true,
- "internal/testenv": true,
- "internal/testlog": true,
- "internal/trace": true,
- "io": true,
- "io/ioutil": true,
- "log": true,
- "log/syslog": true,
- "math": true,
- "math/big": true,
- "math/bits": true,
- "math/cmplx": true,
- "math/rand": true,
- "mime": true,
- "mime/multipart": true,
- "mime/quotedprintable": true,
- "net": true,
- "net/http": true,
- "net/http/cgi": true,
- "net/http/cookiejar": true,
- "net/http/fcgi": true,
- "net/http/httptest": true,
- "net/http/httptrace": true,
- "net/http/httputil": true,
- "net/http/internal": true,
- "net/http/pprof": true,
- "net/internal/socktest": true,
- "net/mail": true,
- "net/rpc": true,
- "net/rpc/jsonrpc": true,
- "net/smtp": true,
- "net/textproto": true,
- "net/url": true,
- "os": true,
- "os/exec": true,
- "os/signal": true,
- "os/signal/internal/pty": true,
- "os/user": true,
- "path": true,
- "path/filepath": true,
- "plugin": true,
- "reflect": true,
- "regexp": true,
- "regexp/syntax": true,
- "runtime": true,
- "runtime/cgo": true,
- "runtime/debug": true,
- "runtime/internal/atomic": true,
- "runtime/internal/sys": true,
- "runtime/pprof": true,
- "runtime/pprof/internal/profile": true,
- "runtime/race": true,
- "runtime/trace": true,
- "sort": true,
- "strconv": true,
- "strings": true,
- "sync": true,
- "sync/atomic": true,
- "syscall": true,
- "testing": true,
- "testing/internal/testdeps": true,
- "testing/iotest": true,
- "testing/quick": true,
- "text/scanner": true,
- "text/tabwriter": true,
- "text/template": true,
- "text/template/parse": true,
- "time": true,
- "unicode": true,
- "unicode/utf16": true,
- "unicode/utf8": true,
- "unsafe": true,
+ "archive/tar": true,
+ "archive/zip": true,
+ "bufio": true,
+ "bytes": true,
+ "cmp": true,
+ "compress/bzip2": true,
+ "compress/flate": true,
+ "compress/gzip": true,
+ "compress/lzw": true,
+ "compress/zlib": true,
+ "container/heap": true,
+ "container/list": true,
+ "container/ring": true,
+ "context": true,
+ "crypto": true,
+ "crypto/aes": true,
+ "crypto/cipher": true,
+ "crypto/des": true,
+ "crypto/dsa": true,
+ "crypto/ecdh": true,
+ "crypto/ecdsa": true,
+ "crypto/ed25519": true,
+ "crypto/elliptic": true,
+ "crypto/hmac": true,
+ "crypto/md5": true,
+ "crypto/rand": true,
+ "crypto/rc4": true,
+ "crypto/rsa": true,
+ "crypto/sha1": true,
+ "crypto/sha256": true,
+ "crypto/sha512": true,
+ "crypto/subtle": true,
+ "crypto/tls": true,
+ "crypto/x509": true,
+ "crypto/x509/pkix": true,
+ "database/sql": true,
+ "database/sql/driver": true,
+ "debug/buildinfo": true,
+ "debug/dwarf": true,
+ "debug/elf": true,
+ "debug/gosym": true,
+ "debug/macho": true,
+ "debug/pe": true,
+ "debug/plan9obj": true,
+ "embed": true,
+ "encoding": true,
+ "encoding/ascii85": true,
+ "encoding/asn1": true,
+ "encoding/base32": true,
+ "encoding/base64": true,
+ "encoding/binary": true,
+ "encoding/csv": true,
+ "encoding/gob": true,
+ "encoding/hex": true,
+ "encoding/json": true,
+ "encoding/pem": true,
+ "encoding/xml": true,
+ "errors": true,
+ "expvar": true,
+ "flag": true,
+ "fmt": true,
+ "go/ast": true,
+ "go/build": true,
+ "go/build/constraint": true,
+ "go/constant": true,
+ "go/doc": true,
+ "go/doc/comment": true,
+ "go/format": true,
+ "go/importer": true,
+ "go/parser": true,
+ "go/printer": true,
+ "go/scanner": true,
+ "go/token": true,
+ "go/types": true,
+ "go/version": true,
+ "hash": true,
+ "hash/adler32": true,
+ "hash/crc32": true,
+ "hash/crc64": true,
+ "hash/fnv": true,
+ "hash/maphash": true,
+ "html": true,
+ "html/template": true,
+ "image": true,
+ "image/color": true,
+ "image/color/palette": true,
+ "image/draw": true,
+ "image/gif": true,
+ "image/jpeg": true,
+ "image/png": true,
+ "index/suffixarray": true,
+ "io": true,
+ "io/fs": true,
+ "io/ioutil": true,
+ "iter": true,
+ "log": true,
+ "log/slog": true,
+ "log/syslog": true,
+ "maps": true,
+ "math": true,
+ "math/big": true,
+ "math/bits": true,
+ "math/cmplx": true,
+ "math/rand": true,
+ "math/rand/v2": true,
+ "mime": true,
+ "mime/multipart": true,
+ "mime/quotedprintable": true,
+ "net": true,
+ "net/http": true,
+ "net/http/cgi": true,
+ "net/http/cookiejar": true,
+ "net/http/fcgi": true,
+ "net/http/httptest": true,
+ "net/http/httptrace": true,
+ "net/http/httputil": true,
+ "net/http/pprof": true,
+ "net/mail": true,
+ "net/netip": true,
+ "net/rpc": true,
+ "net/rpc/jsonrpc": true,
+ "net/smtp": true,
+ "net/textproto": true,
+ "net/url": true,
+ "os": true,
+ "os/exec": true,
+ "os/signal": true,
+ "os/user": true,
+ "path": true,
+ "path/filepath": true,
+ "plugin": true,
+ "reflect": true,
+ "regexp": true,
+ "regexp/syntax": true,
+ "runtime": true,
+ "runtime/cgo": true,
+ "runtime/coverage": true,
+ "runtime/debug": true,
+ "runtime/metrics": true,
+ "runtime/pprof": true,
+ "runtime/race": true,
+ "runtime/trace": true,
+ "slices": true,
+ "sort": true,
+ "strconv": true,
+ "strings": true,
+ "structs": true,
+ "sync": true,
+ "sync/atomic": true,
+ "syscall": true,
+ "testing": true,
+ "testing/fstest": true,
+ "testing/iotest": true,
+ "testing/quick": true,
+ "testing/slogtest": true,
+ "text/scanner": true,
+ "text/tabwriter": true,
+ "text/template": true,
+ "text/template/parse": true,
+ "time": true,
+ "time/tzdata": true,
+ "unicode": true,
+ "unicode/utf16": true,
+ "unicode/utf8": true,
+ "unique": true,
+ "unsafe": true,
}
var goBuiltins = map[string]bool{
// Types
+ "any": true,
"bool": true,
"byte": true,
+ "comparable": true,
"complex64": true,
"complex128": true,
"error": true,
@@ -216,6 +216,7 @@ var goBuiltins = map[string]bool{
// Functions
"append": true,
"cap": true,
+ "clear": true,
"close": true,
"complex": true,
"copy": true,
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/robustio/readme.md b/vendor/github.com/golangci/golangci-lint/internal/go/robustio/readme.md
deleted file mode 100644
index f4dbc162..00000000
--- a/vendor/github.com/golangci/golangci-lint/internal/go/robustio/readme.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# robustio
-
-Extracted from go1.19.1/src/cmd/go/internal/robustio
-
-There is only one modification:
-- ERROR_SHARING_VIOLATION extracted from go1.19.1/src/internal/syscall/windows/syscall_windows.go to remove the dependencies to `internal/syscall/windows`
-
-## History
-
-- https://github.com/golangci/golangci-lint/pull/5100
- - Move package from `internal/robustio` to `internal/go/robustio`
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/help.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/help.go
deleted file mode 100644
index de4a9998..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/help.go
+++ /dev/null
@@ -1,235 +0,0 @@
-package commands
-
-import (
- "encoding/json"
- "fmt"
- "slices"
- "sort"
- "strings"
- "unicode"
- "unicode/utf8"
-
- "github.com/fatih/color"
- "github.com/spf13/cobra"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/lint/lintersdb"
- "github.com/golangci/golangci-lint/pkg/logutils"
-)
-
-type linterHelp struct {
- Name string `json:"name"`
- Desc string `json:"description"`
- Fast bool `json:"fast"`
- AutoFix bool `json:"autoFix"`
- Presets []string `json:"presets"`
- EnabledByDefault bool `json:"enabledByDefault"`
- Deprecated bool `json:"deprecated"`
- Since string `json:"since"`
- OriginalURL string `json:"originalURL,omitempty"`
-}
-
-type helpOptions struct {
- JSON bool
-}
-
-type helpCommand struct {
- cmd *cobra.Command
-
- opts helpOptions
-
- dbManager *lintersdb.Manager
-
- log logutils.Log
-}
-
-func newHelpCommand(logger logutils.Log) *helpCommand {
- c := &helpCommand{log: logger}
-
- helpCmd := &cobra.Command{
- Use: "help",
- Short: "Help",
- Args: cobra.NoArgs,
- RunE: func(cmd *cobra.Command, _ []string) error {
- return cmd.Help()
- },
- }
-
- lintersCmd := &cobra.Command{
- Use: "linters",
- Short: "Help about linters",
- Args: cobra.NoArgs,
- ValidArgsFunction: cobra.NoFileCompletions,
- RunE: c.execute,
- PreRunE: c.preRunE,
- }
-
- helpCmd.AddCommand(lintersCmd)
-
- fs := lintersCmd.Flags()
- fs.SortFlags = false // sort them as they are defined here
-
- fs.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
-
- c.cmd = helpCmd
-
- return c
-}
-
-func (c *helpCommand) preRunE(_ *cobra.Command, _ []string) error {
- // The command doesn't depend on the real configuration.
- // It just needs the list of all plugins and all presets.
- dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), config.NewDefault(), lintersdb.NewLinterBuilder())
- if err != nil {
- return err
- }
-
- c.dbManager = dbManager
-
- return nil
-}
-
-func (c *helpCommand) execute(_ *cobra.Command, _ []string) error {
- if c.opts.JSON {
- return c.printJSON()
- }
-
- c.print()
-
- return nil
-}
-
-func (c *helpCommand) printJSON() error {
- var linters []linterHelp
-
- for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
- if lc.Internal {
- continue
- }
-
- linters = append(linters, linterHelp{
- Name: lc.Name(),
- Desc: formatDescription(lc.Linter.Desc()),
- Fast: !lc.IsSlowLinter(),
- AutoFix: lc.CanAutoFix,
- Presets: lc.InPresets,
- EnabledByDefault: lc.EnabledByDefault,
- Deprecated: lc.IsDeprecated(),
- Since: lc.Since,
- OriginalURL: lc.OriginalURL,
- })
- }
-
- return json.NewEncoder(c.cmd.OutOrStdout()).Encode(linters)
-}
-
-func (c *helpCommand) print() {
- var enabledLCs, disabledLCs []*linter.Config
- for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
- if lc.Internal {
- continue
- }
-
- if lc.EnabledByDefault {
- enabledLCs = append(enabledLCs, lc)
- } else {
- disabledLCs = append(disabledLCs, lc)
- }
- }
-
- color.Green("Enabled by default linters:\n")
- printLinters(enabledLCs)
-
- color.Red("\nDisabled by default linters:\n")
- printLinters(disabledLCs)
-
- color.Green("\nLinters presets:")
- c.printPresets()
-}
-
-func (c *helpCommand) printPresets() {
- for _, p := range lintersdb.AllPresets() {
- linters := c.dbManager.GetAllLinterConfigsForPreset(p)
-
- var linterNames []string
- for _, lc := range linters {
- if lc.Internal {
- continue
- }
-
- linterNames = append(linterNames, lc.Name())
- }
- sort.Strings(linterNames)
-
- _, _ = fmt.Fprintf(logutils.StdOut, "%s: %s\n", color.YellowString(p), strings.Join(linterNames, ", "))
- }
-}
-
-func printLinters(lcs []*linter.Config) {
- slices.SortFunc(lcs, func(a, b *linter.Config) int {
- if a.IsDeprecated() && b.IsDeprecated() {
- return strings.Compare(a.Name(), b.Name())
- }
-
- if a.IsDeprecated() {
- return 1
- }
-
- if b.IsDeprecated() {
- return -1
- }
-
- return strings.Compare(a.Name(), b.Name())
- })
-
- for _, lc := range lcs {
- desc := formatDescription(lc.Linter.Desc())
-
- deprecatedMark := ""
- if lc.IsDeprecated() {
- deprecatedMark = " [" + color.RedString("deprecated") + "]"
- }
-
- var capabilities []string
- if !lc.IsSlowLinter() {
- capabilities = append(capabilities, color.BlueString("fast"))
- }
- if lc.CanAutoFix {
- capabilities = append(capabilities, color.GreenString("auto-fix"))
- }
-
- var capability string
- if capabilities != nil {
- capability = " [" + strings.Join(capabilities, ", ") + "]"
- }
-
- _, _ = fmt.Fprintf(logutils.StdOut, "%s%s: %s%s\n",
- color.YellowString(lc.Name()), deprecatedMark, desc, capability)
- }
-}
-
-func formatDescription(desc string) string {
- desc = strings.TrimSpace(desc)
-
- if desc == "" {
- return desc
- }
-
- // If the linter description spans multiple lines, truncate everything following the first newline
- endFirstLine := strings.IndexRune(desc, '\n')
- if endFirstLine > 0 {
- desc = desc[:endFirstLine]
- }
-
- rawDesc := []rune(desc)
-
- r, _ := utf8.DecodeRuneInString(desc)
- rawDesc[0] = unicode.ToUpper(r)
-
- if rawDesc[len(rawDesc)-1] != '.' {
- rawDesc = append(rawDesc, '.')
- }
-
- return string(rawDesc)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/issues.go b/vendor/github.com/golangci/golangci-lint/pkg/config/issues.go
deleted file mode 100644
index d5b6650f..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/config/issues.go
+++ /dev/null
@@ -1,163 +0,0 @@
-package config
-
-import (
- "fmt"
-)
-
-var DefaultExcludePatterns = []ExcludePattern{
- {
- ID: "EXC0001",
- Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close" +
- "|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked",
- Linter: "errcheck",
- Why: "Almost all programs ignore errors on these functions and in most cases it's ok.",
- },
- {
- ID: "EXC0002", // TODO(ldez): should be remove in v2
- Pattern: "(comment on exported (method|function|type|const)|" +
- "should have( a package)? comment|comment should be of the form)",
- Linter: "golint",
- Why: "Annoying issue about not having a comment. The rare codebase has such comments.",
- },
- {
- ID: "EXC0003", // TODO(ldez): should be remove in v2
- Pattern: "func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this",
- Linter: "golint",
- Why: "False positive when tests are defined in package 'test'.",
- },
- {
- ID: "EXC0004",
- Pattern: "(possible misuse of unsafe.Pointer|should have signature)",
- Linter: "govet",
- Why: "Common false positives.",
- },
- {
- ID: "EXC0005",
- Pattern: "SA4011", // CheckScopedBreak
- Linter: "staticcheck",
- Why: "Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore.",
- },
- {
- ID: "EXC0006",
- Pattern: "G103: Use of unsafe calls should be audited",
- Linter: "gosec",
- Why: "Too many false-positives on 'unsafe' usage.",
- },
- {
- ID: "EXC0007",
- Pattern: "G204: Subprocess launched with variable",
- Linter: "gosec",
- Why: "Too many false-positives for parametrized shell calls.",
- },
- {
- ID: "EXC0008",
- Pattern: "G104", // Errors unhandled.
- Linter: "gosec",
- Why: "Duplicated errcheck checks.",
- },
- {
- ID: "EXC0009",
- Pattern: "(G301|G302|G307): Expect (directory permissions to be 0750|file permissions to be 0600) or less",
- Linter: "gosec",
- Why: "Too many issues in popular repos.",
- },
- {
- ID: "EXC0010",
- Pattern: "G304: Potential file inclusion via variable",
- Linter: "gosec",
- Why: "False positive is triggered by 'src, err := ioutil.ReadFile(filename)'.",
- },
- {
- ID: "EXC0011",
- Pattern: "(ST1000|ST1020|ST1021|ST1022)", // CheckPackageComment, CheckExportedFunctionDocs, CheckExportedTypeDocs, CheckExportedVarDocs
- Linter: "stylecheck",
- Why: "Annoying issue about not having a comment. The rare codebase has such comments.",
- },
- {
- ID: "EXC0012",
- Pattern: `exported (.+) should have comment( \(or a comment on this block\))? or be unexported`, // rule: exported
- Linter: "revive",
- Why: "Annoying issue about not having a comment. The rare codebase has such comments.",
- },
- {
- ID: "EXC0013",
- Pattern: `package comment should be of the form "(.+)..."`, // rule: package-comments
- Linter: "revive",
- Why: "Annoying issue about not having a comment. The rare codebase has such comments.",
- },
- {
- ID: "EXC0014",
- Pattern: `comment on exported (.+) should be of the form "(.+)..."`, // rule: exported
- Linter: "revive",
- Why: "Annoying issue about not having a comment. The rare codebase has such comments.",
- },
- {
- ID: "EXC0015",
- Pattern: `should have a package comment`, // rule: package-comments
- Linter: "revive",
- Why: "Annoying issue about not having a comment. The rare codebase has such comments.",
- },
-}
-
-type Issues struct {
- IncludeDefaultExcludes []string `mapstructure:"include"`
- ExcludeCaseSensitive bool `mapstructure:"exclude-case-sensitive"`
- ExcludePatterns []string `mapstructure:"exclude"`
- ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"`
- UseDefaultExcludes bool `mapstructure:"exclude-use-default"`
-
- ExcludeGenerated string `mapstructure:"exclude-generated"`
-
- ExcludeFiles []string `mapstructure:"exclude-files"`
- ExcludeDirs []string `mapstructure:"exclude-dirs"`
-
- UseDefaultExcludeDirs bool `mapstructure:"exclude-dirs-use-default"`
-
- MaxIssuesPerLinter int `mapstructure:"max-issues-per-linter"`
- MaxSameIssues int `mapstructure:"max-same-issues"`
- UniqByLine bool `mapstructure:"uniq-by-line"`
-
- DiffFromRevision string `mapstructure:"new-from-rev"`
- DiffFromMergeBase string `mapstructure:"new-from-merge-base"`
- DiffPatchFilePath string `mapstructure:"new-from-patch"`
- WholeFiles bool `mapstructure:"whole-files"`
- Diff bool `mapstructure:"new"`
-
- NeedFix bool `mapstructure:"fix"`
-
- ExcludeGeneratedStrict *bool `mapstructure:"exclude-generated-strict"` // Deprecated: use ExcludeGenerated instead.
-}
-
-func (i *Issues) Validate() error {
- for i, rule := range i.ExcludeRules {
- if err := rule.Validate(); err != nil {
- return fmt.Errorf("error in exclude rule #%d: %w", i, err)
- }
- }
-
- return nil
-}
-
-type ExcludePattern struct {
- ID string
- Pattern string
- Linter string
- Why string
-}
-
-// TODO(ldez): this behavior must be changed in v2, because this is confusing.
-func GetExcludePatterns(include []string) []ExcludePattern {
- includeMap := make(map[string]struct{}, len(include))
- for _, inc := range include {
- includeMap[inc] = struct{}{}
- }
-
- var ret []ExcludePattern
- for _, p := range DefaultExcludePatterns {
- if _, ok := includeMap[p.ID]; !ok {
- ret = append(ret, p)
- }
- }
-
- return ret
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/linters.go b/vendor/github.com/golangci/golangci-lint/pkg/config/linters.go
deleted file mode 100644
index 4814d1eb..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/config/linters.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package config
-
-import (
- "errors"
- "fmt"
-)
-
-type Linters struct {
- Enable []string
- Disable []string
- EnableAll bool `mapstructure:"enable-all"`
- DisableAll bool `mapstructure:"disable-all"`
- Fast bool
-
- Presets []string
-
- LinterExclusions LinterExclusions `mapstructure:"exclusions"`
-}
-
-func (l *Linters) Validate() error {
- validators := []func() error{
- l.validateAllDisableEnableOptions,
- l.validateDisabledAndEnabledAtOneMoment,
- l.LinterExclusions.Validate,
- }
-
- for _, v := range validators {
- if err := v(); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (l *Linters) validateAllDisableEnableOptions() error {
- if l.EnableAll && l.DisableAll {
- return errors.New("--enable-all and --disable-all options must not be combined")
- }
-
- if l.DisableAll {
- if len(l.Enable) == 0 && len(l.Presets) == 0 {
- return errors.New("all linters were disabled, but no one linter was enabled: must enable at least one")
- }
-
- if len(l.Disable) != 0 {
- return errors.New("can't combine options --disable-all and --disable")
- }
- }
-
- if l.EnableAll && len(l.Enable) != 0 && !l.Fast {
- return errors.New("can't combine options --enable-all and --enable")
- }
-
- return nil
-}
-
-func (l *Linters) validateDisabledAndEnabledAtOneMoment() error {
- enabledLintersSet := map[string]bool{}
- for _, name := range l.Enable {
- enabledLintersSet[name] = true
- }
-
- for _, name := range l.Disable {
- if enabledLintersSet[name] {
- return fmt.Errorf("linter %q can't be disabled and enabled at one moment", name)
- }
- }
-
- return nil
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/loader.go b/vendor/github.com/golangci/golangci-lint/pkg/config/loader.go
deleted file mode 100644
index dc9ceead..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/config/loader.go
+++ /dev/null
@@ -1,507 +0,0 @@
-package config
-
-import (
- "cmp"
- "context"
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "slices"
-
- "github.com/go-viper/mapstructure/v2"
- "github.com/mitchellh/go-homedir"
- "github.com/spf13/pflag"
- "github.com/spf13/viper"
-
- "github.com/golangci/golangci-lint/pkg/exitcodes"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/goutil"
- "github.com/golangci/golangci-lint/pkg/logutils"
-)
-
-var errConfigDisabled = errors.New("config is disabled by --no-config")
-
-type LoaderOptions struct {
- Config string // Flag only. The path to the golangci config file, as specified with the --config argument.
- NoConfig bool // Flag only.
-}
-
-type LoadOptions struct {
- CheckDeprecation bool
- Validation bool
-}
-
-type Loader struct {
- opts LoaderOptions
-
- viper *viper.Viper
- fs *pflag.FlagSet
-
- log logutils.Log
-
- cfg *Config
- args []string
-}
-
-func NewLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader {
- return &Loader{
- opts: opts,
- viper: v,
- fs: fs,
- log: log,
- cfg: cfg,
- args: args,
- }
-}
-
-func (l *Loader) Load(opts LoadOptions) error {
- err := l.setConfigFile()
- if err != nil {
- return err
- }
-
- err = l.parseConfig()
- if err != nil {
- return err
- }
-
- l.applyStringSliceHack()
-
- if l.cfg.Linters.LinterExclusions.Generated == "" {
- // `l.cfg.Issues.ExcludeGenerated` is always non-empty because of the flag default value.
- l.cfg.Linters.LinterExclusions.Generated = cmp.Or(l.cfg.Issues.ExcludeGenerated, "strict")
- }
-
- // Compatibility layer with v1.
- // TODO(ldez): should be removed in v2.
- if l.cfg.Issues.UseDefaultExcludes {
- l.cfg.Linters.LinterExclusions.Presets = []string{
- ExclusionPresetComments,
- ExclusionPresetStdErrorHandling,
- ExclusionPresetCommonFalsePositives,
- ExclusionPresetLegacy,
- }
- }
-
- if len(l.cfg.Issues.ExcludeRules) > 0 {
- l.cfg.Linters.LinterExclusions.Rules = append(l.cfg.Linters.LinterExclusions.Rules, l.cfg.Issues.ExcludeRules...)
- }
-
- if opts.CheckDeprecation {
- err = l.handleDeprecation()
- if err != nil {
- return err
- }
- }
-
- l.handleGoVersion()
-
- err = goutil.CheckGoVersion(l.cfg.Run.Go)
- if err != nil {
- return err
- }
-
- l.cfg.basePath, err = fsutils.GetBasePath(context.Background(), l.cfg.Run.RelativePathMode, l.cfg.cfgDir)
- if err != nil {
- return fmt.Errorf("get base path: %w", err)
- }
-
- err = l.handleEnableOnlyOption()
- if err != nil {
- return err
- }
-
- if opts.Validation {
- err = l.cfg.Validate()
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (l *Loader) setConfigFile() error {
- configFile, err := l.evaluateOptions()
- if err != nil {
- if errors.Is(err, errConfigDisabled) {
- return nil
- }
-
- return fmt.Errorf("can't parse --config option: %w", err)
- }
-
- if configFile != "" {
- l.viper.SetConfigFile(configFile)
-
- // Assume YAML if the file has no extension.
- if filepath.Ext(configFile) == "" {
- l.viper.SetConfigType("yaml")
- }
- } else {
- l.setupConfigFileSearch()
- }
-
- return nil
-}
-
-func (l *Loader) evaluateOptions() (string, error) {
- if l.opts.NoConfig && l.opts.Config != "" {
- return "", errors.New("can't combine option --config and --no-config")
- }
-
- if l.opts.NoConfig {
- return "", errConfigDisabled
- }
-
- configFile, err := homedir.Expand(l.opts.Config)
- if err != nil {
- return "", errors.New("failed to expand configuration path")
- }
-
- return configFile, nil
-}
-
-func (l *Loader) setupConfigFileSearch() {
- l.viper.SetConfigName(".golangci")
-
- configSearchPaths := l.getConfigSearchPaths()
-
- l.log.Infof("Config search paths: %s", configSearchPaths)
-
- for _, p := range configSearchPaths {
- l.viper.AddConfigPath(p)
- }
-}
-
-func (l *Loader) getConfigSearchPaths() []string {
- firstArg := "./..."
- if len(l.args) > 0 {
- firstArg = l.args[0]
- }
-
- absPath, err := filepath.Abs(firstArg)
- if err != nil {
- l.log.Warnf("Can't make abs path for %q: %s", firstArg, err)
- absPath = filepath.Clean(firstArg)
- }
-
- // start from it
- var currentDir string
- if fsutils.IsDir(absPath) {
- currentDir = absPath
- } else {
- currentDir = filepath.Dir(absPath)
- }
-
- // find all dirs from it up to the root
- searchPaths := []string{"./"}
-
- for {
- searchPaths = append(searchPaths, currentDir)
-
- parent := filepath.Dir(currentDir)
- if currentDir == parent || parent == "" {
- break
- }
-
- currentDir = parent
- }
-
- // find home directory for global config
- if home, err := homedir.Dir(); err != nil {
- l.log.Warnf("Can't get user's home directory: %v", err)
- } else if !slices.Contains(searchPaths, home) {
- searchPaths = append(searchPaths, home)
- }
-
- return searchPaths
-}
-
-func (l *Loader) parseConfig() error {
- if err := l.viper.ReadInConfig(); err != nil {
- var configFileNotFoundError viper.ConfigFileNotFoundError
- if errors.As(err, &configFileNotFoundError) {
- // Load configuration from flags only.
- err = l.viper.Unmarshal(l.cfg, customDecoderHook())
- if err != nil {
- return fmt.Errorf("can't unmarshal config by viper (flags): %w", err)
- }
-
- return nil
- }
-
- return fmt.Errorf("can't read viper config: %w", err)
- }
-
- err := l.setConfigDir()
- if err != nil {
- return err
- }
-
- // Load configuration from all sources (flags, file).
- if err := l.viper.Unmarshal(l.cfg, customDecoderHook()); err != nil {
- return fmt.Errorf("can't unmarshal config by viper (flags, file): %w", err)
- }
-
- if l.cfg.InternalTest { // just for testing purposes: to detect config file usage
- _, _ = fmt.Fprintln(logutils.StdOut, "test")
- os.Exit(exitcodes.Success)
- }
-
- return nil
-}
-
-func (l *Loader) setConfigDir() error {
- usedConfigFile := l.viper.ConfigFileUsed()
- if usedConfigFile == "" {
- return nil
- }
-
- if usedConfigFile == os.Stdin.Name() {
- usedConfigFile = ""
- l.log.Infof("Reading config file stdin")
- } else {
- var err error
- usedConfigFile, err = fsutils.ShortestRelPath(usedConfigFile, "")
- if err != nil {
- l.log.Warnf("Can't pretty print config file path: %v", err)
- }
-
- l.log.Infof("Used config file %s", usedConfigFile)
- }
-
- usedConfigDir, err := filepath.Abs(filepath.Dir(usedConfigFile))
- if err != nil {
- return errors.New("can't get config directory")
- }
-
- l.cfg.cfgDir = usedConfigDir
-
- return nil
-}
-
-// Hack to append values from StringSlice flags.
-// Viper always overrides StringSlice values.
-// https://github.com/spf13/viper/issues/1448
-// So StringSlice flags are not bind to Viper like that their values are obtain via Cobra Flags.
-func (l *Loader) applyStringSliceHack() {
- if l.fs == nil {
- return
- }
-
- l.appendStringSlice("enable", &l.cfg.Linters.Enable)
- l.appendStringSlice("disable", &l.cfg.Linters.Disable)
- l.appendStringSlice("presets", &l.cfg.Linters.Presets)
- l.appendStringSlice("build-tags", &l.cfg.Run.BuildTags)
- l.appendStringSlice("exclude", &l.cfg.Issues.ExcludePatterns)
-
- l.appendStringSlice("skip-dirs", &l.cfg.Run.SkipDirs)
- l.appendStringSlice("skip-files", &l.cfg.Run.SkipFiles)
- l.appendStringSlice("exclude-dirs", &l.cfg.Issues.ExcludeDirs)
- l.appendStringSlice("exclude-files", &l.cfg.Issues.ExcludeFiles)
-}
-
-func (l *Loader) appendStringSlice(name string, current *[]string) {
- if l.fs.Changed(name) {
- val, _ := l.fs.GetStringSlice(name)
- *current = append(*current, val...)
- }
-}
-
-func (l *Loader) handleGoVersion() {
- if l.cfg.Run.Go == "" {
- l.cfg.Run.Go = detectGoVersion(context.Background())
- }
-
- l.cfg.LintersSettings.Govet.Go = l.cfg.Run.Go
-
- l.cfg.LintersSettings.ParallelTest.Go = l.cfg.Run.Go
-
- l.cfg.LintersSettings.Gofumpt.LangVersion = cmp.Or(l.cfg.LintersSettings.Gofumpt.LangVersion, l.cfg.Run.Go)
-
- trimmedGoVersion := goutil.TrimGoVersion(l.cfg.Run.Go)
-
- l.cfg.LintersSettings.Revive.Go = trimmedGoVersion
-
- l.cfg.LintersSettings.Gocritic.Go = trimmedGoVersion
-
- os.Setenv("GOSECGOVERSION", l.cfg.Run.Go)
-}
-
-func (l *Loader) handleDeprecation() error {
- if l.cfg.InternalTest || l.cfg.InternalCmdTest || os.Getenv(logutils.EnvTestRun) == "1" {
- return nil
- }
-
- // Deprecated since v1.57.0
- if len(l.cfg.Run.SkipFiles) > 0 {
- l.log.Warnf("The configuration option `run.skip-files` is deprecated, please use `issues.exclude-files`.")
- l.cfg.Issues.ExcludeFiles = l.cfg.Run.SkipFiles
- }
-
- // Deprecated since v1.57.0
- if len(l.cfg.Run.SkipDirs) > 0 {
- l.log.Warnf("The configuration option `run.skip-dirs` is deprecated, please use `issues.exclude-dirs`.")
- l.cfg.Issues.ExcludeDirs = l.cfg.Run.SkipDirs
- }
-
- // Deprecated since v1.57.0
- if l.cfg.Run.UseDefaultSkipDirs != nil {
- l.log.Warnf("The configuration option `run.skip-dirs-use-default` is deprecated, please use `issues.exclude-dirs-use-default`.")
- l.cfg.Issues.UseDefaultExcludeDirs = *l.cfg.Run.UseDefaultSkipDirs
- }
-
- // Deprecated since v1.57.0
- if l.cfg.Run.ShowStats != nil {
- l.log.Warnf("The configuration option `run.show-stats` is deprecated, please use `output.show-stats`")
- l.cfg.Output.ShowStats = *l.cfg.Run.ShowStats
- }
-
- // Deprecated since v1.63.0
- if l.cfg.Output.UniqByLine != nil {
- l.log.Warnf("The configuration option `output.uniq-by-line` is deprecated, please use `issues.uniq-by-line`")
- l.cfg.Issues.UniqByLine = *l.cfg.Output.UniqByLine
- }
-
- // Deprecated since v1.57.0
- if l.cfg.Output.Format != "" {
- l.log.Warnf("The configuration option `output.format` is deprecated, please use `output.formats`")
-
- var f OutputFormats
- err := f.UnmarshalText([]byte(l.cfg.Output.Format))
- if err != nil {
- return fmt.Errorf("unmarshal output format: %w", err)
- }
-
- l.cfg.Output.Formats = f
- }
-
- for _, format := range l.cfg.Output.Formats {
- if format.Format == OutFormatGithubActions {
- l.log.Warnf("The output format `%s` is deprecated, please use `%s`", OutFormatGithubActions, OutFormatColoredLineNumber)
- break // To avoid repeating the message if there are several usages of github-actions format.
- }
- }
-
- // Deprecated since v1.59.0
- if l.cfg.Issues.ExcludeGeneratedStrict != nil {
- l.log.Warnf("The configuration option `issues.exclude-generated-strict` is deprecated, please use `issues.exclude-generated`")
- if !*l.cfg.Issues.ExcludeGeneratedStrict {
- l.cfg.Issues.ExcludeGenerated = "strict" // Don't use the constants to avoid cyclic dependencies.
- }
- }
-
- l.handleLinterOptionDeprecations()
-
- return nil
-}
-
-func (l *Loader) handleLinterOptionDeprecations() {
- // Deprecated since v1.57.0,
- // but it was unofficially deprecated since v1.19 (2019) (https://github.com/golangci/golangci-lint/pull/697).
- if l.cfg.LintersSettings.Govet.CheckShadowing != nil {
- l.log.Warnf("The configuration option `linters.govet.check-shadowing` is deprecated. " +
- "Please enable `shadow` instead, if you are not using `enable-all`.")
- }
-
- if l.cfg.LintersSettings.CopyLoopVar.IgnoreAlias != nil {
- l.log.Warnf("The configuration option `linters.copyloopvar.ignore-alias` is deprecated and ignored," +
- "please use `linters.copyloopvar.check-alias`.")
- }
-
- // Deprecated since v1.42.0.
- if l.cfg.LintersSettings.Errcheck.Exclude != "" {
- l.log.Warnf("The configuration option `linters.errcheck.exclude` is deprecated, please use `linters.errcheck.exclude-functions`.")
- }
-
- // Deprecated since v1.59.0,
- // but it was unofficially deprecated since v1.13 (2018) (https://github.com/golangci/golangci-lint/pull/332).
- if l.cfg.LintersSettings.Errcheck.Ignore != "" {
- l.log.Warnf("The configuration option `linters.errcheck.ignore` is deprecated, please use `linters.errcheck.exclude-functions`.")
- }
-
- // Deprecated since v1.44.0.
- if l.cfg.LintersSettings.Gci.LocalPrefixes != "" {
- l.log.Warnf("The configuration option `linters.gci.local-prefixes` is deprecated, please use `prefix()` inside `linters.gci.sections`.")
- }
-
- // Deprecated since v1.33.0.
- if l.cfg.LintersSettings.Godot.CheckAll != nil {
- l.log.Warnf("The configuration option `linters.godot.check-all` is deprecated, please use `linters.godot.scope: all`.")
- }
-
- // Deprecated since v1.47.0
- if l.cfg.LintersSettings.Gofumpt.LangVersion != "" {
- l.log.Warnf("The configuration option `linters.gofumpt.lang-version` is deprecated, please use global `run.go`.")
- }
-
- // Deprecated since v1.47.0
- if l.cfg.LintersSettings.Staticcheck.GoVersion != "" {
- l.log.Warnf("The configuration option `linters.staticcheck.go` is deprecated, please use global `run.go`.")
- }
-
- // Deprecated since v1.47.0
- if l.cfg.LintersSettings.Gosimple.GoVersion != "" {
- l.log.Warnf("The configuration option `linters.gosimple.go` is deprecated, please use global `run.go`.")
- }
-
- // Deprecated since v1.47.0
- if l.cfg.LintersSettings.Stylecheck.GoVersion != "" {
- l.log.Warnf("The configuration option `linters.stylecheck.go` is deprecated, please use global `run.go`.")
- }
-
- // Deprecated since v1.60.0
- if l.cfg.LintersSettings.Unused.ExportedIsUsed != nil {
- l.log.Warnf("The configuration option `linters.unused.exported-is-used` is deprecated.")
- }
-
- // Deprecated since v1.58.0
- if l.cfg.LintersSettings.SlogLint.ContextOnly != nil {
- l.log.Warnf("The configuration option `linters.sloglint.context-only` is deprecated, please use `linters.sloglint.context`.")
- l.cfg.LintersSettings.SlogLint.Context = cmp.Or(l.cfg.LintersSettings.SlogLint.Context, "all")
- }
-
- // Deprecated since v1.51.0
- if l.cfg.LintersSettings.UseStdlibVars.OSDevNull != nil {
- l.log.Warnf("The configuration option `linters.usestdlibvars.os-dev-null` is deprecated.")
- }
-
- // Deprecated since v1.51.0
- if l.cfg.LintersSettings.UseStdlibVars.SyslogPriority != nil {
- l.log.Warnf("The configuration option `linters.usestdlibvars.syslog-priority` is deprecated.")
- }
-}
-
-func (l *Loader) handleEnableOnlyOption() error {
- lookup := l.fs.Lookup("enable-only")
- if lookup == nil {
- return nil
- }
-
- only, err := l.fs.GetStringSlice("enable-only")
- if err != nil {
- return err
- }
-
- if len(only) > 0 {
- l.cfg.Linters = Linters{
- Enable: only,
- DisableAll: true,
- }
- }
-
- return nil
-}
-
-func customDecoderHook() viper.DecoderConfigOption {
- return viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
- // Default hooks (https://github.com/spf13/viper/blob/518241257478c557633ab36e474dfcaeb9a3c623/viper.go#L135-L138).
- mapstructure.StringToTimeDurationHookFunc(),
- mapstructure.StringToSliceHookFunc(","),
-
- // Needed for forbidigo, and output.formats.
- mapstructure.TextUnmarshallerHookFunc(),
- ))
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/output.go b/vendor/github.com/golangci/golangci-lint/pkg/config/output.go
deleted file mode 100644
index caddb095..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/config/output.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package config
-
-import (
- "errors"
- "fmt"
- "slices"
- "strings"
-)
-
-const (
- OutFormatJSON = "json"
- OutFormatLineNumber = "line-number"
- OutFormatColoredLineNumber = "colored-line-number"
- OutFormatTab = "tab"
- OutFormatColoredTab = "colored-tab"
- OutFormatCheckstyle = "checkstyle"
- OutFormatCodeClimate = "code-climate"
- OutFormatHTML = "html"
- OutFormatJUnitXML = "junit-xml"
- OutFormatJUnitXMLExtended = "junit-xml-extended"
- OutFormatGithubActions = "github-actions" // Deprecated
- OutFormatTeamCity = "teamcity"
- OutFormatSarif = "sarif"
-)
-
-var AllOutputFormats = []string{
- OutFormatJSON,
- OutFormatLineNumber,
- OutFormatColoredLineNumber,
- OutFormatTab,
- OutFormatColoredTab,
- OutFormatCheckstyle,
- OutFormatCodeClimate,
- OutFormatHTML,
- OutFormatJUnitXML,
- OutFormatJUnitXMLExtended,
- OutFormatGithubActions,
- OutFormatTeamCity,
- OutFormatSarif,
-}
-
-type Output struct {
- Formats OutputFormats `mapstructure:"formats"`
- PrintIssuedLine bool `mapstructure:"print-issued-lines"`
- PrintLinterName bool `mapstructure:"print-linter-name"`
- SortResults bool `mapstructure:"sort-results"`
- SortOrder []string `mapstructure:"sort-order"`
- PathPrefix string `mapstructure:"path-prefix"`
- ShowStats bool `mapstructure:"show-stats"`
-
- // Deprecated: use Formats instead.
- Format string `mapstructure:"format"`
-
- // Deprecated: use [Issues.UniqByLine] instead.
- UniqByLine *bool `mapstructure:"uniq-by-line"`
-}
-
-func (o *Output) Validate() error {
- if !o.SortResults && len(o.SortOrder) > 0 {
- return errors.New("sort-results should be 'true' to use sort-order")
- }
-
- validOrders := []string{"linter", "file", "severity"}
-
- all := strings.Join(o.SortOrder, " ")
-
- for _, order := range o.SortOrder {
- if strings.Count(all, order) > 1 {
- return fmt.Errorf("the sort-order name %q is repeated several times", order)
- }
-
- if !slices.Contains(validOrders, order) {
- return fmt.Errorf("unsupported sort-order name %q", order)
- }
- }
-
- for _, format := range o.Formats {
- err := format.Validate()
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-type OutputFormat struct {
- Format string `mapstructure:"format"`
- Path string `mapstructure:"path"`
-}
-
-func (o *OutputFormat) Validate() error {
- if o.Format == "" {
- return errors.New("the format is required")
- }
-
- if !slices.Contains(AllOutputFormats, o.Format) {
- return fmt.Errorf("unsupported output format %q", o.Format)
- }
-
- return nil
-}
-
-type OutputFormats []OutputFormat
-
-func (p *OutputFormats) UnmarshalText(text []byte) error {
- formats := strings.Split(string(text), ",")
-
- for _, item := range formats {
- format, path, _ := strings.Cut(item, ":")
-
- *p = append(*p, OutputFormat{
- Path: path,
- Format: format,
- })
- }
-
- return nil
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/files.go b/vendor/github.com/golangci/golangci-lint/pkg/fsutils/files.go
deleted file mode 100644
index 4398ab9f..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/files.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package fsutils
-
-import "path/filepath"
-
-// Files combines different operations related to handling file paths and content.
-type Files struct {
- *LineCache
- pathPrefix string
-}
-
-func NewFiles(lc *LineCache, pathPrefix string) *Files {
- return &Files{
- LineCache: lc,
- pathPrefix: pathPrefix,
- }
-}
-
-// WithPathPrefix takes a path that is relative to the current directory (as used in issues)
-// and adds the configured path prefix, if there is one.
-// The resulting path then can be shown to the user or compared against paths specified in the configuration.
-func (f *Files) WithPathPrefix(relativePath string) string {
- return WithPathPrefix(f.pathPrefix, relativePath)
-}
-
-// WithPathPrefix takes a path that is relative to the current directory (as used in issues)
-// and adds the configured path prefix, if there is one.
-// The resulting path then can be shown to the user or compared against paths specified in the configuration.
-func WithPathPrefix(pathPrefix, relativePath string) string {
- if pathPrefix == "" {
- return relativePath
- }
- return filepath.Join(pathPrefix, relativePath)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/meta_formatter.go b/vendor/github.com/golangci/golangci-lint/pkg/goformatters/meta_formatter.go
deleted file mode 100644
index d66878c7..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/meta_formatter.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package goformatters
-
-import (
- "bytes"
- "fmt"
- "go/format"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goformatters/gci"
- "github.com/golangci/golangci-lint/pkg/goformatters/gofmt"
- "github.com/golangci/golangci-lint/pkg/goformatters/gofumpt"
- "github.com/golangci/golangci-lint/pkg/goformatters/goimports"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/logutils"
-)
-
-type MetaFormatter struct {
- log logutils.Log
- formatters []Formatter
-}
-
-func NewMetaFormatter(log logutils.Log, cfg *config.Config, enabledLinters map[string]*linter.Config) (*MetaFormatter, error) {
- m := &MetaFormatter{log: log}
-
- if _, ok := enabledLinters[gofmt.Name]; ok {
- m.formatters = append(m.formatters, gofmt.New(&cfg.LintersSettings.Gofmt))
- }
-
- if _, ok := enabledLinters[gofumpt.Name]; ok {
- m.formatters = append(m.formatters, gofumpt.New(&cfg.LintersSettings.Gofumpt, cfg.Run.Go))
- }
-
- if _, ok := enabledLinters[goimports.Name]; ok {
- m.formatters = append(m.formatters, goimports.New(&cfg.LintersSettings.Goimports))
- }
-
- // gci is a last because the only goal of gci is to handle imports.
- if _, ok := enabledLinters[gci.Name]; ok {
- formatter, err := gci.New(&cfg.LintersSettings.Gci)
- if err != nil {
- return nil, fmt.Errorf("gci: creating formatter: %w", err)
- }
-
- m.formatters = append(m.formatters, formatter)
- }
-
- return m, nil
-}
-
-func (m *MetaFormatter) Format(filename string, src []byte) []byte {
- if len(m.formatters) == 0 {
- data, err := format.Source(src)
- if err != nil {
- m.log.Warnf("(fmt) formatting file %s: %v", filename, err)
- return src
- }
-
- return data
- }
-
- data := bytes.Clone(src)
-
- for _, formatter := range m.formatters {
- formatted, err := formatter.Format(filename, data)
- if err != nil {
- m.log.Warnf("(%s) formatting file %s: %v", formatter.Name(), filename, err)
- continue
- }
-
- data = formatted
- }
-
- return data
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errcheck/errcheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/errcheck/errcheck.go
deleted file mode 100644
index 67a1b2ca..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errcheck/errcheck.go
+++ /dev/null
@@ -1,269 +0,0 @@
-package errcheck
-
-import (
- "bufio"
- "cmp"
- "fmt"
- "os"
- "os/user"
- "path/filepath"
- "regexp"
- "strings"
- "sync"
-
- "github.com/kisielk/errcheck/errcheck"
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/packages"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
-)
-
-const linterName = "errcheck"
-
-func New(settings *config.ErrcheckSettings) *goanalysis.Linter {
- var mu sync.Mutex
- var resIssues []goanalysis.Issue
-
- analyzer := &analysis.Analyzer{
- Name: linterName,
- Doc: goanalysis.TheOnlyanalyzerDoc,
- Run: goanalysis.DummyRun,
- }
-
- return goanalysis.NewLinter(
- linterName,
- "errcheck is a program for checking for unchecked errors in Go code. "+
- "These unchecked errors can be critical bugs in some cases",
- []*analysis.Analyzer{analyzer},
- nil,
- ).WithContextSetter(func(lintCtx *linter.Context) {
- // copied from errcheck
- checker, err := getChecker(settings)
- if err != nil {
- lintCtx.Log.Errorf("failed to get checker: %v", err)
- return
- }
-
- checker.Tags = lintCtx.Cfg.Run.BuildTags
-
- analyzer.Run = func(pass *analysis.Pass) (any, error) {
- issues := runErrCheck(lintCtx, pass, checker)
- if err != nil {
- return nil, err
- }
-
- if len(issues) == 0 {
- return nil, nil
- }
-
- mu.Lock()
- resIssues = append(resIssues, issues...)
- mu.Unlock()
-
- return nil, nil
- }
- }).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
- return resIssues
- }).WithLoadMode(goanalysis.LoadModeTypesInfo)
-}
-
-func runErrCheck(lintCtx *linter.Context, pass *analysis.Pass, checker *errcheck.Checker) []goanalysis.Issue {
- pkg := &packages.Package{
- Fset: pass.Fset,
- Syntax: pass.Files,
- Types: pass.Pkg,
- TypesInfo: pass.TypesInfo,
- }
-
- lintIssues := checker.CheckPackage(pkg).Unique()
- if len(lintIssues.UncheckedErrors) == 0 {
- return nil
- }
-
- issues := make([]goanalysis.Issue, len(lintIssues.UncheckedErrors))
-
- for i, err := range lintIssues.UncheckedErrors {
- text := "Error return value is not checked"
-
- if err.FuncName != "" {
- code := cmp.Or(err.SelectorName, err.FuncName)
-
- text = fmt.Sprintf("Error return value of %s is not checked", internal.FormatCode(code, lintCtx.Cfg))
- }
-
- issues[i] = goanalysis.NewIssue(
- &result.Issue{
- FromLinter: linterName,
- Text: text,
- Pos: err.Pos,
- },
- pass,
- )
- }
-
- return issues
-}
-
-// parseIgnoreConfig was taken from errcheck in order to keep the API identical.
-// https://github.com/kisielk/errcheck/blob/1787c4bee836470bf45018cfbc783650db3c6501/main.go#L25-L60
-func parseIgnoreConfig(s string) (map[string]*regexp.Regexp, error) {
- if s == "" {
- return nil, nil
- }
-
- cfg := map[string]*regexp.Regexp{}
-
- for _, pair := range strings.Split(s, ",") {
- colonIndex := strings.Index(pair, ":")
- var pkg, re string
- if colonIndex == -1 {
- pkg = ""
- re = pair
- } else {
- pkg = pair[:colonIndex]
- re = pair[colonIndex+1:]
- }
- regex, err := regexp.Compile(re)
- if err != nil {
- return nil, err
- }
- cfg[pkg] = regex
- }
-
- return cfg, nil
-}
-
-func getChecker(errCfg *config.ErrcheckSettings) (*errcheck.Checker, error) {
- ignoreConfig, err := parseIgnoreConfig(errCfg.Ignore)
- if err != nil {
- return nil, fmt.Errorf("failed to parse 'ignore' directive: %w", err)
- }
-
- checker := errcheck.Checker{
- Exclusions: errcheck.Exclusions{
- BlankAssignments: !errCfg.CheckAssignToBlank,
- TypeAssertions: !errCfg.CheckTypeAssertions,
- SymbolRegexpsByPackage: map[string]*regexp.Regexp{},
- },
- }
-
- if !errCfg.DisableDefaultExclusions {
- checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, errcheck.DefaultExcludedSymbols...)
- }
-
- for pkg, re := range ignoreConfig {
- checker.Exclusions.SymbolRegexpsByPackage[pkg] = re
- }
-
- if errCfg.Exclude != "" {
- exclude, err := readExcludeFile(errCfg.Exclude)
- if err != nil {
- return nil, err
- }
-
- checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, exclude...)
- }
-
- checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, errCfg.ExcludeFunctions...)
-
- return &checker, nil
-}
-
-func getFirstPathArg() string {
- args := os.Args
-
- // skip all args ([golangci-lint, run/linters]) before files/dirs list
- for len(args) != 0 {
- if args[0] == "run" {
- args = args[1:]
- break
- }
-
- args = args[1:]
- }
-
- // find first file/dir arg
- firstArg := "./..."
- for _, arg := range args {
- if !strings.HasPrefix(arg, "-") {
- firstArg = arg
- break
- }
- }
-
- return firstArg
-}
-
-func setupConfigFileSearch(name string) []string {
- if strings.HasPrefix(name, "~") {
- if u, err := user.Current(); err == nil {
- name = strings.Replace(name, "~", u.HomeDir, 1)
- }
- }
-
- if filepath.IsAbs(name) {
- return []string{name}
- }
-
- firstArg := getFirstPathArg()
-
- absStartPath, err := filepath.Abs(firstArg)
- if err != nil {
- absStartPath = filepath.Clean(firstArg)
- }
-
- // start from it
- var curDir string
- if fsutils.IsDir(absStartPath) {
- curDir = absStartPath
- } else {
- curDir = filepath.Dir(absStartPath)
- }
-
- // find all dirs from it up to the root
- configSearchPaths := []string{filepath.Join(".", name)}
- for {
- configSearchPaths = append(configSearchPaths, filepath.Join(curDir, name))
- newCurDir := filepath.Dir(curDir)
- if curDir == newCurDir || newCurDir == "" {
- break
- }
- curDir = newCurDir
- }
-
- return configSearchPaths
-}
-
-func readExcludeFile(name string) ([]string, error) {
- var err error
- var fh *os.File
-
- for _, path := range setupConfigFileSearch(name) {
- if fh, err = os.Open(path); err == nil {
- break
- }
- }
-
- if fh == nil {
- return nil, fmt.Errorf("failed reading exclude file: %s: %w", name, err)
- }
- defer func() { _ = fh.Close() }()
-
- scanner := bufio.NewScanner(fh)
-
- var excludes []string
- for scanner.Scan() {
- excludes = append(excludes, scanner.Text())
- }
-
- if err := scanner.Err(); err != nil {
- return nil, fmt.Errorf("failed scanning file: %s: %w", name, err)
- }
-
- return excludes, nil
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goconst/goconst.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/goconst/goconst.go
deleted file mode 100644
index 07bed301..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goconst/goconst.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package goconst
-
-import (
- "fmt"
- "sync"
-
- goconstAPI "github.com/jgautheron/goconst"
- "golang.org/x/tools/go/analysis"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
-)
-
-const linterName = "goconst"
-
-func New(settings *config.GoConstSettings) *goanalysis.Linter {
- var mu sync.Mutex
- var resIssues []goanalysis.Issue
-
- analyzer := &analysis.Analyzer{
- Name: linterName,
- Doc: goanalysis.TheOnlyanalyzerDoc,
- Run: func(pass *analysis.Pass) (any, error) {
- issues, err := runGoconst(pass, settings)
- if err != nil {
- return nil, err
- }
-
- if len(issues) == 0 {
- return nil, nil
- }
-
- mu.Lock()
- resIssues = append(resIssues, issues...)
- mu.Unlock()
-
- return nil, nil
- },
- }
-
- return goanalysis.NewLinter(
- linterName,
- "Finds repeated strings that could be replaced by a constant",
- []*analysis.Analyzer{analyzer},
- nil,
- ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
- return resIssues
- }).WithLoadMode(goanalysis.LoadModeSyntax)
-}
-
-func runGoconst(pass *analysis.Pass, settings *config.GoConstSettings) ([]goanalysis.Issue, error) {
- cfg := goconstAPI.Config{
- IgnoreStrings: settings.IgnoreStrings,
- IgnoreTests: settings.IgnoreTests,
- MatchWithConstants: settings.MatchWithConstants,
- MinStringLength: settings.MinStringLen,
- MinOccurrences: settings.MinOccurrencesCount,
- ParseNumbers: settings.ParseNumbers,
- NumberMin: settings.NumberMin,
- NumberMax: settings.NumberMax,
- ExcludeTypes: map[goconstAPI.Type]bool{},
- }
-
- if settings.IgnoreCalls {
- cfg.ExcludeTypes[goconstAPI.Call] = true
- }
-
- lintIssues, err := goconstAPI.Run(pass.Files, pass.Fset, &cfg)
- if err != nil {
- return nil, err
- }
-
- if len(lintIssues) == 0 {
- return nil, nil
- }
-
- res := make([]goanalysis.Issue, 0, len(lintIssues))
- for _, i := range lintIssues {
- text := fmt.Sprintf("string %s has %d occurrences", internal.FormatCode(i.Str, nil), i.OccurrencesCount)
-
- if i.MatchingConst == "" {
- text += ", make it a constant"
- } else {
- text += fmt.Sprintf(", but such constant %s already exists", internal.FormatCode(i.MatchingConst, nil))
- }
-
- res = append(res, goanalysis.NewIssue(&result.Issue{
- Pos: i.Pos,
- Text: text,
- FromLinter: linterName,
- }, pass))
- }
-
- return res, nil
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosimple/gosimple.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosimple/gosimple.go
deleted file mode 100644
index c03871ad..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosimple/gosimple.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package gosimple
-
-import (
- "honnef.co/go/tools/simple"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
-)
-
-func New(settings *config.StaticCheckSettings) *goanalysis.Linter {
- cfg := internal.StaticCheckConfig(settings)
-
- analyzers := internal.SetupStaticCheckAnalyzers(simple.Analyzers, cfg.Checks)
-
- return goanalysis.NewLinter(
- "gosimple",
- "Linter for Go source code that specializes in simplifying code",
- analyzers,
- nil,
- ).WithLoadMode(goanalysis.LoadModeTypesInfo)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/commons.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/commons.go
deleted file mode 100644
index ebb0b13a..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/commons.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package internal
-
-import "github.com/golangci/golangci-lint/pkg/logutils"
-
-// LinterLogger must be use only when the context logger is not available.
-var LinterLogger = logutils.NewStderrLog(logutils.DebugKeyLinter)
-
-// Placeholders used inside linters to evaluate relative paths.
-const (
- PlaceholderBasePath = "${base-path}"
- // Deprecated: it must be removed in v2.
- // [PlaceholderBasePath] will be the only one placeholder as it is a dynamic value based on
- // [github.com/golangci/golangci-lint/pkg/config.Run.RelativePathMode].
- PlaceholderConfigDir = "${configDir}"
-)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nakedret/nakedret.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nakedret/nakedret.go
deleted file mode 100644
index e69fa5e9..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nakedret/nakedret.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package nakedret
-
-import (
- "github.com/alexkohler/nakedret/v2"
- "golang.org/x/tools/go/analysis"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
-)
-
-func New(settings *config.NakedretSettings) *goanalysis.Linter {
- var maxLines uint
- if settings != nil {
- maxLines = settings.MaxFuncLines
- }
-
- a := nakedret.NakedReturnAnalyzer(maxLines, false)
-
- return goanalysis.NewLinter(
- a.Name,
- a.Doc,
- []*analysis.Analyzer{a},
- nil,
- ).WithLoadMode(goanalysis.LoadModeSyntax)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/staticcheck/staticcheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/staticcheck/staticcheck.go
deleted file mode 100644
index 79394bdb..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/staticcheck/staticcheck.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package staticcheck
-
-import (
- "honnef.co/go/tools/staticcheck"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
-)
-
-func New(settings *config.StaticCheckSettings) *goanalysis.Linter {
- cfg := internal.StaticCheckConfig(settings)
- analyzers := internal.SetupStaticCheckAnalyzers(staticcheck.Analyzers, cfg.Checks)
-
- return goanalysis.NewLinter(
- "staticcheck",
- "It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary."+
- " The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint.",
- analyzers,
- nil,
- ).WithLoadMode(goanalysis.LoadModeTypesInfo)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/stylecheck/stylecheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/stylecheck/stylecheck.go
deleted file mode 100644
index 60859f28..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/stylecheck/stylecheck.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package stylecheck
-
-import (
- "golang.org/x/tools/go/analysis"
- scconfig "honnef.co/go/tools/config"
- "honnef.co/go/tools/stylecheck"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
-)
-
-func New(settings *config.StaticCheckSettings) *goanalysis.Linter {
- cfg := internal.StaticCheckConfig(settings)
-
- // `scconfig.Analyzer` is a singleton, then it's not possible to have more than one instance for all staticcheck "sub-linters".
- // When we will merge the 4 "sub-linters", the problem will disappear: https://github.com/golangci/golangci-lint/issues/357
- // Currently only stylecheck analyzer has a configuration in staticcheck.
- scconfig.Analyzer.Run = func(_ *analysis.Pass) (any, error) {
- return cfg, nil
- }
-
- analyzers := internal.SetupStaticCheckAnalyzers(stylecheck.Analyzers, cfg.Checks)
-
- return goanalysis.NewLinter(
- "stylecheck",
- "Stylecheck is a replacement for golint",
- analyzers,
- nil,
- ).WithLoadMode(goanalysis.LoadModeTypesInfo)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tenv/tenv.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/tenv/tenv.go
deleted file mode 100644
index 2fc247fa..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tenv/tenv.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package tenv
-
-import (
- "github.com/sivchari/tenv"
- "golang.org/x/tools/go/analysis"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
-)
-
-func New(settings *config.TenvSettings) *goanalysis.Linter {
- a := tenv.Analyzer
-
- var cfg map[string]map[string]any
- if settings != nil {
- cfg = map[string]map[string]any{
- a.Name: {
- tenv.A: settings.All,
- },
- }
- }
-
- return goanalysis.NewLinter(
- a.Name,
- a.Doc,
- []*analysis.Analyzer{a},
- cfg,
- ).WithLoadMode(goanalysis.LoadModeTypesInfo)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_linter.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_linter.go
deleted file mode 100644
index ddeb99e1..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_linter.go
+++ /dev/null
@@ -1,893 +0,0 @@
-package lintersdb
-
-import (
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/golinters"
- "github.com/golangci/golangci-lint/pkg/golinters/asasalint"
- "github.com/golangci/golangci-lint/pkg/golinters/asciicheck"
- "github.com/golangci/golangci-lint/pkg/golinters/bidichk"
- "github.com/golangci/golangci-lint/pkg/golinters/bodyclose"
- "github.com/golangci/golangci-lint/pkg/golinters/canonicalheader"
- "github.com/golangci/golangci-lint/pkg/golinters/containedctx"
- "github.com/golangci/golangci-lint/pkg/golinters/contextcheck"
- "github.com/golangci/golangci-lint/pkg/golinters/copyloopvar"
- "github.com/golangci/golangci-lint/pkg/golinters/cyclop"
- "github.com/golangci/golangci-lint/pkg/golinters/decorder"
- "github.com/golangci/golangci-lint/pkg/golinters/depguard"
- "github.com/golangci/golangci-lint/pkg/golinters/dogsled"
- "github.com/golangci/golangci-lint/pkg/golinters/dupl"
- "github.com/golangci/golangci-lint/pkg/golinters/dupword"
- "github.com/golangci/golangci-lint/pkg/golinters/durationcheck"
- "github.com/golangci/golangci-lint/pkg/golinters/err113"
- "github.com/golangci/golangci-lint/pkg/golinters/errcheck"
- "github.com/golangci/golangci-lint/pkg/golinters/errchkjson"
- "github.com/golangci/golangci-lint/pkg/golinters/errname"
- "github.com/golangci/golangci-lint/pkg/golinters/errorlint"
- "github.com/golangci/golangci-lint/pkg/golinters/exhaustive"
- "github.com/golangci/golangci-lint/pkg/golinters/exhaustruct"
- "github.com/golangci/golangci-lint/pkg/golinters/exptostd"
- "github.com/golangci/golangci-lint/pkg/golinters/fatcontext"
- "github.com/golangci/golangci-lint/pkg/golinters/forbidigo"
- "github.com/golangci/golangci-lint/pkg/golinters/forcetypeassert"
- "github.com/golangci/golangci-lint/pkg/golinters/funlen"
- "github.com/golangci/golangci-lint/pkg/golinters/gci"
- "github.com/golangci/golangci-lint/pkg/golinters/ginkgolinter"
- "github.com/golangci/golangci-lint/pkg/golinters/gocheckcompilerdirectives"
- "github.com/golangci/golangci-lint/pkg/golinters/gochecknoglobals"
- "github.com/golangci/golangci-lint/pkg/golinters/gochecknoinits"
- "github.com/golangci/golangci-lint/pkg/golinters/gochecksumtype"
- "github.com/golangci/golangci-lint/pkg/golinters/gocognit"
- "github.com/golangci/golangci-lint/pkg/golinters/goconst"
- "github.com/golangci/golangci-lint/pkg/golinters/gocritic"
- "github.com/golangci/golangci-lint/pkg/golinters/gocyclo"
- "github.com/golangci/golangci-lint/pkg/golinters/godot"
- "github.com/golangci/golangci-lint/pkg/golinters/godox"
- "github.com/golangci/golangci-lint/pkg/golinters/gofmt"
- "github.com/golangci/golangci-lint/pkg/golinters/gofumpt"
- "github.com/golangci/golangci-lint/pkg/golinters/goheader"
- "github.com/golangci/golangci-lint/pkg/golinters/goimports"
- "github.com/golangci/golangci-lint/pkg/golinters/gomoddirectives"
- "github.com/golangci/golangci-lint/pkg/golinters/gomodguard"
- "github.com/golangci/golangci-lint/pkg/golinters/goprintffuncname"
- "github.com/golangci/golangci-lint/pkg/golinters/gosec"
- "github.com/golangci/golangci-lint/pkg/golinters/gosimple"
- "github.com/golangci/golangci-lint/pkg/golinters/gosmopolitan"
- "github.com/golangci/golangci-lint/pkg/golinters/govet"
- "github.com/golangci/golangci-lint/pkg/golinters/grouper"
- "github.com/golangci/golangci-lint/pkg/golinters/iface"
- "github.com/golangci/golangci-lint/pkg/golinters/importas"
- "github.com/golangci/golangci-lint/pkg/golinters/inamedparam"
- "github.com/golangci/golangci-lint/pkg/golinters/ineffassign"
- "github.com/golangci/golangci-lint/pkg/golinters/interfacebloat"
- "github.com/golangci/golangci-lint/pkg/golinters/intrange"
- "github.com/golangci/golangci-lint/pkg/golinters/ireturn"
- "github.com/golangci/golangci-lint/pkg/golinters/lll"
- "github.com/golangci/golangci-lint/pkg/golinters/loggercheck"
- "github.com/golangci/golangci-lint/pkg/golinters/maintidx"
- "github.com/golangci/golangci-lint/pkg/golinters/makezero"
- "github.com/golangci/golangci-lint/pkg/golinters/mirror"
- "github.com/golangci/golangci-lint/pkg/golinters/misspell"
- "github.com/golangci/golangci-lint/pkg/golinters/mnd"
- "github.com/golangci/golangci-lint/pkg/golinters/musttag"
- "github.com/golangci/golangci-lint/pkg/golinters/nakedret"
- "github.com/golangci/golangci-lint/pkg/golinters/nestif"
- "github.com/golangci/golangci-lint/pkg/golinters/nilerr"
- "github.com/golangci/golangci-lint/pkg/golinters/nilnesserr"
- "github.com/golangci/golangci-lint/pkg/golinters/nilnil"
- "github.com/golangci/golangci-lint/pkg/golinters/nlreturn"
- "github.com/golangci/golangci-lint/pkg/golinters/noctx"
- "github.com/golangci/golangci-lint/pkg/golinters/nolintlint"
- "github.com/golangci/golangci-lint/pkg/golinters/nonamedreturns"
- "github.com/golangci/golangci-lint/pkg/golinters/nosprintfhostport"
- "github.com/golangci/golangci-lint/pkg/golinters/paralleltest"
- "github.com/golangci/golangci-lint/pkg/golinters/perfsprint"
- "github.com/golangci/golangci-lint/pkg/golinters/prealloc"
- "github.com/golangci/golangci-lint/pkg/golinters/predeclared"
- "github.com/golangci/golangci-lint/pkg/golinters/promlinter"
- "github.com/golangci/golangci-lint/pkg/golinters/protogetter"
- "github.com/golangci/golangci-lint/pkg/golinters/reassign"
- "github.com/golangci/golangci-lint/pkg/golinters/recvcheck"
- "github.com/golangci/golangci-lint/pkg/golinters/revive"
- "github.com/golangci/golangci-lint/pkg/golinters/rowserrcheck"
- "github.com/golangci/golangci-lint/pkg/golinters/sloglint"
- "github.com/golangci/golangci-lint/pkg/golinters/spancheck"
- "github.com/golangci/golangci-lint/pkg/golinters/sqlclosecheck"
- "github.com/golangci/golangci-lint/pkg/golinters/staticcheck"
- "github.com/golangci/golangci-lint/pkg/golinters/stylecheck"
- "github.com/golangci/golangci-lint/pkg/golinters/tagalign"
- "github.com/golangci/golangci-lint/pkg/golinters/tagliatelle"
- "github.com/golangci/golangci-lint/pkg/golinters/tenv"
- "github.com/golangci/golangci-lint/pkg/golinters/testableexamples"
- "github.com/golangci/golangci-lint/pkg/golinters/testifylint"
- "github.com/golangci/golangci-lint/pkg/golinters/testpackage"
- "github.com/golangci/golangci-lint/pkg/golinters/thelper"
- "github.com/golangci/golangci-lint/pkg/golinters/tparallel"
- "github.com/golangci/golangci-lint/pkg/golinters/unconvert"
- "github.com/golangci/golangci-lint/pkg/golinters/unparam"
- "github.com/golangci/golangci-lint/pkg/golinters/unused"
- "github.com/golangci/golangci-lint/pkg/golinters/usestdlibvars"
- "github.com/golangci/golangci-lint/pkg/golinters/usetesting"
- "github.com/golangci/golangci-lint/pkg/golinters/varnamelen"
- "github.com/golangci/golangci-lint/pkg/golinters/wastedassign"
- "github.com/golangci/golangci-lint/pkg/golinters/whitespace"
- "github.com/golangci/golangci-lint/pkg/golinters/wrapcheck"
- "github.com/golangci/golangci-lint/pkg/golinters/wsl"
- "github.com/golangci/golangci-lint/pkg/golinters/zerologlint"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
-)
-
-// LinterBuilder builds the "internal" linters based on the configuration.
-type LinterBuilder struct{}
-
-// NewLinterBuilder creates a new LinterBuilder.
-func NewLinterBuilder() *LinterBuilder {
- return &LinterBuilder{}
-}
-
-// Build loads all the "internal" linters.
-// The configuration is use for the linter settings.
-func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
- if cfg == nil {
- return nil, nil
- }
-
- const megacheckName = "megacheck"
-
- // The linters are sorted in the alphabetical order (case-insensitive).
- // When a new linter is added the version in `WithSince(...)` must be the next minor version of golangci-lint.
- return []*linter.Config{
- linter.NewConfig(asasalint.New(&cfg.LintersSettings.Asasalint)).
- WithSince("v1.47.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/alingse/asasalint"),
-
- linter.NewConfig(asciicheck.New()).
- WithSince("v1.26.0").
- WithPresets(linter.PresetBugs, linter.PresetStyle).
- WithURL("https://github.com/tdakkota/asciicheck"),
-
- linter.NewConfig(bidichk.New(&cfg.LintersSettings.BiDiChk)).
- WithSince("v1.43.0").
- WithPresets(linter.PresetBugs).
- WithURL("https://github.com/breml/bidichk"),
-
- linter.NewConfig(bodyclose.New()).
- WithSince("v1.18.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetPerformance, linter.PresetBugs).
- WithURL("https://github.com/timakin/bodyclose"),
-
- linter.NewConfig(canonicalheader.New()).
- WithSince("v1.58.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithAutoFix().
- WithURL("https://github.com/lasiar/canonicalheader"),
-
- linter.NewConfig(containedctx.New()).
- WithSince("v1.44.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/sivchari/containedctx"),
-
- linter.NewConfig(contextcheck.New()).
- WithSince("v1.43.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/kkHAIKE/contextcheck"),
-
- linter.NewConfig(copyloopvar.New(&cfg.LintersSettings.CopyLoopVar)).
- WithSince("v1.57.0").
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/karamaru-alpha/copyloopvar").
- WithNoopFallback(cfg, linter.IsGoLowerThanGo122()),
-
- linter.NewConfig(cyclop.New(&cfg.LintersSettings.Cyclop)).
- WithSince("v1.37.0").
- WithPresets(linter.PresetComplexity).
- WithURL("https://github.com/bkielbasa/cyclop"),
-
- linter.NewConfig(decorder.New(&cfg.LintersSettings.Decorder)).
- WithSince("v1.44.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://gitlab.com/bosi/decorder"),
-
- linter.NewConfig(linter.NewNoopDeprecated("deadcode", cfg, linter.DeprecationError)).
- WithSince("v1.0.0").
- WithPresets(linter.PresetUnused).
- WithURL("https://github.com/remyoudompheng/go-misc/tree/HEAD/deadcode").
- DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
-
- linter.NewConfig(depguard.New(&cfg.LintersSettings.Depguard, cfg.GetBasePath())).
- WithSince("v1.4.0").
- WithPresets(linter.PresetStyle, linter.PresetImport, linter.PresetModule).
- WithURL("https://github.com/OpenPeeDeeP/depguard"),
-
- linter.NewConfig(dogsled.New(&cfg.LintersSettings.Dogsled)).
- WithSince("v1.19.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/alexkohler/dogsled"),
-
- linter.NewConfig(dupl.New(&cfg.LintersSettings.Dupl)).
- WithSince("v1.0.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/mibk/dupl"),
-
- linter.NewConfig(dupword.New(&cfg.LintersSettings.DupWord)).
- WithSince("v1.50.0").
- WithPresets(linter.PresetComment).
- WithAutoFix().
- WithURL("https://github.com/Abirdcfly/dupword"),
-
- linter.NewConfig(durationcheck.New()).
- WithSince("v1.37.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/charithe/durationcheck"),
-
- linter.NewConfig(errcheck.New(&cfg.LintersSettings.Errcheck)).
- WithEnabledByDefault().
- WithSince("v1.0.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetBugs, linter.PresetError).
- WithURL("https://github.com/kisielk/errcheck"),
-
- linter.NewConfig(errchkjson.New(&cfg.LintersSettings.ErrChkJSON)).
- WithSince("v1.44.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/breml/errchkjson"),
-
- linter.NewConfig(errname.New()).
- WithSince("v1.42.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/Antonboom/errname"),
-
- linter.NewConfig(errorlint.New(&cfg.LintersSettings.ErrorLint)).
- WithSince("v1.32.0").
- WithPresets(linter.PresetBugs, linter.PresetError).
- WithLoadForGoAnalysis().
- WithAutoFix().
- WithURL("https://github.com/polyfloyd/go-errorlint"),
-
- linter.NewConfig(linter.NewNoopDeprecated("execinquery", cfg, linter.DeprecationError)).
- WithSince("v1.46.0").
- WithPresets(linter.PresetSQL).
- WithURL("https://github.com/1uf3/execinquery").
- DeprecatedError("The repository of the linter has been archived by the owner.", "v1.58.0", ""),
-
- linter.NewConfig(exhaustive.New(&cfg.LintersSettings.Exhaustive)).
- WithSince(" v1.28.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/nishanths/exhaustive"),
-
- linter.NewConfig(linter.NewNoopDeprecated("exhaustivestruct", cfg, linter.DeprecationError)).
- WithSince("v1.32.0").
- WithPresets(linter.PresetStyle, linter.PresetTest).
- WithURL("https://github.com/mbilski/exhaustivestruct").
- DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.46.0", "exhaustruct"),
-
- linter.NewConfig(exhaustruct.New(&cfg.LintersSettings.Exhaustruct)).
- WithSince("v1.46.0").
- WithPresets(linter.PresetStyle, linter.PresetTest).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/GaijinEntertainment/go-exhaustruct"),
-
- linter.NewConfig(linter.NewNoopDeprecated("exportloopref", cfg, linter.DeprecationError)).
- WithSince("v1.28.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/kyoh86/exportloopref").
- DeprecatedError("Since Go1.22 (loopvar) this linter is no longer relevant.", "v1.60.2", "copyloopvar"),
-
- linter.NewConfig(exptostd.New()).
- WithSince("v1.63.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithAutoFix().
- WithURL("https://github.com/ldez/exptostd"),
-
- linter.NewConfig(forbidigo.New(&cfg.LintersSettings.Forbidigo)).
- WithSince("v1.34.0").
- WithPresets(linter.PresetStyle).
- // Strictly speaking,
- // the additional information is only needed when forbidigoCfg.AnalyzeTypes is chosen by the user.
- // But we don't know that here in all cases (sometimes config is not loaded),
- // so we have to assume that it is needed to be on the safe side.
- WithLoadForGoAnalysis().
- WithURL("https://github.com/ashanbrown/forbidigo"),
-
- linter.NewConfig(forcetypeassert.New()).
- WithSince("v1.38.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/gostaticanalysis/forcetypeassert"),
-
- linter.NewConfig(fatcontext.New(&cfg.LintersSettings.Fatcontext)).
- WithSince("v1.58.0").
- WithPresets(linter.PresetPerformance).
- WithLoadForGoAnalysis().
- WithAutoFix().
- WithURL("https://github.com/Crocmagnon/fatcontext"),
-
- linter.NewConfig(funlen.New(&cfg.LintersSettings.Funlen)).
- WithSince("v1.18.0").
- WithPresets(linter.PresetComplexity).
- WithURL("https://github.com/ultraware/funlen"),
-
- linter.NewConfig(gci.New(&cfg.LintersSettings.Gci)).
- WithSince("v1.30.0").
- WithPresets(linter.PresetFormatting, linter.PresetImport).
- WithAutoFix().
- WithURL("https://github.com/daixiang0/gci"),
-
- linter.NewConfig(ginkgolinter.New(&cfg.LintersSettings.GinkgoLinter)).
- WithSince("v1.51.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/nunnatsa/ginkgolinter"),
-
- linter.NewConfig(gocheckcompilerdirectives.New()).
- WithSince("v1.51.0").
- WithPresets(linter.PresetBugs).
- WithURL("https://github.com/leighmcculloch/gocheckcompilerdirectives"),
-
- linter.NewConfig(gochecknoglobals.New()).
- WithSince("v1.12.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/leighmcculloch/gochecknoglobals"),
-
- linter.NewConfig(gochecknoinits.New()).
- WithSince("v1.12.0").
- WithPresets(linter.PresetStyle),
-
- linter.NewConfig(gochecksumtype.New(&cfg.LintersSettings.GoChecksumType)).
- WithSince("v1.55.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/alecthomas/go-check-sumtype"),
-
- linter.NewConfig(gocognit.New(&cfg.LintersSettings.Gocognit)).
- WithSince("v1.20.0").
- WithPresets(linter.PresetComplexity).
- WithURL("https://github.com/uudashr/gocognit"),
-
- linter.NewConfig(goconst.New(&cfg.LintersSettings.Goconst)).
- WithSince("v1.0.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/jgautheron/goconst"),
-
- linter.NewConfig(gocritic.New(&cfg.LintersSettings.Gocritic)).
- WithSince("v1.12.0").
- WithPresets(linter.PresetStyle, linter.PresetMetaLinter).
- WithLoadForGoAnalysis().
- WithAutoFix().
- WithURL("https://github.com/go-critic/go-critic"),
-
- linter.NewConfig(gocyclo.New(&cfg.LintersSettings.Gocyclo)).
- WithSince("v1.0.0").
- WithPresets(linter.PresetComplexity).
- WithURL("https://github.com/fzipp/gocyclo"),
-
- linter.NewConfig(godot.New(&cfg.LintersSettings.Godot)).
- WithSince("v1.25.0").
- WithPresets(linter.PresetStyle, linter.PresetComment).
- WithAutoFix().
- WithURL("https://github.com/tetafro/godot"),
-
- linter.NewConfig(godox.New(&cfg.LintersSettings.Godox)).
- WithSince("v1.19.0").
- WithPresets(linter.PresetStyle, linter.PresetComment).
- WithURL("https://github.com/matoous/godox"),
-
- linter.NewConfig(err113.New()).
- WithSince("v1.26.0").
- WithPresets(linter.PresetStyle, linter.PresetError).
- WithLoadForGoAnalysis().
- WithAlternativeNames("goerr113").
- WithAutoFix().
- WithURL("https://github.com/Djarvur/go-err113"),
-
- linter.NewConfig(gofmt.New(&cfg.LintersSettings.Gofmt)).
- WithSince("v1.0.0").
- WithPresets(linter.PresetFormatting).
- WithAutoFix().
- WithURL("https://pkg.go.dev/cmd/gofmt"),
-
- linter.NewConfig(gofumpt.New(&cfg.LintersSettings.Gofumpt)).
- WithSince("v1.28.0").
- WithPresets(linter.PresetFormatting).
- WithAutoFix().
- WithURL("https://github.com/mvdan/gofumpt"),
-
- linter.NewConfig(goheader.New(&cfg.LintersSettings.Goheader, cfg.GetBasePath())).
- WithSince("v1.28.0").
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/denis-tingaikin/go-header"),
-
- linter.NewConfig(goimports.New(&cfg.LintersSettings.Goimports)).
- WithSince("v1.20.0").
- WithPresets(linter.PresetFormatting, linter.PresetImport).
- WithAutoFix().
- WithURL("https://pkg.go.dev/golang.org/x/tools/cmd/goimports"),
-
- linter.NewConfig(linter.NewNoopDeprecated("golint", cfg, linter.DeprecationError)).
- WithSince("v1.0.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/golang/lint").
- DeprecatedError("The repository of the linter has been archived by the owner.", "v1.41.0", "revive"),
-
- linter.NewConfig(mnd.New(&cfg.LintersSettings.Mnd)).
- WithSince("v1.22.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/tommy-muehle/go-mnd"),
-
- linter.NewConfig(linter.NewNoopDeprecated("gomnd", cfg, linter.DeprecationError)).
- WithSince("v1.22.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/tommy-muehle/go-mnd").
- DeprecatedError("The linter has been renamed.", "v1.58.0", "mnd"),
-
- linter.NewConfig(gomoddirectives.New(&cfg.LintersSettings.GoModDirectives)).
- WithSince("v1.39.0").
- WithPresets(linter.PresetStyle, linter.PresetModule).
- WithURL("https://github.com/ldez/gomoddirectives"),
-
- linter.NewConfig(gomodguard.New(&cfg.LintersSettings.Gomodguard)).
- WithSince("v1.25.0").
- WithPresets(linter.PresetStyle, linter.PresetImport, linter.PresetModule).
- WithURL("https://github.com/ryancurrah/gomodguard"),
-
- linter.NewConfig(goprintffuncname.New()).
- WithSince("v1.23.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/golangci/go-printf-func-name"),
-
- linter.NewConfig(gosec.New(&cfg.LintersSettings.Gosec)).
- WithSince("v1.0.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetBugs).
- WithURL("https://github.com/securego/gosec").
- WithAlternativeNames("gas"),
-
- linter.NewConfig(gosimple.New(&cfg.LintersSettings.Gosimple)).
- WithEnabledByDefault().
- WithSince("v1.20.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle).
- WithAlternativeNames(megacheckName).
- WithAutoFix().
- WithURL("https://github.com/dominikh/go-tools/tree/HEAD/simple"),
-
- linter.NewConfig(gosmopolitan.New(&cfg.LintersSettings.Gosmopolitan)).
- WithSince("v1.53.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetBugs).
- WithURL("https://github.com/xen0n/gosmopolitan"),
-
- linter.NewConfig(govet.New(&cfg.LintersSettings.Govet)).
- WithEnabledByDefault().
- WithSince("v1.0.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetBugs, linter.PresetMetaLinter).
- WithAutoFix().
- WithAlternativeNames("vet", "vetshadow").
- WithURL("https://pkg.go.dev/cmd/vet"),
-
- linter.NewConfig(grouper.New(&cfg.LintersSettings.Grouper)).
- WithSince("v1.44.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/leonklingele/grouper"),
-
- linter.NewConfig(linter.NewNoopDeprecated("ifshort", cfg, linter.DeprecationError)).
- WithSince("v1.36.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/esimonov/ifshort").
- DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.48.0", ""),
-
- linter.NewConfig(iface.New(&cfg.LintersSettings.Iface)).
- WithSince("v1.62.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/uudashr/iface"),
-
- linter.NewConfig(importas.New(&cfg.LintersSettings.ImportAs)).
- WithSince("v1.38.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithAutoFix().
- WithURL("https://github.com/julz/importas"),
-
- linter.NewConfig(inamedparam.New(&cfg.LintersSettings.Inamedparam)).
- WithSince("v1.55.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/macabu/inamedparam"),
-
- linter.NewConfig(ineffassign.New()).
- WithEnabledByDefault().
- WithSince("v1.0.0").
- WithPresets(linter.PresetUnused).
- WithURL("https://github.com/gordonklaus/ineffassign"),
-
- linter.NewConfig(interfacebloat.New(&cfg.LintersSettings.InterfaceBloat)).
- WithSince("v1.49.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/sashamelentyev/interfacebloat"),
-
- linter.NewConfig(linter.NewNoopDeprecated("interfacer", cfg, linter.DeprecationError)).
- WithSince("v1.0.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/mvdan/interfacer").
- DeprecatedError("The repository of the linter has been archived by the owner.", "v1.38.0", ""),
-
- linter.NewConfig(intrange.New()).
- WithSince("v1.57.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/ckaznocha/intrange").
- WithNoopFallback(cfg, linter.IsGoLowerThanGo122()),
-
- linter.NewConfig(ireturn.New(&cfg.LintersSettings.Ireturn)).
- WithSince("v1.43.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/butuzov/ireturn"),
-
- linter.NewConfig(lll.New(&cfg.LintersSettings.Lll)).
- WithSince("v1.8.0").
- WithPresets(linter.PresetStyle),
-
- linter.NewConfig(loggercheck.New(&cfg.LintersSettings.LoggerCheck)).
- WithSince("v1.49.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle, linter.PresetBugs).
- WithAlternativeNames("logrlint").
- WithURL("https://github.com/timonwong/loggercheck"),
-
- linter.NewConfig(maintidx.New(&cfg.LintersSettings.MaintIdx)).
- WithSince("v1.44.0").
- WithPresets(linter.PresetComplexity).
- WithURL("https://github.com/yagipy/maintidx"),
-
- linter.NewConfig(makezero.New(&cfg.LintersSettings.Makezero)).
- WithSince("v1.34.0").
- WithPresets(linter.PresetStyle, linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/ashanbrown/makezero"),
-
- linter.NewConfig(linter.NewNoopDeprecated("maligned", cfg, linter.DeprecationError)).
- WithSince("v1.0.0").
- WithPresets(linter.PresetPerformance).
- WithURL("https://github.com/mdempsky/maligned").
- DeprecatedError("The repository of the linter has been archived by the owner.", "v1.38.0", "govet 'fieldalignment'"),
-
- linter.NewConfig(mirror.New()).
- WithSince("v1.53.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithAutoFix().
- WithURL("https://github.com/butuzov/mirror"),
-
- linter.NewConfig(misspell.New(&cfg.LintersSettings.Misspell)).
- WithSince("v1.8.0").
- WithPresets(linter.PresetStyle, linter.PresetComment).
- WithAutoFix().
- WithURL("https://github.com/client9/misspell"),
-
- linter.NewConfig(musttag.New(&cfg.LintersSettings.MustTag)).
- WithSince("v1.51.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle, linter.PresetBugs).
- WithURL("https://github.com/go-simpler/musttag"),
-
- linter.NewConfig(nakedret.New(&cfg.LintersSettings.Nakedret)).
- WithSince("v1.19.0").
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/alexkohler/nakedret"),
-
- linter.NewConfig(nestif.New(&cfg.LintersSettings.Nestif)).
- WithSince("v1.25.0").
- WithPresets(linter.PresetComplexity).
- WithURL("https://github.com/nakabonne/nestif"),
-
- linter.NewConfig(nilerr.New()).
- WithSince("v1.38.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetBugs).
- WithURL("https://github.com/gostaticanalysis/nilerr"),
-
- linter.NewConfig(nilnesserr.New()).
- WithSince("v1.63.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetBugs).
- WithURL("https://github.com/alingse/nilnesserr"),
-
- linter.NewConfig(nilnil.New(&cfg.LintersSettings.NilNil)).
- WithSince("v1.43.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/Antonboom/nilnil"),
-
- linter.NewConfig(nlreturn.New(&cfg.LintersSettings.Nlreturn)).
- WithSince("v1.30.0").
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/ssgreg/nlreturn"),
-
- linter.NewConfig(noctx.New()).
- WithSince("v1.28.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetPerformance, linter.PresetBugs).
- WithURL("https://github.com/sonatard/noctx"),
-
- linter.NewConfig(nonamedreturns.New(&cfg.LintersSettings.NoNamedReturns)).
- WithSince("v1.46.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/firefart/nonamedreturns"),
-
- linter.NewConfig(linter.NewNoopDeprecated("nosnakecase", cfg, linter.DeprecationError)).
- WithSince("v1.47.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/sivchari/nosnakecase").
- DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.48.1", "revive 'var-naming'"),
-
- linter.NewConfig(nosprintfhostport.New()).
- WithSince("v1.46.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/stbenjam/no-sprintf-host-port"),
-
- linter.NewConfig(paralleltest.New(&cfg.LintersSettings.ParallelTest)).
- WithSince("v1.33.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle, linter.PresetTest).
- WithURL("https://github.com/kunwardeep/paralleltest"),
-
- linter.NewConfig(perfsprint.New(&cfg.LintersSettings.PerfSprint)).
- WithSince("v1.55.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetPerformance).
- WithAutoFix().
- WithURL("https://github.com/catenacyber/perfsprint"),
-
- linter.NewConfig(prealloc.New(&cfg.LintersSettings.Prealloc)).
- WithSince("v1.19.0").
- WithPresets(linter.PresetPerformance).
- WithURL("https://github.com/alexkohler/prealloc"),
-
- linter.NewConfig(predeclared.New(&cfg.LintersSettings.Predeclared)).
- WithSince("v1.35.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/nishanths/predeclared"),
-
- linter.NewConfig(promlinter.New(&cfg.LintersSettings.Promlinter)).
- WithSince("v1.40.0").
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/yeya24/promlinter"),
-
- linter.NewConfig(protogetter.New(&cfg.LintersSettings.ProtoGetter)).
- WithSince("v1.55.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithAutoFix().
- WithURL("https://github.com/ghostiam/protogetter"),
-
- linter.NewConfig(reassign.New(&cfg.LintersSettings.Reassign)).
- WithSince("v1.49.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/curioswitch/go-reassign"),
-
- linter.NewConfig(recvcheck.New(&cfg.LintersSettings.Recvcheck)).
- WithSince("v1.62.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/raeperd/recvcheck"),
-
- linter.NewConfig(revive.New(&cfg.LintersSettings.Revive)).
- WithSince("v1.37.0").
- WithPresets(linter.PresetStyle, linter.PresetMetaLinter).
- ConsiderSlow().
- WithAutoFix().
- WithURL("https://github.com/mgechev/revive"),
-
- linter.NewConfig(rowserrcheck.New(&cfg.LintersSettings.RowsErrCheck)).
- WithSince("v1.23.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetBugs, linter.PresetSQL).
- WithURL("https://github.com/jingyugao/rowserrcheck"),
-
- linter.NewConfig(sloglint.New(&cfg.LintersSettings.SlogLint)).
- WithSince("v1.55.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/go-simpler/sloglint"),
-
- linter.NewConfig(linter.NewNoopDeprecated("scopelint", cfg, linter.DeprecationError)).
- WithSince("v1.12.0").
- WithPresets(linter.PresetBugs).
- WithURL("https://github.com/kyoh86/scopelint").
- DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.39.0", "exportloopref"),
-
- linter.NewConfig(sqlclosecheck.New()).
- WithSince("v1.28.0").
- WithPresets(linter.PresetBugs, linter.PresetSQL).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/ryanrolds/sqlclosecheck"),
-
- linter.NewConfig(spancheck.New(&cfg.LintersSettings.Spancheck)).
- WithSince("v1.56.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetBugs).
- WithURL("https://github.com/jjti/go-spancheck"),
-
- linter.NewConfig(staticcheck.New(&cfg.LintersSettings.Staticcheck)).
- WithEnabledByDefault().
- WithSince("v1.0.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetBugs, linter.PresetMetaLinter).
- WithAlternativeNames(megacheckName).
- WithAutoFix().
- WithURL("https://staticcheck.dev/"),
-
- linter.NewConfig(linter.NewNoopDeprecated("structcheck", cfg, linter.DeprecationError)).
- WithSince("v1.0.0").
- WithPresets(linter.PresetUnused).
- WithURL("https://github.com/opennota/check").
- DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
-
- linter.NewConfig(stylecheck.New(&cfg.LintersSettings.Stylecheck)).
- WithSince("v1.20.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/dominikh/go-tools/tree/HEAD/stylecheck"),
-
- linter.NewConfig(tagalign.New(&cfg.LintersSettings.TagAlign)).
- WithSince("v1.53.0").
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/4meepo/tagalign"),
-
- linter.NewConfig(tagliatelle.New(&cfg.LintersSettings.Tagliatelle)).
- WithSince("v1.40.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/ldez/tagliatelle"),
-
- linter.NewConfig(tenv.New(&cfg.LintersSettings.Tenv)).
- WithSince("v1.43.0").
- WithPresets(linter.PresetTest).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/sivchari/tenv").
- DeprecatedWarning("Duplicate feature in another linter.", "v1.64.0", "usetesting"),
-
- linter.NewConfig(testableexamples.New()).
- WithSince("v1.50.0").
- WithPresets(linter.PresetTest).
- WithURL("https://github.com/maratori/testableexamples"),
-
- linter.NewConfig(testifylint.New(&cfg.LintersSettings.Testifylint)).
- WithSince("v1.55.0").
- WithPresets(linter.PresetTest, linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithAutoFix().
- WithURL("https://github.com/Antonboom/testifylint"),
-
- linter.NewConfig(testpackage.New(&cfg.LintersSettings.Testpackage)).
- WithSince("v1.25.0").
- WithPresets(linter.PresetStyle, linter.PresetTest).
- WithURL("https://github.com/maratori/testpackage"),
-
- linter.NewConfig(thelper.New(&cfg.LintersSettings.Thelper)).
- WithSince("v1.34.0").
- WithPresets(linter.PresetTest).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/kulti/thelper"),
-
- linter.NewConfig(tparallel.New()).
- WithSince("v1.32.0").
- WithPresets(linter.PresetStyle, linter.PresetTest).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/moricho/tparallel"),
-
- linter.NewConfig(golinters.NewTypecheck()).
- WithInternal().
- WithEnabledByDefault().
- WithSince("v1.3.0"),
-
- linter.NewConfig(unconvert.New(&cfg.LintersSettings.Unconvert)).
- WithSince("v1.0.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetStyle).
- WithURL("https://github.com/mdempsky/unconvert"),
-
- linter.NewConfig(unparam.New(&cfg.LintersSettings.Unparam)).
- WithSince("v1.9.0").
- WithPresets(linter.PresetUnused).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/mvdan/unparam"),
-
- linter.NewConfig(unused.New(&cfg.LintersSettings.Unused)).
- WithEnabledByDefault().
- WithSince("v1.20.0").
- WithLoadForGoAnalysis().
- WithPresets(linter.PresetUnused).
- WithAlternativeNames(megacheckName).
- ConsiderSlow().
- WithChangeTypes().
- WithURL("https://github.com/dominikh/go-tools/tree/HEAD/unused"),
-
- linter.NewConfig(usestdlibvars.New(&cfg.LintersSettings.UseStdlibVars)).
- WithSince("v1.48.0").
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/sashamelentyev/usestdlibvars"),
-
- linter.NewConfig(usetesting.New(&cfg.LintersSettings.UseTesting)).
- WithSince("v1.63.0").
- WithPresets(linter.PresetTest).
- WithLoadForGoAnalysis().
- WithAutoFix().
- WithURL("https://github.com/ldez/usetesting"),
-
- linter.NewConfig(linter.NewNoopDeprecated("varcheck", cfg, linter.DeprecationError)).
- WithSince("v1.0.0").
- WithPresets(linter.PresetUnused).
- WithURL("https://github.com/opennota/check").
- DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
-
- linter.NewConfig(varnamelen.New(&cfg.LintersSettings.Varnamelen)).
- WithSince("v1.43.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/blizzy78/varnamelen"),
-
- linter.NewConfig(wastedassign.New()).
- WithSince("v1.38.0").
- WithPresets(linter.PresetStyle).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/sanposhiho/wastedassign"),
-
- linter.NewConfig(whitespace.New(&cfg.LintersSettings.Whitespace)).
- WithSince("v1.19.0").
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/ultraware/whitespace"),
-
- linter.NewConfig(wrapcheck.New(&cfg.LintersSettings.Wrapcheck)).
- WithSince("v1.32.0").
- WithPresets(linter.PresetStyle, linter.PresetError).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/tomarrell/wrapcheck"),
-
- linter.NewConfig(wsl.New(&cfg.LintersSettings.WSL)).
- WithSince("v1.20.0").
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/bombsimon/wsl"),
-
- linter.NewConfig(zerologlint.New()).
- WithSince("v1.53.0").
- WithPresets(linter.PresetBugs).
- WithLoadForGoAnalysis().
- WithURL("https://github.com/ykadowak/zerologlint"),
-
- // nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
- linter.NewConfig(nolintlint.New(&cfg.LintersSettings.NoLintLint)).
- WithSince("v1.26.0").
- WithPresets(linter.PresetStyle).
- WithAutoFix().
- WithURL("https://github.com/golangci/golangci-lint/tree/HEAD/pkg/golinters/nolintlint/internal"),
- }, nil
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/githubaction.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/githubaction.go
deleted file mode 100644
index d9cdb1e6..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/githubaction.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package printers
-
-import (
- "fmt"
- "io"
- "path/filepath"
-
- "github.com/golangci/golangci-lint/pkg/result"
-)
-
-const defaultGithubSeverity = "error"
-
-type GitHubAction struct {
- w io.Writer
-}
-
-// NewGitHubAction output format outputs issues according to GitHub Action.
-// Deprecated
-func NewGitHubAction(w io.Writer) *GitHubAction {
- return &GitHubAction{w: w}
-}
-
-func (p *GitHubAction) Print(issues []result.Issue) error {
- for ind := range issues {
- _, err := fmt.Fprintln(p.w, formatIssueAsGitHub(&issues[ind]))
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-// print each line as: ::error file=app.js,line=10,col=15::Something went wrong
-func formatIssueAsGitHub(issue *result.Issue) string {
- severity := defaultGithubSeverity
- if issue.Severity != "" {
- severity = issue.Severity
- }
-
- // Convert backslashes to forward slashes.
- // This is needed when running on windows.
- // Otherwise, GitHub won't be able to show the annotations pointing to the file path with backslashes.
- file := filepath.ToSlash(issue.FilePath())
-
- ret := fmt.Sprintf("::%s file=%s,line=%d", severity, file, issue.Line())
- if issue.Pos.Column != 0 {
- ret += fmt.Sprintf(",col=%d", issue.Pos.Column)
- }
-
- ret += fmt.Sprintf("::%s (%s)", issue.Text, issue.FromLinter)
- return ret
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/printer.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/printer.go
deleted file mode 100644
index 613e4abe..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/printer.go
+++ /dev/null
@@ -1,184 +0,0 @@
-package printers
-
-import (
- "errors"
- "fmt"
- "io"
- "os"
- "path/filepath"
- "slices"
- "strings"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/report"
- "github.com/golangci/golangci-lint/pkg/result"
-)
-
-const defaultFileMode = 0o644
-
-type issuePrinter interface {
- Print(issues []result.Issue) error
-}
-
-// Printer prints issues
-type Printer struct {
- cfg *config.Output
- reportData *report.Data
- basePath string
-
- log logutils.Log
-
- stdOut io.Writer
- stdErr io.Writer
-}
-
-// NewPrinter creates a new Printer.
-func NewPrinter(log logutils.Log, cfg *config.Output, reportData *report.Data, basePath string) (*Printer, error) {
- if log == nil {
- return nil, errors.New("missing log argument in constructor")
- }
- if cfg == nil {
- return nil, errors.New("missing config argument in constructor")
- }
- if reportData == nil {
- return nil, errors.New("missing reportData argument in constructor")
- }
-
- return &Printer{
- cfg: cfg,
- reportData: reportData,
- basePath: basePath,
- log: log,
- stdOut: logutils.StdOut,
- stdErr: logutils.StdErr,
- }, nil
-}
-
-// Print prints issues based on the formats defined
-func (c *Printer) Print(issues []result.Issue) error {
- for _, format := range c.cfg.Formats {
- err := c.printReports(issues, format)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (c *Printer) printReports(issues []result.Issue, format config.OutputFormat) error {
- w, shouldClose, err := c.createWriter(format.Path)
- if err != nil {
- return fmt.Errorf("can't create output for %s: %w", format.Path, err)
- }
-
- defer func() {
- if file, ok := w.(io.Closer); shouldClose && ok {
- _ = file.Close()
- }
- }()
-
- p, err := c.createPrinter(format.Format, w)
- if err != nil {
- return err
- }
-
- if err = p.Print(issues); err != nil {
- return fmt.Errorf("can't print %d issues: %w", len(issues), err)
- }
-
- return nil
-}
-
-func (c *Printer) createWriter(path string) (io.Writer, bool, error) {
- if path == "" || path == "stdout" {
- return c.stdOut, false, nil
- }
-
- if path == "stderr" {
- return c.stdErr, false, nil
- }
-
- if !filepath.IsAbs(path) {
- path = filepath.Join(c.basePath, path)
- }
-
- err := os.MkdirAll(filepath.Dir(path), os.ModePerm)
- if err != nil {
- return nil, false, err
- }
-
- f, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, defaultFileMode)
- if err != nil {
- return nil, false, err
- }
-
- return f, true, nil
-}
-
-func (c *Printer) createPrinter(format string, w io.Writer) (issuePrinter, error) {
- var p issuePrinter
-
- switch format {
- case config.OutFormatJSON:
- p = NewJSON(w, c.reportData)
- case config.OutFormatLineNumber, config.OutFormatColoredLineNumber:
- p = NewText(c.log, w, c.cfg.PrintLinterName, c.cfg.PrintIssuedLine, format == config.OutFormatColoredLineNumber)
- case config.OutFormatTab, config.OutFormatColoredTab:
- p = NewTab(c.log, w, c.cfg.PrintLinterName, format == config.OutFormatColoredTab)
- case config.OutFormatCheckstyle:
- p = NewCheckstyle(c.log, w)
- case config.OutFormatCodeClimate:
- p = NewCodeClimate(c.log, w)
- case config.OutFormatHTML:
- p = NewHTML(w)
- case config.OutFormatJUnitXML, config.OutFormatJUnitXMLExtended:
- p = NewJUnitXML(w, format == config.OutFormatJUnitXMLExtended)
- case config.OutFormatGithubActions:
- p = NewGitHubAction(w)
- case config.OutFormatTeamCity:
- p = NewTeamCity(c.log, w)
- case config.OutFormatSarif:
- p = NewSarif(c.log, w)
- default:
- return nil, fmt.Errorf("unknown output format %q", format)
- }
-
- return p, nil
-}
-
-type severitySanitizer struct {
- allowedSeverities []string
- defaultSeverity string
-
- unsupportedSeverities map[string]struct{}
-}
-
-func (s *severitySanitizer) Sanitize(severity string) string {
- if slices.Contains(s.allowedSeverities, severity) {
- return severity
- }
-
- if s.unsupportedSeverities == nil {
- s.unsupportedSeverities = make(map[string]struct{})
- }
-
- s.unsupportedSeverities[severity] = struct{}{}
-
- return s.defaultSeverity
-}
-
-func (s *severitySanitizer) Err() error {
- if len(s.unsupportedSeverities) == 0 {
- return nil
- }
-
- var names []string
- for k := range s.unsupportedSeverities {
- names = append(names, "'"+k+"'")
- }
-
- return fmt.Errorf("severities (%v) are not inside supported values (%v), fallback to '%s'",
- strings.Join(names, ", "), strings.Join(s.allowedSeverities, ", "), s.defaultSeverity)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_generated_file_filter.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_generated_file_filter.go
deleted file mode 100644
index ce4e2e21..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_generated_file_filter.go
+++ /dev/null
@@ -1,181 +0,0 @@
-package processors
-
-import (
- "fmt"
- "go/parser"
- "go/token"
- "path/filepath"
- "regexp"
- "strings"
-
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
-)
-
-const (
- AutogeneratedModeLax = "lax"
- AutogeneratedModeStrict = "strict"
- AutogeneratedModeDisable = "disable"
-)
-
-// The values must be in lowercase.
-const (
- genCodeGenerated = "code generated"
- genDoNotEdit = "do not edit"
-
- // Related to easyjson.
- genAutoFile = "autogenerated file"
-
- //nolint:lll // Long URL
- // Related to Swagger Codegen.
- // https://github.com/swagger-api/swagger-codegen/blob/61cfeac3b9d855b4eb8bffa0d118bece117bcb7d/modules/swagger-codegen/src/main/resources/go/partial_header.mustache#L16
- // https://github.com/swagger-api/swagger-codegen/issues/12358
- genSwaggerCodegen = "* generated by: swagger codegen "
-)
-
-var _ Processor = (*GeneratedFileFilter)(nil)
-
-type fileSummary struct {
- generated bool
-}
-
-// GeneratedFileFilter filters generated files.
-// - mode "lax": see `isGeneratedFileLax` documentation.
-// - mode "strict": see `isGeneratedFileStrict` documentation.
-// - mode "disable": skips this processor.
-type GeneratedFileFilter struct {
- debugf logutils.DebugFunc
-
- mode string
- strictPattern *regexp.Regexp
-
- fileSummaryCache map[string]*fileSummary
-}
-
-func NewGeneratedFileFilter(mode string) *GeneratedFileFilter {
- return &GeneratedFileFilter{
- debugf: logutils.Debug(logutils.DebugKeyGeneratedFileFilter),
- mode: mode,
- strictPattern: regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`),
- fileSummaryCache: map[string]*fileSummary{},
- }
-}
-
-func (*GeneratedFileFilter) Name() string {
- return "generated_file_filter"
-}
-
-func (p *GeneratedFileFilter) Process(issues []result.Issue) ([]result.Issue, error) {
- if p.mode == AutogeneratedModeDisable {
- return issues, nil
- }
-
- return filterIssuesErr(issues, p.shouldPassIssue)
-}
-
-func (*GeneratedFileFilter) Finish() {}
-
-func (p *GeneratedFileFilter) shouldPassIssue(issue *result.Issue) (bool, error) {
- if filepath.Base(issue.FilePath()) == "go.mod" {
- return true, nil
- }
-
- // The file is already known.
- fs := p.fileSummaryCache[issue.FilePath()]
- if fs != nil {
- return !fs.generated, nil
- }
-
- fs = &fileSummary{}
- p.fileSummaryCache[issue.FilePath()] = fs
-
- if p.mode == AutogeneratedModeStrict {
- var err error
- fs.generated, err = p.isGeneratedFileStrict(issue.FilePath())
- if err != nil {
- return false, fmt.Errorf("failed to get doc (strict) of file %s: %w", issue.FilePath(), err)
- }
- } else {
- doc, err := getComments(issue.FilePath())
- if err != nil {
- return false, fmt.Errorf("failed to get doc (lax) of file %s: %w", issue.FilePath(), err)
- }
-
- fs.generated = p.isGeneratedFileLax(doc)
- }
-
- p.debugf("file %q is generated: %t", issue.FilePath(), fs.generated)
-
- // don't report issues for autogenerated files
- return !fs.generated, nil
-}
-
-// isGeneratedFileLax reports whether the source file is generated code.
-// The function uses a bit laxer rules than isGeneratedFileStrict to match more generated code.
-// See https://github.com/golangci/golangci-lint/issues/48 and https://github.com/golangci/golangci-lint/issues/72.
-func (p *GeneratedFileFilter) isGeneratedFileLax(doc string) bool {
- markers := []string{genCodeGenerated, genDoNotEdit, genAutoFile, genSwaggerCodegen}
-
- doc = strings.ToLower(doc)
-
- for _, marker := range markers {
- if strings.Contains(doc, marker) {
- p.debugf("doc contains marker %q: file is generated", marker)
-
- return true
- }
- }
-
- p.debugf("doc of len %d doesn't contain any of markers: %s", len(doc), markers)
-
- return false
-}
-
-// isGeneratedFileStrict returns true if the source file has a line that matches the regular expression:
-//
-// ^// Code generated .* DO NOT EDIT\.$
-//
-// This line must appear before the first non-comment, non-blank text in the file.
-// Based on https://go.dev/s/generatedcode.
-func (p *GeneratedFileFilter) isGeneratedFileStrict(filePath string) (bool, error) {
- file, err := parser.ParseFile(token.NewFileSet(), filePath, nil, parser.PackageClauseOnly|parser.ParseComments)
- if err != nil {
- return false, fmt.Errorf("failed to parse file: %w", err)
- }
-
- if file == nil || len(file.Comments) == 0 {
- return false, nil
- }
-
- for _, comment := range file.Comments {
- if comment.Pos() > file.Package {
- return false, nil
- }
-
- for _, line := range comment.List {
- generated := p.strictPattern.MatchString(line.Text)
- if generated {
- p.debugf("doc contains ignore expression: file is generated")
-
- return true, nil
- }
- }
- }
-
- return false, nil
-}
-
-func getComments(filePath string) (string, error) {
- fset := token.NewFileSet()
- syntax, err := parser.ParseFile(fset, filePath, nil, parser.PackageClauseOnly|parser.ParseComments)
- if err != nil {
- return "", fmt.Errorf("failed to parse file: %w", err)
- }
-
- var docLines []string
- for _, c := range syntax.Comments {
- docLines = append(docLines, strings.TrimSpace(c.Text()))
- }
-
- return strings.Join(docLines, "\n"), nil
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/identifier_marker.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/identifier_marker.go
deleted file mode 100644
index 9f332705..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/identifier_marker.go
+++ /dev/null
@@ -1,145 +0,0 @@
-package processors
-
-import (
- "regexp"
-
- "github.com/golangci/golangci-lint/pkg/result"
-)
-
-var _ Processor = (*IdentifierMarker)(nil)
-
-type replacePattern struct {
- exp *regexp.Regexp
- repl string
-}
-
-// IdentifierMarker modifies report text.
-// It must be before [Exclude] and [ExcludeRules]:
-// users configure exclusions based on the modified text.
-type IdentifierMarker struct {
- patterns map[string][]replacePattern
-}
-
-func NewIdentifierMarker() *IdentifierMarker {
- return &IdentifierMarker{
- patterns: map[string][]replacePattern{
- "unparam": {
- {
- exp: regexp.MustCompile(`^(\S+) - (\S+) is unused$`),
- repl: "`${1}` - `${2}` is unused",
- },
- {
- exp: regexp.MustCompile(`^(\S+) - (\S+) always receives (\S+) \((.*)\)$`),
- repl: "`${1}` - `${2}` always receives `${3}` (`${4}`)",
- },
- {
- exp: regexp.MustCompile(`^(\S+) - (\S+) always receives (.*)$`),
- repl: "`${1}` - `${2}` always receives `${3}`",
- },
- {
- exp: regexp.MustCompile(`^(\S+) - result (\S+) is always (\S+)`),
- repl: "`${1}` - result `${2}` is always `${3}`",
- },
- },
- "govet": {
- {
- // printf
- exp: regexp.MustCompile(`^printf: (\S+) arg list ends with redundant newline$`),
- repl: "printf: `${1}` arg list ends with redundant newline",
- },
- },
- "gosec": {
- {
- exp: regexp.MustCompile(`^TLS InsecureSkipVerify set true.$`),
- repl: "TLS `InsecureSkipVerify` set true.",
- },
- },
- "gosimple": {
- {
- // s1011
- exp: regexp.MustCompile(`should replace loop with (.*)$`),
- repl: "should replace loop with `${1}`",
- },
- {
- // s1000
- exp: regexp.MustCompile(`should use a simple channel send/receive instead of select with a single case`),
- repl: "should use a simple channel send/receive instead of `select` with a single case",
- },
- {
- // s1002
- exp: regexp.MustCompile(`should omit comparison to bool constant, can be simplified to (.+)$`),
- repl: "should omit comparison to bool constant, can be simplified to `${1}`",
- },
- {
- // s1023
- exp: regexp.MustCompile(`redundant return statement$`),
- repl: "redundant `return` statement",
- },
- {
- // s1017
- exp: regexp.MustCompile(`should replace this if statement with an unconditional strings.TrimPrefix`),
- repl: "should replace this `if` statement with an unconditional `strings.TrimPrefix`",
- },
- },
- "staticcheck": {
- {
- // sa4006
- exp: regexp.MustCompile(`this value of (\S+) is never used$`),
- repl: "this value of `${1}` is never used",
- },
- {
- // s1012
- exp: regexp.MustCompile(`should use time.Since instead of time.Now\(\).Sub$`),
- repl: "should use `time.Since` instead of `time.Now().Sub`",
- },
- {
- // sa5001
- exp: regexp.MustCompile(`should check returned error before deferring response.Close\(\)$`),
- repl: "should check returned error before deferring `response.Close()`",
- },
- {
- // sa4003
- exp: regexp.MustCompile(`no value of type uint is less than 0$`),
- repl: "no value of type `uint` is less than `0`",
- },
- },
- "unused": {
- {
- exp: regexp.MustCompile(`(func|const|field|type|var) (\S+) is unused$`),
- repl: "${1} `${2}` is unused",
- },
- },
- },
- }
-}
-
-func (*IdentifierMarker) Name() string {
- return "identifier_marker"
-}
-
-func (p *IdentifierMarker) Process(issues []result.Issue) ([]result.Issue, error) {
- return transformIssues(issues, func(issue *result.Issue) *result.Issue {
- re, ok := p.patterns[issue.FromLinter]
- if !ok {
- return issue
- }
-
- newIssue := *issue
- newIssue.Text = markIdentifiers(re, newIssue.Text)
-
- return &newIssue
- }), nil
-}
-
-func (*IdentifierMarker) Finish() {}
-
-func markIdentifiers(re []replacePattern, text string) string {
- for _, rr := range re {
- rs := rr.exp.ReplaceAllString(text, rr.repl)
- if rs != text {
- return rs
- }
- }
-
- return text
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_prettifier.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_prettifier.go
deleted file mode 100644
index 6a04b1c3..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_prettifier.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package processors
-
-import (
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
-)
-
-var _ Processor = (*PathPrettifier)(nil)
-
-// PathPrettifier modifies report file path to be relative to the base path.
-// Also handles the `output.path-prefix` option.
-type PathPrettifier struct {
- prefix string
- log logutils.Log
-}
-
-func NewPathPrettifier(log logutils.Log, prefix string) *PathPrettifier {
- return &PathPrettifier{
- prefix: prefix,
- log: log.Child(logutils.DebugKeyPathPrettifier),
- }
-}
-
-func (*PathPrettifier) Name() string {
- return "path_prettifier"
-}
-
-func (p *PathPrettifier) Process(issues []result.Issue) ([]result.Issue, error) {
- return transformIssues(issues, func(issue *result.Issue) *result.Issue {
- newIssue := issue
-
- newIssue.Pos.Filename = fsutils.WithPathPrefix(p.prefix, issue.RelativePath)
-
- return newIssue
- }), nil
-}
-
-func (*PathPrettifier) Finish() {}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_dirs.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_dirs.go
deleted file mode 100644
index 8900c96a..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_dirs.go
+++ /dev/null
@@ -1,180 +0,0 @@
-package processors
-
-import (
- "fmt"
- "path/filepath"
- "regexp"
-
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
-)
-
-var _ Processor = (*SkipDirs)(nil)
-
-var StdExcludeDirRegexps = []string{
- normalizePathRegex("vendor"),
- normalizePathRegex("third_party"),
- normalizePathRegex("testdata"),
- normalizePathRegex("examples"),
- normalizePathRegex("Godeps"),
- normalizePathRegex("builtin"),
-}
-
-type skipStat struct {
- pattern string
- count int
-}
-
-// SkipDirs filters reports based on directory names.
-// It uses the shortest relative paths and `path-prefix` option.
-// TODO(ldez): should be removed in v2.
-type SkipDirs struct {
- patterns []*regexp.Regexp
- pathPrefix string
-
- log logutils.Log
-
- skippedDirs map[string]*skipStat
- absArgsDirs []string
- skippedDirsCache map[string]bool
-}
-
-func NewSkipDirs(log logutils.Log, patterns, args []string, pathPrefix string) (*SkipDirs, error) {
- var patternsRe []*regexp.Regexp
- for _, p := range patterns {
- p = fsutils.NormalizePathInRegex(p)
-
- patternRe, err := regexp.Compile(p)
- if err != nil {
- return nil, fmt.Errorf("can't compile regexp %q: %w", p, err)
- }
-
- patternsRe = append(patternsRe, patternRe)
- }
-
- absArgsDirs, err := absDirs(args)
- if err != nil {
- return nil, err
- }
-
- return &SkipDirs{
- patterns: patternsRe,
- pathPrefix: pathPrefix,
- log: log,
- skippedDirs: map[string]*skipStat{},
- absArgsDirs: absArgsDirs,
- skippedDirsCache: map[string]bool{},
- }, nil
-}
-
-func (*SkipDirs) Name() string {
- return "skip_dirs"
-}
-
-func (p *SkipDirs) Process(issues []result.Issue) ([]result.Issue, error) {
- if len(p.patterns) == 0 {
- return issues, nil
- }
-
- return filterIssues(issues, p.shouldPassIssue), nil
-}
-
-func (p *SkipDirs) Finish() {
- for dir, stat := range p.skippedDirs {
- p.log.Infof("Skipped %d issues from dir %s by pattern %s", stat.count, dir, stat.pattern)
- }
-}
-
-func (p *SkipDirs) shouldPassIssue(issue *result.Issue) bool {
- issueRelDir := filepath.Dir(issue.RelativePath)
-
- if toPass, ok := p.skippedDirsCache[issueRelDir]; ok {
- if !toPass {
- p.skippedDirs[issueRelDir].count++
- }
-
- return toPass
- }
-
- issueAbsDir, err := filepath.Abs(issueRelDir)
- if err != nil {
- p.log.Warnf("Can't abs-ify path %q: %s", issueRelDir, err)
-
- return true
- }
-
- toPass := p.shouldPassIssueDirs(issueRelDir, issueAbsDir)
-
- p.skippedDirsCache[issueRelDir] = toPass
-
- return toPass
-}
-
-func (p *SkipDirs) shouldPassIssueDirs(issueRelDir, issueAbsDir string) bool {
- for _, absArgDir := range p.absArgsDirs {
- if absArgDir == issueAbsDir {
- // we must not skip issues if they are from explicitly set dirs
- // even if they match skip patterns
- return true
- }
- }
-
- // We use issueRelDir for matching: it's the relative to the current
- // work dir path of directory of source file with the issue. It can lead
- // to unexpected behavior if we're analyzing files out of current work dir.
- // The alternative solution is to find relative to args path, but it has
- // disadvantages (https://github.com/golangci/golangci-lint/pull/313).
-
- path := fsutils.WithPathPrefix(p.pathPrefix, issueRelDir)
-
- for _, pattern := range p.patterns {
- if pattern.MatchString(path) {
- ps := pattern.String()
-
- if p.skippedDirs[issueRelDir] == nil {
- p.skippedDirs[issueRelDir] = &skipStat{
- pattern: ps,
- }
- }
-
- p.skippedDirs[issueRelDir].count++
-
- return false
- }
- }
-
- return true
-}
-
-func absDirs(args []string) ([]string, error) {
- if len(args) == 0 {
- args = append(args, "./...")
- }
-
- var absArgsDirs []string
- for _, arg := range args {
- base := filepath.Base(arg)
- if base == "..." || isGoFile(base) {
- arg = filepath.Dir(arg)
- }
-
- absArg, err := filepath.Abs(arg)
- if err != nil {
- return nil, fmt.Errorf("failed to abs-ify arg %q: %w", arg, err)
- }
-
- absArgsDirs = append(absArgsDirs, absArg)
- }
-
- return absArgsDirs, nil
-}
-
-func normalizePathRegex(e string) string {
- return createPathRegex(e, filepath.Separator)
-}
-
-func createPathRegex(e string, sep rune) string {
- escapedSep := regexp.QuoteMeta(string(sep)) // needed for windows sep '\\'
- return fmt.Sprintf(`(^|%[1]s)%[2]s($|%[1]s)`, escapedSep, e)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_files.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_files.go
deleted file mode 100644
index 5907cf67..00000000
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_files.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package processors
-
-import (
- "fmt"
- "regexp"
-
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/result"
-)
-
-var _ Processor = (*SkipFiles)(nil)
-
-// SkipFiles filters reports based on filename.
-//
-// It uses the shortest relative paths and `path-prefix` option.
-// TODO(ldez): should be removed in v2.
-type SkipFiles struct {
- patterns []*regexp.Regexp
- pathPrefix string
-}
-
-func NewSkipFiles(patterns []string, pathPrefix string) (*SkipFiles, error) {
- var patternsRe []*regexp.Regexp
- for _, p := range patterns {
- p = fsutils.NormalizePathInRegex(p)
-
- patternRe, err := regexp.Compile(p)
- if err != nil {
- return nil, fmt.Errorf("can't compile regexp %q: %w", p, err)
- }
-
- patternsRe = append(patternsRe, patternRe)
- }
-
- return &SkipFiles{
- patterns: patternsRe,
- pathPrefix: pathPrefix,
- }, nil
-}
-
-func (*SkipFiles) Name() string {
- return "skip_files"
-}
-
-func (p *SkipFiles) Process(issues []result.Issue) ([]result.Issue, error) {
- if len(p.patterns) == 0 {
- return issues, nil
- }
-
- return filterIssues(issues, p.shouldPassIssue), nil
-}
-
-func (*SkipFiles) Finish() {}
-
-func (p *SkipFiles) shouldPassIssue(issue *result.Issue) bool {
- path := fsutils.WithPathPrefix(p.pathPrefix, issue.RelativePath)
-
- for _, pattern := range p.patterns {
- if pattern.MatchString(path) {
- return false
- }
- }
-
- return true
-}
diff --git a/vendor/github.com/golangci/golangci-lint/LICENSE b/vendor/github.com/golangci/golangci-lint/v2/LICENSE
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/LICENSE
rename to vendor/github.com/golangci/golangci-lint/v2/LICENSE
diff --git a/vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/main.go b/vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/main.go
similarity index 81%
rename from vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/main.go
rename to vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/main.go
index bf235bf1..f7f3091d 100644
--- a/vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/main.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/main.go
@@ -6,8 +6,8 @@ import (
"os"
"runtime/debug"
- "github.com/golangci/golangci-lint/pkg/commands"
- "github.com/golangci/golangci-lint/pkg/exitcodes"
+ "github.com/golangci/golangci-lint/v2/pkg/commands"
+ "github.com/golangci/golangci-lint/v2/pkg/exitcodes"
)
var (
@@ -64,11 +64,10 @@ func createBuildInfo() commands.BuildInfo {
}
}
- revision = cmp.Or(revision, "unknown")
- modified = cmp.Or(modified, "?")
info.Date = cmp.Or(info.Date, "(unknown)")
- info.Commit = fmt.Sprintf("(%s, modified: %s, mod sum: %q)", revision, modified, buildInfo.Main.Sum)
+ info.Commit = fmt.Sprintf("(%s, modified: %s, mod sum: %q)",
+ cmp.Or(revision, "unknown"), cmp.Or(modified, "?"), buildInfo.Main.Sum)
return info
}
diff --git a/vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/plugins.go b/vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/plugins.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/plugins.go
rename to vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/plugins.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/cache/cache.go b/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go
similarity index 97%
rename from vendor/github.com/golangci/golangci-lint/internal/cache/cache.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go
index 41eb5c82..627993d2 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/cache/cache.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go
@@ -14,9 +14,9 @@ import (
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/internal/go/cache"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/timeutils"
+ "github.com/golangci/golangci-lint/v2/internal/go/cache"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/timeutils"
)
type HashMode int
diff --git a/vendor/github.com/golangci/golangci-lint/internal/errorutil/errors.go b/vendor/github.com/golangci/golangci-lint/v2/internal/errorutil/errors.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/errorutil/errors.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/errorutil/errors.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/LICENSE b/vendor/github.com/golangci/golangci-lint/v2/internal/go/LICENSE
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/LICENSE
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/LICENSE
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_notunix.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_notunix.go
new file mode 100644
index 00000000..c7780fa3
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_notunix.go
@@ -0,0 +1,12 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !unix
+
+package base
+
+func IsETXTBSY(err error) bool {
+ // syscall.ETXTBSY is only meaningful on Unix platforms.
+ return false
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_unix.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_unix.go
new file mode 100644
index 00000000..2dcd75e5
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_unix.go
@@ -0,0 +1,16 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix
+
+package base
+
+import (
+ "errors"
+ "syscall"
+)
+
+func IsETXTBSY(err error) bool {
+ return errors.Is(err, syscall.ETXTBSY)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/readme.md
new file mode 100644
index 00000000..93afe9f2
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/readme.md
@@ -0,0 +1,10 @@
+# quoted
+
+Extracted from `go/src/cmd/go/internal/base/` (related to `cache`).
+
+Only the function `IsETXTBSY` is extracted.
+
+## History
+
+- https://github.com/golangci/golangci-lint/pull/5576
+ - sync go1.24.1
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/cache/cache.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/internal/go/cache/cache.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache.go
index 85899ebc..c514613d 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/go/cache/cache.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache.go
@@ -22,9 +22,11 @@ import (
"strings"
"time"
- "github.com/golangci/golangci-lint/internal/go/mmap"
- "github.com/golangci/golangci-lint/internal/go/robustio"
"github.com/rogpeppe/go-internal/lockedfile"
+ "github.com/rogpeppe/go-internal/robustio"
+
+ "github.com/golangci/golangci-lint/v2/internal/go/base"
+ "github.com/golangci/golangci-lint/v2/internal/go/mmap"
)
// An ActionID is a cache action key, the hash of a complete description of a
@@ -40,8 +42,8 @@ type Cache interface {
// Get returns the cache entry for the provided ActionID.
// On miss, the error type should be of type *entryNotFoundError.
//
- // After a success call to Get, OutputFile(Entry.OutputID) must
- // exist on disk for until Close is called (at the end of the process).
+ // After a successful call to Get, OutputFile(Entry.OutputID) must
+ // exist on disk until Close is called (at the end of the process).
Get(ActionID) (Entry, error)
// Put adds an item to the cache.
@@ -52,14 +54,14 @@ type Cache interface {
// As a special case, if the ReadSeeker is of type noVerifyReadSeeker,
// the verification from GODEBUG=goverifycache=1 is skipped.
//
- // After a success call to Get, OutputFile(Entry.OutputID) must
- // exist on disk for until Close is called (at the end of the process).
+ // After a successful call to Put, OutputFile(OutputID) must
+ // exist on disk until Close is called (at the end of the process).
Put(ActionID, io.ReadSeeker) (_ OutputID, size int64, _ error)
// Close is called at the end of the go process. Implementations can do
// cache cleanup work at this phase, or wait for and report any errors from
- // background cleanup work started earlier. Any cache trimming should in one
- // process should not violate cause the invariants of this interface to be
+ // background cleanup work started earlier. Any cache trimming in one
+ // process should not cause the invariants of this interface to be
// violated in another process. Namely, a cache trim from one process should
// not delete an ObjectID from disk that was recently Get or Put from
// another process. As a rule of thumb, don't trim things used in the last
@@ -104,7 +106,7 @@ func Open(dir string) (*DiskCache, error) {
}
for i := 0; i < 256; i++ {
name := filepath.Join(dir, fmt.Sprintf("%02x", i))
- if err := os.MkdirAll(name, 0744); err != nil {
+ if err := os.MkdirAll(name, 0o777); err != nil {
return nil, err
}
}
@@ -160,13 +162,13 @@ var errVerifyMode = errors.New("gocacheverify=1")
var DebugTest = false
// func init() { initEnv() }
-
+//
// var (
// gocacheverify = godebug.New("gocacheverify")
// gocachehash = godebug.New("gocachehash")
// gocachetest = godebug.New("gocachetest")
// )
-
+//
// func initEnv() {
// if gocacheverify.Value() == "1" {
// gocacheverify.IncNonDefault()
@@ -257,10 +259,7 @@ func (c *DiskCache) get(id ActionID) (Entry, error) {
return missing(errors.New("negative timestamp"))
}
- err = c.used(c.fileName(id, "a"))
- if err != nil {
- return Entry{}, fmt.Errorf("failed to mark %s as used: %w", c.fileName(id, "a"), err)
- }
+ c.markUsed(c.fileName(id, "a"))
return Entry{buf, size, time.Unix(0, tm)}, nil
}
@@ -304,25 +303,35 @@ func GetBytes(c Cache, id ActionID) ([]byte, Entry, error) {
// GetMmap looks up the action ID in the cache and returns
// the corresponding output bytes.
// GetMmap should only be used for data that can be expected to fit in memory.
-func GetMmap(c Cache, id ActionID) ([]byte, Entry, error) {
+func GetMmap(c Cache, id ActionID) ([]byte, Entry, bool, error) {
entry, err := c.Get(id)
if err != nil {
- return nil, entry, err
+ return nil, entry, false, err
}
- md, err := mmap.Mmap(c.OutputFile(entry.OutputID))
+ md, opened, err := mmap.Mmap(c.OutputFile(entry.OutputID))
if err != nil {
- return nil, Entry{}, err
+ return nil, Entry{}, opened, err
}
if int64(len(md.Data)) != entry.Size {
- return nil, Entry{}, &entryNotFoundError{Err: errors.New("file incomplete")}
+ return nil, Entry{}, true, &entryNotFoundError{Err: errors.New("file incomplete")}
}
- return md.Data, entry, nil
+ return md.Data, entry, true, nil
}
// OutputFile returns the name of the cache file storing output with the given OutputID.
func (c *DiskCache) OutputFile(out OutputID) string {
file := c.fileName(out, "d")
- c.used(file)
+ isDir := c.markUsed(file)
+ if isDir { // => cached executable
+ entries, err := os.ReadDir(file)
+ if err != nil {
+ return fmt.Sprintf("DO NOT USE - missing binary cache entry: %v", err)
+ }
+ if len(entries) != 1 {
+ return "DO NOT USE - invalid binary cache entry"
+ }
+ return filepath.Join(file, entries[0].Name())
+ }
return file
}
@@ -344,7 +353,7 @@ const (
trimLimit = 5 * 24 * time.Hour
)
-// used makes a best-effort attempt to update mtime on file,
+// markUsed makes a best-effort attempt to update mtime on file,
// so that mtime reflects cache access time.
//
// Because the reflection only needs to be approximate,
@@ -353,25 +362,17 @@ const (
// mtime is more than an hour old. This heuristic eliminates
// nearly all of the mtime updates that would otherwise happen,
// while still keeping the mtimes useful for cache trimming.
-func (c *DiskCache) used(file string) error {
+//
+// markUsed reports whether the file is a directory (an executable cache entry).
+func (c *DiskCache) markUsed(file string) (isDir bool) {
info, err := os.Stat(file)
- if err == nil && c.now().Sub(info.ModTime()) < mtimeInterval {
- return nil
- }
-
if err != nil {
- if os.IsNotExist(err) {
- return &entryNotFoundError{Err: err}
- }
- return &entryNotFoundError{Err: fmt.Errorf("failed to stat file %s: %w", file, err)}
+ return false
}
-
- err = os.Chtimes(file, c.now(), c.now())
- if err != nil {
- return fmt.Errorf("failed to change time of file %s: %w", file, err)
+ if now := c.now(); now.Sub(info.ModTime()) >= mtimeInterval {
+ os.Chtimes(file, now, now)
}
-
- return nil
+ return info.IsDir()
}
func (c *DiskCache) Close() error { return c.Trim() }
@@ -409,7 +410,7 @@ func (c *DiskCache) Trim() error {
// cache will appear older than it is, and we'll trim it again next time.
var b bytes.Buffer
fmt.Fprintf(&b, "%d", now.Unix())
- if err := lockedfile.Write(filepath.Join(c.dir, "trim.txt"), &b, 0666); err != nil {
+ if err := lockedfile.Write(filepath.Join(c.dir, "trim.txt"), &b, 0o666); err != nil {
return err
}
@@ -438,6 +439,10 @@ func (c *DiskCache) trimSubdir(subdir string, cutoff time.Time) {
entry := filepath.Join(subdir, name)
info, err := os.Stat(entry)
if err == nil && info.ModTime().Before(cutoff) {
+ if info.IsDir() { // executable cache entry
+ os.RemoveAll(entry)
+ continue
+ }
os.Remove(entry)
}
}
@@ -470,7 +475,7 @@ func (c *DiskCache) putIndexEntry(id ActionID, out OutputID, size int64, allowVe
// Copy file to cache directory.
mode := os.O_WRONLY | os.O_CREATE
- f, err := os.OpenFile(file, mode, 0666)
+ f, err := os.OpenFile(file, mode, 0o666)
if err != nil {
return err
}
@@ -516,7 +521,21 @@ func (c *DiskCache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error
if isNoVerify {
file = wrapper.ReadSeeker
}
- return c.put(id, file, !isNoVerify)
+ return c.put(id, "", file, !isNoVerify)
+}
+
+// PutExecutable is used to store the output as the output for the action ID into a
+// file with the given base name, with the executable mode bit set.
+// It may read file twice. The content of file must not change between the two passes.
+func (c *DiskCache) PutExecutable(id ActionID, name string, file io.ReadSeeker) (OutputID, int64, error) {
+ if name == "" {
+ panic("PutExecutable called without a name")
+ }
+ wrapper, isNoVerify := file.(noVerifyReadSeeker)
+ if isNoVerify {
+ file = wrapper.ReadSeeker
+ }
+ return c.put(id, name, file, !isNoVerify)
}
// PutNoVerify is like Put but disables the verify check
@@ -527,7 +546,7 @@ func PutNoVerify(c Cache, id ActionID, file io.ReadSeeker) (OutputID, int64, err
return c.Put(id, noVerifyReadSeeker{file})
}
-func (c *DiskCache) put(id ActionID, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) {
+func (c *DiskCache) put(id ActionID, executableName string, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) {
// Compute output ID.
h := sha256.New()
if _, err := file.Seek(0, 0); err != nil {
@@ -541,7 +560,11 @@ func (c *DiskCache) put(id ActionID, file io.ReadSeeker, allowVerify bool) (Outp
h.Sum(out[:0])
// Copy to cached output file (if not already present).
- if err := c.copyFile(file, out, size); err != nil {
+ fileMode := fs.FileMode(0o666)
+ if executableName != "" {
+ fileMode = 0o777
+ }
+ if err := c.copyFile(file, executableName, out, size, fileMode); err != nil {
return out, size, err
}
@@ -557,9 +580,33 @@ func PutBytes(c Cache, id ActionID, data []byte) error {
// copyFile copies file into the cache, expecting it to have the given
// output ID and size, if that file is not present already.
-func (c *DiskCache) copyFile(file io.ReadSeeker, out OutputID, size int64) error {
- name := c.fileName(out, "d")
+func (c *DiskCache) copyFile(file io.ReadSeeker, executableName string, out OutputID, size int64, perm os.FileMode) error {
+ name := c.fileName(out, "d") // TODO(matloob): use a different suffix for the executable cache?
info, err := os.Stat(name)
+ if executableName != "" {
+ // This is an executable file. The file at name won't hold the output itself, but will
+ // be a directory that holds the output, named according to executableName. Check to see
+ // if the directory already exists, and if it does not, create it. Then reset name
+ // to the name we want the output written to.
+ if err != nil {
+ if !os.IsNotExist(err) {
+ return err
+ }
+ if err := os.Mkdir(name, 0o777); err != nil {
+ return err
+ }
+ if info, err = os.Stat(name); err != nil {
+ return err
+ }
+ }
+ if !info.IsDir() {
+ return errors.New("internal error: invalid binary cache entry: not a directory")
+ }
+
+ // directory exists. now set name to the inner file
+ name = filepath.Join(name, executableName)
+ info, err = os.Stat(name)
+ }
if err == nil && info.Size() == size {
// Check hash.
if f, err := os.Open(name); err == nil {
@@ -584,8 +631,14 @@ func (c *DiskCache) copyFile(file io.ReadSeeker, out OutputID, size int64) error
if err == nil && info.Size() > size { // shouldn't happen but fix in case
mode |= os.O_TRUNC
}
- f, err := os.OpenFile(name, mode, 0666)
+ f, err := os.OpenFile(name, mode, perm)
if err != nil {
+ if base.IsETXTBSY(err) {
+ // This file is being used by an executable. It must have
+ // already been written by another go process and then run.
+ // return without an error.
+ return nil
+ }
return err
}
defer f.Close()
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/cache/cache_gcil.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache_gcil.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/cache/cache_gcil.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache_gcil.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/cache/default.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default.go
similarity index 80%
rename from vendor/github.com/golangci/golangci-lint/internal/go/cache/default.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default.go
index 7232f1ef..cf38ab3d 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/go/cache/default.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default.go
@@ -15,14 +15,10 @@ import (
// Default returns the default cache to use.
// It never returns nil.
func Default() Cache {
- defaultOnce.Do(initDefaultCache)
- return defaultCache
+ return initDefaultCacheOnce()
}
-var (
- defaultOnce sync.Once
- defaultCache Cache
-)
+var initDefaultCacheOnce = sync.OnceValue(initDefaultCache)
// cacheREADME is a message stored in a README in the cache directory.
// Because the cache lives outside the normal Go trees, we leave the
@@ -32,22 +28,20 @@ const cacheREADME = `This directory holds cached build artifacts from golangci-l
// initDefaultCache does the work of finding the default cache
// the first time Default is called.
-func initDefaultCache() {
+func initDefaultCache() Cache {
dir, _ := DefaultDir()
if dir == "off" {
if defaultDirErr != nil {
base.Fatalf("build cache is required, but could not be located: %v", defaultDirErr)
}
- base.Fatalf("build cache is disabled by %s=off, but required", envGolangciLintCache)
+ base.Fatalf("build cache is disabled by %s=off, but required as of Go 1.12", envGolangciLintCache)
}
- if err := os.MkdirAll(dir, 0744); err != nil {
+ if err := os.MkdirAll(dir, 0o777); err != nil {
base.Fatalf("failed to initialize build cache at %s: %s\n", dir, err)
}
if _, err := os.Stat(filepath.Join(dir, "README")); err != nil {
// Best effort.
- if wErr := os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666); wErr != nil {
- base.Fatalf("Failed to write README file to cache dir %s: %s", dir, err)
- }
+ os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666)
}
diskCache, err := Open(dir)
@@ -56,10 +50,10 @@ func initDefaultCache() {
}
if v := os.Getenv(envGolangciLintCacheProg); v != "" {
- defaultCache = startCacheProg(v, diskCache)
- } else {
- defaultCache = diskCache
+ return startCacheProg(v, diskCache)
}
+
+ return diskCache
}
var (
@@ -74,7 +68,7 @@ var (
// and reports whether the effective value differs from GOLANGCI_LINT_CACHE.
func DefaultDir() (string, bool) {
// Save the result of the first call to DefaultDir for later use in
- // initDefaultCache. cmd/go/main.go explicitly sets GOCACHE so that
+ // initDefaultCache. cmd/go/main.go explicitly sets GOLANGCI_LINT_CACHE so that
// subprocesses will inherit it, but that means initDefaultCache can't
// otherwise distinguish between an explicit "off" and a UserCacheDir error.
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/cache/default_gcil.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default_gcil.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/cache/default_gcil.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default_gcil.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/cache/hash.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash.go
similarity index 99%
rename from vendor/github.com/golangci/golangci-lint/internal/go/cache/hash.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash.go
index d5169dd4..6a53dd88 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/go/cache/hash.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash.go
@@ -50,7 +50,7 @@ func stripExperiment(version string) string {
// action ID with a string description of the subkey.
func Subkey(parent ActionID, desc string) (ActionID, error) {
h := sha256.New()
- h.Write([]byte(("subkey:")))
+ h.Write([]byte("subkey:"))
n, err := h.Write(parent[:])
if n != len(parent) {
return ActionID{}, fmt.Errorf("wrote %d/%d bytes of parent with error %s", n, len(parent), err)
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/cache/hash_gcil.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash_gcil.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/cache/hash_gcil.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash_gcil.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/cache/prog.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/prog.go
similarity index 66%
rename from vendor/github.com/golangci/golangci-lint/internal/go/cache/prog.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/prog.go
index a93740a3..dc44e138 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/go/cache/prog.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/prog.go
@@ -21,7 +21,8 @@ import (
"sync/atomic"
"time"
- "github.com/golangci/golangci-lint/internal/go/quoted"
+ "github.com/golangci/golangci-lint/v2/internal/go/cacheprog"
+ "github.com/golangci/golangci-lint/v2/internal/go/quoted"
)
// ProgCache implements Cache via JSON messages over stdin/stdout to a child
@@ -38,7 +39,7 @@ type ProgCache struct {
// can are the commands that the child process declared that it supports.
// This is effectively the versioning mechanism.
- can map[ProgCmd]bool
+ can map[cacheprog.Cmd]bool
// fuzzDirCache is another Cache implementation to use for the FuzzDir
// method. In practice this is the default GOCACHE disk-based
@@ -55,7 +56,7 @@ type ProgCache struct {
mu sync.Mutex // guards following fields
nextID int64
- inFlight map[int64]chan<- *ProgResponse
+ inFlight map[int64]chan<- *cacheprog.Response
outputFile map[OutputID]string // object => abs path on disk
// writeMu serializes writing to the child process.
@@ -63,84 +64,6 @@ type ProgCache struct {
writeMu sync.Mutex
}
-// ProgCmd is a command that can be issued to a child process.
-//
-// If the interface needs to grow, we can add new commands or new versioned
-// commands like "get2".
-type ProgCmd string
-
-const (
- cmdGet = ProgCmd("get")
- cmdPut = ProgCmd("put")
- cmdClose = ProgCmd("close")
-)
-
-// ProgRequest is the JSON-encoded message that's sent from cmd/go to
-// the GOLANGCI_LINT_CACHEPROG child process over stdin. Each JSON object is on its
-// own line. A ProgRequest of Type "put" with BodySize > 0 will be followed
-// by a line containing a base64-encoded JSON string literal of the body.
-type ProgRequest struct {
- // ID is a unique number per process across all requests.
- // It must be echoed in the ProgResponse from the child.
- ID int64
-
- // Command is the type of request.
- // The cmd/go tool will only send commands that were declared
- // as supported by the child.
- Command ProgCmd
-
- // ActionID is non-nil for get and puts.
- ActionID []byte `json:",omitempty"` // or nil if not used
-
- // ObjectID is set for Type "put" and "output-file".
- ObjectID []byte `json:",omitempty"` // or nil if not used
-
- // Body is the body for "put" requests. It's sent after the JSON object
- // as a base64-encoded JSON string when BodySize is non-zero.
- // It's sent as a separate JSON value instead of being a struct field
- // send in this JSON object so large values can be streamed in both directions.
- // The base64 string body of a ProgRequest will always be written
- // immediately after the JSON object and a newline.
- Body io.Reader `json:"-"`
-
- // BodySize is the number of bytes of Body. If zero, the body isn't written.
- BodySize int64 `json:",omitempty"`
-}
-
-// ProgResponse is the JSON response from the child process to cmd/go.
-//
-// With the exception of the first protocol message that the child writes to its
-// stdout with ID==0 and KnownCommands populated, these are only sent in
-// response to a ProgRequest from cmd/go.
-//
-// ProgResponses can be sent in any order. The ID must match the request they're
-// replying to.
-type ProgResponse struct {
- ID int64 // that corresponds to ProgRequest; they can be answered out of order
- Err string `json:",omitempty"` // if non-empty, the error
-
- // KnownCommands is included in the first message that cache helper program
- // writes to stdout on startup (with ID==0). It includes the
- // ProgRequest.Command types that are supported by the program.
- //
- // This lets us extend the protocol gracefully over time (adding "get2",
- // etc), or fail gracefully when needed. It also lets us verify the program
- // wants to be a cache helper.
- KnownCommands []ProgCmd `json:",omitempty"`
-
- // For Get requests.
-
- Miss bool `json:",omitempty"` // cache miss
- OutputID []byte `json:",omitempty"`
- Size int64 `json:",omitempty"` // in bytes
- Time *time.Time `json:",omitempty"` // an Entry.Time; when the object was added to the docs
-
- // DiskPath is the absolute path on disk of the ObjectID corresponding
- // a "get" request's ActionID (on cache hit) or a "put" request's
- // provided ObjectID.
- DiskPath string `json:",omitempty"`
-}
-
// startCacheProg starts the prog binary (with optional space-separated flags)
// and returns a Cache implementation that talks to it.
//
@@ -165,13 +88,15 @@ func startCacheProg(progAndArgs string, fuzzDirCache Cache) Cache {
cmd := exec.CommandContext(ctx, prog, args...)
out, err := cmd.StdoutPipe()
if err != nil {
- base.Fatalf("StdoutPipe to %s: %v", envGolangciLintCacheProg, err)
+ base.Fatalf("StdoutPipe to %s: envGolangciLintCacheProg, %v", envGolangciLintCacheProg, err)
}
in, err := cmd.StdinPipe()
if err != nil {
- base.Fatalf("StdinPipe to %s: %v", envGolangciLintCacheProg, err)
+ base.Fatalf("StdinPipe to %s: envGolangciLintCacheProg, %v", envGolangciLintCacheProg, err)
}
cmd.Stderr = os.Stderr
+ // On close, we cancel the context. Rather than killing the helper,
+ // close its stdin.
cmd.Cancel = in.Close
if err := cmd.Start(); err != nil {
@@ -186,14 +111,14 @@ func startCacheProg(progAndArgs string, fuzzDirCache Cache) Cache {
stdout: out,
stdin: in,
bw: bufio.NewWriter(in),
- inFlight: make(map[int64]chan<- *ProgResponse),
+ inFlight: make(map[int64]chan<- *cacheprog.Response),
outputFile: make(map[OutputID]string),
readLoopDone: make(chan struct{}),
}
// Register our interest in the initial protocol message from the child to
// us, saying what it can do.
- capResc := make(chan *ProgResponse, 1)
+ capResc := make(chan *cacheprog.Response, 1)
pc.inFlight[0] = capResc
pc.jenc = json.NewEncoder(pc.bw)
@@ -208,7 +133,7 @@ func startCacheProg(progAndArgs string, fuzzDirCache Cache) Cache {
case <-timer.C:
log.Printf("# still waiting for %s %v ...", envGolangciLintCacheProg, prog)
case capRes := <-capResc:
- can := map[ProgCmd]bool{}
+ can := map[cacheprog.Cmd]bool{}
for _, cmd := range capRes.KnownCommands {
can[cmd] = true
}
@@ -225,9 +150,15 @@ func (c *ProgCache) readLoop(readLoopDone chan<- struct{}) {
defer close(readLoopDone)
jd := json.NewDecoder(c.stdout)
for {
- res := new(ProgResponse)
+ res := new(cacheprog.Response)
if err := jd.Decode(res); err != nil {
if c.closing.Load() {
+ c.mu.Lock()
+ for _, ch := range c.inFlight {
+ close(ch)
+ }
+ c.inFlight = nil
+ c.mu.Unlock()
return // quietly
}
if err == io.EOF {
@@ -250,13 +181,18 @@ func (c *ProgCache) readLoop(readLoopDone chan<- struct{}) {
}
}
-func (c *ProgCache) send(ctx context.Context, req *ProgRequest) (*ProgResponse, error) {
- resc := make(chan *ProgResponse, 1)
+var errCacheprogClosed = fmt.Errorf("%s program closed unexpectedly", envGolangciLintCacheProg)
+
+func (c *ProgCache) send(ctx context.Context, req *cacheprog.Request) (*cacheprog.Response, error) {
+ resc := make(chan *cacheprog.Response, 1)
if err := c.writeToChild(req, resc); err != nil {
return nil, err
}
select {
case res := <-resc:
+ if res == nil {
+ return nil, errCacheprogClosed
+ }
if res.Err != "" {
return nil, errors.New(res.Err)
}
@@ -266,8 +202,11 @@ func (c *ProgCache) send(ctx context.Context, req *ProgRequest) (*ProgResponse,
}
}
-func (c *ProgCache) writeToChild(req *ProgRequest, resc chan<- *ProgResponse) (err error) {
+func (c *ProgCache) writeToChild(req *cacheprog.Request, resc chan<- *cacheprog.Response) (err error) {
c.mu.Lock()
+ if c.inFlight == nil {
+ return errCacheprogClosed
+ }
c.nextID++
req.ID = c.nextID
c.inFlight[req.ID] = resc
@@ -276,7 +215,9 @@ func (c *ProgCache) writeToChild(req *ProgRequest, resc chan<- *ProgResponse) (e
defer func() {
if err != nil {
c.mu.Lock()
- delete(c.inFlight, req.ID)
+ if c.inFlight != nil {
+ delete(c.inFlight, req.ID)
+ }
c.mu.Unlock()
}
}()
@@ -303,8 +244,8 @@ func (c *ProgCache) writeToChild(req *ProgRequest, resc chan<- *ProgResponse) (e
return nil
}
if wrote != req.BodySize {
- return fmt.Errorf("short write writing body to %s for action %x, object %x: wrote %v; expected %v",
- envGolangciLintCacheProg, req.ActionID, req.ObjectID, wrote, req.BodySize)
+ return fmt.Errorf("short write writing body to %s for action %x, output %x: wrote %v; expected %v",
+ envGolangciLintCacheProg, req.ActionID, req.OutputID, wrote, req.BodySize)
}
if _, err := c.bw.WriteString("\"\n"); err != nil {
return err
@@ -317,7 +258,7 @@ func (c *ProgCache) writeToChild(req *ProgRequest, resc chan<- *ProgResponse) (e
}
func (c *ProgCache) Get(a ActionID) (Entry, error) {
- if !c.can[cmdGet] {
+ if !c.can[cacheprog.CmdGet] {
// They can't do a "get". Maybe they're a write-only cache.
//
// TODO(bradfitz,bcmills): figure out the proper error type here. Maybe
@@ -327,8 +268,8 @@ func (c *ProgCache) Get(a ActionID) (Entry, error) {
// error types on the Cache interface.
return Entry{}, &entryNotFoundError{}
}
- res, err := c.send(c.ctx, &ProgRequest{
- Command: cmdGet,
+ res, err := c.send(c.ctx, &cacheprog.Request{
+ Command: cacheprog.CmdGet,
ActionID: a[:],
})
if err != nil {
@@ -384,15 +325,15 @@ func (c *ProgCache) Put(a ActionID, file io.ReadSeeker) (_ OutputID, size int64,
return OutputID{}, 0, err
}
- if !c.can[cmdPut] {
+ if !c.can[cacheprog.CmdPut] {
// Child is a read-only cache. Do nothing.
return out, size, nil
}
- res, err := c.send(c.ctx, &ProgRequest{
- Command: cmdPut,
+ res, err := c.send(c.ctx, &cacheprog.Request{
+ Command: cacheprog.CmdPut,
ActionID: a[:],
- ObjectID: out[:],
+ OutputID: out[:],
Body: file,
BodySize: size,
})
@@ -413,10 +354,16 @@ func (c *ProgCache) Close() error {
// First write a "close" message to the child so it can exit nicely
// and clean up if it wants. Only after that exchange do we cancel
// the context that kills the process.
- if c.can[cmdClose] {
- _, err = c.send(c.ctx, &ProgRequest{Command: cmdClose})
+ if c.can[cacheprog.CmdClose] {
+ _, err = c.send(c.ctx, &cacheprog.Request{Command: cacheprog.CmdClose})
+ if errors.Is(err, errCacheprogClosed) {
+ // Allow the child to quit without responding to close.
+ err = nil
+ }
}
+ // Cancel the context, which will close the helper's stdin.
c.ctxCancel()
+ // Wait until the helper closes its stdout.
<-c.readLoopDone
return err
}
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/cache/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/readme.md
similarity index 97%
rename from vendor/github.com/golangci/golangci-lint/internal/go/cache/readme.md
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/readme.md
index 5be600e4..66341fd4 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/go/cache/readme.md
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/readme.md
@@ -12,6 +12,8 @@ The main modifications are:
## History
+- https://github.com/golangci/golangci-lint/pull/5576
+ - sync go1.24.1
- https://github.com/golangci/golangci-lint/pull/5100
- Move package from `internal/cache` to `internal/go/cache`
- https://github.com/golangci/golangci-lint/pull/5098
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/cacheprog.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/cacheprog.go
new file mode 100644
index 00000000..a2796592
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/cacheprog.go
@@ -0,0 +1,137 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cacheprog defines the protocol for a GOCACHEPROG program.
+//
+// By default, the go command manages a build cache stored in the file system
+// itself. GOCACHEPROG can be set to the name of a command (with optional
+// space-separated flags) that implements the go command build cache externally.
+// This permits defining a different cache policy.
+//
+// The go command will start the GOCACHEPROG as a subprocess and communicate
+// with it via JSON messages over stdin/stdout. The subprocess's stderr will be
+// connected to the go command's stderr.
+//
+// The subprocess should immediately send a [Response] with its capabilities.
+// After that, the go command will send a stream of [Request] messages and the
+// subprocess should reply to each [Request] with a [Response] message.
+package cacheprog
+
+import (
+ "io"
+ "time"
+)
+
+// Cmd is a command that can be issued to a child process.
+//
+// If the interface needs to grow, the go command can add new commands or new
+// versioned commands like "get2" in the future. The initial [Response] from
+// the child process indicates which commands it supports.
+type Cmd string
+
+const (
+ // CmdPut tells the cache program to store an object in the cache.
+ //
+ // [Request.ActionID] is the cache key of this object. The cache should
+ // store [Request.OutputID] and [Request.Body] under this key for a
+ // later "get" request. It must also store the Body in a file in the local
+ // file system and return the path to that file in [Response.DiskPath],
+ // which must exist at least until a "close" request.
+ CmdPut = Cmd("put")
+
+ // CmdGet tells the cache program to retrieve an object from the cache.
+ //
+ // [Request.ActionID] specifies the key of the object to get. If the
+ // cache does not contain this object, it should set [Response.Miss] to
+ // true. Otherwise, it should populate the fields of [Response],
+ // including setting [Response.OutputID] to the OutputID of the original
+ // "put" request and [Response.DiskPath] to the path of a local file
+ // containing the Body of the original "put" request. That file must
+ // continue to exist at least until a "close" request.
+ CmdGet = Cmd("get")
+
+ // CmdClose requests that the cache program exit gracefully.
+ //
+ // The cache program should reply to this request and then exit
+ // (thus closing its stdout).
+ CmdClose = Cmd("close")
+)
+
+// Request is the JSON-encoded message that's sent from the go command to
+// the GOCACHEPROG child process over stdin. Each JSON object is on its own
+// line. A ProgRequest of Type "put" with BodySize > 0 will be followed by a
+// line containing a base64-encoded JSON string literal of the body.
+type Request struct {
+ // ID is a unique number per process across all requests.
+ // It must be echoed in the Response from the child.
+ ID int64
+
+ // Command is the type of request.
+ // The go command will only send commands that were declared
+ // as supported by the child.
+ Command Cmd
+
+ // ActionID is the cache key for "put" and "get" requests.
+ ActionID []byte `json:",omitempty"` // or nil if not used
+
+ // OutputID is stored with the body for "put" requests.
+ //
+ // Prior to Go 1.24, when GOCACHEPROG was still an experiment, this was
+ // accidentally named ObjectID. It was renamed to OutputID in Go 1.24.
+ OutputID []byte `json:",omitempty"` // or nil if not used
+
+ // Body is the body for "put" requests. It's sent after the JSON object
+ // as a base64-encoded JSON string when BodySize is non-zero.
+ // It's sent as a separate JSON value instead of being a struct field
+ // send in this JSON object so large values can be streamed in both directions.
+ // The base64 string body of a Request will always be written
+ // immediately after the JSON object and a newline.
+ Body io.Reader `json:"-"`
+
+ // BodySize is the number of bytes of Body. If zero, the body isn't written.
+ BodySize int64 `json:",omitempty"`
+
+ // ObjectID is the accidental spelling of OutputID that was used prior to Go
+ // 1.24.
+ //
+ // Deprecated: use OutputID. This field is only populated temporarily for
+ // backwards compatibility with Go 1.23 and earlier when
+ // GOEXPERIMENT=gocacheprog is set. It will be removed in Go 1.25.
+ ObjectID []byte `json:",omitempty"`
+}
+
+// Response is the JSON response from the child process to the go command.
+//
+// With the exception of the first protocol message that the child writes to its
+// stdout with ID==0 and KnownCommands populated, these are only sent in
+// response to a Request from the go command.
+//
+// Responses can be sent in any order. The ID must match the request they're
+// replying to.
+type Response struct {
+ ID int64 // that corresponds to Request; they can be answered out of order
+ Err string `json:",omitempty"` // if non-empty, the error
+
+ // KnownCommands is included in the first message that cache helper program
+ // writes to stdout on startup (with ID==0). It includes the
+ // Request.Command types that are supported by the program.
+ //
+ // This lets the go command extend the protocol gracefully over time (adding
+ // "get2", etc), or fail gracefully when needed. It also lets the go command
+ // verify the program wants to be a cache helper.
+ KnownCommands []Cmd `json:",omitempty"`
+
+ // For "get" requests.
+
+ Miss bool `json:",omitempty"` // cache miss
+ OutputID []byte `json:",omitempty"` // the ObjectID stored with the body
+ Size int64 `json:",omitempty"` // body size in bytes
+ Time *time.Time `json:",omitempty"` // when the object was put in the cache (optional; used for cache expiration)
+
+ // For "get" and "put" requests.
+
+ // DiskPath is the absolute path on disk of the body corresponding to a
+ // "get" (on cache hit) or "put" request's ActionID.
+ DiskPath string `json:",omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/readme.md
new file mode 100644
index 00000000..1b08c848
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/readme.md
@@ -0,0 +1,9 @@
+# quoted
+
+Extracted from `go/src/cmd/go/internal/cacheprog/` (related to `cache`).
+This is just a copy of the Go code without any changes.
+
+## History
+
+- https://github.com/golangci/golangci-lint/pull/5576
+ - sync go1.24.1
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/mmap/mmap.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/internal/go/mmap/mmap.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap.go
index fcbd3e08..fd374df8 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/go/mmap/mmap.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap.go
@@ -22,10 +22,11 @@ type Data struct {
}
// Mmap maps the given file into memory.
-func Mmap(file string) (Data, error) {
+func Mmap(file string) (Data, bool, error) {
f, err := os.Open(file)
if err != nil {
- return Data{}, err
+ return Data{}, false, err
}
- return mmapFile(f)
+ data, err := mmapFile(f)
+ return data, true, err
}
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/mmap/mmap_other.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_other.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/mmap/mmap_other.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_other.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/mmap/mmap_unix.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_unix.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/mmap/mmap_unix.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_unix.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/mmap/mmap_windows.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_windows.go
similarity index 74%
rename from vendor/github.com/golangci/golangci-lint/internal/go/mmap/mmap_windows.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_windows.go
index 479ee307..256fab4b 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/go/mmap/mmap_windows.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_windows.go
@@ -37,5 +37,11 @@ func mmapFile(f *os.File) (Data, error) {
return Data{}, fmt.Errorf("VirtualQuery %s: %w", f.Name(), err)
}
data := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.RegionSize))
- return Data{f, data}, nil
+ if len(data) < int(size) {
+ // In some cases, especially on 386, we may not receive a in incomplete mapping:
+ // one that is shorter than the file itself. Return an error in those cases because
+ // incomplete mappings are not useful.
+ return Data{}, fmt.Errorf("mmapFile: received incomplete mapping of file")
+ }
+ return Data{f, data[:int(size)]}, nil
}
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/mmap/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/readme.md
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/internal/go/mmap/readme.md
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/readme.md
index f68aef09..5cbfdeef 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/go/mmap/readme.md
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/readme.md
@@ -5,6 +5,8 @@ This is just a copy of the Go code without any changes.
## History
+- https://github.com/golangci/golangci-lint/pull/5576
+ - sync go1.24.1
- https://github.com/golangci/golangci-lint/pull/5100
- Move package from `internal/mmap` to `internal/go/mmap`
- https://github.com/golangci/golangci-lint/pull/5098
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/quoted/quoted.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/quoted.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/quoted/quoted.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/quoted.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/quoted/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/readme.md
similarity index 81%
rename from vendor/github.com/golangci/golangci-lint/internal/go/quoted/readme.md
rename to vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/readme.md
index a5e4c4bb..97868185 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/go/quoted/readme.md
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/readme.md
@@ -5,6 +5,8 @@ This is just a copy of the Go code without any changes.
## History
+- https://github.com/golangci/golangci-lint/pull/5576
+ - sync go1.24.1 (no change)
- https://github.com/golangci/golangci-lint/pull/5100
- Move package from `internal/quoted` to `internal/go/quoted`
- https://github.com/golangci/golangci-lint/pull/5098
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/LICENSE b/vendor/github.com/golangci/golangci-lint/v2/internal/x/LICENSE
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/LICENSE
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/LICENSE
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/analysisflags/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/readme.md
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/analysisflags/readme.md
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/readme.md
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/analysisflags/url.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/url.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/analysisflags/url.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/url.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/analysisinternal/analysis.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/analysis.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/analysisinternal/analysis.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/analysis.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/analysisinternal/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/readme.md
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/analysisinternal/readme.md
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/readme.md
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/diff.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/diff.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/diff.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/diff.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/common.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/common.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/common.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/common.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/doc.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/doc.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/doc.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/doc.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/git.sh b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/git.sh
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/git.sh
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/git.sh
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/labels.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/labels.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/labels.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/labels.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/old.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/old.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/old.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/old.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/sequence.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/sequence.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/lcs/sequence.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/sequence.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/ndiff.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/ndiff.go
similarity index 97%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/ndiff.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/ndiff.go
index f7aa2b79..b429a69e 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/ndiff.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/ndiff.go
@@ -8,7 +8,7 @@ import (
"bytes"
"unicode/utf8"
- "github.com/golangci/golangci-lint/internal/x/tools/diff/lcs"
+ "github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs"
)
// Strings computes the differences between two strings.
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/readme.md
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/readme.md
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/readme.md
diff --git a/vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/unified.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/unified.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/x/tools/diff/unified.go
rename to vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/unified.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/cache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/cache.go
similarity index 91%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/cache.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/cache.go
index 4f2c812d..13e89505 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/cache.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/cache.go
@@ -7,9 +7,9 @@ import (
"github.com/spf13/cobra"
- "github.com/golangci/golangci-lint/internal/cache"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/internal/cache"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type cacheCommand struct {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config.go
similarity index 70%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/config.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config.go
index 935ec5e8..6628aa42 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/config.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config.go
@@ -1,25 +1,32 @@
package commands
import (
+ "encoding/json"
"fmt"
"os"
+ "path/filepath"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/spf13/viper"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/exitcodes"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/exitcodes"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
+type pathOptions struct {
+ JSON bool
+}
+
type configCommand struct {
viper *viper.Viper
cmd *cobra.Command
opts config.LoaderOptions
verifyOpts verifyOptions
+ pathOpts pathOptions
buildInfo BuildInfo
@@ -53,14 +60,16 @@ func newConfigCommand(log logutils.Log, info BuildInfo) *configCommand {
SilenceErrors: true,
}
+ pathCommand := &cobra.Command{
+ Use: "path",
+ Short: "Print used config path",
+ Args: cobra.NoArgs,
+ ValidArgsFunction: cobra.NoFileCompletions,
+ RunE: c.executePath,
+ }
+
configCmd.AddCommand(
- &cobra.Command{
- Use: "path",
- Short: "Print used config path",
- Args: cobra.NoArgs,
- ValidArgsFunction: cobra.NoFileCompletions,
- Run: c.executePath,
- },
+ pathCommand,
verifyCommand,
)
@@ -74,6 +83,9 @@ func newConfigCommand(log logutils.Log, info BuildInfo) *configCommand {
verifyFlagSet.StringVar(&c.verifyOpts.schemaURL, "schema", "", color.GreenString("JSON schema URL"))
_ = verifyFlagSet.MarkHidden("schema")
+ pathFlagSet := pathCommand.Flags()
+ pathFlagSet.BoolVar(&c.pathOpts.JSON, "json", false, color.GreenString("Display as JSON"))
+
c.cmd = configCmd
return c
@@ -84,7 +96,7 @@ func (c *configCommand) preRunE(cmd *cobra.Command, args []string) error {
// It only needs to know the path of the configuration file.
cfg := config.NewDefault()
- loader := config.NewLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts, cfg, args)
+ loader := config.NewLintersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts, cfg, args)
err := loader.Load(config.LoadOptions{})
if err != nil {
@@ -94,14 +106,29 @@ func (c *configCommand) preRunE(cmd *cobra.Command, args []string) error {
return nil
}
-func (c *configCommand) executePath(cmd *cobra.Command, _ []string) {
+func (c *configCommand) executePath(cmd *cobra.Command, _ []string) error {
usedConfigFile := c.getUsedConfig()
+
+ if c.pathOpts.JSON {
+ abs, err := filepath.Abs(usedConfigFile)
+ if err != nil {
+ return err
+ }
+
+ return json.NewEncoder(cmd.OutOrStdout()).Encode(map[string]string{
+ "path": usedConfigFile,
+ "absolutePath": abs,
+ })
+ }
+
if usedConfigFile == "" {
c.log.Warnf("No config file detected")
os.Exit(exitcodes.NoConfigFileDetected)
}
cmd.Println(usedConfigFile)
+
+ return nil
}
// getUsedConfig returns the resolved path to the golangci config file,
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/config_verify.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config_verify.go
similarity index 99%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/config_verify.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config_verify.go
index 76e09581..ef7a4e09 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/config_verify.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config_verify.go
@@ -19,7 +19,7 @@ import (
"github.com/spf13/pflag"
"gopkg.in/yaml.v3"
- "github.com/golangci/golangci-lint/pkg/exitcodes"
+ "github.com/golangci/golangci-lint/v2/pkg/exitcodes"
)
type verifyOptions struct {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/custom.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/custom.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/custom.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/custom.go
index 1bc9f901..a53197ce 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/custom.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/custom.go
@@ -7,8 +7,8 @@ import (
"github.com/spf13/cobra"
- "github.com/golangci/golangci-lint/pkg/commands/internal"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
const envKeepTempFiles = "CUSTOM_GCL_KEEP_TEMP_FILES"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/flagsets.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/flagsets.go
similarity index 54%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/flagsets.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/flagsets.go
index d514f127..cc4b0043 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/flagsets.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/flagsets.go
@@ -1,56 +1,49 @@
package commands
import (
- "fmt"
- "strings"
-
"github.com/fatih/color"
"github.com/spf13/pflag"
"github.com/spf13/viper"
- "github.com/golangci/golangci-lint/pkg/commands/internal"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/exitcodes"
- "github.com/golangci/golangci-lint/pkg/lint/lintersdb"
- "github.com/golangci/golangci-lint/pkg/result/processors"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/exitcodes"
)
const defaultMaxIssuesPerLinter = 50
func setupLintersFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
- internal.AddHackedStringSliceP(fs, "disable", "D", color.GreenString("Disable specific linter"))
- internal.AddFlagAndBind(v, fs, fs.Bool, "disable-all", "linters.disable-all", false, color.GreenString("Disable all linters"))
+ internal.AddFlagAndBind(v, fs, fs.String, "default", "linters.default", config.GroupStandard,
+ color.GreenString("Default set of linters to enable"))
+ internal.AddHackedStringSliceP(fs, "disable", "D", color.GreenString("Disable specific linter"))
internal.AddHackedStringSliceP(fs, "enable", "E", color.GreenString("Enable specific linter"))
- internal.AddFlagAndBind(v, fs, fs.Bool, "enable-all", "linters.enable-all", false, color.GreenString("Enable all linters"))
-
- internal.AddFlagAndBind(v, fs, fs.Bool, "fast", "linters.fast", false,
- color.GreenString("Enable only fast linters from enabled linters set (first run won't be fast)"))
-
- internal.AddHackedStringSliceP(fs, "presets", "p",
- formatList("Enable presets of linters:", lintersdb.AllPresets(),
- "Run 'golangci-lint help linters' to see them.",
- "This option implies option --disable-all",
- ),
- )
fs.StringSlice("enable-only", nil,
color.GreenString("Override linters configuration section to only run the specific linter(s)")) // Flags only.
+
+ internal.AddFlagAndBind(v, fs, fs.Bool, "fast-only", "linters.fast-only", false,
+ color.GreenString("Filter enabled linters to run only fast linters"))
+}
+
+func setupFormattersFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
+ internal.AddFlagAndBindP(v, fs, fs.StringSliceP, "enable", "E", "formatters.enable", nil,
+ color.GreenString("Enable specific formatter"))
}
func setupRunFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
- internal.AddFlagAndBindP(v, fs, fs.IntP, "concurrency", "j", "run.concurrency", getDefaultConcurrency(),
- color.GreenString("Number of CPUs to use (Default: number of logical CPUs)"))
+ internal.AddFlagAndBindP(v, fs, fs.IntP, "concurrency", "j", "run.concurrency", 0,
+ color.GreenString("Number of CPUs to use (Default: Automatically set to match Linux container CPU quota"+
+ " and fall back to the number of logical CPUs in the machine)"))
internal.AddFlagAndBind(v, fs, fs.String, "modules-download-mode", "run.modules-download-mode", "",
color.GreenString("Modules download mode. If not empty, passed as -mod= to go tools"))
internal.AddFlagAndBind(v, fs, fs.Int, "issues-exit-code", "run.issues-exit-code", exitcodes.IssuesFound,
color.GreenString("Exit code when issues were found"))
- internal.AddFlagAndBind(v, fs, fs.String, "go", "run.go", "", color.GreenString("Targeted Go version"))
internal.AddHackedStringSlice(fs, "build-tags", color.GreenString("Build tags"))
internal.AddFlagAndBind(v, fs, fs.Duration, "timeout", "run.timeout", defaultTimeout,
- color.GreenString("Timeout for total work. If <= 0, the timeout is disabled"))
+ color.GreenString("Timeout for total work. Disabled by default"))
internal.AddFlagAndBind(v, fs, fs.Bool, "tests", "run.tests", true, color.GreenString("Analyze tests (*_test.go)"))
@@ -67,29 +60,61 @@ func setupRunFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
}
func setupOutputFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
- internal.AddFlagAndBind(v, fs, fs.String, "out-format", "output.formats", config.OutFormatColoredLineNumber,
- formatList("Formats of output:", config.AllOutputFormats))
- internal.AddFlagAndBind(v, fs, fs.Bool, "print-issued-lines", "output.print-issued-lines", true,
- color.GreenString("Print lines of code with issue"))
- internal.AddFlagAndBind(v, fs, fs.Bool, "print-linter-name", "output.print-linter-name", true,
- color.GreenString("Print linter name in issue line"))
- internal.AddFlagAndBind(v, fs, fs.Bool, "sort-results", "output.sort-results", false,
- color.GreenString("Sort linter results"))
- internal.AddFlagAndBind(v, fs, fs.StringSlice, "sort-order", "output.sort-order", nil,
- color.GreenString("Sort order of linter results"))
internal.AddFlagAndBind(v, fs, fs.String, "path-prefix", "output.path-prefix", "",
color.GreenString("Path prefix to add to output"))
- internal.AddFlagAndBind(v, fs, fs.Bool, "show-stats", "output.show-stats", false, color.GreenString("Show statistics per linter"))
+ internal.AddFlagAndBind(v, fs, fs.String, "path-mode", "output.path-mode", "",
+ color.GreenString("Path mode to use (empty, or 'abs')"))
+ internal.AddFlagAndBind(v, fs, fs.Bool, "show-stats", "output.show-stats", true, color.GreenString("Show statistics per linter"))
+
+ setupOutputFormatsFlagSet(v, fs)
}
-//nolint:gomnd // magic numbers here is ok
-func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
- internal.AddHackedStringSliceP(fs, "exclude", "e", color.GreenString("Exclude issue by regexp"))
- internal.AddFlagAndBind(v, fs, fs.Bool, "exclude-use-default", "issues.exclude-use-default", true,
- getDefaultIssueExcludeHelp())
- internal.AddFlagAndBind(v, fs, fs.Bool, "exclude-case-sensitive", "issues.exclude-case-sensitive", false,
- color.GreenString("If set to true exclude and exclude rules regular expressions are case-sensitive"))
+func setupOutputFormatsFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
+ outputPathDesc := "Output path can be either `stdout`, `stderr` or path to the file to write to."
+ printLinterNameDesc := "Print linter name in the end of issue text."
+ colorsDesc := "Use colors."
+
+ internal.AddFlagAndBind(v, fs, fs.String, "output.text.path", "output.formats.text.path", "",
+ color.GreenString(outputPathDesc))
+ internal.AddFlagAndBind(v, fs, fs.Bool, "output.text.print-linter-name", "output.formats.text.print-linter-name", true,
+ color.GreenString(printLinterNameDesc))
+ internal.AddFlagAndBind(v, fs, fs.Bool, "output.text.print-issued-lines", "output.formats.text.print-issued-lines", true,
+ color.GreenString("Print lines of code with issue."))
+ internal.AddFlagAndBind(v, fs, fs.Bool, "output.text.colors", "output.formats.text.colors", true,
+ color.GreenString(colorsDesc))
+
+ internal.AddFlagAndBind(v, fs, fs.String, "output.json.path", "output.formats.json.path", "",
+ color.GreenString(outputPathDesc))
+
+ internal.AddFlagAndBind(v, fs, fs.String, "output.tab.path", "output.formats.tab.path", "",
+ color.GreenString(outputPathDesc))
+ internal.AddFlagAndBind(v, fs, fs.Bool, "output.tab.print-linter-name", "output.formats.tab.print-linter-name",
+ true, color.GreenString(printLinterNameDesc))
+ internal.AddFlagAndBind(v, fs, fs.Bool, "output.tab.colors", "output.formats.tab.colors", true,
+ color.GreenString(colorsDesc))
+
+ internal.AddFlagAndBind(v, fs, fs.String, "output.html.path", "output.formats.html.path", "",
+ color.GreenString(outputPathDesc))
+
+ internal.AddFlagAndBind(v, fs, fs.String, "output.checkstyle.path", "output.formats.checkstyle.path", "",
+ color.GreenString(outputPathDesc))
+
+ internal.AddFlagAndBind(v, fs, fs.String, "output.code-climate.path", "output.formats.code-climate.path", "",
+ color.GreenString(outputPathDesc))
+
+ internal.AddFlagAndBind(v, fs, fs.String, "output.junit-xml.path", "output.formats.junit-xml.path", "",
+ color.GreenString(outputPathDesc))
+ internal.AddFlagAndBind(v, fs, fs.Bool, "output.junit-xml.extended", "output.formats.junit-xml.extended", false,
+ color.GreenString("Support extra JUnit XML fields."))
+
+ internal.AddFlagAndBind(v, fs, fs.String, "output.teamcity.path", "output.formats.teamcity.path", "",
+ color.GreenString(outputPathDesc))
+
+ internal.AddFlagAndBind(v, fs, fs.String, "output.sarif.path", "output.formats.sarif.path", "",
+ color.GreenString(outputPathDesc))
+}
+func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
internal.AddFlagAndBind(v, fs, fs.Int, "max-issues-per-linter", "issues.max-issues-per-linter", defaultMaxIssuesPerLinter,
color.GreenString("Maximum issues count per one linter. Set to 0 to disable"))
internal.AddFlagAndBind(v, fs, fs.Int, "max-same-issues", "issues.max-same-issues", 3,
@@ -97,14 +122,6 @@ func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
internal.AddFlagAndBind(v, fs, fs.Bool, "uniq-by-line", "issues.uniq-by-line", true,
color.GreenString("Make issues output unique by line"))
- internal.AddHackedStringSlice(fs, "exclude-files", color.GreenString("Regexps of files to exclude"))
- internal.AddHackedStringSlice(fs, "exclude-dirs", color.GreenString("Regexps of directories to exclude"))
- internal.AddFlagAndBind(v, fs, fs.Bool, "exclude-dirs-use-default", "issues.exclude-dirs-use-default", true,
- formatList("Use or not use default excluded directories:", processors.StdExcludeDirRegexps))
-
- internal.AddFlagAndBind(v, fs, fs.String, "exclude-generated", "issues.exclude-generated", processors.AutogeneratedModeLax,
- color.GreenString("Mode of the generated files analysis"))
-
const newDesc = "Show only new issues: if there are unstaged changes or untracked files, only those changes " +
"are analyzed, else only changes in HEAD~ are analyzed.\nIt's a super-useful option for integration " +
"of golangci-lint into existing large codebase.\nIt's not practical to fix all existing issues at " +
@@ -123,33 +140,3 @@ func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
internal.AddFlagAndBind(v, fs, fs.Bool, "fix", "issues.fix", false,
color.GreenString("Fix found issues (if it's supported by the linter)"))
}
-
-func formatList(head string, items []string, foot ...string) string {
- parts := []string{color.GreenString(head)}
- for _, p := range items {
- parts = append(parts, fmt.Sprintf(" - %s", color.YellowString(p)))
- }
-
- for _, s := range foot {
- parts = append(parts, color.GreenString(s))
- }
-
- if len(foot) == 0 {
- parts = append(parts, "")
- }
-
- return strings.Join(parts, "\n")
-}
-
-func getDefaultIssueExcludeHelp() string {
- parts := []string{color.GreenString("Use or not use default excludes:")}
-
- for _, ep := range config.DefaultExcludePatterns {
- parts = append(parts,
- fmt.Sprintf(" - %s (%s): %s", color.BlueString(ep.ID), color.CyanString(ep.Linter), ep.Why),
- fmt.Sprintf(` Pattern: %s`, color.YellowString(`'`+ep.Pattern+`'`)),
- )
- }
-
- return strings.Join(parts, "\n")
-}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/fmt.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/fmt.go
new file mode 100644
index 00000000..502dcebd
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/fmt.go
@@ -0,0 +1,160 @@
+package commands
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/fatih/color"
+ "github.com/spf13/cobra"
+ "github.com/spf13/viper"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goformat"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result/processors"
+)
+
+type fmtOptions struct {
+ config.LoaderOptions
+
+ diff bool // Flag only.
+ diffColored bool // Flag only.
+ stdin bool // Flag only.
+}
+
+type fmtCommand struct {
+ viper *viper.Viper
+ cmd *cobra.Command
+
+ opts fmtOptions
+
+ cfg *config.Config
+
+ buildInfo BuildInfo
+
+ runner *goformat.Runner
+
+ log logutils.Log
+ debugf logutils.DebugFunc
+}
+
+func newFmtCommand(logger logutils.Log, info BuildInfo) *fmtCommand {
+ c := &fmtCommand{
+ viper: viper.New(),
+ log: logger,
+ debugf: logutils.Debug(logutils.DebugKeyExec),
+ cfg: config.NewDefault(),
+ buildInfo: info,
+ }
+
+ fmtCmd := &cobra.Command{
+ Use: "fmt",
+ Short: "Format Go source files",
+ RunE: c.execute,
+ PreRunE: c.preRunE,
+ PersistentPreRunE: c.persistentPreRunE,
+ PersistentPostRun: c.persistentPostRun,
+ SilenceUsage: true,
+ }
+
+ fmtCmd.SetOut(logutils.StdOut) // use custom output to properly color it in Windows terminals
+ fmtCmd.SetErr(logutils.StdErr)
+
+ fs := fmtCmd.Flags()
+ fs.SortFlags = false // sort them as they are defined here
+
+ setupConfigFileFlagSet(fs, &c.opts.LoaderOptions)
+
+ setupFormattersFlagSet(c.viper, fs)
+
+ fs.BoolVarP(&c.opts.diff, "diff", "d", false, color.GreenString("Display diffs instead of rewriting files"))
+ fs.BoolVar(&c.opts.diffColored, "diff-colored", false, color.GreenString("Display diffs instead of rewriting files (with colors)"))
+ fs.BoolVar(&c.opts.stdin, "stdin", false, color.GreenString("Use standard input for piping source files"))
+
+ c.cmd = fmtCmd
+
+ return c
+}
+
+func (c *fmtCommand) persistentPreRunE(cmd *cobra.Command, args []string) error {
+ c.log.Infof("%s", c.buildInfo.String())
+
+ loader := config.NewFormattersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args)
+
+ err := loader.Load(config.LoadOptions{CheckDeprecation: true, Validation: true})
+ if err != nil {
+ return fmt.Errorf("can't load config: %w", err)
+ }
+
+ return nil
+}
+
+func (c *fmtCommand) preRunE(_ *cobra.Command, _ []string) error {
+ if c.cfg.GetConfigDir() != "" && c.cfg.Version != "2" {
+ return fmt.Errorf("invalid version of the configuration: %q", c.cfg.Version)
+ }
+
+ metaFormatter, err := goformatters.NewMetaFormatter(c.log, &c.cfg.Formatters, &c.cfg.Run)
+ if err != nil {
+ return fmt.Errorf("failed to create meta-formatter: %w", err)
+ }
+
+ matcher := processors.NewGeneratedFileMatcher(c.cfg.Formatters.Exclusions.Generated)
+
+ opts, err := goformat.NewRunnerOptions(c.cfg, c.opts.diff, c.opts.diffColored, c.opts.stdin)
+ if err != nil {
+ return fmt.Errorf("build walk options: %w", err)
+ }
+
+ c.runner = goformat.NewRunner(c.log, metaFormatter, matcher, opts)
+
+ return nil
+}
+
+func (c *fmtCommand) execute(_ *cobra.Command, args []string) error {
+ paths, err := cleanArgs(args)
+ if err != nil {
+ return fmt.Errorf("failed to clean arguments: %w", err)
+ }
+
+ c.log.Infof("Formatting Go files...")
+
+ err = c.runner.Run(paths)
+ if err != nil {
+ return fmt.Errorf("failed to process files: %w", err)
+ }
+
+ return nil
+}
+
+func (c *fmtCommand) persistentPostRun(_ *cobra.Command, _ []string) {
+ if c.runner.ExitCode() != 0 {
+ os.Exit(c.runner.ExitCode())
+ }
+}
+
+func cleanArgs(args []string) ([]string, error) {
+ if len(args) == 0 {
+ abs, err := filepath.Abs(".")
+ if err != nil {
+ return nil, err
+ }
+
+ return []string{abs}, nil
+ }
+
+ var expanded []string
+ for _, arg := range args {
+ abs, err := filepath.Abs(strings.ReplaceAll(arg, "...", ""))
+ if err != nil {
+ return nil, err
+ }
+
+ expanded = append(expanded, abs)
+ }
+
+ return expanded, nil
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/formatters.go
new file mode 100644
index 00000000..a3fafd1d
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/formatters.go
@@ -0,0 +1,136 @@
+package commands
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/fatih/color"
+ "github.com/spf13/cobra"
+ "github.com/spf13/viper"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+)
+
+type formattersHelp struct {
+ Enabled []formatterHelp
+ Disabled []formatterHelp
+}
+
+type formattersOptions struct {
+ config.LoaderOptions
+ JSON bool
+}
+
+type formattersCommand struct {
+ viper *viper.Viper
+ cmd *cobra.Command
+
+ opts formattersOptions
+
+ cfg *config.Config
+
+ log logutils.Log
+
+ dbManager *lintersdb.Manager
+}
+
+func newFormattersCommand(logger logutils.Log) *formattersCommand {
+ c := &formattersCommand{
+ viper: viper.New(),
+ cfg: config.NewDefault(),
+ log: logger,
+ }
+
+ formattersCmd := &cobra.Command{
+ Use: "formatters",
+ Short: "List current formatters configuration",
+ Args: cobra.NoArgs,
+ ValidArgsFunction: cobra.NoFileCompletions,
+ RunE: c.execute,
+ PreRunE: c.preRunE,
+ SilenceUsage: true,
+ }
+
+ fs := formattersCmd.Flags()
+ fs.SortFlags = false // sort them as they are defined here
+
+ setupConfigFileFlagSet(fs, &c.opts.LoaderOptions)
+ setupLintersFlagSet(c.viper, fs)
+
+ fs.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
+
+ c.cmd = formattersCmd
+
+ return c
+}
+
+func (c *formattersCommand) preRunE(cmd *cobra.Command, args []string) error {
+ loader := config.NewFormattersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args)
+
+ err := loader.Load(config.LoadOptions{Validation: true})
+ if err != nil {
+ return fmt.Errorf("can't load config: %w", err)
+ }
+
+ dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), c.cfg,
+ lintersdb.NewLinterBuilder(), lintersdb.NewPluginModuleBuilder(c.log), lintersdb.NewPluginGoBuilder(c.log))
+ if err != nil {
+ return err
+ }
+
+ c.dbManager = dbManager
+
+ return nil
+}
+
+func (c *formattersCommand) execute(_ *cobra.Command, _ []string) error {
+ enabledLintersMap, err := c.dbManager.GetEnabledLintersMap()
+ if err != nil {
+ return fmt.Errorf("can't get enabled formatters: %w", err)
+ }
+
+ var enabledFormatters []*linter.Config
+ var disabledFormatters []*linter.Config
+
+ for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
+ if lc.Internal {
+ continue
+ }
+
+ if !goformatters.IsFormatter(lc.Name()) {
+ continue
+ }
+
+ if enabledLintersMap[lc.Name()] == nil {
+ disabledFormatters = append(disabledFormatters, lc)
+ } else {
+ enabledFormatters = append(enabledFormatters, lc)
+ }
+ }
+
+ if c.opts.JSON {
+ formatters := formattersHelp{}
+
+ for _, lc := range enabledFormatters {
+ formatters.Enabled = append(formatters.Enabled, newFormatterHelp(lc))
+ }
+
+ for _, lc := range disabledFormatters {
+ formatters.Disabled = append(formatters.Disabled, newFormatterHelp(lc))
+ }
+
+ return json.NewEncoder(c.cmd.OutOrStdout()).Encode(formatters)
+ }
+
+ color.Green("Enabled by your configuration formatters:\n")
+ printFormatters(enabledFormatters)
+
+ color.Red("\nDisabled by your configuration formatters:\n")
+ printFormatters(disabledFormatters)
+
+ return nil
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help.go
new file mode 100644
index 00000000..bb5696e7
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help.go
@@ -0,0 +1,101 @@
+package commands
+
+import (
+ "strings"
+ "unicode"
+ "unicode/utf8"
+
+ "github.com/fatih/color"
+ "github.com/spf13/cobra"
+
+ "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+)
+
+type helpOptions struct {
+ JSON bool
+}
+
+type helpCommand struct {
+ cmd *cobra.Command
+
+ opts helpOptions
+
+ dbManager *lintersdb.Manager
+
+ log logutils.Log
+}
+
+func newHelpCommand(logger logutils.Log) *helpCommand {
+ c := &helpCommand{log: logger}
+
+ helpCmd := &cobra.Command{
+ Use: "help",
+ Short: "Help",
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, _ []string) error {
+ return cmd.Help()
+ },
+ }
+
+ lintersCmd := &cobra.Command{
+ Use: "linters",
+ Short: "Help about linters",
+ Args: cobra.NoArgs,
+ ValidArgsFunction: cobra.NoFileCompletions,
+ RunE: c.lintersExecute,
+ PreRunE: c.lintersPreRunE,
+ }
+
+ fsLinter := lintersCmd.Flags()
+ fsLinter.SortFlags = false // sort them as they are defined here
+
+ fsLinter.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
+
+ helpCmd.AddCommand(lintersCmd)
+
+ formattersCmd := &cobra.Command{
+ Use: "formatters",
+ Short: "Help about formatters",
+ Args: cobra.NoArgs,
+ ValidArgsFunction: cobra.NoFileCompletions,
+ RunE: c.formattersExecute,
+ PreRunE: c.formattersPreRunE,
+ }
+
+ fsFormatter := formattersCmd.Flags()
+ fsFormatter.SortFlags = false // sort them as they are defined here
+
+ fsFormatter.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
+
+ helpCmd.AddCommand(formattersCmd)
+
+ c.cmd = helpCmd
+
+ return c
+}
+
+func formatDescription(desc string) string {
+ desc = strings.TrimSpace(desc)
+
+ if desc == "" {
+ return desc
+ }
+
+ // If the linter description spans multiple lines, truncate everything following the first newline
+ endFirstLine := strings.IndexRune(desc, '\n')
+ if endFirstLine > 0 {
+ desc = desc[:endFirstLine]
+ }
+
+ rawDesc := []rune(desc)
+
+ r, _ := utf8.DecodeRuneInString(desc)
+ rawDesc[0] = unicode.ToUpper(r)
+
+ if rawDesc[len(rawDesc)-1] != '.' {
+ rawDesc = append(rawDesc, '.')
+ }
+
+ return string(rawDesc)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_formatters.go
new file mode 100644
index 00000000..e41cea36
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_formatters.go
@@ -0,0 +1,123 @@
+package commands
+
+import (
+ "encoding/json"
+ "fmt"
+ "slices"
+ "strings"
+
+ "github.com/fatih/color"
+ "github.com/spf13/cobra"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+)
+
+type formatterHelp struct {
+ Name string `json:"name"`
+ Desc string `json:"description"`
+ Deprecated bool `json:"deprecated"`
+ Since string `json:"since"`
+ OriginalURL string `json:"originalURL,omitempty"`
+}
+
+func newFormatterHelp(lc *linter.Config) formatterHelp {
+ return formatterHelp{
+ Name: lc.Name(),
+ Desc: formatDescription(lc.Linter.Desc()),
+ Deprecated: lc.IsDeprecated(),
+ Since: lc.Since,
+ OriginalURL: lc.OriginalURL,
+ }
+}
+
+func (c *helpCommand) formattersPreRunE(_ *cobra.Command, _ []string) error {
+ // The command doesn't depend on the real configuration.
+ dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), config.NewDefault(), lintersdb.NewLinterBuilder())
+ if err != nil {
+ return err
+ }
+
+ c.dbManager = dbManager
+
+ return nil
+}
+
+func (c *helpCommand) formattersExecute(_ *cobra.Command, _ []string) error {
+ if c.opts.JSON {
+ return c.formattersPrintJSON()
+ }
+
+ c.formattersPrint()
+
+ return nil
+}
+
+func (c *helpCommand) formattersPrintJSON() error {
+ var formatters []formatterHelp
+
+ for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
+ if lc.Internal {
+ continue
+ }
+
+ if !goformatters.IsFormatter(lc.Name()) {
+ continue
+ }
+
+ formatters = append(formatters, newFormatterHelp(lc))
+ }
+
+ return json.NewEncoder(c.cmd.OutOrStdout()).Encode(formatters)
+}
+
+func (c *helpCommand) formattersPrint() {
+ var lcs []*linter.Config
+ for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
+ if lc.Internal {
+ continue
+ }
+
+ if !goformatters.IsFormatter(lc.Name()) {
+ continue
+ }
+
+ lcs = append(lcs, lc)
+ }
+
+ color.Green("Disabled by default formatters:\n")
+ printFormatters(lcs)
+}
+
+func printFormatters(lcs []*linter.Config) {
+ slices.SortFunc(lcs, func(a, b *linter.Config) int {
+ if a.IsDeprecated() && b.IsDeprecated() {
+ return strings.Compare(a.Name(), b.Name())
+ }
+
+ if a.IsDeprecated() {
+ return 1
+ }
+
+ if b.IsDeprecated() {
+ return -1
+ }
+
+ return strings.Compare(a.Name(), b.Name())
+ })
+
+ for _, lc := range lcs {
+ desc := formatDescription(lc.Linter.Desc())
+
+ deprecatedMark := ""
+ if lc.IsDeprecated() {
+ deprecatedMark = " [" + color.RedString("deprecated") + "]"
+ }
+
+ _, _ = fmt.Fprintf(logutils.StdOut, "%s%s: %s\n",
+ color.YellowString(lc.Name()), deprecatedMark, desc)
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_linters.go
new file mode 100644
index 00000000..b4e64770
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_linters.go
@@ -0,0 +1,156 @@
+package commands
+
+import (
+ "encoding/json"
+ "fmt"
+ "maps"
+ "slices"
+ "strings"
+
+ "github.com/fatih/color"
+ "github.com/spf13/cobra"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+)
+
+type linterHelp struct {
+ Name string `json:"name"`
+ Desc string `json:"description"`
+ Groups []string `json:"groups"`
+ Fast bool `json:"fast"`
+ AutoFix bool `json:"autoFix"`
+ Deprecated bool `json:"deprecated"`
+ Since string `json:"since"`
+ OriginalURL string `json:"originalURL,omitempty"`
+}
+
+func newLinterHelp(lc *linter.Config) linterHelp {
+ groups := []string{config.GroupAll}
+
+ if !lc.IsSlowLinter() {
+ groups = append(groups, config.GroupFast)
+ }
+
+ return linterHelp{
+ Name: lc.Name(),
+ Desc: formatDescription(lc.Linter.Desc()),
+ Groups: slices.Concat(groups, slices.Collect(maps.Keys(lc.Groups))),
+ Fast: !lc.IsSlowLinter(),
+ AutoFix: lc.CanAutoFix,
+ Deprecated: lc.IsDeprecated(),
+ Since: lc.Since,
+ OriginalURL: lc.OriginalURL,
+ }
+}
+
+func (c *helpCommand) lintersPreRunE(_ *cobra.Command, _ []string) error {
+ // The command doesn't depend on the real configuration.
+ dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), config.NewDefault(), lintersdb.NewLinterBuilder())
+ if err != nil {
+ return err
+ }
+
+ c.dbManager = dbManager
+
+ return nil
+}
+
+func (c *helpCommand) lintersExecute(_ *cobra.Command, _ []string) error {
+ if c.opts.JSON {
+ return c.lintersPrintJSON()
+ }
+
+ c.lintersPrint()
+
+ return nil
+}
+
+func (c *helpCommand) lintersPrintJSON() error {
+ var linters []linterHelp
+
+ for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
+ if lc.Internal {
+ continue
+ }
+
+ if goformatters.IsFormatter(lc.Name()) {
+ continue
+ }
+
+ linters = append(linters, newLinterHelp(lc))
+ }
+
+ return json.NewEncoder(c.cmd.OutOrStdout()).Encode(linters)
+}
+
+func (c *helpCommand) lintersPrint() {
+ var enabledLCs, disabledLCs []*linter.Config
+ for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
+ if lc.Internal {
+ continue
+ }
+
+ if goformatters.IsFormatter(lc.Name()) {
+ continue
+ }
+
+ if lc.FromGroup(config.GroupStandard) {
+ enabledLCs = append(enabledLCs, lc)
+ } else {
+ disabledLCs = append(disabledLCs, lc)
+ }
+ }
+
+ color.Green("Enabled by default linters:\n")
+ printLinters(enabledLCs)
+
+ color.Red("\nDisabled by default linters:\n")
+ printLinters(disabledLCs)
+}
+
+func printLinters(lcs []*linter.Config) {
+ slices.SortFunc(lcs, func(a, b *linter.Config) int {
+ if a.IsDeprecated() && b.IsDeprecated() {
+ return strings.Compare(a.Name(), b.Name())
+ }
+
+ if a.IsDeprecated() {
+ return 1
+ }
+
+ if b.IsDeprecated() {
+ return -1
+ }
+
+ return strings.Compare(a.Name(), b.Name())
+ })
+
+ for _, lc := range lcs {
+ desc := formatDescription(lc.Linter.Desc())
+
+ deprecatedMark := ""
+ if lc.IsDeprecated() {
+ deprecatedMark = " [" + color.RedString("deprecated") + "]"
+ }
+
+ var capabilities []string
+ if !lc.IsSlowLinter() {
+ capabilities = append(capabilities, color.BlueString("fast"))
+ }
+ if lc.CanAutoFix {
+ capabilities = append(capabilities, color.GreenString("auto-fix"))
+ }
+
+ var capability string
+ if capabilities != nil {
+ capability = " [" + strings.Join(capabilities, ", ") + "]"
+ }
+
+ _, _ = fmt.Fprintf(logutils.StdOut, "%s%s: %s%s\n",
+ color.YellowString(lc.Name()), deprecatedMark, desc, capability)
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/builder.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/builder.go
similarity index 97%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/internal/builder.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/builder.go
index f0e259fb..c008f193 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/builder.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/builder.go
@@ -12,7 +12,7 @@ import (
"time"
"unicode"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
// Builder runs all the required commands to build a binary.
@@ -243,7 +243,7 @@ func (b Builder) getBinaryName() string {
func sanitizeVersion(v string) string {
fn := func(c rune) bool {
- return !(unicode.IsLetter(c) || unicode.IsNumber(c) || c == '.' || c == '/')
+ return !unicode.IsLetter(c) && !unicode.IsNumber(c) && c != '.' && c != '/'
}
return strings.Join(strings.FieldsFunc(v, fn), "")
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/configuration.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/configuration.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/internal/configuration.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/configuration.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/imports.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/imports.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/internal/imports.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/imports.go
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/config.go
new file mode 100644
index 00000000..159f4cba
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/config.go
@@ -0,0 +1,22 @@
+package fakeloader
+
+// Config implements [config.BaseConfig].
+// This only the stub for the real file loader.
+type Config struct {
+ Version string `mapstructure:"version"`
+
+ cfgDir string // Path to the directory containing golangci-lint config file.
+}
+
+func NewConfig() *Config {
+ return &Config{}
+}
+
+// SetConfigDir sets the path to directory that contains golangci-lint config file.
+func (c *Config) SetConfigDir(dir string) {
+ c.cfgDir = dir
+}
+
+func (*Config) IsInternalTest() bool {
+ return false
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/fakeloader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/fakeloader.go
new file mode 100644
index 00000000..fd17449b
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/fakeloader.go
@@ -0,0 +1,48 @@
+package fakeloader
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/go-viper/mapstructure/v2"
+
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+)
+
+// Load is used to keep case of configuration.
+// Viper serialize raw map keys in lowercase, this is a problem with the configuration of some linters.
+func Load(srcPath string, old any) error {
+ file, err := os.Open(srcPath)
+ if err != nil {
+ return fmt.Errorf("open file: %w", err)
+ }
+
+ defer func() { _ = file.Close() }()
+
+ raw := map[string]any{}
+
+ err = parser.Decode(file, raw)
+ if err != nil {
+ return err
+ }
+
+ // NOTE: this is inspired by viper internals.
+ cc := &mapstructure.DecoderConfig{
+ Result: old,
+ WeaklyTypedInput: true,
+ DecodeHook: config.DecodeHookFunc(),
+ }
+
+ decoder, err := mapstructure.NewDecoder(cc)
+ if err != nil {
+ return fmt.Errorf("constructing mapstructure decoder: %w", err)
+ }
+
+ err = decoder.Decode(raw)
+ if err != nil {
+ return fmt.Errorf("decoding configuration file: %w", err)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate.go
new file mode 100644
index 00000000..69b6c7c4
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate.go
@@ -0,0 +1,19 @@
+package migrate
+
+import (
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
+)
+
+func ToConfig(old *versionone.Config) *versiontwo.Config {
+ return &versiontwo.Config{
+ Version: ptr.Pointer("2"),
+ Linters: toLinters(old),
+ Formatters: toFormatters(old),
+ Issues: toIssues(old),
+ Output: toOutput(old),
+ Severity: toSeverity(old),
+ Run: toRun(old),
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_formatters.go
new file mode 100644
index 00000000..8836e6db
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_formatters.go
@@ -0,0 +1,105 @@
+package migrate
+
+import (
+ "slices"
+ "strings"
+
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
+)
+
+func toFormatters(old *versionone.Config) versiontwo.Formatters {
+ enable := ProcessEffectiveFormatters(old.Linters)
+
+ var paths []string
+ if len(enable) > 0 {
+ paths = slices.Concat(old.Issues.ExcludeFiles, old.Issues.ExcludeDirs)
+ }
+
+ if old.Issues.UseDefaultExcludeDirs == nil || ptr.Deref(old.Issues.UseDefaultExcludeDirs) {
+ paths = append(paths, "third_party$", "builtin$", "examples$")
+ }
+
+ paths = append(paths, toFormattersPathsFromRules(old.Issues)...)
+
+ return versiontwo.Formatters{
+ Enable: enable,
+ Settings: versiontwo.FormatterSettings{
+ Gci: toGciSettings(old.LintersSettings.Gci),
+ GoFmt: toGoFmtSettings(old.LintersSettings.GoFmt),
+ GoFumpt: toGoFumptSettings(old.LintersSettings.GoFumpt),
+ GoImports: toGoImportsSettings(old.LintersSettings.GoImports),
+ },
+ Exclusions: versiontwo.FormatterExclusions{
+ Generated: toExclusionGenerated(old.Issues.ExcludeGenerated),
+ Paths: paths,
+ },
+ }
+}
+
+func toFormattersPathsFromRules(old versionone.Issues) []string {
+ var results []string
+
+ for _, rule := range old.ExcludeRules {
+ allNames := convertStaticcheckLinterNames(convertAlternativeNames(rule.Linters))
+
+ names := onlyFormatterNames(allNames)
+ if len(names) == 0 {
+ continue
+ }
+
+ if ptr.Deref(rule.Path) == "" {
+ continue
+ }
+
+ results = append(results, ptr.Deref(rule.Path))
+ }
+
+ return results
+}
+
+func toGciSettings(old versionone.GciSettings) versiontwo.GciSettings {
+ return versiontwo.GciSettings{
+ Sections: old.Sections,
+ NoInlineComments: old.NoInlineComments,
+ NoPrefixComments: old.NoPrefixComments,
+ CustomOrder: old.CustomOrder,
+ NoLexOrder: old.NoLexOrder,
+ }
+}
+
+func toGoFmtSettings(old versionone.GoFmtSettings) versiontwo.GoFmtSettings {
+ settings := versiontwo.GoFmtSettings{
+ Simplify: old.Simplify,
+ }
+
+ for _, rule := range old.RewriteRules {
+ settings.RewriteRules = append(settings.RewriteRules, versiontwo.GoFmtRewriteRule{
+ Pattern: rule.Pattern,
+ Replacement: rule.Replacement,
+ })
+ }
+
+ return settings
+}
+
+func toGoFumptSettings(old versionone.GoFumptSettings) versiontwo.GoFumptSettings {
+ return versiontwo.GoFumptSettings{
+ ModulePath: old.ModulePath,
+ ExtraRules: old.ExtraRules,
+ }
+}
+
+func toGoImportsSettings(old versionone.GoImportsSettings) versiontwo.GoImportsSettings {
+ var localPrefixes []string
+
+ prefixes := ptr.Deref(old.LocalPrefixes)
+ if prefixes != "" {
+ localPrefixes = strings.Split(prefixes, ",")
+ }
+
+ return versiontwo.GoImportsSettings{
+ LocalPrefixes: localPrefixes,
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_issues.go
new file mode 100644
index 00000000..eab9d17c
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_issues.go
@@ -0,0 +1,20 @@
+package migrate
+
+import (
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
+)
+
+func toIssues(old *versionone.Config) versiontwo.Issues {
+ return versiontwo.Issues{
+ MaxIssuesPerLinter: old.Issues.MaxIssuesPerLinter,
+ MaxSameIssues: old.Issues.MaxSameIssues,
+ UniqByLine: old.Issues.UniqByLine,
+ DiffFromRevision: old.Issues.DiffFromRevision,
+ DiffFromMergeBase: old.Issues.DiffFromMergeBase,
+ DiffPatchFilePath: old.Issues.DiffPatchFilePath,
+ WholeFiles: old.Issues.WholeFiles,
+ Diff: old.Issues.Diff,
+ NeedFix: old.Issues.NeedFix,
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linter_names.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linter_names.go
new file mode 100644
index 00000000..da003e9a
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linter_names.go
@@ -0,0 +1,972 @@
+package migrate
+
+import (
+ "cmp"
+ "slices"
+
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+)
+
+type LinterInfo struct {
+ Name string `json:"name"`
+ Presets []string `json:"inPresets"`
+ Slow bool `json:"isSlow,omitempty"`
+ Default bool `json:"enabledByDefault,omitempty"`
+ AlternativeNames []string `json:"alternativeNames,omitempty"`
+}
+
+func (l *LinterInfo) isName(name string) bool {
+ if name == l.Name {
+ return true
+ }
+
+ return slices.Contains(l.AlternativeNames, name)
+}
+
+func (l *LinterInfo) hasPresets(names []string) bool {
+ for _, name := range names {
+ if slices.Contains(l.Presets, name) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func ProcessEffectiveLinters(old versionone.Linters) (enable, disable []string) {
+ switch {
+ case ptr.Deref(old.DisableAll):
+ return disableAllFilter(old), nil
+
+ case ptr.Deref(old.EnableAll):
+ return nil, enableAllFilter(old)
+
+ default:
+ return defaultLintersFilter(old)
+ }
+}
+
+func ProcessEffectiveFormatters(old versionone.Linters) []string {
+ enabled, disabled := ProcessEffectiveLinters(old)
+
+ if ptr.Deref(old.EnableAll) {
+ var formatterNames []string
+
+ for _, f := range getAllFormatterNames() {
+ if !slices.Contains(disabled, f) {
+ formatterNames = append(formatterNames, f)
+ }
+ }
+
+ return formatterNames
+ }
+
+ return onlyFormatterNames(enabled)
+}
+
+// disableAllFilter generates the value of `enable` when `disable-all` is `true`.
+func disableAllFilter(old versionone.Linters) []string {
+ // Note:
+ // - disable-all + enable-all
+ // => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L38)
+ // - disable-all + disable
+ // => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L47)
+
+ // if disable-all -> presets fast enable
+ // - presets fast enable: (presets - [slow]) + enable => effective enable + none
+ // - presets fast: presets - slow => effective enable + none
+ // - presets fast enable: presets + enable => effective enable + none
+ // - enable => effective enable + none
+ // - fast => nothing
+ // - fast enable: enable => effective enable + none
+
+ // (presets - [slow]) + enable => effective enable + none
+ names := toNames(
+ slices.Concat(
+ filter(
+ allLinters(), onlyPresets(old), keepFast(old), // presets - [slow]
+ ),
+ allEnabled(old, allLinters()), // + enable
+ ),
+ )
+
+ return slices.Concat(names, unknownLinterNames(old.Enable, allLinters()))
+}
+
+// enableAllFilter generates the value of `disable` when `enable-all` is `true`.
+func enableAllFilter(old versionone.Linters) []string {
+ // Note:
+ // - enable-all + disable-all
+ // => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L38)
+ // - enable-all + enable + fast=false
+ // => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L52)
+ // - enable-all + enable + fast=true
+ // => possible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L51)
+
+ // if enable-all -> presets fast enable disable
+ // - presets fast enable disable: all - fast - enable + disable => effective disable + all
+ // - presets fast disable: all - fast + disable => effective disable + all
+ // - presets fast: all - fast => effective disable + all
+ // - presets disable: disable => effective disable + all
+ // - disable => effective disable + all
+ // - fast: all - fast => effective disable + all
+ // - fast disable: all - fast + disable => effective disable + all
+
+ // all - [fast] - enable + disable => effective disable + all
+ names := toNames(
+ slices.Concat(
+ removeLinters(
+ filter(
+ allLinters(), keepSlow(old), // all - fast
+ ),
+ allEnabled(old, allLinters()), // - enable
+ ),
+ allDisabled(old, allLinters()), // + disable
+ ),
+ )
+
+ return slices.Concat(names, unknownLinterNames(old.Disable, allLinters()))
+}
+
+// defaultLintersFilter generates the values of `enable` and `disable` when using default linters.
+func defaultLintersFilter(old versionone.Linters) (enable, disable []string) {
+ // Note:
+ // - a linter cannot be inside `enable` and `disable` in the same configuration
+ // => https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L66
+
+ // if default -> presets fast disable
+ // - presets > fast > disable > enable => effective enable + disable + standard
+ // - (default - fast) - enable + disable => effective disable
+ // - presets - slow + enable - default - [effective disable] => effective enable
+ // - presets + fast + disable => effective enable + disable + standard
+ // - (default - fast) + disable => effective disable
+ // - presets - slow - default - [effective disable] => effective enable
+ // - presets + fast + enable
+ // - (default - fast) - enable => effective disable
+ // - presets - slow + enable - default - [effective disable] => effective enable
+ // - presets + fast
+ // - (default - fast) => effective disable
+ // - presets - slow - default - [effective disable] => effective enable
+ // - presets + disable
+ // - default + disable => effective disable
+ // - presets - default - [effective disable] => effective enable
+ // - presets + enable
+ // - default - enable => effective disable
+ // - presets + enable - default - [effective disable] => effective enable
+ // - disable
+ // - default + disable => effective disable
+ // - default - [effective disable] => effective enable
+ // - enable
+ // - default - enable => effective disable
+ // - enable - default - [effective disable] => effective enable
+ // - fast
+ // - default - fast => effective disable
+ // - default - [effective disable] => effective enable
+ // - fast + disable
+ // - (default - fast) + disable => effective disable
+ // - default - [effective disable] => effective enable
+ // - fast + enable
+ // - (default - fast) - enable => effective disable
+ // - enable - default - [effective disable] => effective enable
+
+ disabledLinters := defaultLintersDisableFilter(old)
+
+ enabledLinters := defaultLintersEnableFilter(old, disabledLinters)
+
+ enabled := toNames(enabledLinters)
+ disabled := toNames(disabledLinters)
+
+ return slices.Concat(enabled, unknownLinterNames(old.Enable, allLinters())),
+ slices.Concat(disabled, unknownLinterNames(old.Disable, allLinters()))
+}
+
+// defaultLintersEnableFilter generates the value of `enable` when using default linters.
+func defaultLintersEnableFilter(old versionone.Linters, effectiveDisabled []LinterInfo) []LinterInfo {
+ // presets - slow + enable - default - [effective disable] => effective enable
+ return removeLinters(
+ filter(
+ slices.Concat(
+ filter(
+ allLinters(), onlyPresets(old), keepFast(old), // presets - slow
+ ),
+ allEnabled(old, allLinters()), // + enable
+ ),
+ notDefault, // - default
+ ),
+ effectiveDisabled, // - [effective disable]
+ )
+}
+
+// defaultLintersDisableFilter generates the value of `disable` when using default linters.
+func defaultLintersDisableFilter(old versionone.Linters) []LinterInfo {
+ // (default - fast) - enable + disable => effective disable
+ return slices.Concat(
+ removeLinters(
+ filter(allLinters(), onlyDefault, keepSlow(old)), // (default - fast)
+ allEnabled(old, allLinters()), // - enable
+ ),
+ allDisabled(old, allLinters()), // + disable
+ )
+}
+
+func allLinters() []LinterInfo {
+ return []LinterInfo{
+ {
+ Name: "asasalint",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "asciicheck",
+ Presets: []string{"bugs", "style"},
+ },
+ {
+ Name: "bidichk",
+ Presets: []string{"bugs"},
+ },
+ {
+ Name: "bodyclose",
+ Presets: []string{"performance", "bugs"},
+ Slow: true,
+ },
+ {
+ Name: "canonicalheader",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "containedctx",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "contextcheck",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "copyloopvar",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "cyclop",
+ Presets: []string{"complexity"},
+ },
+ {
+ Name: "decorder",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "depguard",
+ Presets: []string{"style", "import", "module"},
+ },
+ {
+ Name: "dogsled",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "dupl",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "dupword",
+ Presets: []string{"comment"},
+ },
+ {
+ Name: "durationcheck",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "errcheck",
+ Presets: []string{"bugs", "error"},
+ Slow: true,
+ Default: true,
+ },
+ {
+ Name: "errchkjson",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "errname",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "errorlint",
+ Presets: []string{"bugs", "error"},
+ Slow: true,
+ },
+ {
+ Name: "exhaustive",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "exhaustruct",
+ Presets: []string{"style", "test"},
+ Slow: true,
+ },
+ {
+ Name: "exptostd",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "forbidigo",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "forcetypeassert",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "fatcontext",
+ Presets: []string{"performance"},
+ Slow: true,
+ },
+ {
+ Name: "funlen",
+ Presets: []string{"complexity"},
+ },
+ {
+ Name: "gci",
+ Presets: []string{"format", "import"},
+ },
+ {
+ Name: "ginkgolinter",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "gocheckcompilerdirectives",
+ Presets: []string{"bugs"},
+ },
+ {
+ Name: "gochecknoglobals",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "gochecknoinits",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "gochecksumtype",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "gocognit",
+ Presets: []string{"complexity"},
+ },
+ {
+ Name: "goconst",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "gocritic",
+ Presets: []string{"style", "metalinter"},
+ Slow: true,
+ },
+ {
+ Name: "gocyclo",
+ Presets: []string{"complexity"},
+ },
+ {
+ Name: "godot",
+ Presets: []string{"style", "comment"},
+ },
+ {
+ Name: "godox",
+ Presets: []string{"style", "comment"},
+ },
+ {
+ Name: "err113",
+ Presets: []string{"style", "error"},
+ Slow: true,
+ AlternativeNames: []string{"goerr113"},
+ },
+ {
+ Name: "gofmt",
+ Presets: []string{"format"},
+ },
+ {
+ Name: "gofumpt",
+ Presets: []string{"format"},
+ },
+ {
+ Name: "goheader",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "goimports",
+ Presets: []string{"format", "import"},
+ },
+ {
+ Name: "mnd",
+ Presets: []string{"style"},
+ AlternativeNames: []string{"gomnd"},
+ },
+ {
+ Name: "gomoddirectives",
+ Presets: []string{"style", "module"},
+ },
+ {
+ Name: "gomodguard",
+ Presets: []string{"style", "import", "module"},
+ },
+ {
+ Name: "goprintffuncname",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "gosec",
+ Presets: []string{"bugs"},
+ Slow: true,
+ AlternativeNames: []string{"gas"},
+ },
+ {
+ Name: "gosimple",
+ Presets: []string{"style"},
+ Slow: true,
+ Default: true,
+ AlternativeNames: []string{"megacheck"},
+ },
+ {
+ Name: "gosmopolitan",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "govet",
+ Presets: []string{"bugs", "metalinter"},
+ Slow: true,
+ Default: true,
+ AlternativeNames: []string{"vet", "vetshadow"},
+ },
+ {
+ Name: "grouper",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "iface",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "importas",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "inamedparam",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "ineffassign",
+ Presets: []string{"unused"},
+ Default: true,
+ },
+ {
+ Name: "interfacebloat",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "intrange",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "ireturn",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "lll",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "loggercheck",
+ Presets: []string{"style", "bugs"},
+ Slow: true,
+ AlternativeNames: []string{"logrlint"},
+ },
+ {
+ Name: "maintidx",
+ Presets: []string{"complexity"},
+ },
+ {
+ Name: "makezero",
+ Presets: []string{"style", "bugs"},
+ Slow: true,
+ },
+ {
+ Name: "mirror",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "misspell",
+ Presets: []string{"style", "comment"},
+ },
+ {
+ Name: "musttag",
+ Presets: []string{"style", "bugs"},
+ Slow: true,
+ },
+ {
+ Name: "nakedret",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "nestif",
+ Presets: []string{"complexity"},
+ },
+ {
+ Name: "nilerr",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "nilnesserr",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "nilnil",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "nlreturn",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "noctx",
+ Presets: []string{"performance", "bugs"},
+ Slow: true,
+ },
+ {
+ Name: "nonamedreturns",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "nosprintfhostport",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "paralleltest",
+ Presets: []string{"style", "test"},
+ Slow: true,
+ },
+ {
+ Name: "perfsprint",
+ Presets: []string{"performance"},
+ Slow: true,
+ },
+ {
+ Name: "prealloc",
+ Presets: []string{"performance"},
+ },
+ {
+ Name: "predeclared",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "promlinter",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "protogetter",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "reassign",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "recvcheck",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "revive",
+ Presets: []string{"style", "metalinter"},
+ Slow: true,
+ },
+ {
+ Name: "rowserrcheck",
+ Presets: []string{"bugs", "sql"},
+ Slow: true,
+ },
+ {
+ Name: "sloglint",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "sqlclosecheck",
+ Presets: []string{"bugs", "sql"},
+ Slow: true,
+ },
+ {
+ Name: "spancheck",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "staticcheck",
+ Presets: []string{"bugs", "metalinter"},
+ Slow: true,
+ Default: true,
+ AlternativeNames: []string{"megacheck"},
+ },
+ {
+ Name: "stylecheck",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "tagalign",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "tagliatelle",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "testableexamples",
+ Presets: []string{"test"},
+ },
+ {
+ Name: "testifylint",
+ Presets: []string{"test", "bugs"},
+ Slow: true,
+ },
+ {
+ Name: "testpackage",
+ Presets: []string{"style", "test"},
+ },
+ {
+ Name: "thelper",
+ Presets: []string{"test"},
+ Slow: true,
+ },
+ {
+ Name: "tparallel",
+ Presets: []string{"style", "test"},
+ Slow: true,
+ },
+ {
+ Name: "unconvert",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "unparam",
+ Presets: []string{"unused"},
+ Slow: true,
+ },
+ {
+ Name: "unused",
+ Presets: []string{"unused"},
+ Slow: true,
+ Default: true,
+ AlternativeNames: []string{"megacheck"},
+ },
+ {
+ Name: "usestdlibvars",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "usetesting",
+ Presets: []string{"test"},
+ Slow: true,
+ },
+ {
+ Name: "varnamelen",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "wastedassign",
+ Presets: []string{"style"},
+ Slow: true,
+ },
+ {
+ Name: "whitespace",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "wrapcheck",
+ Presets: []string{"style", "error"},
+ Slow: true,
+ },
+ {
+ Name: "wsl",
+ Presets: []string{"style"},
+ },
+ {
+ Name: "zerologlint",
+ Presets: []string{"bugs"},
+ Slow: true,
+ },
+ {
+ Name: "nolintlint",
+ Presets: []string{"style"},
+ },
+ }
+}
+
+func toNames(linters []LinterInfo) []string {
+ var results []string
+
+ for _, linter := range linters {
+ results = append(results, linter.Name)
+ }
+
+ return Unique(results)
+}
+
+func removeLinters(linters, toRemove []LinterInfo) []LinterInfo {
+ return slices.DeleteFunc(linters, func(info LinterInfo) bool {
+ return slices.ContainsFunc(toRemove, func(en LinterInfo) bool {
+ return info.Name == en.Name
+ })
+ })
+}
+
+func allEnabled(old versionone.Linters, linters []LinterInfo) []LinterInfo {
+ var results []LinterInfo
+
+ for _, linter := range linters {
+ for _, name := range old.Enable {
+ if linter.isName(name) {
+ results = append(results, linter)
+ break
+ }
+ }
+ }
+
+ return results
+}
+
+func allDisabled(old versionone.Linters, linters []LinterInfo) []LinterInfo {
+ var results []LinterInfo
+
+ for _, linter := range linters {
+ for _, name := range old.Disable {
+ if linter.isName(name) {
+ results = append(results, linter)
+ break
+ }
+ }
+ }
+
+ return results
+}
+
+func filter(linters []LinterInfo, fns ...fnFilter) []LinterInfo {
+ var results []LinterInfo
+
+ for _, linter := range linters {
+ if mergeFilters(linter, fns) {
+ results = append(results, linter)
+ }
+ }
+
+ return results
+}
+
+func mergeFilters(linter LinterInfo, fns []fnFilter) bool {
+ for _, fn := range fns {
+ if !fn(linter) {
+ return false
+ }
+ }
+
+ return true
+}
+
+type fnFilter func(linter LinterInfo) bool
+
+func onlyPresets(old versionone.Linters) fnFilter {
+ return func(linter LinterInfo) bool {
+ return linter.hasPresets(old.Presets)
+ }
+}
+
+func onlyDefault(linter LinterInfo) bool {
+ return linter.Default
+}
+
+func notDefault(linter LinterInfo) bool {
+ return !linter.Default
+}
+
+func keepFast(old versionone.Linters) fnFilter {
+ return func(linter LinterInfo) bool {
+ if !ptr.Deref(old.Fast) {
+ return true
+ }
+
+ return !linter.Slow
+ }
+}
+
+func keepSlow(old versionone.Linters) fnFilter {
+ return func(linter LinterInfo) bool {
+ if !ptr.Deref(old.Fast) {
+ return false
+ }
+
+ return linter.Slow
+ }
+}
+
+func unknownLinterNames(names []string, linters []LinterInfo) []string {
+ deprecatedLinters := []string{
+ "deadcode",
+ "execinquery",
+ "exhaustivestruct",
+ "exportloopref",
+ "golint",
+ "ifshort",
+ "interfacer",
+ "maligned",
+ "nosnakecase",
+ "scopelint",
+ "structcheck",
+ "tenv",
+ "typecheck",
+ "varcheck",
+ }
+
+ var results []string
+
+ for _, name := range names {
+ found := slices.ContainsFunc(linters, func(l LinterInfo) bool {
+ return l.isName(name)
+ })
+
+ if !found {
+ if slices.Contains(deprecatedLinters, name) {
+ continue
+ }
+
+ results = append(results, name)
+ }
+ }
+
+ return Unique(results)
+}
+
+func convertStaticcheckLinterNames(names []string) []string {
+ var results []string
+
+ for _, name := range names {
+ if slices.Contains([]string{"stylecheck", "gosimple"}, name) {
+ results = append(results, "staticcheck")
+ continue
+ }
+
+ results = append(results, name)
+ }
+
+ return Unique(results)
+}
+
+func convertDisabledStaticcheckLinterNames(names []string) []string {
+ removeStaticcheck := slices.Contains(names, "staticcheck") && slices.Contains(names, "stylecheck") && slices.Contains(names, "gosimple")
+
+ var results []string
+
+ for _, name := range names {
+ if removeStaticcheck && slices.Contains([]string{"stylecheck", "gosimple", "staticcheck"}, name) {
+ results = append(results, "staticcheck")
+ continue
+ }
+
+ if slices.Contains([]string{"stylecheck", "gosimple"}, name) {
+ continue
+ }
+
+ results = append(results, name)
+ }
+
+ return Unique(results)
+}
+
+func onlyLinterNames(names []string) []string {
+ formatters := []string{"gci", "gofmt", "gofumpt", "goimports"}
+
+ var results []string
+
+ for _, name := range names {
+ if !slices.Contains(formatters, name) {
+ results = append(results, name)
+ }
+ }
+
+ return results
+}
+
+func onlyFormatterNames(names []string) []string {
+ formatters := getAllFormatterNames()
+
+ var results []string
+
+ for _, name := range names {
+ if slices.Contains(formatters, name) {
+ results = append(results, name)
+ }
+ }
+
+ return results
+}
+
+func convertAlternativeNames(names []string) []string {
+ altNames := map[string]string{
+ "gas": "gosec",
+ "goerr113": "err113",
+ "gomnd": "mnd",
+ "logrlint": "loggercheck",
+ "megacheck": "staticcheck",
+ "vet": "govet",
+ "vetshadow": "govet",
+ }
+
+ var results []string
+
+ for _, name := range names {
+ if name == "typecheck" {
+ continue
+ }
+
+ if n, ok := altNames[name]; ok {
+ results = append(results, n)
+ continue
+ }
+
+ results = append(results, name)
+ }
+
+ return Unique(results)
+}
+
+func Unique[S ~[]E, E cmp.Ordered](s S) S {
+ return slices.Compact(slices.Sorted(slices.Values(s)))
+}
+
+func getAllFormatterNames() []string {
+ return []string{"gci", "gofmt", "gofumpt", "goimports"}
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters.go
new file mode 100644
index 00000000..c070119b
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters.go
@@ -0,0 +1,31 @@
+package migrate
+
+import (
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
+)
+
+func toLinters(old *versionone.Config) versiontwo.Linters {
+ enable, disable := ProcessEffectiveLinters(old.Linters)
+
+ return versiontwo.Linters{
+ Default: getDefaultName(old.Linters),
+ Enable: onlyLinterNames(convertStaticcheckLinterNames(enable)),
+ Disable: onlyLinterNames(convertDisabledStaticcheckLinterNames(disable)),
+ FastOnly: nil,
+ Settings: toLinterSettings(old.LintersSettings),
+ Exclusions: toExclusions(old),
+ }
+}
+
+func getDefaultName(old versionone.Linters) *string {
+ switch {
+ case ptr.Deref(old.DisableAll):
+ return ptr.Pointer("none")
+ case ptr.Deref(old.EnableAll):
+ return ptr.Pointer("all")
+ default:
+ return nil // standard is the default
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_exclusions.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_exclusions.go
new file mode 100644
index 00000000..aac4d381
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_exclusions.go
@@ -0,0 +1,144 @@
+package migrate
+
+import (
+ "slices"
+
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/result/processors"
+)
+
+func toExclusions(old *versionone.Config) versiontwo.LinterExclusions {
+ return versiontwo.LinterExclusions{
+ Generated: toExclusionGenerated(old.Issues.ExcludeGenerated),
+ Presets: toPresets(old.Issues),
+ Rules: toExclusionRules(old),
+ Paths: toExclusionPaths(old.Issues),
+ }
+}
+
+func toExclusionGenerated(excludeGenerated *string) *string {
+ if excludeGenerated == nil || ptr.Deref(excludeGenerated) == "" {
+ return ptr.Pointer("lax")
+ }
+
+ if ptr.Deref(excludeGenerated) == "strict" {
+ return nil
+ }
+
+ return excludeGenerated
+}
+
+func toPresets(old versionone.Issues) []string {
+ if old.UseDefaultExcludes != nil && !ptr.Deref(old.UseDefaultExcludes) {
+ return nil
+ }
+
+ if len(old.IncludeDefaultExcludes) != 0 {
+ var pp []string
+ for p, rules := range processors.LinterExclusionPresets {
+ found := slices.ContainsFunc(rules, func(rule config.ExcludeRule) bool {
+ return slices.Contains(old.IncludeDefaultExcludes, rule.InternalReference)
+ })
+ if !found {
+ pp = append(pp, p)
+ }
+ }
+
+ slices.Sort(pp)
+
+ return pp
+ }
+
+ return []string{
+ config.ExclusionPresetComments,
+ config.ExclusionPresetCommonFalsePositives,
+ config.ExclusionPresetLegacy,
+ config.ExclusionPresetStdErrorHandling,
+ }
+}
+
+func toExclusionRules(old *versionone.Config) []versiontwo.ExcludeRule {
+ var results []versiontwo.ExcludeRule
+
+ for _, rule := range old.Issues.ExcludeRules {
+ names := onlyLinterNames(convertStaticcheckLinterNames(convertAlternativeNames(rule.Linters)))
+ if len(rule.Linters) > 0 && len(names) == 0 {
+ continue
+ }
+
+ results = append(results, versiontwo.ExcludeRule{
+ BaseRule: versiontwo.BaseRule{
+ Linters: names,
+ Path: rule.Path,
+ PathExcept: rule.PathExcept,
+ Text: addPrefix(old.Issues, rule.Text),
+ Source: addPrefix(old.Issues, rule.Source),
+ },
+ })
+ }
+
+ for _, pattern := range old.Issues.ExcludePatterns {
+ results = append(results, versiontwo.ExcludeRule{
+ BaseRule: versiontwo.BaseRule{
+ Path: ptr.Pointer(`(.+)\.go$`),
+ Text: addPrefix(old.Issues, ptr.Pointer(pattern)),
+ },
+ })
+ }
+
+ return slices.Concat(results, linterTestExclusions(old.LintersSettings))
+}
+
+func addPrefix(old versionone.Issues, s *string) *string {
+ if s == nil || ptr.Deref(s) == "" {
+ return s
+ }
+
+ var prefix string
+ if ptr.Deref(old.ExcludeCaseSensitive) {
+ prefix = "(?i)"
+ }
+
+ return ptr.Pointer(prefix + ptr.Deref(s))
+}
+
+func linterTestExclusions(old versionone.LintersSettings) []versiontwo.ExcludeRule {
+ var excludedTestLinters []string
+
+ if ptr.Deref(old.Asasalint.IgnoreTest) {
+ excludedTestLinters = append(excludedTestLinters, "asasalint")
+ }
+ if ptr.Deref(old.Cyclop.SkipTests) {
+ excludedTestLinters = append(excludedTestLinters, "cyclop")
+ }
+ if ptr.Deref(old.Goconst.IgnoreTests) {
+ excludedTestLinters = append(excludedTestLinters, "goconst")
+ }
+ if ptr.Deref(old.Gosmopolitan.IgnoreTests) {
+ excludedTestLinters = append(excludedTestLinters, "gosmopolitan")
+ }
+
+ if len(excludedTestLinters) == 0 {
+ return nil
+ }
+
+ return []versiontwo.ExcludeRule{{
+ BaseRule: versiontwo.BaseRule{
+ Linters: excludedTestLinters,
+ Path: ptr.Pointer(`(.+)_test\.go`),
+ },
+ }}
+}
+
+func toExclusionPaths(old versionone.Issues) []string {
+ results := slices.Concat(old.ExcludeFiles, old.ExcludeDirs)
+
+ if old.UseDefaultExcludeDirs == nil || ptr.Deref(old.UseDefaultExcludeDirs) {
+ results = append(results, "third_party$", "builtin$", "examples$")
+ }
+
+ return results
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_settings.go
new file mode 100644
index 00000000..5accd9f5
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_settings.go
@@ -0,0 +1,1037 @@
+package migrate
+
+import (
+ "slices"
+ "strings"
+
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
+)
+
+func toLinterSettings(old versionone.LintersSettings) versiontwo.LintersSettings {
+ return versiontwo.LintersSettings{
+ Asasalint: toAsasalintSettings(old.Asasalint),
+ BiDiChk: toBiDiChkSettings(old.BiDiChk),
+ CopyLoopVar: toCopyLoopVarSettings(old.CopyLoopVar),
+ Cyclop: toCyclopSettings(old.Cyclop),
+ Decorder: toDecorderSettings(old.Decorder),
+ Depguard: toDepGuardSettings(old.Depguard),
+ Dogsled: toDogsledSettings(old.Dogsled),
+ Dupl: toDuplSettings(old.Dupl),
+ DupWord: toDupWordSettings(old.DupWord),
+ Errcheck: toErrcheckSettings(old.Errcheck),
+ ErrChkJSON: toErrChkJSONSettings(old.ErrChkJSON),
+ ErrorLint: toErrorLintSettings(old.ErrorLint),
+ Exhaustive: toExhaustiveSettings(old.Exhaustive),
+ Exhaustruct: toExhaustructSettings(old.Exhaustruct),
+ Fatcontext: toFatcontextSettings(old.Fatcontext),
+ Forbidigo: toForbidigoSettings(old.Forbidigo),
+ Funlen: toFunlenSettings(old.Funlen),
+ GinkgoLinter: toGinkgoLinterSettings(old.GinkgoLinter),
+ Gocognit: toGocognitSettings(old.Gocognit),
+ GoChecksumType: toGoChecksumTypeSettings(old.GoChecksumType),
+ Goconst: toGoConstSettings(old.Goconst),
+ Gocritic: toGoCriticSettings(old.Gocritic),
+ Gocyclo: toGoCycloSettings(old.Gocyclo),
+ Godot: toGodotSettings(old.Godot),
+ Godox: toGodoxSettings(old.Godox),
+ Goheader: toGoHeaderSettings(old.Goheader),
+ GoModDirectives: toGoModDirectivesSettings(old.GoModDirectives),
+ Gomodguard: toGoModGuardSettings(old.Gomodguard),
+ Gosec: toGoSecSettings(old.Gosec),
+ Gosmopolitan: toGosmopolitanSettings(old.Gosmopolitan),
+ Govet: toGovetSettings(old.Govet),
+ Grouper: toGrouperSettings(old.Grouper),
+ Iface: toIfaceSettings(old.Iface),
+ ImportAs: toImportAsSettings(old.ImportAs),
+ Inamedparam: toINamedParamSettings(old.Inamedparam),
+ InterfaceBloat: toInterfaceBloatSettings(old.InterfaceBloat),
+ Ireturn: toIreturnSettings(old.Ireturn),
+ Lll: toLllSettings(old.Lll),
+ LoggerCheck: toLoggerCheckSettings(old.LoggerCheck),
+ MaintIdx: toMaintIdxSettings(old.MaintIdx),
+ Makezero: toMakezeroSettings(old.Makezero),
+ Misspell: toMisspellSettings(old.Misspell),
+ Mnd: toMndSettings(old.Mnd),
+ MustTag: toMustTagSettings(old.MustTag),
+ Nakedret: toNakedretSettings(old.Nakedret),
+ Nestif: toNestifSettings(old.Nestif),
+ NilNil: toNilNilSettings(old.NilNil),
+ Nlreturn: toNlreturnSettings(old.Nlreturn),
+ NoLintLint: toNoLintLintSettings(old.NoLintLint),
+ NoNamedReturns: toNoNamedReturnsSettings(old.NoNamedReturns),
+ ParallelTest: toParallelTestSettings(old.ParallelTest),
+ PerfSprint: toPerfSprintSettings(old.PerfSprint),
+ Prealloc: toPreallocSettings(old.Prealloc),
+ Predeclared: toPredeclaredSettings(old.Predeclared),
+ Promlinter: toPromlinterSettings(old.Promlinter),
+ ProtoGetter: toProtoGetterSettings(old.ProtoGetter),
+ Reassign: toReassignSettings(old.Reassign),
+ Recvcheck: toRecvcheckSettings(old.Recvcheck),
+ Revive: toReviveSettings(old.Revive),
+ RowsErrCheck: toRowsErrCheckSettings(old.RowsErrCheck),
+ SlogLint: toSlogLintSettings(old.SlogLint),
+ Spancheck: toSpancheckSettings(old.Spancheck),
+ Staticcheck: toStaticCheckSettings(old),
+ TagAlign: toTagAlignSettings(old.TagAlign),
+ Tagliatelle: toTagliatelleSettings(old.Tagliatelle),
+ Testifylint: toTestifylintSettings(old.Testifylint),
+ Testpackage: toTestpackageSettings(old.Testpackage),
+ Thelper: toThelperSettings(old.Thelper),
+ Unconvert: toUnconvertSettings(old.Unconvert),
+ Unparam: toUnparamSettings(old.Unparam),
+ Unused: toUnusedSettings(old.Unused),
+ UseStdlibVars: toUseStdlibVarsSettings(old.UseStdlibVars),
+ UseTesting: toUseTestingSettings(old.UseTesting),
+ Varnamelen: toVarnamelenSettings(old.Varnamelen),
+ Whitespace: toWhitespaceSettings(old.Whitespace),
+ Wrapcheck: toWrapcheckSettings(old.Wrapcheck),
+ WSL: toWSLSettings(old.WSL),
+ Custom: toCustom(old.Custom),
+ }
+}
+
+func toAsasalintSettings(old versionone.AsasalintSettings) versiontwo.AsasalintSettings {
+ return versiontwo.AsasalintSettings{
+ Exclude: old.Exclude,
+ UseBuiltinExclusions: old.UseBuiltinExclusions,
+ }
+}
+
+func toBiDiChkSettings(old versionone.BiDiChkSettings) versiontwo.BiDiChkSettings {
+ // The values are true be default, but the default are defined after the configuration loading.
+ // So the serialization doesn't have good results, but it's complex to do better.
+ return versiontwo.BiDiChkSettings{
+ LeftToRightEmbedding: old.LeftToRightEmbedding,
+ RightToLeftEmbedding: old.RightToLeftEmbedding,
+ PopDirectionalFormatting: old.PopDirectionalFormatting,
+ LeftToRightOverride: old.LeftToRightOverride,
+ RightToLeftOverride: old.RightToLeftOverride,
+ LeftToRightIsolate: old.LeftToRightIsolate,
+ RightToLeftIsolate: old.RightToLeftIsolate,
+ FirstStrongIsolate: old.FirstStrongIsolate,
+ PopDirectionalIsolate: old.PopDirectionalIsolate,
+ }
+}
+
+func toCopyLoopVarSettings(old versionone.CopyLoopVarSettings) versiontwo.CopyLoopVarSettings {
+ return versiontwo.CopyLoopVarSettings{
+ CheckAlias: old.CheckAlias,
+ }
+}
+
+func toCyclopSettings(old versionone.Cyclop) versiontwo.CyclopSettings {
+ return versiontwo.CyclopSettings{
+ MaxComplexity: old.MaxComplexity,
+ PackageAverage: old.PackageAverage,
+ }
+}
+
+func toDecorderSettings(old versionone.DecorderSettings) versiontwo.DecorderSettings {
+ return versiontwo.DecorderSettings{
+ DecOrder: old.DecOrder,
+ IgnoreUnderscoreVars: old.IgnoreUnderscoreVars,
+ DisableDecNumCheck: old.DisableDecNumCheck,
+ DisableTypeDecNumCheck: old.DisableTypeDecNumCheck,
+ DisableConstDecNumCheck: old.DisableConstDecNumCheck,
+ DisableVarDecNumCheck: old.DisableVarDecNumCheck,
+ DisableDecOrderCheck: old.DisableDecOrderCheck,
+ DisableInitFuncFirstCheck: old.DisableInitFuncFirstCheck,
+ }
+}
+
+func toDepGuardSettings(old versionone.DepGuardSettings) versiontwo.DepGuardSettings {
+ settings := versiontwo.DepGuardSettings{}
+
+ for k, r := range old.Rules {
+ if settings.Rules == nil {
+ settings.Rules = make(map[string]*versiontwo.DepGuardList)
+ }
+
+ list := &versiontwo.DepGuardList{
+ ListMode: r.ListMode,
+ Files: r.Files,
+ Allow: r.Allow,
+ }
+
+ for _, deny := range r.Deny {
+ list.Deny = append(list.Deny, versiontwo.DepGuardDeny{
+ Pkg: deny.Pkg,
+ Desc: deny.Desc,
+ })
+ }
+
+ settings.Rules[k] = list
+ }
+
+ return settings
+}
+
+func toDogsledSettings(old versionone.DogsledSettings) versiontwo.DogsledSettings {
+ return versiontwo.DogsledSettings{
+ MaxBlankIdentifiers: old.MaxBlankIdentifiers,
+ }
+}
+
+func toDuplSettings(old versionone.DuplSettings) versiontwo.DuplSettings {
+ return versiontwo.DuplSettings{
+ Threshold: old.Threshold,
+ }
+}
+
+func toDupWordSettings(old versionone.DupWordSettings) versiontwo.DupWordSettings {
+ return versiontwo.DupWordSettings{
+ Keywords: old.Keywords,
+ Ignore: old.Ignore,
+ }
+}
+
+func toErrcheckSettings(old versionone.ErrcheckSettings) versiontwo.ErrcheckSettings {
+ return versiontwo.ErrcheckSettings{
+ DisableDefaultExclusions: old.DisableDefaultExclusions,
+ CheckTypeAssertions: old.CheckTypeAssertions,
+ CheckAssignToBlank: old.CheckAssignToBlank,
+ ExcludeFunctions: old.ExcludeFunctions,
+ }
+}
+
+func toErrChkJSONSettings(old versionone.ErrChkJSONSettings) versiontwo.ErrChkJSONSettings {
+ return versiontwo.ErrChkJSONSettings{
+ CheckErrorFreeEncoding: old.CheckErrorFreeEncoding,
+ ReportNoExported: old.ReportNoExported,
+ }
+}
+
+func toErrorLintSettings(old versionone.ErrorLintSettings) versiontwo.ErrorLintSettings {
+ settings := versiontwo.ErrorLintSettings{
+ Errorf: old.Errorf,
+ ErrorfMulti: old.ErrorfMulti,
+ Asserts: old.Asserts,
+ Comparison: old.Comparison,
+ }
+
+ for _, allowedError := range old.AllowedErrors {
+ settings.AllowedErrors = append(settings.AllowedErrors, versiontwo.ErrorLintAllowPair{
+ Err: allowedError.Err,
+ Fun: allowedError.Fun,
+ })
+ }
+ for _, allowedError := range old.AllowedErrorsWildcard {
+ settings.AllowedErrorsWildcard = append(settings.AllowedErrorsWildcard, versiontwo.ErrorLintAllowPair{
+ Err: allowedError.Err,
+ Fun: allowedError.Fun,
+ })
+ }
+
+ return settings
+}
+
+func toExhaustiveSettings(old versionone.ExhaustiveSettings) versiontwo.ExhaustiveSettings {
+ return versiontwo.ExhaustiveSettings{
+ Check: old.Check,
+ DefaultSignifiesExhaustive: old.DefaultSignifiesExhaustive,
+ IgnoreEnumMembers: old.IgnoreEnumMembers,
+ IgnoreEnumTypes: old.IgnoreEnumTypes,
+ PackageScopeOnly: old.PackageScopeOnly,
+ ExplicitExhaustiveMap: old.ExplicitExhaustiveMap,
+ ExplicitExhaustiveSwitch: old.ExplicitExhaustiveSwitch,
+ DefaultCaseRequired: old.DefaultCaseRequired,
+ }
+}
+
+func toExhaustructSettings(old versionone.ExhaustructSettings) versiontwo.ExhaustructSettings {
+ return versiontwo.ExhaustructSettings{
+ Include: old.Include,
+ Exclude: old.Exclude,
+ }
+}
+
+func toFatcontextSettings(old versionone.FatcontextSettings) versiontwo.FatcontextSettings {
+ return versiontwo.FatcontextSettings{
+ CheckStructPointers: old.CheckStructPointers,
+ }
+}
+
+func toForbidigoSettings(old versionone.ForbidigoSettings) versiontwo.ForbidigoSettings {
+ settings := versiontwo.ForbidigoSettings{
+ ExcludeGodocExamples: old.ExcludeGodocExamples,
+ AnalyzeTypes: old.AnalyzeTypes,
+ }
+
+ for _, pattern := range old.Forbid {
+ if pattern.Pattern == nil && pattern.Msg == nil && pattern.Package == nil {
+ buffer, err := pattern.MarshalString()
+ if err != nil {
+ // impossible case
+ panic(err)
+ }
+
+ settings.Forbid = append(settings.Forbid, versiontwo.ForbidigoPattern{
+ Pattern: ptr.Pointer(string(buffer)),
+ })
+
+ continue
+ }
+
+ settings.Forbid = append(settings.Forbid, versiontwo.ForbidigoPattern{
+ Pattern: pattern.Pattern,
+ Package: pattern.Package,
+ Msg: pattern.Msg,
+ })
+ }
+
+ return settings
+}
+
+func toFunlenSettings(old versionone.FunlenSettings) versiontwo.FunlenSettings {
+ return versiontwo.FunlenSettings{
+ Lines: old.Lines,
+ Statements: old.Statements,
+ IgnoreComments: old.IgnoreComments,
+ }
+}
+
+func toGinkgoLinterSettings(old versionone.GinkgoLinterSettings) versiontwo.GinkgoLinterSettings {
+ return versiontwo.GinkgoLinterSettings{
+ SuppressLenAssertion: old.SuppressLenAssertion,
+ SuppressNilAssertion: old.SuppressNilAssertion,
+ SuppressErrAssertion: old.SuppressErrAssertion,
+ SuppressCompareAssertion: old.SuppressCompareAssertion,
+ SuppressAsyncAssertion: old.SuppressAsyncAssertion,
+ SuppressTypeCompareWarning: old.SuppressTypeCompareWarning,
+ ForbidFocusContainer: old.ForbidFocusContainer,
+ AllowHaveLenZero: old.AllowHaveLenZero,
+ ForceExpectTo: old.ForceExpectTo,
+ ValidateAsyncIntervals: old.ValidateAsyncIntervals,
+ ForbidSpecPollution: old.ForbidSpecPollution,
+ ForceSucceedForFuncs: old.ForceSucceedForFuncs,
+ }
+}
+
+func toGocognitSettings(old versionone.GocognitSettings) versiontwo.GocognitSettings {
+ return versiontwo.GocognitSettings{
+ MinComplexity: old.MinComplexity,
+ }
+}
+
+func toGoChecksumTypeSettings(old versionone.GoChecksumTypeSettings) versiontwo.GoChecksumTypeSettings {
+ return versiontwo.GoChecksumTypeSettings{
+ DefaultSignifiesExhaustive: old.DefaultSignifiesExhaustive,
+ IncludeSharedInterfaces: old.IncludeSharedInterfaces,
+ }
+}
+
+func toGoConstSettings(old versionone.GoConstSettings) versiontwo.GoConstSettings {
+ return versiontwo.GoConstSettings{
+ IgnoreStrings: old.IgnoreStrings,
+ MatchWithConstants: old.MatchWithConstants,
+ MinStringLen: old.MinStringLen,
+ MinOccurrencesCount: old.MinOccurrencesCount,
+ ParseNumbers: old.ParseNumbers,
+ NumberMin: old.NumberMin,
+ NumberMax: old.NumberMax,
+ IgnoreCalls: old.IgnoreCalls,
+ }
+}
+
+func toGoCriticSettings(old versionone.GoCriticSettings) versiontwo.GoCriticSettings {
+ settings := versiontwo.GoCriticSettings{
+ Go: old.Go,
+ DisableAll: old.DisableAll,
+ EnabledChecks: old.EnabledChecks,
+ EnableAll: old.EnableAll,
+ DisabledChecks: old.DisabledChecks,
+ EnabledTags: old.EnabledTags,
+ DisabledTags: old.DisabledTags,
+ }
+
+ for k, checkSettings := range old.SettingsPerCheck {
+ if settings.SettingsPerCheck == nil {
+ settings.SettingsPerCheck = make(map[string]versiontwo.GoCriticCheckSettings)
+ }
+
+ if k != "ruleguard" {
+ settings.SettingsPerCheck[k] = versiontwo.GoCriticCheckSettings(checkSettings)
+
+ continue
+ }
+
+ gccs := versiontwo.GoCriticCheckSettings{}
+
+ for sk, value := range checkSettings {
+ if sk != "rules" {
+ gccs[sk] = value
+
+ continue
+ }
+
+ if rules, ok := value.(string); ok {
+ gccs[sk] = strings.ReplaceAll(rules, "${configDir}", "${base-path}")
+ }
+ }
+
+ settings.SettingsPerCheck[k] = gccs
+ }
+
+ return settings
+}
+
+func toGoCycloSettings(old versionone.GoCycloSettings) versiontwo.GoCycloSettings {
+ return versiontwo.GoCycloSettings{
+ MinComplexity: old.MinComplexity,
+ }
+}
+
+func toGodotSettings(old versionone.GodotSettings) versiontwo.GodotSettings {
+ return versiontwo.GodotSettings{
+ Scope: old.Scope,
+ Exclude: old.Exclude,
+ Capital: old.Capital,
+ Period: old.Period,
+ }
+}
+
+func toGodoxSettings(old versionone.GodoxSettings) versiontwo.GodoxSettings {
+ return versiontwo.GodoxSettings{
+ Keywords: old.Keywords,
+ }
+}
+
+func toGoHeaderSettings(old versionone.GoHeaderSettings) versiontwo.GoHeaderSettings {
+ return versiontwo.GoHeaderSettings{
+ Values: old.Values,
+ Template: old.Template,
+ TemplatePath: old.TemplatePath,
+ }
+}
+
+func toGoModDirectivesSettings(old versionone.GoModDirectivesSettings) versiontwo.GoModDirectivesSettings {
+ return versiontwo.GoModDirectivesSettings{
+ ReplaceAllowList: old.ReplaceAllowList,
+ ReplaceLocal: old.ReplaceLocal,
+ ExcludeForbidden: old.ExcludeForbidden,
+ RetractAllowNoExplanation: old.RetractAllowNoExplanation,
+ ToolchainForbidden: old.ToolchainForbidden,
+ ToolchainPattern: old.ToolchainPattern,
+ ToolForbidden: old.ToolForbidden,
+ GoDebugForbidden: old.GoDebugForbidden,
+ GoVersionPattern: old.GoVersionPattern,
+ }
+}
+
+func toGoModGuardSettings(old versionone.GoModGuardSettings) versiontwo.GoModGuardSettings {
+ blocked := versiontwo.GoModGuardBlocked{
+ LocalReplaceDirectives: old.Blocked.LocalReplaceDirectives,
+ }
+
+ for _, version := range old.Blocked.Modules {
+ data := map[string]versiontwo.GoModGuardModule{}
+
+ for k, v := range version {
+ data[k] = versiontwo.GoModGuardModule{
+ Recommendations: v.Recommendations,
+ Reason: v.Reason,
+ }
+ }
+
+ blocked.Modules = append(blocked.Modules, data)
+ }
+
+ for _, version := range old.Blocked.Versions {
+ data := map[string]versiontwo.GoModGuardVersion{}
+
+ for k, v := range version {
+ data[k] = versiontwo.GoModGuardVersion{
+ Version: v.Version,
+ Reason: v.Reason,
+ }
+ }
+
+ blocked.Versions = append(blocked.Versions, data)
+ }
+
+ return versiontwo.GoModGuardSettings{
+ Allowed: versiontwo.GoModGuardAllowed{
+ Modules: old.Allowed.Modules,
+ Domains: old.Allowed.Domains,
+ },
+ Blocked: blocked,
+ }
+}
+
+func toGoSecSettings(old versionone.GoSecSettings) versiontwo.GoSecSettings {
+ return versiontwo.GoSecSettings{
+ Includes: old.Includes,
+ Excludes: old.Excludes,
+ Severity: old.Severity,
+ Confidence: old.Confidence,
+ Config: old.Config,
+ Concurrency: old.Concurrency,
+ }
+}
+
+func toGosmopolitanSettings(old versionone.GosmopolitanSettings) versiontwo.GosmopolitanSettings {
+ return versiontwo.GosmopolitanSettings{
+ AllowTimeLocal: old.AllowTimeLocal,
+ EscapeHatches: old.EscapeHatches,
+ WatchForScripts: old.WatchForScripts,
+ }
+}
+
+func toGovetSettings(old versionone.GovetSettings) versiontwo.GovetSettings {
+ return versiontwo.GovetSettings{
+ Go: old.Go,
+ Enable: old.Enable,
+ Disable: old.Disable,
+ EnableAll: old.EnableAll,
+ DisableAll: old.DisableAll,
+ Settings: old.Settings,
+ }
+}
+
+func toGrouperSettings(old versionone.GrouperSettings) versiontwo.GrouperSettings {
+ return versiontwo.GrouperSettings{
+ ConstRequireSingleConst: old.ConstRequireSingleConst,
+ ConstRequireGrouping: old.ConstRequireGrouping,
+ ImportRequireSingleImport: old.ImportRequireSingleImport,
+ ImportRequireGrouping: old.ImportRequireGrouping,
+ TypeRequireSingleType: old.TypeRequireSingleType,
+ TypeRequireGrouping: old.TypeRequireGrouping,
+ VarRequireSingleVar: old.VarRequireSingleVar,
+ VarRequireGrouping: old.VarRequireGrouping,
+ }
+}
+
+func toIfaceSettings(old versionone.IfaceSettings) versiontwo.IfaceSettings {
+ return versiontwo.IfaceSettings{
+ Enable: old.Enable,
+ Settings: old.Settings,
+ }
+}
+
+func toImportAsSettings(old versionone.ImportAsSettings) versiontwo.ImportAsSettings {
+ settings := versiontwo.ImportAsSettings{
+ NoUnaliased: old.NoUnaliased,
+ NoExtraAliases: old.NoExtraAliases,
+ }
+
+ for _, alias := range old.Alias {
+ settings.Alias = append(settings.Alias, versiontwo.ImportAsAlias{
+ Pkg: alias.Pkg,
+ Alias: alias.Alias,
+ })
+ }
+
+ return settings
+}
+
+func toINamedParamSettings(old versionone.INamedParamSettings) versiontwo.INamedParamSettings {
+ return versiontwo.INamedParamSettings{
+ SkipSingleParam: old.SkipSingleParam,
+ }
+}
+
+func toInterfaceBloatSettings(old versionone.InterfaceBloatSettings) versiontwo.InterfaceBloatSettings {
+ return versiontwo.InterfaceBloatSettings{
+ Max: old.Max,
+ }
+}
+
+func toIreturnSettings(old versionone.IreturnSettings) versiontwo.IreturnSettings {
+ return versiontwo.IreturnSettings{
+ Allow: old.Allow,
+ Reject: old.Reject,
+ }
+}
+
+func toLllSettings(old versionone.LllSettings) versiontwo.LllSettings {
+ return versiontwo.LllSettings{
+ LineLength: old.LineLength,
+ TabWidth: old.TabWidth,
+ }
+}
+
+func toLoggerCheckSettings(old versionone.LoggerCheckSettings) versiontwo.LoggerCheckSettings {
+ return versiontwo.LoggerCheckSettings{
+ Kitlog: old.Kitlog,
+ Klog: old.Klog,
+ Logr: old.Logr,
+ Slog: old.Slog,
+ Zap: old.Zap,
+ RequireStringKey: old.RequireStringKey,
+ NoPrintfLike: old.NoPrintfLike,
+ Rules: old.Rules,
+ }
+}
+
+func toMaintIdxSettings(old versionone.MaintIdxSettings) versiontwo.MaintIdxSettings {
+ return versiontwo.MaintIdxSettings{
+ Under: old.Under,
+ }
+}
+
+func toMakezeroSettings(old versionone.MakezeroSettings) versiontwo.MakezeroSettings {
+ return versiontwo.MakezeroSettings{
+ Always: old.Always,
+ }
+}
+
+func toMisspellSettings(old versionone.MisspellSettings) versiontwo.MisspellSettings {
+ settings := versiontwo.MisspellSettings{
+ Mode: old.Mode,
+ Locale: old.Locale,
+ IgnoreRules: old.IgnoreWords,
+ }
+
+ for _, word := range old.ExtraWords {
+ settings.ExtraWords = append(settings.ExtraWords, versiontwo.MisspellExtraWords{
+ Typo: word.Typo,
+ Correction: word.Correction,
+ })
+ }
+
+ return settings
+}
+
+func toMndSettings(old versionone.MndSettings) versiontwo.MndSettings {
+ return versiontwo.MndSettings{
+ Checks: old.Checks,
+ IgnoredNumbers: old.IgnoredNumbers,
+ IgnoredFiles: old.IgnoredFiles,
+ IgnoredFunctions: old.IgnoredFunctions,
+ }
+}
+
+func toMustTagSettings(old versionone.MustTagSettings) versiontwo.MustTagSettings {
+ settings := versiontwo.MustTagSettings{}
+
+ for _, function := range old.Functions {
+ settings.Functions = append(settings.Functions, versiontwo.MustTagFunction{
+ Name: function.Name,
+ Tag: function.Tag,
+ ArgPos: function.ArgPos,
+ })
+ }
+
+ return settings
+}
+
+func toNakedretSettings(old versionone.NakedretSettings) versiontwo.NakedretSettings {
+ return versiontwo.NakedretSettings{
+ MaxFuncLines: old.MaxFuncLines,
+ }
+}
+
+func toNestifSettings(old versionone.NestifSettings) versiontwo.NestifSettings {
+ return versiontwo.NestifSettings{
+ MinComplexity: old.MinComplexity,
+ }
+}
+
+func toNilNilSettings(old versionone.NilNilSettings) versiontwo.NilNilSettings {
+ return versiontwo.NilNilSettings{
+ DetectOpposite: old.DetectOpposite,
+ CheckedTypes: old.CheckedTypes,
+ }
+}
+
+func toNlreturnSettings(old versionone.NlreturnSettings) versiontwo.NlreturnSettings {
+ return versiontwo.NlreturnSettings{
+ BlockSize: old.BlockSize,
+ }
+}
+
+func toNoLintLintSettings(old versionone.NoLintLintSettings) versiontwo.NoLintLintSettings {
+ return versiontwo.NoLintLintSettings{
+ RequireExplanation: old.RequireExplanation,
+ RequireSpecific: old.RequireSpecific,
+ AllowNoExplanation: old.AllowNoExplanation,
+ AllowUnused: old.AllowUnused,
+ }
+}
+
+func toNoNamedReturnsSettings(old versionone.NoNamedReturnsSettings) versiontwo.NoNamedReturnsSettings {
+ return versiontwo.NoNamedReturnsSettings{
+ ReportErrorInDefer: old.ReportErrorInDefer,
+ }
+}
+
+func toParallelTestSettings(old versionone.ParallelTestSettings) versiontwo.ParallelTestSettings {
+ return versiontwo.ParallelTestSettings{
+ Go: nil,
+ IgnoreMissing: old.IgnoreMissing,
+ IgnoreMissingSubtests: old.IgnoreMissingSubtests,
+ }
+}
+
+func toPerfSprintSettings(old versionone.PerfSprintSettings) versiontwo.PerfSprintSettings {
+ return versiontwo.PerfSprintSettings{
+ IntegerFormat: old.IntegerFormat,
+ IntConversion: old.IntConversion,
+ ErrorFormat: old.ErrorFormat,
+ ErrError: old.ErrError,
+ ErrorF: old.ErrorF,
+ StringFormat: old.StringFormat,
+ SprintF1: old.SprintF1,
+ StrConcat: old.StrConcat,
+ BoolFormat: old.BoolFormat,
+ HexFormat: old.HexFormat,
+ }
+}
+
+func toPreallocSettings(old versionone.PreallocSettings) versiontwo.PreallocSettings {
+ return versiontwo.PreallocSettings{
+ Simple: old.Simple,
+ RangeLoops: old.RangeLoops,
+ ForLoops: old.ForLoops,
+ }
+}
+
+func toPredeclaredSettings(old versionone.PredeclaredSettings) versiontwo.PredeclaredSettings {
+ var ignore []string
+ if ptr.Deref(old.Ignore) != "" {
+ ignore = strings.Split(ptr.Deref(old.Ignore), ",")
+ }
+
+ return versiontwo.PredeclaredSettings{
+ Ignore: ignore,
+ Qualified: old.Qualified,
+ }
+}
+
+func toPromlinterSettings(old versionone.PromlinterSettings) versiontwo.PromlinterSettings {
+ return versiontwo.PromlinterSettings{
+ Strict: old.Strict,
+ DisabledLinters: old.DisabledLinters,
+ }
+}
+
+func toProtoGetterSettings(old versionone.ProtoGetterSettings) versiontwo.ProtoGetterSettings {
+ return versiontwo.ProtoGetterSettings{
+ SkipGeneratedBy: old.SkipGeneratedBy,
+ SkipFiles: old.SkipFiles,
+ SkipAnyGenerated: old.SkipAnyGenerated,
+ ReplaceFirstArgInAppend: old.ReplaceFirstArgInAppend,
+ }
+}
+
+func toReassignSettings(old versionone.ReassignSettings) versiontwo.ReassignSettings {
+ return versiontwo.ReassignSettings{
+ Patterns: old.Patterns,
+ }
+}
+
+func toRecvcheckSettings(old versionone.RecvcheckSettings) versiontwo.RecvcheckSettings {
+ return versiontwo.RecvcheckSettings{
+ DisableBuiltin: old.DisableBuiltin,
+ Exclusions: old.Exclusions,
+ }
+}
+
+func toReviveSettings(old versionone.ReviveSettings) versiontwo.ReviveSettings {
+ settings := versiontwo.ReviveSettings{
+ MaxOpenFiles: old.MaxOpenFiles,
+ Confidence: old.Confidence,
+ Severity: old.Severity,
+ EnableAllRules: old.EnableAllRules,
+ ErrorCode: old.ErrorCode,
+ WarningCode: old.WarningCode,
+ }
+
+ for _, rule := range old.Rules {
+ settings.Rules = append(settings.Rules, versiontwo.ReviveRule{
+ Name: rule.Name,
+ Arguments: rule.Arguments,
+ Severity: rule.Severity,
+ Disabled: rule.Disabled,
+ Exclude: rule.Exclude,
+ })
+ }
+
+ for _, directive := range old.Directives {
+ settings.Directives = append(settings.Directives, versiontwo.ReviveDirective{
+ Name: directive.Name,
+ Severity: directive.Severity,
+ })
+ }
+
+ return settings
+}
+
+func toRowsErrCheckSettings(old versionone.RowsErrCheckSettings) versiontwo.RowsErrCheckSettings {
+ return versiontwo.RowsErrCheckSettings{
+ Packages: old.Packages,
+ }
+}
+
+func toSlogLintSettings(old versionone.SlogLintSettings) versiontwo.SlogLintSettings {
+ return versiontwo.SlogLintSettings{
+ NoMixedArgs: old.NoMixedArgs,
+ KVOnly: old.KVOnly,
+ AttrOnly: old.AttrOnly,
+ NoGlobal: old.NoGlobal,
+ Context: old.Context,
+ StaticMsg: old.StaticMsg,
+ NoRawKeys: old.NoRawKeys,
+ KeyNamingCase: old.KeyNamingCase,
+ ForbiddenKeys: old.ForbiddenKeys,
+ ArgsOnSepLines: old.ArgsOnSepLines,
+ }
+}
+
+func toSpancheckSettings(old versionone.SpancheckSettings) versiontwo.SpancheckSettings {
+ return versiontwo.SpancheckSettings{
+ Checks: old.Checks,
+ IgnoreCheckSignatures: old.IgnoreCheckSignatures,
+ ExtraStartSpanSignatures: old.ExtraStartSpanSignatures,
+ }
+}
+
+func toStaticCheckSettings(old versionone.LintersSettings) versiontwo.StaticCheckSettings {
+ var checks []string
+
+ for _, check := range slices.Concat(old.Staticcheck.Checks, old.Stylecheck.Checks, old.Gosimple.Checks) {
+ if check == "*" {
+ checks = append(checks, "all")
+ continue
+ }
+ checks = append(checks, check)
+ }
+
+ checks = Unique(checks)
+
+ slices.SortFunc(checks, func(a, b string) int {
+ if a == "all" {
+ return -1
+ }
+
+ if b == "all" {
+ return 1
+ }
+
+ return strings.Compare(a, b)
+ })
+
+ return versiontwo.StaticCheckSettings{
+ Checks: checks,
+ Initialisms: old.Stylecheck.Initialisms,
+ DotImportWhitelist: old.Stylecheck.DotImportWhitelist,
+ HTTPStatusCodeWhitelist: old.Stylecheck.HTTPStatusCodeWhitelist,
+ }
+}
+
+func toTagAlignSettings(old versionone.TagAlignSettings) versiontwo.TagAlignSettings {
+ return versiontwo.TagAlignSettings{
+ Align: old.Align,
+ Sort: old.Sort,
+ Order: old.Order,
+ Strict: old.Strict,
+ }
+}
+
+func toTagliatelleSettings(old versionone.TagliatelleSettings) versiontwo.TagliatelleSettings {
+ tcase := versiontwo.TagliatelleCase{
+ TagliatelleBase: versiontwo.TagliatelleBase{
+ Rules: old.Case.Rules,
+ UseFieldName: old.Case.UseFieldName,
+ IgnoredFields: old.Case.IgnoredFields,
+ },
+ Overrides: []versiontwo.TagliatelleOverrides{},
+ }
+
+ for k, rule := range old.Case.ExtendedRules {
+ if tcase.ExtendedRules == nil {
+ tcase.ExtendedRules = make(map[string]versiontwo.TagliatelleExtendedRule)
+ }
+
+ tcase.ExtendedRules[k] = versiontwo.TagliatelleExtendedRule{
+ Case: rule.Case,
+ ExtraInitialisms: rule.ExtraInitialisms,
+ InitialismOverrides: rule.InitialismOverrides,
+ }
+ }
+
+ return versiontwo.TagliatelleSettings{Case: tcase}
+}
+
+func toTestifylintSettings(old versionone.TestifylintSettings) versiontwo.TestifylintSettings {
+ return versiontwo.TestifylintSettings{
+ EnableAll: old.EnableAll,
+ DisableAll: old.DisableAll,
+ EnabledCheckers: old.EnabledCheckers,
+ DisabledCheckers: old.DisabledCheckers,
+ BoolCompare: versiontwo.TestifylintBoolCompare{
+ IgnoreCustomTypes: old.BoolCompare.IgnoreCustomTypes,
+ },
+ ExpectedActual: versiontwo.TestifylintExpectedActual{
+ ExpVarPattern: old.ExpectedActual.ExpVarPattern,
+ },
+ Formatter: versiontwo.TestifylintFormatter{
+ CheckFormatString: old.Formatter.CheckFormatString,
+ RequireFFuncs: old.Formatter.RequireFFuncs,
+ },
+ GoRequire: versiontwo.TestifylintGoRequire{
+ IgnoreHTTPHandlers: old.GoRequire.IgnoreHTTPHandlers,
+ },
+ RequireError: versiontwo.TestifylintRequireError{
+ FnPattern: old.RequireError.FnPattern,
+ },
+ SuiteExtraAssertCall: versiontwo.TestifylintSuiteExtraAssertCall{
+ Mode: old.SuiteExtraAssertCall.Mode,
+ },
+ }
+}
+
+func toTestpackageSettings(old versionone.TestpackageSettings) versiontwo.TestpackageSettings {
+ return versiontwo.TestpackageSettings{
+ SkipRegexp: old.SkipRegexp,
+ AllowPackages: old.AllowPackages,
+ }
+}
+
+func toThelperSettings(old versionone.ThelperSettings) versiontwo.ThelperSettings {
+ return versiontwo.ThelperSettings{
+ Test: versiontwo.ThelperOptions{
+ First: old.Test.First,
+ Name: old.Test.Name,
+ Begin: old.Test.Begin,
+ },
+ Fuzz: versiontwo.ThelperOptions{
+ First: old.Fuzz.First,
+ Name: old.Fuzz.Name,
+ Begin: old.Fuzz.Begin,
+ },
+ Benchmark: versiontwo.ThelperOptions{
+ First: old.Benchmark.First,
+ Name: old.Benchmark.Name,
+ Begin: old.Benchmark.Begin,
+ },
+ TB: versiontwo.ThelperOptions{
+ First: old.TB.First,
+ Name: old.TB.Name,
+ Begin: old.TB.Begin,
+ },
+ }
+}
+
+func toUnconvertSettings(old versionone.UnconvertSettings) versiontwo.UnconvertSettings {
+ return versiontwo.UnconvertSettings{
+ FastMath: old.FastMath,
+ Safe: old.Safe,
+ }
+}
+
+func toUnparamSettings(old versionone.UnparamSettings) versiontwo.UnparamSettings {
+ return versiontwo.UnparamSettings{
+ CheckExported: old.CheckExported,
+ }
+}
+
+func toUnusedSettings(old versionone.UnusedSettings) versiontwo.UnusedSettings {
+ return versiontwo.UnusedSettings{
+ FieldWritesAreUses: old.FieldWritesAreUses,
+ PostStatementsAreReads: old.PostStatementsAreReads,
+ ExportedFieldsAreUsed: old.ExportedFieldsAreUsed,
+ ParametersAreUsed: old.ParametersAreUsed,
+ LocalVariablesAreUsed: old.LocalVariablesAreUsed,
+ GeneratedIsUsed: old.GeneratedIsUsed,
+ }
+}
+
+func toUseStdlibVarsSettings(old versionone.UseStdlibVarsSettings) versiontwo.UseStdlibVarsSettings {
+ return versiontwo.UseStdlibVarsSettings{
+ HTTPMethod: old.HTTPMethod,
+ HTTPStatusCode: old.HTTPStatusCode,
+ TimeWeekday: old.TimeWeekday,
+ TimeMonth: old.TimeMonth,
+ TimeLayout: old.TimeLayout,
+ CryptoHash: old.CryptoHash,
+ DefaultRPCPath: old.DefaultRPCPath,
+ SQLIsolationLevel: old.SQLIsolationLevel,
+ TLSSignatureScheme: old.TLSSignatureScheme,
+ ConstantKind: old.ConstantKind,
+ }
+}
+
+func toUseTestingSettings(old versionone.UseTestingSettings) versiontwo.UseTestingSettings {
+ return versiontwo.UseTestingSettings{
+ ContextBackground: old.ContextBackground,
+ ContextTodo: old.ContextTodo,
+ OSChdir: old.OSChdir,
+ OSMkdirTemp: old.OSMkdirTemp,
+ OSSetenv: old.OSSetenv,
+ OSTempDir: old.OSTempDir,
+ OSCreateTemp: old.OSCreateTemp,
+ }
+}
+
+func toVarnamelenSettings(old versionone.VarnamelenSettings) versiontwo.VarnamelenSettings {
+ return versiontwo.VarnamelenSettings{
+ MaxDistance: old.MaxDistance,
+ MinNameLength: old.MinNameLength,
+ CheckReceiver: old.CheckReceiver,
+ CheckReturn: old.CheckReturn,
+ CheckTypeParam: old.CheckTypeParam,
+ IgnoreNames: old.IgnoreNames,
+ IgnoreTypeAssertOk: old.IgnoreTypeAssertOk,
+ IgnoreMapIndexOk: old.IgnoreMapIndexOk,
+ IgnoreChanRecvOk: old.IgnoreChanRecvOk,
+ IgnoreDecls: old.IgnoreDecls,
+ }
+}
+
+func toWhitespaceSettings(old versionone.WhitespaceSettings) versiontwo.WhitespaceSettings {
+ return versiontwo.WhitespaceSettings{
+ MultiIf: old.MultiIf,
+ MultiFunc: old.MultiFunc,
+ }
+}
+
+func toWrapcheckSettings(old versionone.WrapcheckSettings) versiontwo.WrapcheckSettings {
+ return versiontwo.WrapcheckSettings{
+ ExtraIgnoreSigs: old.ExtraIgnoreSigs,
+ IgnoreSigs: old.IgnoreSigs,
+ IgnoreSigRegexps: old.IgnoreSigRegexps,
+ IgnorePackageGlobs: old.IgnorePackageGlobs,
+ IgnoreInterfaceRegexps: old.IgnoreInterfaceRegexps,
+ }
+}
+
+func toWSLSettings(old versionone.WSLSettings) versiontwo.WSLSettings {
+ return versiontwo.WSLSettings{
+ StrictAppend: old.StrictAppend,
+ AllowAssignAndCallCuddle: old.AllowAssignAndCallCuddle,
+ AllowAssignAndAnythingCuddle: old.AllowAssignAndAnythingCuddle,
+ AllowMultiLineAssignCuddle: old.AllowMultiLineAssignCuddle,
+ ForceCaseTrailingWhitespaceLimit: old.ForceCaseTrailingWhitespaceLimit,
+ AllowTrailingComment: old.AllowTrailingComment,
+ AllowSeparatedLeadingComment: old.AllowSeparatedLeadingComment,
+ AllowCuddleDeclaration: old.AllowCuddleDeclaration,
+ AllowCuddleWithCalls: old.AllowCuddleWithCalls,
+ AllowCuddleWithRHS: old.AllowCuddleWithRHS,
+ ForceCuddleErrCheckAndAssign: old.ForceCuddleErrCheckAndAssign,
+ ErrorVariableNames: old.ErrorVariableNames,
+ ForceExclusiveShortDeclarations: old.ForceExclusiveShortDeclarations,
+ }
+}
+
+func toCustom(old map[string]versionone.CustomLinterSettings) map[string]versiontwo.CustomLinterSettings {
+ if old == nil {
+ return nil
+ }
+
+ settings := map[string]versiontwo.CustomLinterSettings{}
+
+ for k, s := range old {
+ settings[k] = versiontwo.CustomLinterSettings{
+ Type: s.Type,
+ Path: s.Path,
+ Description: s.Description,
+ OriginalURL: s.OriginalURL,
+ Settings: s.Settings,
+ }
+ }
+
+ return settings
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_output.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_output.go
new file mode 100644
index 00000000..e76f8e44
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_output.go
@@ -0,0 +1,103 @@
+package migrate
+
+import (
+ "slices"
+
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
+)
+
+func toOutput(old *versionone.Config) versiontwo.Output {
+ formats := versiontwo.Formats{}
+
+ oldFormats := cleanIncompatibleFormats(old.Output.Formats, "colored-line-number", "line-number")
+ oldFormats = cleanIncompatibleFormats(oldFormats, "colored-tab", "tab")
+ oldFormats = cleanIncompatibleFormats(oldFormats, "junit-xml-extended", "junit-xml")
+
+ for _, format := range oldFormats {
+ switch ptr.Deref(format.Format) {
+ case "colored-line-number":
+ formats.Text.PrintLinterName = old.Output.PrintLinterName
+ formats.Text.PrintIssuedLine = old.Output.PrintIssuedLine
+ formats.Text.Colors = nil // color is true by default (flags).
+ formats.Text.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "line-number":
+ formats.Text.PrintLinterName = old.Output.PrintLinterName
+ formats.Text.PrintIssuedLine = old.Output.PrintIssuedLine
+ formats.Text.Colors = ptr.Pointer(false)
+ formats.Text.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "json":
+ formats.JSON.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "colored-tab":
+ formats.Tab.PrintLinterName = old.Output.PrintLinterName
+ formats.Tab.Colors = nil // Colors is true by default (flags).
+ formats.Tab.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "tab":
+ formats.Tab.PrintLinterName = old.Output.PrintLinterName
+ formats.Tab.Colors = ptr.Pointer(false)
+ formats.Tab.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "html":
+ formats.HTML.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "checkstyle":
+ formats.Checkstyle.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "code-climate":
+ formats.CodeClimate.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "junit-xml":
+ formats.JUnitXML.Extended = nil // Extended is false by default.
+ formats.JUnitXML.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "junit-xml-extended":
+ formats.JUnitXML.Extended = ptr.Pointer(true)
+ formats.JUnitXML.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "github-actions":
+ // Ignored
+
+ case "teamcity":
+ formats.TeamCity.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+
+ case "sarif":
+ formats.Sarif.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path)))
+ }
+ }
+
+ return versiontwo.Output{
+ Formats: formats,
+ SortOrder: old.Output.SortOrder,
+ PathPrefix: old.Output.PathPrefix,
+ ShowStats: nil, // Enforce the new default. (nil -> omitempty -> true)
+ }
+}
+
+func defaultFormatPath(p string) string {
+ if p == "" {
+ return "stdout"
+ }
+
+ return p
+}
+
+func cleanIncompatibleFormats(old versionone.OutputFormats, f1, f2 string) versionone.OutputFormats {
+ index1 := slices.IndexFunc(old, func(format versionone.OutputFormat) bool {
+ return ptr.Deref(format.Format) == f1
+ })
+
+ index2 := slices.IndexFunc(old, func(format versionone.OutputFormat) bool {
+ return ptr.Deref(format.Format) == f2
+ })
+
+ if index1 >= 0 && index2 >= 0 {
+ return slices.Delete(old, index2, index2+1)
+ }
+
+ return old
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_run.go
new file mode 100644
index 00000000..88db4470
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_run.go
@@ -0,0 +1,34 @@
+package migrate
+
+import (
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
+)
+
+func toRun(old *versionone.Config) versiontwo.Run {
+ var relativePathMode *string
+ if ptr.Deref(old.Run.RelativePathMode) != "cfg" {
+ // cfg is the new default.
+ relativePathMode = old.Run.RelativePathMode
+ }
+
+ var concurrency *int
+ if ptr.Deref(old.Run.Concurrency) != 0 {
+ // 0 is the new default
+ concurrency = old.Run.Concurrency
+ }
+
+ return versiontwo.Run{
+ Timeout: 0, // Enforce new default.
+ Concurrency: concurrency,
+ Go: old.Run.Go,
+ RelativePathMode: relativePathMode,
+ BuildTags: old.Run.BuildTags,
+ ModulesDownloadMode: old.Run.ModulesDownloadMode,
+ ExitCodeIfIssuesFound: old.Run.ExitCodeIfIssuesFound,
+ AnalyzeTests: old.Run.AnalyzeTests,
+ AllowParallelRunners: old.Run.AllowParallelRunners,
+ AllowSerialRunners: old.Run.AllowSerialRunners,
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_severity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_severity.go
new file mode 100644
index 00000000..6db40bca
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_severity.go
@@ -0,0 +1,33 @@
+package migrate
+
+import (
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo"
+)
+
+func toSeverity(old *versionone.Config) versiontwo.Severity {
+ var rules []versiontwo.SeverityRule
+
+ for _, rule := range old.Severity.Rules {
+ names := convertStaticcheckLinterNames(convertAlternativeNames(rule.Linters))
+ if len(rule.Linters) > 0 && len(names) == 0 {
+ continue
+ }
+
+ rules = append(rules, versiontwo.SeverityRule{
+ BaseRule: versiontwo.BaseRule{
+ Linters: names,
+ Path: rule.Path,
+ PathExcept: rule.PathExcept,
+ Text: rule.Text,
+ Source: rule.Source,
+ },
+ Severity: rule.Severity,
+ })
+ }
+
+ return versiontwo.Severity{
+ Default: old.Severity.Default,
+ Rules: rules,
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser/parser.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser/parser.go
new file mode 100644
index 00000000..ea00b41f
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser/parser.go
@@ -0,0 +1,87 @@
+package parser
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "path/filepath"
+ "strings"
+
+ "github.com/pelletier/go-toml/v2"
+ "gopkg.in/yaml.v3"
+)
+
+type File interface {
+ io.ReadWriter
+ Name() string
+}
+
+// Decode decodes a file into data.
+// The choice of the decoder is based on the file extension.
+func Decode(file File, data any) error {
+ ext := filepath.Ext(file.Name())
+
+ switch strings.ToLower(ext) {
+ case ".yaml", ".yml", ".json":
+ err := yaml.NewDecoder(file).Decode(data)
+ if err != nil && !errors.Is(err, io.EOF) {
+ return fmt.Errorf("YAML decode file %s: %w", file.Name(), err)
+ }
+
+ case ".toml":
+ err := toml.NewDecoder(file).Decode(&data)
+ if err != nil {
+ return fmt.Errorf("TOML decode file %s: %w", file.Name(), err)
+ }
+
+ default:
+ return fmt.Errorf("unsupported file type: %s", ext)
+ }
+
+ return nil
+}
+
+// Encode encodes data into a file.
+// The choice of the encoder is based on the file extension.
+func Encode(data any, dstFile File) error {
+ ext := filepath.Ext(dstFile.Name())
+
+ switch strings.ToLower(ext) {
+ case ".yml", ".yaml":
+ encoder := yaml.NewEncoder(dstFile)
+ encoder.SetIndent(2)
+
+ return encoder.Encode(data)
+
+ case ".toml":
+ encoder := toml.NewEncoder(dstFile)
+
+ return encoder.Encode(data)
+
+ case ".json":
+ // The JSON encoder converts empty struct to `{}` instead of nothing (even with omitempty JSON struct tags).
+ // So we need to use the YAML encoder as bridge to create JSON file.
+
+ var buf bytes.Buffer
+ err := yaml.NewEncoder(&buf).Encode(data)
+ if err != nil {
+ return err
+ }
+
+ raw := map[string]any{}
+ err = yaml.NewDecoder(&buf).Decode(raw)
+ if err != nil {
+ return err
+ }
+
+ encoder := json.NewEncoder(dstFile)
+ encoder.SetIndent("", " ")
+
+ return encoder.Encode(raw)
+
+ default:
+ return fmt.Errorf("unsupported file type: %s", ext)
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr/ptr.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr/ptr.go
new file mode 100644
index 00000000..b0c7974e
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr/ptr.go
@@ -0,0 +1,12 @@
+package ptr
+
+func Deref[T any](v *T) T {
+ if v == nil {
+ var zero T
+ return zero
+ }
+
+ return *v
+}
+
+func Pointer[T any](v T) *T { return &v }
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/base_rule.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/base_rule.go
new file mode 100644
index 00000000..244e2599
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/base_rule.go
@@ -0,0 +1,9 @@
+package versionone
+
+type BaseRule struct {
+ Linters []string `mapstructure:"linters"`
+ Path *string `mapstructure:"path"`
+ PathExcept *string `mapstructure:"path-except"`
+ Text *string `mapstructure:"text"`
+ Source *string `mapstructure:"source"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/config.go
new file mode 100644
index 00000000..1e9d0ee1
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/config.go
@@ -0,0 +1,18 @@
+package versionone
+
+type Config struct {
+ Version string `mapstructure:"version"` // From v2, to be able to detect already migrated config file.
+
+ Run Run `mapstructure:"run"`
+
+ Output Output `mapstructure:"output"`
+
+ LintersSettings LintersSettings `mapstructure:"linters-settings"`
+ Linters Linters `mapstructure:"linters"`
+ Issues Issues `mapstructure:"issues"`
+ Severity Severity `mapstructure:"severity"`
+}
+
+func NewConfig() *Config {
+ return &Config{}
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/doc.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/doc.go
new file mode 100644
index 00000000..fb945f3c
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/doc.go
@@ -0,0 +1,4 @@
+// Package versionone contains a modified copy of v1 configuration.
+// The structures are altered to use pointer on builtin types.
+// The field version is added to enforce the detection of already migrated file.
+package versionone
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/issues.go
new file mode 100644
index 00000000..bac6ba9c
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/issues.go
@@ -0,0 +1,32 @@
+package versionone
+
+type Issues struct {
+ IncludeDefaultExcludes []string `mapstructure:"include"`
+ ExcludeCaseSensitive *bool `mapstructure:"exclude-case-sensitive"`
+ ExcludePatterns []string `mapstructure:"exclude"`
+ ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"`
+ UseDefaultExcludes *bool `mapstructure:"exclude-use-default"`
+
+ ExcludeGenerated *string `mapstructure:"exclude-generated"`
+
+ ExcludeFiles []string `mapstructure:"exclude-files"`
+ ExcludeDirs []string `mapstructure:"exclude-dirs"`
+
+ UseDefaultExcludeDirs *bool `mapstructure:"exclude-dirs-use-default"`
+
+ MaxIssuesPerLinter *int `mapstructure:"max-issues-per-linter"`
+ MaxSameIssues *int `mapstructure:"max-same-issues"`
+ UniqByLine *bool `mapstructure:"uniq-by-line"`
+
+ DiffFromRevision *string `mapstructure:"new-from-rev"`
+ DiffFromMergeBase *string `mapstructure:"new-from-merge-base"`
+ DiffPatchFilePath *string `mapstructure:"new-from-patch"`
+ WholeFiles *bool `mapstructure:"whole-files"`
+ Diff *bool `mapstructure:"new"`
+
+ NeedFix *bool `mapstructure:"fix"`
+}
+
+type ExcludeRule struct {
+ BaseRule `mapstructure:",squash"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters.go
new file mode 100644
index 00000000..d6a490fe
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters.go
@@ -0,0 +1,11 @@
+package versionone
+
+type Linters struct {
+ Enable []string `mapstructure:"enable"`
+ Disable []string `mapstructure:"disable"`
+ EnableAll *bool `mapstructure:"enable-all"`
+ DisableAll *bool `mapstructure:"disable-all"`
+ Fast *bool `mapstructure:"fast"`
+
+ Presets []string `mapstructure:"presets"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters_settings.go
new file mode 100644
index 00000000..44583b7d
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters_settings.go
@@ -0,0 +1,865 @@
+package versionone
+
+import (
+ "encoding"
+
+ "gopkg.in/yaml.v3"
+
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
+)
+
+type LintersSettings struct {
+ Asasalint AsasalintSettings `mapstructure:"asasalint"`
+ BiDiChk BiDiChkSettings `mapstructure:"bidichk"`
+ CopyLoopVar CopyLoopVarSettings `mapstructure:"copyloopvar"`
+ Cyclop Cyclop `mapstructure:"cyclop"`
+ Decorder DecorderSettings `mapstructure:"decorder"`
+ Depguard DepGuardSettings `mapstructure:"depguard"`
+ Dogsled DogsledSettings `mapstructure:"dogsled"`
+ Dupl DuplSettings `mapstructure:"dupl"`
+ DupWord DupWordSettings `mapstructure:"dupword"`
+ Errcheck ErrcheckSettings `mapstructure:"errcheck"`
+ ErrChkJSON ErrChkJSONSettings `mapstructure:"errchkjson"`
+ ErrorLint ErrorLintSettings `mapstructure:"errorlint"`
+ Exhaustive ExhaustiveSettings `mapstructure:"exhaustive"`
+ Exhaustruct ExhaustructSettings `mapstructure:"exhaustruct"`
+ Fatcontext FatcontextSettings `mapstructure:"fatcontext"`
+ Forbidigo ForbidigoSettings `mapstructure:"forbidigo"`
+ Funlen FunlenSettings `mapstructure:"funlen"`
+ GinkgoLinter GinkgoLinterSettings `mapstructure:"ginkgolinter"`
+ Gocognit GocognitSettings `mapstructure:"gocognit"`
+ GoChecksumType GoChecksumTypeSettings `mapstructure:"gochecksumtype"`
+ Goconst GoConstSettings `mapstructure:"goconst"`
+ Gocritic GoCriticSettings `mapstructure:"gocritic"`
+ Gocyclo GoCycloSettings `mapstructure:"gocyclo"`
+ Godot GodotSettings `mapstructure:"godot"`
+ Godox GodoxSettings `mapstructure:"godox"`
+ Goheader GoHeaderSettings `mapstructure:"goheader"`
+ GoModDirectives GoModDirectivesSettings `mapstructure:"gomoddirectives"`
+ Gomodguard GoModGuardSettings `mapstructure:"gomodguard"`
+ Gosec GoSecSettings `mapstructure:"gosec"`
+ Gosimple StaticCheckSettings `mapstructure:"gosimple"`
+ Gosmopolitan GosmopolitanSettings `mapstructure:"gosmopolitan"`
+ Govet GovetSettings `mapstructure:"govet"`
+ Grouper GrouperSettings `mapstructure:"grouper"`
+ Iface IfaceSettings `mapstructure:"iface"`
+ ImportAs ImportAsSettings `mapstructure:"importas"`
+ Inamedparam INamedParamSettings `mapstructure:"inamedparam"`
+ InterfaceBloat InterfaceBloatSettings `mapstructure:"interfacebloat"`
+ Ireturn IreturnSettings `mapstructure:"ireturn"`
+ Lll LllSettings `mapstructure:"lll"`
+ LoggerCheck LoggerCheckSettings `mapstructure:"loggercheck"`
+ MaintIdx MaintIdxSettings `mapstructure:"maintidx"`
+ Makezero MakezeroSettings `mapstructure:"makezero"`
+ Misspell MisspellSettings `mapstructure:"misspell"`
+ Mnd MndSettings `mapstructure:"mnd"`
+ MustTag MustTagSettings `mapstructure:"musttag"`
+ Nakedret NakedretSettings `mapstructure:"nakedret"`
+ Nestif NestifSettings `mapstructure:"nestif"`
+ NilNil NilNilSettings `mapstructure:"nilnil"`
+ Nlreturn NlreturnSettings `mapstructure:"nlreturn"`
+ NoLintLint NoLintLintSettings `mapstructure:"nolintlint"`
+ NoNamedReturns NoNamedReturnsSettings `mapstructure:"nonamedreturns"`
+ ParallelTest ParallelTestSettings `mapstructure:"paralleltest"`
+ PerfSprint PerfSprintSettings `mapstructure:"perfsprint"`
+ Prealloc PreallocSettings `mapstructure:"prealloc"`
+ Predeclared PredeclaredSettings `mapstructure:"predeclared"`
+ Promlinter PromlinterSettings `mapstructure:"promlinter"`
+ ProtoGetter ProtoGetterSettings `mapstructure:"protogetter"`
+ Reassign ReassignSettings `mapstructure:"reassign"`
+ Recvcheck RecvcheckSettings `mapstructure:"recvcheck"`
+ Revive ReviveSettings `mapstructure:"revive"`
+ RowsErrCheck RowsErrCheckSettings `mapstructure:"rowserrcheck"`
+ SlogLint SlogLintSettings `mapstructure:"sloglint"`
+ Spancheck SpancheckSettings `mapstructure:"spancheck"`
+ Staticcheck StaticCheckSettings `mapstructure:"staticcheck"`
+ Stylecheck StaticCheckSettings `mapstructure:"stylecheck"`
+ TagAlign TagAlignSettings `mapstructure:"tagalign"`
+ Tagliatelle TagliatelleSettings `mapstructure:"tagliatelle"`
+ Tenv TenvSettings `mapstructure:"tenv"`
+ Testifylint TestifylintSettings `mapstructure:"testifylint"`
+ Testpackage TestpackageSettings `mapstructure:"testpackage"`
+ Thelper ThelperSettings `mapstructure:"thelper"`
+ Unconvert UnconvertSettings `mapstructure:"unconvert"`
+ Unparam UnparamSettings `mapstructure:"unparam"`
+ Unused UnusedSettings `mapstructure:"unused"`
+ UseStdlibVars UseStdlibVarsSettings `mapstructure:"usestdlibvars"`
+ UseTesting UseTestingSettings `mapstructure:"usetesting"`
+ Varnamelen VarnamelenSettings `mapstructure:"varnamelen"`
+ Whitespace WhitespaceSettings `mapstructure:"whitespace"`
+ Wrapcheck WrapcheckSettings `mapstructure:"wrapcheck"`
+ WSL WSLSettings `mapstructure:"wsl"`
+
+ Custom map[string]CustomLinterSettings `mapstructure:"custom"`
+
+ Gci GciSettings `mapstructure:"gci"`
+ GoFmt GoFmtSettings `mapstructure:"gofmt"`
+ GoFumpt GoFumptSettings `mapstructure:"gofumpt"`
+ GoImports GoImportsSettings `mapstructure:"goimports"`
+}
+
+type AsasalintSettings struct {
+ Exclude []string `mapstructure:"exclude"`
+ UseBuiltinExclusions *bool `mapstructure:"use-builtin-exclusions"`
+ IgnoreTest *bool `mapstructure:"ignore-test"`
+}
+
+type BiDiChkSettings struct {
+ LeftToRightEmbedding *bool `mapstructure:"left-to-right-embedding"`
+ RightToLeftEmbedding *bool `mapstructure:"right-to-left-embedding"`
+ PopDirectionalFormatting *bool `mapstructure:"pop-directional-formatting"`
+ LeftToRightOverride *bool `mapstructure:"left-to-right-override"`
+ RightToLeftOverride *bool `mapstructure:"right-to-left-override"`
+ LeftToRightIsolate *bool `mapstructure:"left-to-right-isolate"`
+ RightToLeftIsolate *bool `mapstructure:"right-to-left-isolate"`
+ FirstStrongIsolate *bool `mapstructure:"first-strong-isolate"`
+ PopDirectionalIsolate *bool `mapstructure:"pop-directional-isolate"`
+}
+
+type CopyLoopVarSettings struct {
+ CheckAlias *bool `mapstructure:"check-alias"`
+
+ // Deprecated: use CheckAlias
+ IgnoreAlias *bool `mapstructure:"ignore-alias"`
+}
+
+type Cyclop struct {
+ MaxComplexity *int `mapstructure:"max-complexity"`
+ PackageAverage *float64 `mapstructure:"package-average"`
+ SkipTests *bool `mapstructure:"skip-tests"`
+}
+
+type DepGuardSettings struct {
+ Rules map[string]*DepGuardList `mapstructure:"rules"`
+}
+
+type DepGuardList struct {
+ ListMode *string `mapstructure:"list-mode"`
+ Files []string `mapstructure:"files"`
+ Allow []string `mapstructure:"allow"`
+ Deny []DepGuardDeny `mapstructure:"deny"`
+}
+
+type DepGuardDeny struct {
+ Pkg *string `mapstructure:"pkg"`
+ Desc *string `mapstructure:"desc"`
+}
+
+type DecorderSettings struct {
+ DecOrder []string `mapstructure:"dec-order"`
+ IgnoreUnderscoreVars *bool `mapstructure:"ignore-underscore-vars"`
+ DisableDecNumCheck *bool `mapstructure:"disable-dec-num-check"`
+ DisableTypeDecNumCheck *bool `mapstructure:"disable-type-dec-num-check"`
+ DisableConstDecNumCheck *bool `mapstructure:"disable-const-dec-num-check"`
+ DisableVarDecNumCheck *bool `mapstructure:"disable-var-dec-num-check"`
+ DisableDecOrderCheck *bool `mapstructure:"disable-dec-order-check"`
+ DisableInitFuncFirstCheck *bool `mapstructure:"disable-init-func-first-check"`
+}
+
+type DogsledSettings struct {
+ MaxBlankIdentifiers *int `mapstructure:"max-blank-identifiers"`
+}
+
+type DuplSettings struct {
+ Threshold *int `mapstructure:"threshold"`
+}
+
+type DupWordSettings struct {
+ Keywords []string `mapstructure:"keywords"`
+ Ignore []string `mapstructure:"ignore"`
+}
+
+type ErrcheckSettings struct {
+ DisableDefaultExclusions *bool `mapstructure:"disable-default-exclusions"`
+ CheckTypeAssertions *bool `mapstructure:"check-type-assertions"`
+ CheckAssignToBlank *bool `mapstructure:"check-blank"`
+ ExcludeFunctions []string `mapstructure:"exclude-functions"`
+
+ // Deprecated: use ExcludeFunctions instead
+ Exclude *string `mapstructure:"exclude"`
+
+ // Deprecated: use ExcludeFunctions instead
+ Ignore *string `mapstructure:"ignore"`
+}
+
+type ErrChkJSONSettings struct {
+ CheckErrorFreeEncoding *bool `mapstructure:"check-error-free-encoding"`
+ ReportNoExported *bool `mapstructure:"report-no-exported"`
+}
+
+type ErrorLintSettings struct {
+ Errorf *bool `mapstructure:"errorf"`
+ ErrorfMulti *bool `mapstructure:"errorf-multi"`
+ Asserts *bool `mapstructure:"asserts"`
+ Comparison *bool `mapstructure:"comparison"`
+ AllowedErrors []ErrorLintAllowPair `mapstructure:"allowed-errors"`
+ AllowedErrorsWildcard []ErrorLintAllowPair `mapstructure:"allowed-errors-wildcard"`
+}
+
+type ErrorLintAllowPair struct {
+ Err *string `mapstructure:"err"`
+ Fun *string `mapstructure:"fun"`
+}
+
+type ExhaustiveSettings struct {
+ Check []string `mapstructure:"check"`
+ CheckGenerated *bool `mapstructure:"check-generated"`
+ DefaultSignifiesExhaustive *bool `mapstructure:"default-signifies-exhaustive"`
+ IgnoreEnumMembers *string `mapstructure:"ignore-enum-members"`
+ IgnoreEnumTypes *string `mapstructure:"ignore-enum-types"`
+ PackageScopeOnly *bool `mapstructure:"package-scope-only"`
+ ExplicitExhaustiveMap *bool `mapstructure:"explicit-exhaustive-map"`
+ ExplicitExhaustiveSwitch *bool `mapstructure:"explicit-exhaustive-switch"`
+ DefaultCaseRequired *bool `mapstructure:"default-case-required"`
+}
+
+type ExhaustructSettings struct {
+ Include []string `mapstructure:"include"`
+ Exclude []string `mapstructure:"exclude"`
+}
+
+type FatcontextSettings struct {
+ CheckStructPointers *bool `mapstructure:"check-struct-pointers"`
+}
+
+type ForbidigoSettings struct {
+ Forbid []ForbidigoPattern `mapstructure:"forbid"`
+ ExcludeGodocExamples *bool `mapstructure:"exclude-godoc-examples"`
+ AnalyzeTypes *bool `mapstructure:"analyze-types"`
+}
+
+var _ encoding.TextUnmarshaler = &ForbidigoPattern{}
+
+// ForbidigoPattern corresponds to forbidigo.pattern and adds mapstructure support.
+// The YAML field names must match what forbidigo expects.
+type ForbidigoPattern struct {
+ // patternString gets populated when the config contains a *string as entry in ForbidigoSettings.Forbid[]
+ // because ForbidigoPattern implements encoding.TextUnmarshaler
+ // and the reader uses the mapstructure.TextUnmarshallerHookFunc as decoder hook.
+ //
+ // If the entry is a map, then the other fields are set as usual by mapstructure.
+ patternString *string
+ Pattern *string `yaml:"p" mapstructure:"p"`
+ Package *string `yaml:"pkg,omitempty" mapstructure:"pkg,omitempty"`
+ Msg *string `yaml:"msg,omitempty" mapstructure:"msg,omitempty"`
+}
+
+func (p *ForbidigoPattern) UnmarshalText(text []byte) error {
+ // Validation happens when instantiating forbidigo.
+ p.patternString = ptr.Pointer(string(text))
+ return nil
+}
+
+// MarshalString converts the pattern into a *string as needed by forbidigo.NewLinter.
+//
+// MarshalString is intentionally not called MarshalText,
+// although it has the same signature
+// because implementing encoding.TextMarshaler led to infinite recursion when yaml.Marshal called MarshalText.
+func (p *ForbidigoPattern) MarshalString() ([]byte, error) {
+ if ptr.Deref(p.patternString) != "" {
+ return []byte(ptr.Deref(p.patternString)), nil
+ }
+
+ return yaml.Marshal(p)
+}
+
+type FunlenSettings struct {
+ Lines *int `mapstructure:"lines"`
+ Statements *int `mapstructure:"statements"`
+ IgnoreComments *bool `mapstructure:"ignore-comments"`
+}
+
+type GinkgoLinterSettings struct {
+ SuppressLenAssertion *bool `mapstructure:"suppress-len-assertion"`
+ SuppressNilAssertion *bool `mapstructure:"suppress-nil-assertion"`
+ SuppressErrAssertion *bool `mapstructure:"suppress-err-assertion"`
+ SuppressCompareAssertion *bool `mapstructure:"suppress-compare-assertion"`
+ SuppressAsyncAssertion *bool `mapstructure:"suppress-async-assertion"`
+ SuppressTypeCompareWarning *bool `mapstructure:"suppress-type-compare-assertion"`
+ ForbidFocusContainer *bool `mapstructure:"forbid-focus-container"`
+ AllowHaveLenZero *bool `mapstructure:"allow-havelen-zero"`
+ ForceExpectTo *bool `mapstructure:"force-expect-to"`
+ ValidateAsyncIntervals *bool `mapstructure:"validate-async-intervals"`
+ ForbidSpecPollution *bool `mapstructure:"forbid-spec-pollution"`
+ ForceSucceedForFuncs *bool `mapstructure:"force-succeed"`
+}
+
+type GoChecksumTypeSettings struct {
+ DefaultSignifiesExhaustive *bool `mapstructure:"default-signifies-exhaustive"`
+ IncludeSharedInterfaces *bool `mapstructure:"include-shared-interfaces"`
+}
+
+type GocognitSettings struct {
+ MinComplexity *int `mapstructure:"min-complexity"`
+}
+
+type GoConstSettings struct {
+ IgnoreStrings *string `mapstructure:"ignore-strings"`
+ IgnoreTests *bool `mapstructure:"ignore-tests"`
+ MatchWithConstants *bool `mapstructure:"match-constant"`
+ MinStringLen *int `mapstructure:"min-len"`
+ MinOccurrencesCount *int `mapstructure:"min-occurrences"`
+ ParseNumbers *bool `mapstructure:"numbers"`
+ NumberMin *int `mapstructure:"min"`
+ NumberMax *int `mapstructure:"max"`
+ IgnoreCalls *bool `mapstructure:"ignore-calls"`
+}
+
+type GoCriticSettings struct {
+ Go *string `mapstructure:"-"`
+ DisableAll *bool `mapstructure:"disable-all"`
+ EnabledChecks []string `mapstructure:"enabled-checks"`
+ EnableAll *bool `mapstructure:"enable-all"`
+ DisabledChecks []string `mapstructure:"disabled-checks"`
+ EnabledTags []string `mapstructure:"enabled-tags"`
+ DisabledTags []string `mapstructure:"disabled-tags"`
+ SettingsPerCheck map[string]GoCriticCheckSettings `mapstructure:"settings"`
+}
+
+type GoCriticCheckSettings map[string]any
+
+type GoCycloSettings struct {
+ MinComplexity *int `mapstructure:"min-complexity"`
+}
+
+type GodotSettings struct {
+ Scope *string `mapstructure:"scope"`
+ Exclude []string `mapstructure:"exclude"`
+ Capital *bool `mapstructure:"capital"`
+ Period *bool `mapstructure:"period"`
+
+ // Deprecated: use Scope instead
+ CheckAll *bool `mapstructure:"check-all"`
+}
+
+type GodoxSettings struct {
+ Keywords []string `mapstructure:"keywords"`
+}
+
+type GoHeaderSettings struct {
+ Values map[string]map[string]string `mapstructure:"values"`
+ Template *string `mapstructure:"template"`
+ TemplatePath *string `mapstructure:"template-path"`
+}
+
+type GoModDirectivesSettings struct {
+ ReplaceAllowList []string `mapstructure:"replace-allow-list"`
+ ReplaceLocal *bool `mapstructure:"replace-local"`
+ ExcludeForbidden *bool `mapstructure:"exclude-forbidden"`
+ RetractAllowNoExplanation *bool `mapstructure:"retract-allow-no-explanation"`
+ ToolchainForbidden *bool `mapstructure:"toolchain-forbidden"`
+ ToolchainPattern *string `mapstructure:"toolchain-pattern"`
+ ToolForbidden *bool `mapstructure:"tool-forbidden"`
+ GoDebugForbidden *bool `mapstructure:"go-debug-forbidden"`
+ GoVersionPattern *string `mapstructure:"go-version-pattern"`
+}
+
+type GoModGuardSettings struct {
+ Allowed struct {
+ Modules []string `mapstructure:"modules"`
+ Domains []string `mapstructure:"domains"`
+ } `mapstructure:"allowed"`
+ Blocked struct {
+ Modules []map[string]struct {
+ Recommendations []string `mapstructure:"recommendations"`
+ Reason *string `mapstructure:"reason"`
+ } `mapstructure:"modules"`
+ Versions []map[string]struct {
+ Version *string `mapstructure:"version"`
+ Reason *string `mapstructure:"reason"`
+ } `mapstructure:"versions"`
+ LocalReplaceDirectives *bool `mapstructure:"local_replace_directives"`
+ } `mapstructure:"blocked"`
+}
+
+type GoSecSettings struct {
+ Includes []string `mapstructure:"includes"`
+ Excludes []string `mapstructure:"excludes"`
+ Severity *string `mapstructure:"severity"`
+ Confidence *string `mapstructure:"confidence"`
+ ExcludeGenerated *bool `mapstructure:"exclude-generated"`
+ Config map[string]any `mapstructure:"config"`
+ Concurrency *int `mapstructure:"concurrency"`
+}
+
+type GosmopolitanSettings struct {
+ AllowTimeLocal *bool `mapstructure:"allow-time-local"`
+ EscapeHatches []string `mapstructure:"escape-hatches"`
+ IgnoreTests *bool `mapstructure:"ignore-tests"`
+ WatchForScripts []string `mapstructure:"watch-for-scripts"`
+}
+
+type GovetSettings struct {
+ Go *string `mapstructure:"-"`
+
+ Enable []string `mapstructure:"enable"`
+ Disable []string `mapstructure:"disable"`
+ EnableAll *bool `mapstructure:"enable-all"`
+ DisableAll *bool `mapstructure:"disable-all"`
+
+ Settings map[string]map[string]any `mapstructure:"settings"`
+
+ // Deprecated: the linter should be enabled inside Enable.
+ CheckShadowing *bool `mapstructure:"check-shadowing"`
+}
+
+type GrouperSettings struct {
+ ConstRequireSingleConst *bool `mapstructure:"const-require-single-const"`
+ ConstRequireGrouping *bool `mapstructure:"const-require-grouping"`
+ ImportRequireSingleImport *bool `mapstructure:"import-require-single-import"`
+ ImportRequireGrouping *bool `mapstructure:"import-require-grouping"`
+ TypeRequireSingleType *bool `mapstructure:"type-require-single-type"`
+ TypeRequireGrouping *bool `mapstructure:"type-require-grouping"`
+ VarRequireSingleVar *bool `mapstructure:"var-require-single-var"`
+ VarRequireGrouping *bool `mapstructure:"var-require-grouping"`
+}
+
+type IfaceSettings struct {
+ Enable []string `mapstructure:"enable"`
+ Settings map[string]map[string]any `mapstructure:"settings"`
+}
+
+type ImportAsSettings struct {
+ Alias []ImportAsAlias `mapstructure:"alias"`
+ NoUnaliased *bool `mapstructure:"no-unaliased"`
+ NoExtraAliases *bool `mapstructure:"no-extra-aliases"`
+}
+
+type ImportAsAlias struct {
+ Pkg *string `mapstructure:"pkg"`
+ Alias *string `mapstructure:"alias"`
+}
+
+type INamedParamSettings struct {
+ SkipSingleParam *bool `mapstructure:"skip-single-param"`
+}
+
+type InterfaceBloatSettings struct {
+ Max *int `mapstructure:"max"`
+}
+
+type IreturnSettings struct {
+ Allow []string `mapstructure:"allow"`
+ Reject []string `mapstructure:"reject"`
+}
+
+type LllSettings struct {
+ LineLength *int `mapstructure:"line-length"`
+ TabWidth *int `mapstructure:"tab-width"`
+}
+
+type LoggerCheckSettings struct {
+ Kitlog *bool `mapstructure:"kitlog"`
+ Klog *bool `mapstructure:"klog"`
+ Logr *bool `mapstructure:"logr"`
+ Slog *bool `mapstructure:"slog"`
+ Zap *bool `mapstructure:"zap"`
+ RequireStringKey *bool `mapstructure:"require-string-key"`
+ NoPrintfLike *bool `mapstructure:"no-printf-like"`
+ Rules []string `mapstructure:"rules"`
+}
+
+type MaintIdxSettings struct {
+ Under *int `mapstructure:"under"`
+}
+
+type MakezeroSettings struct {
+ Always *bool `mapstructure:"always"`
+}
+
+type MisspellSettings struct {
+ Mode *string `mapstructure:"mode"`
+ Locale *string `mapstructure:"locale"`
+ ExtraWords []MisspellExtraWords `mapstructure:"extra-words"`
+ // TODO(ldez): v2 the option must be renamed to `IgnoredRules`.
+ IgnoreWords []string `mapstructure:"ignore-words"`
+}
+
+type MisspellExtraWords struct {
+ Typo *string `mapstructure:"typo"`
+ Correction *string `mapstructure:"correction"`
+}
+
+type MustTagSettings struct {
+ Functions []struct {
+ Name *string `mapstructure:"name"`
+ Tag *string `mapstructure:"tag"`
+ ArgPos *int `mapstructure:"arg-pos"`
+ } `mapstructure:"functions"`
+}
+
+type NakedretSettings struct {
+ MaxFuncLines *uint `mapstructure:"max-func-lines"`
+}
+
+type NestifSettings struct {
+ MinComplexity *int `mapstructure:"min-complexity"`
+}
+
+type NilNilSettings struct {
+ DetectOpposite *bool `mapstructure:"detect-opposite"`
+ CheckedTypes []string `mapstructure:"checked-types"`
+}
+
+type NlreturnSettings struct {
+ BlockSize *int `mapstructure:"block-size"`
+}
+
+type MndSettings struct {
+ Checks []string `mapstructure:"checks"`
+ IgnoredNumbers []string `mapstructure:"ignored-numbers"`
+ IgnoredFiles []string `mapstructure:"ignored-files"`
+ IgnoredFunctions []string `mapstructure:"ignored-functions"`
+}
+
+type NoLintLintSettings struct {
+ RequireExplanation *bool `mapstructure:"require-explanation"`
+ RequireSpecific *bool `mapstructure:"require-specific"`
+ AllowNoExplanation []string `mapstructure:"allow-no-explanation"`
+ AllowUnused *bool `mapstructure:"allow-unused"`
+}
+
+type NoNamedReturnsSettings struct {
+ ReportErrorInDefer *bool `mapstructure:"report-error-in-defer"`
+}
+
+type ParallelTestSettings struct {
+ Go *string `mapstructure:"-"`
+ IgnoreMissing *bool `mapstructure:"ignore-missing"`
+ IgnoreMissingSubtests *bool `mapstructure:"ignore-missing-subtests"`
+}
+
+type PerfSprintSettings struct {
+ IntegerFormat *bool `mapstructure:"integer-format"`
+ IntConversion *bool `mapstructure:"int-conversion"`
+
+ ErrorFormat *bool `mapstructure:"error-format"`
+ ErrError *bool `mapstructure:"err-error"`
+ ErrorF *bool `mapstructure:"errorf"`
+
+ StringFormat *bool `mapstructure:"string-format"`
+ SprintF1 *bool `mapstructure:"sprintf1"`
+ StrConcat *bool `mapstructure:"strconcat"`
+
+ BoolFormat *bool `mapstructure:"bool-format"`
+ HexFormat *bool `mapstructure:"hex-format"`
+}
+
+type PreallocSettings struct {
+ Simple *bool `mapstructure:"simple"`
+ RangeLoops *bool `mapstructure:"range-loops"`
+ ForLoops *bool `mapstructure:"for-loops"`
+}
+
+type PredeclaredSettings struct {
+ Ignore *string `mapstructure:"ignore"`
+ Qualified *bool `mapstructure:"q"`
+}
+
+type PromlinterSettings struct {
+ Strict *bool `mapstructure:"strict"`
+ DisabledLinters []string `mapstructure:"disabled-linters"`
+}
+
+type ProtoGetterSettings struct {
+ SkipGeneratedBy []string `mapstructure:"skip-generated-by"`
+ SkipFiles []string `mapstructure:"skip-files"`
+ SkipAnyGenerated *bool `mapstructure:"skip-any-generated"`
+ ReplaceFirstArgInAppend *bool `mapstructure:"replace-first-arg-in-append"`
+}
+
+type ReassignSettings struct {
+ Patterns []string `mapstructure:"patterns"`
+}
+
+type RecvcheckSettings struct {
+ DisableBuiltin *bool `mapstructure:"disable-builtin"`
+ Exclusions []string `mapstructure:"exclusions"`
+}
+
+type ReviveSettings struct {
+ Go *string `mapstructure:"-"`
+ MaxOpenFiles *int `mapstructure:"max-open-files"`
+ IgnoreGeneratedHeader *bool `mapstructure:"ignore-generated-header"`
+ Confidence *float64 `mapstructure:"confidence"`
+ Severity *string `mapstructure:"severity"`
+ EnableAllRules *bool `mapstructure:"enable-all-rules"`
+ Rules []struct {
+ Name *string `mapstructure:"name"`
+ Arguments []any `mapstructure:"arguments"`
+ Severity *string `mapstructure:"severity"`
+ Disabled *bool `mapstructure:"disabled"`
+ Exclude []string `mapstructure:"exclude"`
+ } `mapstructure:"rules"`
+ ErrorCode *int `mapstructure:"error-code"`
+ WarningCode *int `mapstructure:"warning-code"`
+ Directives []struct {
+ Name *string `mapstructure:"name"`
+ Severity *string `mapstructure:"severity"`
+ } `mapstructure:"directives"`
+}
+
+type RowsErrCheckSettings struct {
+ Packages []string `mapstructure:"packages"`
+}
+
+type SlogLintSettings struct {
+ NoMixedArgs *bool `mapstructure:"no-mixed-args"`
+ KVOnly *bool `mapstructure:"kv-only"`
+ AttrOnly *bool `mapstructure:"attr-only"`
+ NoGlobal *string `mapstructure:"no-global"`
+ Context *string `mapstructure:"context"`
+ StaticMsg *bool `mapstructure:"static-msg"`
+ NoRawKeys *bool `mapstructure:"no-raw-keys"`
+ KeyNamingCase *string `mapstructure:"key-naming-case"`
+ ForbiddenKeys []string `mapstructure:"forbidden-keys"`
+ ArgsOnSepLines *bool `mapstructure:"args-on-sep-lines"`
+}
+
+type SpancheckSettings struct {
+ Checks []string `mapstructure:"checks"`
+ IgnoreCheckSignatures []string `mapstructure:"ignore-check-signatures"`
+ ExtraStartSpanSignatures []string `mapstructure:"extra-start-span-signatures"`
+}
+
+type StaticCheckSettings struct {
+ Checks []string `mapstructure:"checks"`
+ Initialisms []string `mapstructure:"initialisms"` // only for stylecheck
+ DotImportWhitelist []string `mapstructure:"dot-import-whitelist"` // only for stylecheck
+ HTTPStatusCodeWhitelist []string `mapstructure:"http-status-code-whitelist"` // only for stylecheck
+}
+
+type TagAlignSettings struct {
+ Align *bool `mapstructure:"align"`
+ Sort *bool `mapstructure:"sort"`
+ Order []string `mapstructure:"order"`
+ Strict *bool `mapstructure:"strict"`
+}
+
+type TagliatelleSettings struct {
+ Case TagliatelleCase `mapstructure:"case"`
+}
+
+type TagliatelleCase struct {
+ TagliatelleBase `mapstructure:",squash"`
+ Overrides []TagliatelleOverrides `mapstructure:"overrides"`
+}
+
+type TagliatelleOverrides struct {
+ TagliatelleBase `mapstructure:",squash"`
+ Package *string `mapstructure:"pkg"`
+ Ignore *bool `mapstructure:"ignore"`
+}
+
+type TagliatelleBase struct {
+ Rules map[string]string `mapstructure:"rules"`
+ ExtendedRules map[string]TagliatelleExtendedRule `mapstructure:"extended-rules"`
+ UseFieldName *bool `mapstructure:"use-field-name"`
+ IgnoredFields []string `mapstructure:"ignored-fields"`
+}
+
+type TagliatelleExtendedRule struct {
+ Case *string `mapstructure:"case"`
+ ExtraInitialisms *bool `mapstructure:"extra-initialisms"`
+ InitialismOverrides map[string]bool `mapstructure:"initialism-overrides"`
+}
+
+type TestifylintSettings struct {
+ EnableAll *bool `mapstructure:"enable-all"`
+ DisableAll *bool `mapstructure:"disable-all"`
+ EnabledCheckers []string `mapstructure:"enable"`
+ DisabledCheckers []string `mapstructure:"disable"`
+
+ BoolCompare struct {
+ IgnoreCustomTypes *bool `mapstructure:"ignore-custom-types"`
+ } `mapstructure:"bool-compare"`
+
+ ExpectedActual struct {
+ ExpVarPattern *string `mapstructure:"pattern"`
+ } `mapstructure:"expected-actual"`
+
+ Formatter struct {
+ CheckFormatString *bool `mapstructure:"check-format-string"`
+ RequireFFuncs *bool `mapstructure:"require-f-funcs"`
+ } `mapstructure:"formatter"`
+
+ GoRequire struct {
+ IgnoreHTTPHandlers *bool `mapstructure:"ignore-http-handlers"`
+ } `mapstructure:"go-require"`
+
+ RequireError struct {
+ FnPattern *string `mapstructure:"fn-pattern"`
+ } `mapstructure:"require-error"`
+
+ SuiteExtraAssertCall struct {
+ Mode *string `mapstructure:"mode"`
+ } `mapstructure:"suite-extra-assert-call"`
+}
+
+type TestpackageSettings struct {
+ SkipRegexp *string `mapstructure:"skip-regexp"`
+ AllowPackages []string `mapstructure:"allow-packages"`
+}
+
+type ThelperSettings struct {
+ Test ThelperOptions `mapstructure:"test"`
+ Fuzz ThelperOptions `mapstructure:"fuzz"`
+ Benchmark ThelperOptions `mapstructure:"benchmark"`
+ TB ThelperOptions `mapstructure:"tb"`
+}
+
+type ThelperOptions struct {
+ First *bool `mapstructure:"first"`
+ Name *bool `mapstructure:"name"`
+ Begin *bool `mapstructure:"begin"`
+}
+
+type TenvSettings struct {
+ All *bool `mapstructure:"all"`
+}
+
+type UseStdlibVarsSettings struct {
+ HTTPMethod *bool `mapstructure:"http-method"`
+ HTTPStatusCode *bool `mapstructure:"http-status-code"`
+ TimeWeekday *bool `mapstructure:"time-weekday"`
+ TimeMonth *bool `mapstructure:"time-month"`
+ TimeLayout *bool `mapstructure:"time-layout"`
+ CryptoHash *bool `mapstructure:"crypto-hash"`
+ DefaultRPCPath *bool `mapstructure:"default-rpc-path"`
+ SQLIsolationLevel *bool `mapstructure:"sql-isolation-level"`
+ TLSSignatureScheme *bool `mapstructure:"tls-signature-scheme"`
+ ConstantKind *bool `mapstructure:"constant-kind"`
+
+ // Deprecated
+ OSDevNull *bool `mapstructure:"os-dev-null"`
+ // Deprecated
+ SyslogPriority *bool `mapstructure:"syslog-priority"`
+}
+
+type UseTestingSettings struct {
+ ContextBackground *bool `mapstructure:"context-background"`
+ ContextTodo *bool `mapstructure:"context-todo"`
+ OSChdir *bool `mapstructure:"os-chdir"`
+ OSMkdirTemp *bool `mapstructure:"os-mkdir-temp"`
+ OSSetenv *bool `mapstructure:"os-setenv"`
+ OSTempDir *bool `mapstructure:"os-temp-dir"`
+ OSCreateTemp *bool `mapstructure:"os-create-temp"`
+}
+
+type UnconvertSettings struct {
+ FastMath *bool `mapstructure:"fast-math"`
+ Safe *bool `mapstructure:"safe"`
+}
+
+type UnparamSettings struct {
+ CheckExported *bool `mapstructure:"check-exported"`
+ Algo *string `mapstructure:"algo"`
+}
+
+type UnusedSettings struct {
+ FieldWritesAreUses *bool `mapstructure:"field-writes-are-uses"`
+ PostStatementsAreReads *bool `mapstructure:"post-statements-are-reads"`
+ ExportedFieldsAreUsed *bool `mapstructure:"exported-fields-are-used"`
+ ParametersAreUsed *bool `mapstructure:"parameters-are-used"`
+ LocalVariablesAreUsed *bool `mapstructure:"local-variables-are-used"`
+ GeneratedIsUsed *bool `mapstructure:"generated-is-used"`
+
+ // Deprecated
+ ExportedIsUsed *bool `mapstructure:"exported-is-used"`
+}
+
+type VarnamelenSettings struct {
+ MaxDistance *int `mapstructure:"max-distance"`
+ MinNameLength *int `mapstructure:"min-name-length"`
+ CheckReceiver *bool `mapstructure:"check-receiver"`
+ CheckReturn *bool `mapstructure:"check-return"`
+ CheckTypeParam *bool `mapstructure:"check-type-param"`
+ IgnoreNames []string `mapstructure:"ignore-names"`
+ IgnoreTypeAssertOk *bool `mapstructure:"ignore-type-assert-ok"`
+ IgnoreMapIndexOk *bool `mapstructure:"ignore-map-index-ok"`
+ IgnoreChanRecvOk *bool `mapstructure:"ignore-chan-recv-ok"`
+ IgnoreDecls []string `mapstructure:"ignore-decls"`
+}
+
+type WhitespaceSettings struct {
+ MultiIf *bool `mapstructure:"multi-if"`
+ MultiFunc *bool `mapstructure:"multi-func"`
+}
+
+type WrapcheckSettings struct {
+ ExtraIgnoreSigs []string `mapstructure:"extra-ignore-sigs"`
+ // TODO(ldez): v2 the options must be renamed to use hyphen.
+ IgnoreSigs []string `mapstructure:"ignoreSigs"`
+ IgnoreSigRegexps []string `mapstructure:"ignoreSigRegexps"`
+ IgnorePackageGlobs []string `mapstructure:"ignorePackageGlobs"`
+ IgnoreInterfaceRegexps []string `mapstructure:"ignoreInterfaceRegexps"`
+}
+
+type WSLSettings struct {
+ StrictAppend *bool `mapstructure:"strict-append"`
+ AllowAssignAndCallCuddle *bool `mapstructure:"allow-assign-and-call"`
+ AllowAssignAndAnythingCuddle *bool `mapstructure:"allow-assign-and-anything"`
+ AllowMultiLineAssignCuddle *bool `mapstructure:"allow-multiline-assign"`
+ ForceCaseTrailingWhitespaceLimit *int `mapstructure:"force-case-trailing-whitespace"`
+ AllowTrailingComment *bool `mapstructure:"allow-trailing-comment"`
+ AllowSeparatedLeadingComment *bool `mapstructure:"allow-separated-leading-comment"`
+ AllowCuddleDeclaration *bool `mapstructure:"allow-cuddle-declarations"`
+ AllowCuddleWithCalls []string `mapstructure:"allow-cuddle-with-calls"`
+ AllowCuddleWithRHS []string `mapstructure:"allow-cuddle-with-rhs"`
+ ForceCuddleErrCheckAndAssign *bool `mapstructure:"force-err-cuddling"`
+ ErrorVariableNames []string `mapstructure:"error-variable-names"`
+ ForceExclusiveShortDeclarations *bool `mapstructure:"force-short-decl-cuddling"`
+}
+
+// CustomLinterSettings encapsulates the meta-data of a private linter.
+type CustomLinterSettings struct {
+ // Type plugin type.
+ // It can be `goplugin` or `module`.
+ Type *string `mapstructure:"type"`
+
+ // Path to a plugin *.so file that implements the private linter.
+ // Only for Go plugin system.
+ Path *string `mapstructure:"path"`
+
+ // Description describes the purpose of the private linter.
+ Description *string `mapstructure:"description"`
+ // OriginalURL The URL containing the source code for the private linter.
+ OriginalURL *string `mapstructure:"original-url"`
+
+ // Settings plugin settings only work with linterdb.PluginConstructor symbol.
+ Settings any `mapstructure:"settings"`
+}
+
+type GciSettings struct {
+ Sections []string `mapstructure:"sections"`
+ NoInlineComments *bool `mapstructure:"no-inline-comments"`
+ NoPrefixComments *bool `mapstructure:"no-prefix-comments"`
+ SkipGenerated *bool `mapstructure:"skip-generated"`
+ CustomOrder *bool `mapstructure:"custom-order"`
+ NoLexOrder *bool `mapstructure:"no-lex-order"`
+
+ // Deprecated: use Sections instead.
+ LocalPrefixes *string `mapstructure:"local-prefixes"`
+}
+
+type GoFmtSettings struct {
+ Simplify *bool `mapstructure:"simplify"`
+ RewriteRules []GoFmtRewriteRule `mapstructure:"rewrite-rules"`
+}
+
+type GoFmtRewriteRule struct {
+ Pattern *string `mapstructure:"pattern"`
+ Replacement *string `mapstructure:"replacement"`
+}
+
+type GoFumptSettings struct {
+ ModulePath *string `mapstructure:"module-path"`
+ ExtraRules *bool `mapstructure:"extra-rules"`
+
+ // Deprecated: use the global `run.go` instead.
+ LangVersion *string `mapstructure:"lang-version"`
+}
+
+type GoImportsSettings struct {
+ LocalPrefixes *string `mapstructure:"local-prefixes"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/output.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/output.go
new file mode 100644
index 00000000..408a07ab
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/output.go
@@ -0,0 +1,39 @@
+package versionone
+
+import (
+ "strings"
+
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr"
+)
+
+type Output struct {
+ Formats OutputFormats `mapstructure:"formats"`
+ PrintIssuedLine *bool `mapstructure:"print-issued-lines"`
+ PrintLinterName *bool `mapstructure:"print-linter-name"`
+ SortResults *bool `mapstructure:"sort-results"`
+ SortOrder []string `mapstructure:"sort-order"`
+ PathPrefix *string `mapstructure:"path-prefix"`
+ ShowStats *bool `mapstructure:"show-stats"`
+}
+
+type OutputFormat struct {
+ Format *string `mapstructure:"format"`
+ Path *string `mapstructure:"path"`
+}
+
+type OutputFormats []OutputFormat
+
+func (p *OutputFormats) UnmarshalText(text []byte) error {
+ formats := strings.Split(string(text), ",")
+
+ for _, item := range formats {
+ format, path, _ := strings.Cut(item, ":")
+
+ *p = append(*p, OutputFormat{
+ Path: ptr.Pointer(path),
+ Format: ptr.Pointer(format),
+ })
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/run.go
new file mode 100644
index 00000000..db3e0edc
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/run.go
@@ -0,0 +1,25 @@
+package versionone
+
+import (
+ "time"
+)
+
+// Run encapsulates the config options for running the linter analysis.
+type Run struct {
+ Timeout time.Duration `mapstructure:"timeout"`
+
+ Concurrency *int `mapstructure:"concurrency"`
+
+ Go *string `mapstructure:"go"`
+
+ RelativePathMode *string `mapstructure:"relative-path-mode"`
+
+ BuildTags []string `mapstructure:"build-tags"`
+ ModulesDownloadMode *string `mapstructure:"modules-download-mode"`
+
+ ExitCodeIfIssuesFound *int `mapstructure:"issues-exit-code"`
+ AnalyzeTests *bool `mapstructure:"tests"`
+
+ AllowParallelRunners *bool `mapstructure:"allow-parallel-runners"`
+ AllowSerialRunners *bool `mapstructure:"allow-serial-runners"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/severity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/severity.go
new file mode 100644
index 00000000..b9d52e69
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/severity.go
@@ -0,0 +1,12 @@
+package versionone
+
+type Severity struct {
+ Default *string `mapstructure:"default-severity"`
+ CaseSensitive *bool `mapstructure:"case-sensitive"`
+ Rules []SeverityRule `mapstructure:"rules"`
+}
+
+type SeverityRule struct {
+ BaseRule `mapstructure:",squash"`
+ Severity *string `mapstructure:"severity"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/base_rule.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/base_rule.go
new file mode 100644
index 00000000..469592dc
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/base_rule.go
@@ -0,0 +1,13 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type BaseRule struct {
+ Linters []string `yaml:"linters,omitempty" toml:"linters,multiline,omitempty"`
+ Path *string `yaml:"path,omitempty" toml:"path,multiline,omitempty"`
+ PathExcept *string `yaml:"path-except,omitempty" toml:"path-except,multiline,omitempty"`
+ Text *string `yaml:"text,omitempty" toml:"text,multiline,omitempty"`
+ Source *string `yaml:"source,omitempty" toml:"source,multiline,omitempty"`
+
+ InternalReference *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/config.go
new file mode 100644
index 00000000..341b47b6
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/config.go
@@ -0,0 +1,18 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type Config struct {
+ Version *string `yaml:"version,omitempty" toml:"version,multiline,omitempty"`
+
+ Run Run `yaml:"run,omitempty" toml:"run,multiline,omitempty"`
+
+ Output Output `yaml:"output,omitempty" toml:"output,multiline,omitempty"`
+
+ Linters Linters `yaml:"linters,omitempty" toml:"linters,multiline,omitempty"`
+
+ Issues Issues `yaml:"issues,omitempty" toml:"issues,multiline,omitempty"`
+ Severity Severity `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
+
+ Formatters Formatters `yaml:"formatters,omitempty" toml:"formatters,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters.go
new file mode 100644
index 00000000..41771494
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters.go
@@ -0,0 +1,15 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type Formatters struct {
+ Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
+ Settings FormatterSettings `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
+ Exclusions FormatterExclusions `yaml:"exclusions,omitempty" toml:"exclusions,multiline,omitempty"`
+}
+
+type FormatterExclusions struct {
+ Generated *string `yaml:"generated,omitempty" toml:"generated,multiline,omitempty"`
+ Paths []string `yaml:"paths,omitempty" toml:"paths,multiline,omitempty"`
+ WarnUnused *bool `yaml:"warn-unused,omitempty" toml:"warn-unused,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters_settings.go
new file mode 100644
index 00000000..878b2c41
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters_settings.go
@@ -0,0 +1,48 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type FormatterSettings struct {
+ Gci GciSettings `yaml:"gci,omitempty" toml:"gci,multiline,omitempty"`
+ GoFmt GoFmtSettings `yaml:"gofmt,omitempty" toml:"gofmt,multiline,omitempty"`
+ GoFumpt GoFumptSettings `yaml:"gofumpt,omitempty" toml:"gofumpt,multiline,omitempty"`
+ GoImports GoImportsSettings `yaml:"goimports,omitempty" toml:"goimports,multiline,omitempty"`
+ GoLines GoLinesSettings `yaml:"golines,omitempty" toml:"golines,multiline,omitempty"`
+}
+
+type GciSettings struct {
+ Sections []string `yaml:"sections,omitempty" toml:"sections,multiline,omitempty"`
+ NoInlineComments *bool `yaml:"no-inline-comments,omitempty" toml:"no-inline-comments,multiline,omitempty"`
+ NoPrefixComments *bool `yaml:"no-prefix-comments,omitempty" toml:"no-prefix-comments,multiline,omitempty"`
+ CustomOrder *bool `yaml:"custom-order,omitempty" toml:"custom-order,multiline,omitempty"`
+ NoLexOrder *bool `yaml:"no-lex-order,omitempty" toml:"no-lex-order,multiline,omitempty"`
+}
+
+type GoFmtSettings struct {
+ Simplify *bool `yaml:"simplify,omitempty" toml:"simplify,multiline,omitempty"`
+ RewriteRules []GoFmtRewriteRule `yaml:"rewrite-rules,omitempty" toml:"rewrite-rules,multiline,omitempty"`
+}
+
+type GoFmtRewriteRule struct {
+ Pattern *string `yaml:"pattern,omitempty" toml:"pattern,multiline,omitempty"`
+ Replacement *string `yaml:"replacement,omitempty" toml:"replacement,multiline,omitempty"`
+}
+
+type GoFumptSettings struct {
+ ModulePath *string `yaml:"module-path,omitempty" toml:"module-path,multiline,omitempty"`
+ ExtraRules *bool `yaml:"extra-rules,omitempty" toml:"extra-rules,multiline,omitempty"`
+
+ LangVersion *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
+}
+
+type GoImportsSettings struct {
+ LocalPrefixes []string `yaml:"local-prefixes,omitempty" toml:"local-prefixes,multiline,omitempty"`
+}
+
+type GoLinesSettings struct {
+ MaxLen *int `yaml:"max-len,omitempty" toml:"max-len,multiline,omitempty"`
+ TabLen *int `yaml:"tab-len,omitempty" toml:"tab-len,multiline,omitempty"`
+ ShortenComments *bool `yaml:"shorten-comments,omitempty" toml:"shorten-comments,multiline,omitempty"`
+ ReformatTags *bool `yaml:"reformat-tags,omitempty" toml:"reformat-tags,multiline,omitempty"`
+ ChainSplitDots *bool `yaml:"chain-split-dots,omitempty" toml:"chain-split-dots,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/issues.go
new file mode 100644
index 00000000..fa3b06ac
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/issues.go
@@ -0,0 +1,17 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type Issues struct {
+ MaxIssuesPerLinter *int `yaml:"max-issues-per-linter,omitempty" toml:"max-issues-per-linter,multiline,omitempty"`
+ MaxSameIssues *int `yaml:"max-same-issues,omitempty" toml:"max-same-issues,multiline,omitempty"`
+ UniqByLine *bool `yaml:"uniq-by-line,omitempty" toml:"uniq-by-line,multiline,omitempty"`
+
+ DiffFromRevision *string `yaml:"new-from-rev,omitempty" toml:"new-from-rev,multiline,omitempty"`
+ DiffFromMergeBase *string `yaml:"new-from-merge-base,omitempty" toml:"new-from-merge-base,multiline,omitempty"`
+ DiffPatchFilePath *string `yaml:"new-from-patch,omitempty" toml:"new-from-patch,multiline,omitempty"`
+ WholeFiles *bool `yaml:"whole-files,omitempty" toml:"whole-files,multiline,omitempty"`
+ Diff *bool `yaml:"new,omitempty" toml:"new,multiline,omitempty"`
+
+ NeedFix *bool `yaml:"fix,omitempty" toml:"fix,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters.go
new file mode 100644
index 00000000..79731311
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters.go
@@ -0,0 +1,14 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type Linters struct {
+ Default *string `yaml:"default,omitempty" toml:"default,multiline,omitempty"`
+ Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
+ Disable []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"`
+ FastOnly *bool `yaml:"fast-only,omitempty" toml:"fast-only,multiline,omitempty"`
+
+ Settings LintersSettings `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
+
+ Exclusions LinterExclusions `yaml:"exclusions,omitempty" toml:"exclusions,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_exclusions.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_exclusions.go
new file mode 100644
index 00000000..d4ecb972
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_exclusions.go
@@ -0,0 +1,16 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type LinterExclusions struct {
+ Generated *string `yaml:"generated,omitempty" toml:"generated,multiline,omitempty"`
+ WarnUnused *bool `yaml:"warn-unused,omitempty" toml:"warn-unused,multiline,omitempty"`
+ Presets []string `yaml:"presets,omitempty" toml:"presets,multiline,omitempty"`
+ Rules []ExcludeRule `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
+ Paths []string `yaml:"paths,omitempty" toml:"paths,multiline,omitempty"`
+ PathsExcept []string `yaml:"paths-except,omitempty" toml:"paths-except,multiline,omitempty"`
+}
+
+type ExcludeRule struct {
+ BaseRule `yaml:",inline"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_settings.go
new file mode 100644
index 00000000..3a0d6b7b
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_settings.go
@@ -0,0 +1,782 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type LintersSettings struct {
+ FormatterSettings `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
+
+ Asasalint AsasalintSettings `yaml:"asasalint,omitempty" toml:"asasalint,multiline,omitempty"`
+ BiDiChk BiDiChkSettings `yaml:"bidichk,omitempty" toml:"bidichk,multiline,omitempty"`
+ CopyLoopVar CopyLoopVarSettings `yaml:"copyloopvar,omitempty" toml:"copyloopvar,multiline,omitempty"`
+ Cyclop CyclopSettings `yaml:"cyclop,omitempty" toml:"cyclop,multiline,omitempty"`
+ Decorder DecorderSettings `yaml:"decorder,omitempty" toml:"decorder,multiline,omitempty"`
+ Depguard DepGuardSettings `yaml:"depguard,omitempty" toml:"depguard,multiline,omitempty"`
+ Dogsled DogsledSettings `yaml:"dogsled,omitempty" toml:"dogsled,multiline,omitempty"`
+ Dupl DuplSettings `yaml:"dupl,omitempty" toml:"dupl,multiline,omitempty"`
+ DupWord DupWordSettings `yaml:"dupword,omitempty" toml:"dupword,multiline,omitempty"`
+ Errcheck ErrcheckSettings `yaml:"errcheck,omitempty" toml:"errcheck,multiline,omitempty"`
+ ErrChkJSON ErrChkJSONSettings `yaml:"errchkjson,omitempty" toml:"errchkjson,multiline,omitempty"`
+ ErrorLint ErrorLintSettings `yaml:"errorlint,omitempty" toml:"errorlint,multiline,omitempty"`
+ Exhaustive ExhaustiveSettings `yaml:"exhaustive,omitempty" toml:"exhaustive,multiline,omitempty"`
+ Exhaustruct ExhaustructSettings `yaml:"exhaustruct,omitempty" toml:"exhaustruct,multiline,omitempty"`
+ Fatcontext FatcontextSettings `yaml:"fatcontext,omitempty" toml:"fatcontext,multiline,omitempty"`
+ Forbidigo ForbidigoSettings `yaml:"forbidigo,omitempty" toml:"forbidigo,multiline,omitempty"`
+ FuncOrder FuncOrderSettings `yaml:"funcorder,omitempty" toml:"funcorder,multiline,omitempty"`
+ Funlen FunlenSettings `yaml:"funlen,omitempty" toml:"funlen,multiline,omitempty"`
+ GinkgoLinter GinkgoLinterSettings `yaml:"ginkgolinter,omitempty" toml:"ginkgolinter,multiline,omitempty"`
+ Gocognit GocognitSettings `yaml:"gocognit,omitempty" toml:"gocognit,multiline,omitempty"`
+ GoChecksumType GoChecksumTypeSettings `yaml:"gochecksumtype,omitempty" toml:"gochecksumtype,multiline,omitempty"`
+ Goconst GoConstSettings `yaml:"goconst,omitempty" toml:"goconst,multiline,omitempty"`
+ Gocritic GoCriticSettings `yaml:"gocritic,omitempty" toml:"gocritic,multiline,omitempty"`
+ Gocyclo GoCycloSettings `yaml:"gocyclo,omitempty" toml:"gocyclo,multiline,omitempty"`
+ Godot GodotSettings `yaml:"godot,omitempty" toml:"godot,multiline,omitempty"`
+ Godox GodoxSettings `yaml:"godox,omitempty" toml:"godox,multiline,omitempty"`
+ Goheader GoHeaderSettings `yaml:"goheader,omitempty" toml:"goheader,multiline,omitempty"`
+ GoModDirectives GoModDirectivesSettings `yaml:"gomoddirectives,omitempty" toml:"gomoddirectives,multiline,omitempty"`
+ Gomodguard GoModGuardSettings `yaml:"gomodguard,omitempty" toml:"gomodguard,multiline,omitempty"`
+ Gosec GoSecSettings `yaml:"gosec,omitempty" toml:"gosec,multiline,omitempty"`
+ Gosmopolitan GosmopolitanSettings `yaml:"gosmopolitan,omitempty" toml:"gosmopolitan,multiline,omitempty"`
+ Govet GovetSettings `yaml:"govet,omitempty" toml:"govet,multiline,omitempty"`
+ Grouper GrouperSettings `yaml:"grouper,omitempty" toml:"grouper,multiline,omitempty"`
+ Iface IfaceSettings `yaml:"iface,omitempty" toml:"iface,multiline,omitempty"`
+ ImportAs ImportAsSettings `yaml:"importas,omitempty" toml:"importas,multiline,omitempty"`
+ Inamedparam INamedParamSettings `yaml:"inamedparam,omitempty" toml:"inamedparam,multiline,omitempty"`
+ InterfaceBloat InterfaceBloatSettings `yaml:"interfacebloat,omitempty" toml:"interfacebloat,multiline,omitempty"`
+ Ireturn IreturnSettings `yaml:"ireturn,omitempty" toml:"ireturn,multiline,omitempty"`
+ Lll LllSettings `yaml:"lll,omitempty" toml:"lll,multiline,omitempty"`
+ LoggerCheck LoggerCheckSettings `yaml:"loggercheck,omitempty" toml:"loggercheck,multiline,omitempty"`
+ MaintIdx MaintIdxSettings `yaml:"maintidx,omitempty" toml:"maintidx,multiline,omitempty"`
+ Makezero MakezeroSettings `yaml:"makezero,omitempty" toml:"makezero,multiline,omitempty"`
+ Misspell MisspellSettings `yaml:"misspell,omitempty" toml:"misspell,multiline,omitempty"`
+ Mnd MndSettings `yaml:"mnd,omitempty" toml:"mnd,multiline,omitempty"`
+ MustTag MustTagSettings `yaml:"musttag,omitempty" toml:"musttag,multiline,omitempty"`
+ Nakedret NakedretSettings `yaml:"nakedret,omitempty" toml:"nakedret,multiline,omitempty"`
+ Nestif NestifSettings `yaml:"nestif,omitempty" toml:"nestif,multiline,omitempty"`
+ NilNil NilNilSettings `yaml:"nilnil,omitempty" toml:"nilnil,multiline,omitempty"`
+ Nlreturn NlreturnSettings `yaml:"nlreturn,omitempty" toml:"nlreturn,multiline,omitempty"`
+ NoLintLint NoLintLintSettings `yaml:"nolintlint,omitempty" toml:"nolintlint,multiline,omitempty"`
+ NoNamedReturns NoNamedReturnsSettings `yaml:"nonamedreturns,omitempty" toml:"nonamedreturns,multiline,omitempty"`
+ ParallelTest ParallelTestSettings `yaml:"paralleltest,omitempty" toml:"paralleltest,multiline,omitempty"`
+ PerfSprint PerfSprintSettings `yaml:"perfsprint,omitempty" toml:"perfsprint,multiline,omitempty"`
+ Prealloc PreallocSettings `yaml:"prealloc,omitempty" toml:"prealloc,multiline,omitempty"`
+ Predeclared PredeclaredSettings `yaml:"predeclared,omitempty" toml:"predeclared,multiline,omitempty"`
+ Promlinter PromlinterSettings `yaml:"promlinter,omitempty" toml:"promlinter,multiline,omitempty"`
+ ProtoGetter ProtoGetterSettings `yaml:"protogetter,omitempty" toml:"protogetter,multiline,omitempty"`
+ Reassign ReassignSettings `yaml:"reassign,omitempty" toml:"reassign,multiline,omitempty"`
+ Recvcheck RecvcheckSettings `yaml:"recvcheck,omitempty" toml:"recvcheck,multiline,omitempty"`
+ Revive ReviveSettings `yaml:"revive,omitempty" toml:"revive,multiline,omitempty"`
+ RowsErrCheck RowsErrCheckSettings `yaml:"rowserrcheck,omitempty" toml:"rowserrcheck,multiline,omitempty"`
+ SlogLint SlogLintSettings `yaml:"sloglint,omitempty" toml:"sloglint,multiline,omitempty"`
+ Spancheck SpancheckSettings `yaml:"spancheck,omitempty" toml:"spancheck,multiline,omitempty"`
+ Staticcheck StaticCheckSettings `yaml:"staticcheck,omitempty" toml:"staticcheck,multiline,omitempty"`
+ TagAlign TagAlignSettings `yaml:"tagalign,omitempty" toml:"tagalign,multiline,omitempty"`
+ Tagliatelle TagliatelleSettings `yaml:"tagliatelle,omitempty" toml:"tagliatelle,multiline,omitempty"`
+ Testifylint TestifylintSettings `yaml:"testifylint,omitempty" toml:"testifylint,multiline,omitempty"`
+ Testpackage TestpackageSettings `yaml:"testpackage,omitempty" toml:"testpackage,multiline,omitempty"`
+ Thelper ThelperSettings `yaml:"thelper,omitempty" toml:"thelper,multiline,omitempty"`
+ Unconvert UnconvertSettings `yaml:"unconvert,omitempty" toml:"unconvert,multiline,omitempty"`
+ Unparam UnparamSettings `yaml:"unparam,omitempty" toml:"unparam,multiline,omitempty"`
+ Unused UnusedSettings `yaml:"unused,omitempty" toml:"unused,multiline,omitempty"`
+ UseStdlibVars UseStdlibVarsSettings `yaml:"usestdlibvars,omitempty" toml:"usestdlibvars,multiline,omitempty"`
+ UseTesting UseTestingSettings `yaml:"usetesting,omitempty" toml:"usetesting,multiline,omitempty"`
+ Varnamelen VarnamelenSettings `yaml:"varnamelen,omitempty" toml:"varnamelen,multiline,omitempty"`
+ Whitespace WhitespaceSettings `yaml:"whitespace,omitempty" toml:"whitespace,multiline,omitempty"`
+ Wrapcheck WrapcheckSettings `yaml:"wrapcheck,omitempty" toml:"wrapcheck,multiline,omitempty"`
+ WSL WSLSettings `yaml:"wsl,omitempty" toml:"wsl,multiline,omitempty"`
+
+ Custom map[string]CustomLinterSettings `yaml:"custom,omitempty" toml:"custom,multiline,omitempty"`
+}
+
+type AsasalintSettings struct {
+ Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"`
+ UseBuiltinExclusions *bool `yaml:"use-builtin-exclusions,omitempty" toml:"use-builtin-exclusions,multiline,omitempty"`
+}
+
+type BiDiChkSettings struct {
+ LeftToRightEmbedding *bool `yaml:"left-to-right-embedding,omitempty" toml:"left-to-right-embedding,multiline,omitempty"`
+ RightToLeftEmbedding *bool `yaml:"right-to-left-embedding,omitempty" toml:"right-to-left-embedding,multiline,omitempty"`
+ PopDirectionalFormatting *bool `yaml:"pop-directional-formatting,omitempty" toml:"pop-directional-formatting,multiline,omitempty"`
+ LeftToRightOverride *bool `yaml:"left-to-right-override,omitempty" toml:"left-to-right-override,multiline,omitempty"`
+ RightToLeftOverride *bool `yaml:"right-to-left-override,omitempty" toml:"right-to-left-override,multiline,omitempty"`
+ LeftToRightIsolate *bool `yaml:"left-to-right-isolate,omitempty" toml:"left-to-right-isolate,multiline,omitempty"`
+ RightToLeftIsolate *bool `yaml:"right-to-left-isolate,omitempty" toml:"right-to-left-isolate,multiline,omitempty"`
+ FirstStrongIsolate *bool `yaml:"first-strong-isolate,omitempty" toml:"first-strong-isolate,multiline,omitempty"`
+ PopDirectionalIsolate *bool `yaml:"pop-directional-isolate,omitempty" toml:"pop-directional-isolate,multiline,omitempty"`
+}
+
+type CopyLoopVarSettings struct {
+ CheckAlias *bool `yaml:"check-alias,omitempty" toml:"check-alias,multiline,omitempty"`
+}
+
+type CyclopSettings struct {
+ MaxComplexity *int `yaml:"max-complexity,omitempty" toml:"max-complexity,multiline,omitempty"`
+ PackageAverage *float64 `yaml:"package-average,omitempty" toml:"package-average,multiline,omitempty"`
+}
+
+type DepGuardSettings struct {
+ Rules map[string]*DepGuardList `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
+}
+
+type DepGuardList struct {
+ ListMode *string `yaml:"list-mode,omitempty" toml:"list-mode,multiline,omitempty"`
+ Files []string `yaml:"files,omitempty" toml:"files,multiline,omitempty"`
+ Allow []string `yaml:"allow,omitempty" toml:"allow,multiline,omitempty"`
+ Deny []DepGuardDeny `yaml:"deny,omitempty" toml:"deny,multiline,omitempty"`
+}
+
+type DepGuardDeny struct {
+ Pkg *string `yaml:"pkg,omitempty" toml:"pkg,multiline,omitempty"`
+ Desc *string `yaml:"desc,omitempty" toml:"desc,multiline,omitempty"`
+}
+
+type DecorderSettings struct {
+ DecOrder []string `yaml:"dec-order,omitempty" toml:"dec-order,multiline,omitempty"`
+ IgnoreUnderscoreVars *bool `yaml:"ignore-underscore-vars,omitempty" toml:"ignore-underscore-vars,multiline,omitempty"`
+ DisableDecNumCheck *bool `yaml:"disable-dec-num-check,omitempty" toml:"disable-dec-num-check,multiline,omitempty"`
+ DisableTypeDecNumCheck *bool `yaml:"disable-type-dec-num-check,omitempty" toml:"disable-type-dec-num-check,multiline,omitempty"`
+ DisableConstDecNumCheck *bool `yaml:"disable-const-dec-num-check,omitempty" toml:"disable-const-dec-num-check,multiline,omitempty"`
+ DisableVarDecNumCheck *bool `yaml:"disable-var-dec-num-check,omitempty" toml:"disable-var-dec-num-check,multiline,omitempty"`
+ DisableDecOrderCheck *bool `yaml:"disable-dec-order-check,omitempty" toml:"disable-dec-order-check,multiline,omitempty"`
+ DisableInitFuncFirstCheck *bool `yaml:"disable-init-func-first-check,omitempty" toml:"disable-init-func-first-check,multiline,omitempty"`
+}
+
+type DogsledSettings struct {
+ MaxBlankIdentifiers *int `yaml:"max-blank-identifiers,omitempty" toml:"max-blank-identifiers,multiline,omitempty"`
+}
+
+type DuplSettings struct {
+ Threshold *int `yaml:"threshold,omitempty" toml:"threshold,multiline,omitempty"`
+}
+
+type DupWordSettings struct {
+ Keywords []string `yaml:"keywords,omitempty" toml:"keywords,multiline,omitempty"`
+ Ignore []string `yaml:"ignore,omitempty" toml:"ignore,multiline,omitempty"`
+}
+
+type ErrcheckSettings struct {
+ DisableDefaultExclusions *bool `yaml:"disable-default-exclusions,omitempty" toml:"disable-default-exclusions,multiline,omitempty"`
+ CheckTypeAssertions *bool `yaml:"check-type-assertions,omitempty" toml:"check-type-assertions,multiline,omitempty"`
+ CheckAssignToBlank *bool `yaml:"check-blank,omitempty" toml:"check-blank,multiline,omitempty"`
+ ExcludeFunctions []string `yaml:"exclude-functions,omitempty" toml:"exclude-functions,multiline,omitempty"`
+}
+
+type ErrChkJSONSettings struct {
+ CheckErrorFreeEncoding *bool `yaml:"check-error-free-encoding,omitempty" toml:"check-error-free-encoding,multiline,omitempty"`
+ ReportNoExported *bool `yaml:"report-no-exported,omitempty" toml:"report-no-exported,multiline,omitempty"`
+}
+
+type ErrorLintSettings struct {
+ Errorf *bool `yaml:"errorf,omitempty" toml:"errorf,multiline,omitempty"`
+ ErrorfMulti *bool `yaml:"errorf-multi,omitempty" toml:"errorf-multi,multiline,omitempty"`
+ Asserts *bool `yaml:"asserts,omitempty" toml:"asserts,multiline,omitempty"`
+ Comparison *bool `yaml:"comparison,omitempty" toml:"comparison,multiline,omitempty"`
+ AllowedErrors []ErrorLintAllowPair `yaml:"allowed-errors,omitempty" toml:"allowed-errors,multiline,omitempty"`
+ AllowedErrorsWildcard []ErrorLintAllowPair `yaml:"allowed-errors-wildcard,omitempty" toml:"allowed-errors-wildcard,multiline,omitempty"`
+}
+
+type ErrorLintAllowPair struct {
+ Err *string `yaml:"err,omitempty" toml:"err,multiline,omitempty"`
+ Fun *string `yaml:"fun,omitempty" toml:"fun,multiline,omitempty"`
+}
+
+type ExhaustiveSettings struct {
+ Check []string `yaml:"check,omitempty" toml:"check,multiline,omitempty"`
+ DefaultSignifiesExhaustive *bool `yaml:"default-signifies-exhaustive,omitempty" toml:"default-signifies-exhaustive,multiline,omitempty"`
+ IgnoreEnumMembers *string `yaml:"ignore-enum-members,omitempty" toml:"ignore-enum-members,multiline,omitempty"`
+ IgnoreEnumTypes *string `yaml:"ignore-enum-types,omitempty" toml:"ignore-enum-types,multiline,omitempty"`
+ PackageScopeOnly *bool `yaml:"package-scope-only,omitempty" toml:"package-scope-only,multiline,omitempty"`
+ ExplicitExhaustiveMap *bool `yaml:"explicit-exhaustive-map,omitempty" toml:"explicit-exhaustive-map,multiline,omitempty"`
+ ExplicitExhaustiveSwitch *bool `yaml:"explicit-exhaustive-switch,omitempty" toml:"explicit-exhaustive-switch,multiline,omitempty"`
+ DefaultCaseRequired *bool `yaml:"default-case-required,omitempty" toml:"default-case-required,multiline,omitempty"`
+}
+
+type ExhaustructSettings struct {
+ Include []string `yaml:"include,omitempty" toml:"include,multiline,omitempty"`
+ Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"`
+}
+
+type FatcontextSettings struct {
+ CheckStructPointers *bool `yaml:"check-struct-pointers,omitempty" toml:"check-struct-pointers,multiline,omitempty"`
+}
+
+type ForbidigoSettings struct {
+ Forbid []ForbidigoPattern `yaml:"forbid,omitempty" toml:"forbid,multiline,omitempty"`
+ ExcludeGodocExamples *bool `yaml:"exclude-godoc-examples,omitempty" toml:"exclude-godoc-examples,multiline,omitempty"`
+ AnalyzeTypes *bool `yaml:"analyze-types,omitempty" toml:"analyze-types,multiline,omitempty"`
+}
+
+type ForbidigoPattern struct {
+ Pattern *string `yaml:"pattern,omitempty" toml:"pattern,multiline,omitempty"`
+ Package *string `yaml:"pkg,omitempty,omitempty" toml:"pkg,omitempty,multiline,omitempty"`
+ Msg *string `yaml:"msg,omitempty,omitempty" toml:"msg,omitempty,multiline,omitempty"`
+}
+
+type FuncOrderSettings struct {
+ Constructor *bool `yaml:"constructor,omitempty,omitempty" toml:"constructor,omitempty,multiline,omitempty"`
+ StructMethod *bool `yaml:"struct-method,omitempty,omitempty" toml:"struct-method,omitempty,multiline,omitempty"`
+}
+
+type FunlenSettings struct {
+ Lines *int `yaml:"lines,omitempty" toml:"lines,multiline,omitempty"`
+ Statements *int `yaml:"statements,omitempty" toml:"statements,multiline,omitempty"`
+ IgnoreComments *bool `yaml:"ignore-comments,omitempty" toml:"ignore-comments,multiline,omitempty"`
+}
+
+type GinkgoLinterSettings struct {
+ SuppressLenAssertion *bool `yaml:"suppress-len-assertion,omitempty" toml:"suppress-len-assertion,multiline,omitempty"`
+ SuppressNilAssertion *bool `yaml:"suppress-nil-assertion,omitempty" toml:"suppress-nil-assertion,multiline,omitempty"`
+ SuppressErrAssertion *bool `yaml:"suppress-err-assertion,omitempty" toml:"suppress-err-assertion,multiline,omitempty"`
+ SuppressCompareAssertion *bool `yaml:"suppress-compare-assertion,omitempty" toml:"suppress-compare-assertion,multiline,omitempty"`
+ SuppressAsyncAssertion *bool `yaml:"suppress-async-assertion,omitempty" toml:"suppress-async-assertion,multiline,omitempty"`
+ SuppressTypeCompareWarning *bool `yaml:"suppress-type-compare-assertion,omitempty" toml:"suppress-type-compare-assertion,multiline,omitempty"`
+ ForbidFocusContainer *bool `yaml:"forbid-focus-container,omitempty" toml:"forbid-focus-container,multiline,omitempty"`
+ AllowHaveLenZero *bool `yaml:"allow-havelen-zero,omitempty" toml:"allow-havelen-zero,multiline,omitempty"`
+ ForceExpectTo *bool `yaml:"force-expect-to,omitempty" toml:"force-expect-to,multiline,omitempty"`
+ ValidateAsyncIntervals *bool `yaml:"validate-async-intervals,omitempty" toml:"validate-async-intervals,multiline,omitempty"`
+ ForbidSpecPollution *bool `yaml:"forbid-spec-pollution,omitempty" toml:"forbid-spec-pollution,multiline,omitempty"`
+ ForceSucceedForFuncs *bool `yaml:"force-succeed,omitempty" toml:"force-succeed,multiline,omitempty"`
+}
+
+type GoChecksumTypeSettings struct {
+ DefaultSignifiesExhaustive *bool `yaml:"default-signifies-exhaustive,omitempty" toml:"default-signifies-exhaustive,multiline,omitempty"`
+ IncludeSharedInterfaces *bool `yaml:"include-shared-interfaces,omitempty" toml:"include-shared-interfaces,multiline,omitempty"`
+}
+
+type GocognitSettings struct {
+ MinComplexity *int `yaml:"min-complexity,omitempty" toml:"min-complexity,multiline,omitempty"`
+}
+
+type GoConstSettings struct {
+ IgnoreStringValues []string `yaml:"ignore-string-values,omitempty" toml:"ignore-string-values,multiline,omitempty"`
+ MatchWithConstants *bool `yaml:"match-constant,omitempty" toml:"match-constant,multiline,omitempty"`
+ MinStringLen *int `yaml:"min-len,omitempty" toml:"min-len,multiline,omitempty"`
+ MinOccurrencesCount *int `yaml:"min-occurrences,omitempty" toml:"min-occurrences,multiline,omitempty"`
+ ParseNumbers *bool `yaml:"numbers,omitempty" toml:"numbers,multiline,omitempty"`
+ NumberMin *int `yaml:"min,omitempty" toml:"min,multiline,omitempty"`
+ NumberMax *int `yaml:"max,omitempty" toml:"max,multiline,omitempty"`
+ IgnoreCalls *bool `yaml:"ignore-calls,omitempty" toml:"ignore-calls,multiline,omitempty"`
+ FindDuplicates *bool `yaml:"find-duplicates,omitempty" toml:"find-duplicates,multiline,omitempty"`
+ EvalConstExpressions *bool `yaml:"eval-const-expressions,omitempty" toml:"eval-const-expressions,multiline,omitempty"`
+
+ IgnoreStrings *string `yaml:"ignore-strings,omitempty" toml:"ignore-strings,multiline,omitempty"`
+}
+
+type GoCriticSettings struct {
+ Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
+ DisableAll *bool `yaml:"disable-all,omitempty" toml:"disable-all,multiline,omitempty"`
+ EnabledChecks []string `yaml:"enabled-checks,omitempty" toml:"enabled-checks,multiline,omitempty"`
+ EnableAll *bool `yaml:"enable-all,omitempty" toml:"enable-all,multiline,omitempty"`
+ DisabledChecks []string `yaml:"disabled-checks,omitempty" toml:"disabled-checks,multiline,omitempty"`
+ EnabledTags []string `yaml:"enabled-tags,omitempty" toml:"enabled-tags,multiline,omitempty"`
+ DisabledTags []string `yaml:"disabled-tags,omitempty" toml:"disabled-tags,multiline,omitempty"`
+ SettingsPerCheck map[string]GoCriticCheckSettings `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
+}
+
+type GoCriticCheckSettings map[string]any
+
+type GoCycloSettings struct {
+ MinComplexity *int `yaml:"min-complexity,omitempty" toml:"min-complexity,multiline,omitempty"`
+}
+
+type GodotSettings struct {
+ Scope *string `yaml:"scope,omitempty" toml:"scope,multiline,omitempty"`
+ Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"`
+ Capital *bool `yaml:"capital,omitempty" toml:"capital,multiline,omitempty"`
+ Period *bool `yaml:"period,omitempty" toml:"period,multiline,omitempty"`
+}
+
+type GodoxSettings struct {
+ Keywords []string `yaml:"keywords,omitempty" toml:"keywords,multiline,omitempty"`
+}
+
+type GoHeaderSettings struct {
+ Values map[string]map[string]string `yaml:"values,omitempty" toml:"values,multiline,omitempty"`
+ Template *string `yaml:"template,omitempty" toml:"template,multiline,omitempty"`
+ TemplatePath *string `yaml:"template-path,omitempty" toml:"template-path,multiline,omitempty"`
+}
+
+type GoModDirectivesSettings struct {
+ ReplaceAllowList []string `yaml:"replace-allow-list,omitempty" toml:"replace-allow-list,multiline,omitempty"`
+ ReplaceLocal *bool `yaml:"replace-local,omitempty" toml:"replace-local,multiline,omitempty"`
+ ExcludeForbidden *bool `yaml:"exclude-forbidden,omitempty" toml:"exclude-forbidden,multiline,omitempty"`
+ RetractAllowNoExplanation *bool `yaml:"retract-allow-no-explanation,omitempty" toml:"retract-allow-no-explanation,multiline,omitempty"`
+ ToolchainForbidden *bool `yaml:"toolchain-forbidden,omitempty" toml:"toolchain-forbidden,multiline,omitempty"`
+ ToolchainPattern *string `yaml:"toolchain-pattern,omitempty" toml:"toolchain-pattern,multiline,omitempty"`
+ ToolForbidden *bool `yaml:"tool-forbidden,omitempty" toml:"tool-forbidden,multiline,omitempty"`
+ GoDebugForbidden *bool `yaml:"go-debug-forbidden,omitempty" toml:"go-debug-forbidden,multiline,omitempty"`
+ GoVersionPattern *string `yaml:"go-version-pattern,omitempty" toml:"go-version-pattern,multiline,omitempty"`
+}
+
+type GoModGuardSettings struct {
+ Allowed GoModGuardAllowed `yaml:"allowed,omitempty" toml:"allowed,multiline,omitempty"`
+ Blocked GoModGuardBlocked `yaml:"blocked,omitempty" toml:"blocked,multiline,omitempty"`
+}
+
+type GoModGuardAllowed struct {
+ Modules []string `yaml:"modules,omitempty" toml:"modules,multiline,omitempty"`
+ Domains []string `yaml:"domains,omitempty" toml:"domains,multiline,omitempty"`
+}
+
+type GoModGuardBlocked struct {
+ Modules []map[string]GoModGuardModule `yaml:"modules,omitempty" toml:"modules,multiline,omitempty"`
+ Versions []map[string]GoModGuardVersion `yaml:"versions,omitempty" toml:"versions,multiline,omitempty"`
+ LocalReplaceDirectives *bool `yaml:"local-replace-directives,omitempty" toml:"local-replace-directives,multiline,omitempty"`
+}
+
+type GoModGuardModule struct {
+ Recommendations []string `yaml:"recommendations,omitempty" toml:"recommendations,multiline,omitempty"`
+ Reason *string `yaml:"reason,omitempty" toml:"reason,multiline,omitempty"`
+}
+
+type GoModGuardVersion struct {
+ Version *string `yaml:"version,omitempty" toml:"version,multiline,omitempty"`
+ Reason *string `yaml:"reason,omitempty" toml:"reason,multiline,omitempty"`
+}
+
+type GoSecSettings struct {
+ Includes []string `yaml:"includes,omitempty" toml:"includes,multiline,omitempty"`
+ Excludes []string `yaml:"excludes,omitempty" toml:"excludes,multiline,omitempty"`
+ Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
+ Confidence *string `yaml:"confidence,omitempty" toml:"confidence,multiline,omitempty"`
+ Config map[string]any `yaml:"config,omitempty" toml:"config,multiline,omitempty"`
+ Concurrency *int `yaml:"concurrency,omitempty" toml:"concurrency,multiline,omitempty"`
+}
+
+type GosmopolitanSettings struct {
+ AllowTimeLocal *bool `yaml:"allow-time-local,omitempty" toml:"allow-time-local,multiline,omitempty"`
+ EscapeHatches []string `yaml:"escape-hatches,omitempty" toml:"escape-hatches,multiline,omitempty"`
+ WatchForScripts []string `yaml:"watch-for-scripts,omitempty" toml:"watch-for-scripts,multiline,omitempty"`
+}
+
+type GovetSettings struct {
+ Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
+
+ Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
+ Disable []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"`
+ EnableAll *bool `yaml:"enable-all,omitempty" toml:"enable-all,multiline,omitempty"`
+ DisableAll *bool `yaml:"disable-all,omitempty" toml:"disable-all,multiline,omitempty"`
+
+ Settings map[string]map[string]any `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
+}
+
+type GrouperSettings struct {
+ ConstRequireSingleConst *bool `yaml:"const-require-single-const,omitempty" toml:"const-require-single-const,multiline,omitempty"`
+ ConstRequireGrouping *bool `yaml:"const-require-grouping,omitempty" toml:"const-require-grouping,multiline,omitempty"`
+ ImportRequireSingleImport *bool `yaml:"import-require-single-import,omitempty" toml:"import-require-single-import,multiline,omitempty"`
+ ImportRequireGrouping *bool `yaml:"import-require-grouping,omitempty" toml:"import-require-grouping,multiline,omitempty"`
+ TypeRequireSingleType *bool `yaml:"type-require-single-type,omitempty" toml:"type-require-single-type,multiline,omitempty"`
+ TypeRequireGrouping *bool `yaml:"type-require-grouping,omitempty" toml:"type-require-grouping,multiline,omitempty"`
+ VarRequireSingleVar *bool `yaml:"var-require-single-var,omitempty" toml:"var-require-single-var,multiline,omitempty"`
+ VarRequireGrouping *bool `yaml:"var-require-grouping,omitempty" toml:"var-require-grouping,multiline,omitempty"`
+}
+
+type IfaceSettings struct {
+ Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
+ Settings map[string]map[string]any `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
+}
+
+type ImportAsSettings struct {
+ Alias []ImportAsAlias `yaml:"alias,omitempty" toml:"alias,multiline,omitempty"`
+ NoUnaliased *bool `yaml:"no-unaliased,omitempty" toml:"no-unaliased,multiline,omitempty"`
+ NoExtraAliases *bool `yaml:"no-extra-aliases,omitempty" toml:"no-extra-aliases,multiline,omitempty"`
+}
+
+type ImportAsAlias struct {
+ Pkg *string `yaml:"pkg,omitempty" toml:"pkg,multiline,omitempty"`
+ Alias *string `yaml:"alias,omitempty" toml:"alias,multiline,omitempty"`
+}
+
+type INamedParamSettings struct {
+ SkipSingleParam *bool `yaml:"skip-single-param,omitempty" toml:"skip-single-param,multiline,omitempty"`
+}
+
+type InterfaceBloatSettings struct {
+ Max *int `yaml:"max,omitempty" toml:"max,multiline,omitempty"`
+}
+
+type IreturnSettings struct {
+ Allow []string `yaml:"allow,omitempty" toml:"allow,multiline,omitempty"`
+ Reject []string `yaml:"reject,omitempty" toml:"reject,multiline,omitempty"`
+}
+
+type LllSettings struct {
+ LineLength *int `yaml:"line-length,omitempty" toml:"line-length,multiline,omitempty"`
+ TabWidth *int `yaml:"tab-width,omitempty" toml:"tab-width,multiline,omitempty"`
+}
+
+type LoggerCheckSettings struct {
+ Kitlog *bool `yaml:"kitlog,omitempty" toml:"kitlog,multiline,omitempty"`
+ Klog *bool `yaml:"klog,omitempty" toml:"klog,multiline,omitempty"`
+ Logr *bool `yaml:"logr,omitempty" toml:"logr,multiline,omitempty"`
+ Slog *bool `yaml:"slog,omitempty" toml:"slog,multiline,omitempty"`
+ Zap *bool `yaml:"zap,omitempty" toml:"zap,multiline,omitempty"`
+ RequireStringKey *bool `yaml:"require-string-key,omitempty" toml:"require-string-key,multiline,omitempty"`
+ NoPrintfLike *bool `yaml:"no-printf-like,omitempty" toml:"no-printf-like,multiline,omitempty"`
+ Rules []string `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
+}
+
+type MaintIdxSettings struct {
+ Under *int `yaml:"under,omitempty" toml:"under,multiline,omitempty"`
+}
+
+type MakezeroSettings struct {
+ Always *bool `yaml:"always,omitempty" toml:"always,multiline,omitempty"`
+}
+
+type MisspellSettings struct {
+ Mode *string `yaml:"mode,omitempty" toml:"mode,multiline,omitempty"`
+ Locale *string `yaml:"locale,omitempty" toml:"locale,multiline,omitempty"`
+ ExtraWords []MisspellExtraWords `yaml:"extra-words,omitempty" toml:"extra-words,multiline,omitempty"`
+ IgnoreRules []string `yaml:"ignore-rules,omitempty" toml:"ignore-rules,multiline,omitempty"`
+}
+
+type MisspellExtraWords struct {
+ Typo *string `yaml:"typo,omitempty" toml:"typo,multiline,omitempty"`
+ Correction *string `yaml:"correction,omitempty" toml:"correction,multiline,omitempty"`
+}
+
+type MustTagSettings struct {
+ Functions []MustTagFunction `yaml:"functions,omitempty" toml:"functions,multiline,omitempty"`
+}
+
+type MustTagFunction struct {
+ Name *string `yaml:"name,omitempty" toml:"name,multiline,omitempty"`
+ Tag *string `yaml:"tag,omitempty" toml:"tag,multiline,omitempty"`
+ ArgPos *int `yaml:"arg-pos,omitempty" toml:"arg-pos,multiline,omitempty"`
+}
+
+type NakedretSettings struct {
+ MaxFuncLines *uint `yaml:"max-func-lines,omitempty" toml:"max-func-lines,multiline,omitempty"`
+}
+
+type NestifSettings struct {
+ MinComplexity *int `yaml:"min-complexity,omitempty" toml:"min-complexity,multiline,omitempty"`
+}
+
+type NilNilSettings struct {
+ OnlyTwo *bool `yaml:"only-two,omitempty" toml:"only-two,multiline,omitempty"`
+ DetectOpposite *bool `yaml:"detect-opposite,omitempty" toml:"detect-opposite,multiline,omitempty"`
+ CheckedTypes []string `yaml:"checked-types,omitempty" toml:"checked-types,multiline,omitempty"`
+}
+
+type NlreturnSettings struct {
+ BlockSize *int `yaml:"block-size,omitempty" toml:"block-size,multiline,omitempty"`
+}
+
+type MndSettings struct {
+ Checks []string `yaml:"checks,omitempty" toml:"checks,multiline,omitempty"`
+ IgnoredNumbers []string `yaml:"ignored-numbers,omitempty" toml:"ignored-numbers,multiline,omitempty"`
+ IgnoredFiles []string `yaml:"ignored-files,omitempty" toml:"ignored-files,multiline,omitempty"`
+ IgnoredFunctions []string `yaml:"ignored-functions,omitempty" toml:"ignored-functions,multiline,omitempty"`
+}
+
+type NoLintLintSettings struct {
+ RequireExplanation *bool `yaml:"require-explanation,omitempty" toml:"require-explanation,multiline,omitempty"`
+ RequireSpecific *bool `yaml:"require-specific,omitempty" toml:"require-specific,multiline,omitempty"`
+ AllowNoExplanation []string `yaml:"allow-no-explanation,omitempty" toml:"allow-no-explanation,multiline,omitempty"`
+ AllowUnused *bool `yaml:"allow-unused,omitempty" toml:"allow-unused,multiline,omitempty"`
+}
+
+type NoNamedReturnsSettings struct {
+ ReportErrorInDefer *bool `yaml:"report-error-in-defer,omitempty" toml:"report-error-in-defer,multiline,omitempty"`
+}
+
+type ParallelTestSettings struct {
+ Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
+ IgnoreMissing *bool `yaml:"ignore-missing,omitempty" toml:"ignore-missing,multiline,omitempty"`
+ IgnoreMissingSubtests *bool `yaml:"ignore-missing-subtests,omitempty" toml:"ignore-missing-subtests,multiline,omitempty"`
+}
+
+type PerfSprintSettings struct {
+ IntegerFormat *bool `yaml:"integer-format,omitempty" toml:"integer-format,multiline,omitempty"`
+ IntConversion *bool `yaml:"int-conversion,omitempty" toml:"int-conversion,multiline,omitempty"`
+
+ ErrorFormat *bool `yaml:"error-format,omitempty" toml:"error-format,multiline,omitempty"`
+ ErrError *bool `yaml:"err-error,omitempty" toml:"err-error,multiline,omitempty"`
+ ErrorF *bool `yaml:"errorf,omitempty" toml:"errorf,multiline,omitempty"`
+
+ StringFormat *bool `yaml:"string-format,omitempty" toml:"string-format,multiline,omitempty"`
+ SprintF1 *bool `yaml:"sprintf1,omitempty" toml:"sprintf1,multiline,omitempty"`
+ StrConcat *bool `yaml:"strconcat,omitempty" toml:"strconcat,multiline,omitempty"`
+
+ BoolFormat *bool `yaml:"bool-format,omitempty" toml:"bool-format,multiline,omitempty"`
+ HexFormat *bool `yaml:"hex-format,omitempty" toml:"hex-format,multiline,omitempty"`
+}
+
+type PreallocSettings struct {
+ Simple *bool `yaml:"simple,omitempty" toml:"simple,multiline,omitempty"`
+ RangeLoops *bool `yaml:"range-loops,omitempty" toml:"range-loops,multiline,omitempty"`
+ ForLoops *bool `yaml:"for-loops,omitempty" toml:"for-loops,multiline,omitempty"`
+}
+
+type PredeclaredSettings struct {
+ Ignore []string `yaml:"ignore,omitempty" toml:"ignore,multiline,omitempty"`
+ Qualified *bool `yaml:"qualified-name,omitempty" toml:"qualified-name,multiline,omitempty"`
+}
+
+type PromlinterSettings struct {
+ Strict *bool `yaml:"strict,omitempty" toml:"strict,multiline,omitempty"`
+ DisabledLinters []string `yaml:"disabled-linters,omitempty" toml:"disabled-linters,multiline,omitempty"`
+}
+
+type ProtoGetterSettings struct {
+ SkipGeneratedBy []string `yaml:"skip-generated-by,omitempty" toml:"skip-generated-by,multiline,omitempty"`
+ SkipFiles []string `yaml:"skip-files,omitempty" toml:"skip-files,multiline,omitempty"`
+ SkipAnyGenerated *bool `yaml:"skip-any-generated,omitempty" toml:"skip-any-generated,multiline,omitempty"`
+ ReplaceFirstArgInAppend *bool `yaml:"replace-first-arg-in-append,omitempty" toml:"replace-first-arg-in-append,multiline,omitempty"`
+}
+
+type ReassignSettings struct {
+ Patterns []string `yaml:"patterns,omitempty" toml:"patterns,multiline,omitempty"`
+}
+
+type RecvcheckSettings struct {
+ DisableBuiltin *bool `yaml:"disable-builtin,omitempty" toml:"disable-builtin,multiline,omitempty"`
+ Exclusions []string `yaml:"exclusions,omitempty" toml:"exclusions,multiline,omitempty"`
+}
+
+type ReviveSettings struct {
+ Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"`
+ MaxOpenFiles *int `yaml:"max-open-files,omitempty" toml:"max-open-files,multiline,omitempty"`
+ Confidence *float64 `yaml:"confidence,omitempty" toml:"confidence,multiline,omitempty"`
+ Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
+ EnableAllRules *bool `yaml:"enable-all-rules,omitempty" toml:"enable-all-rules,multiline,omitempty"`
+ Rules []ReviveRule `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
+ ErrorCode *int `yaml:"error-code,omitempty" toml:"error-code,multiline,omitempty"`
+ WarningCode *int `yaml:"warning-code,omitempty" toml:"warning-code,multiline,omitempty"`
+ Directives []ReviveDirective `yaml:"directives,omitempty" toml:"directives,multiline,omitempty"`
+}
+
+type ReviveRule struct {
+ Name *string `yaml:"name,omitempty" toml:"name,multiline,omitempty"`
+ Arguments []any `yaml:"arguments,omitempty" toml:"arguments,multiline,omitempty"`
+ Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
+ Disabled *bool `yaml:"disabled,omitempty" toml:"disabled,multiline,omitempty"`
+ Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"`
+}
+
+type ReviveDirective struct {
+ Name *string `yaml:"name,omitempty" toml:"name,multiline,omitempty"`
+ Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
+}
+
+type RowsErrCheckSettings struct {
+ Packages []string `yaml:"packages,omitempty" toml:"packages,multiline,omitempty"`
+}
+
+type SlogLintSettings struct {
+ NoMixedArgs *bool `yaml:"no-mixed-args,omitempty" toml:"no-mixed-args,multiline,omitempty"`
+ KVOnly *bool `yaml:"kv-only,omitempty" toml:"kv-only,multiline,omitempty"`
+ AttrOnly *bool `yaml:"attr-only,omitempty" toml:"attr-only,multiline,omitempty"`
+ NoGlobal *string `yaml:"no-global,omitempty" toml:"no-global,multiline,omitempty"`
+ Context *string `yaml:"context,omitempty" toml:"context,multiline,omitempty"`
+ StaticMsg *bool `yaml:"static-msg,omitempty" toml:"static-msg,multiline,omitempty"`
+ MsgStyle *string `yaml:"msg-style,omitempty" toml:"msg-style,multiline,omitempty"`
+ NoRawKeys *bool `yaml:"no-raw-keys,omitempty" toml:"no-raw-keys,multiline,omitempty"`
+ KeyNamingCase *string `yaml:"key-naming-case,omitempty" toml:"key-naming-case,multiline,omitempty"`
+ ForbiddenKeys []string `yaml:"forbidden-keys,omitempty" toml:"forbidden-keys,multiline,omitempty"`
+ ArgsOnSepLines *bool `yaml:"args-on-sep-lines,omitempty" toml:"args-on-sep-lines,multiline,omitempty"`
+}
+
+type SpancheckSettings struct {
+ Checks []string `yaml:"checks,omitempty" toml:"checks,multiline,omitempty"`
+ IgnoreCheckSignatures []string `yaml:"ignore-check-signatures,omitempty" toml:"ignore-check-signatures,multiline,omitempty"`
+ ExtraStartSpanSignatures []string `yaml:"extra-start-span-signatures,omitempty" toml:"extra-start-span-signatures,multiline,omitempty"`
+}
+
+type StaticCheckSettings struct {
+ Checks []string `yaml:"checks,omitempty" toml:"checks,multiline,omitempty"`
+ Initialisms []string `yaml:"initialisms,omitempty" toml:"initialisms,multiline,omitempty"`
+ DotImportWhitelist []string `yaml:"dot-import-whitelist,omitempty" toml:"dot-import-whitelist,multiline,omitempty"`
+ HTTPStatusCodeWhitelist []string `yaml:"http-status-code-whitelist,omitempty" toml:"http-status-code-whitelist,multiline,omitempty"`
+}
+
+type TagAlignSettings struct {
+ Align *bool `yaml:"align,omitempty" toml:"align,multiline,omitempty"`
+ Sort *bool `yaml:"sort,omitempty" toml:"sort,multiline,omitempty"`
+ Order []string `yaml:"order,omitempty" toml:"order,multiline,omitempty"`
+ Strict *bool `yaml:"strict,omitempty" toml:"strict,multiline,omitempty"`
+}
+
+type TagliatelleSettings struct {
+ Case TagliatelleCase `yaml:"case,omitempty" toml:"case,multiline,omitempty"`
+}
+
+type TagliatelleCase struct {
+ TagliatelleBase `yaml:",inline"`
+ Overrides []TagliatelleOverrides `yaml:"overrides,omitempty" toml:"overrides,multiline,omitempty"`
+}
+
+type TagliatelleOverrides struct {
+ TagliatelleBase `yaml:",inline"`
+ Package *string `yaml:"pkg,omitempty" toml:"pkg,multiline,omitempty"`
+ Ignore *bool `yaml:"ignore,omitempty" toml:"ignore,multiline,omitempty"`
+}
+
+type TagliatelleBase struct {
+ Rules map[string]string `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
+ ExtendedRules map[string]TagliatelleExtendedRule `yaml:"extended-rules,omitempty" toml:"extended-rules,multiline,omitempty"`
+ UseFieldName *bool `yaml:"use-field-name,omitempty" toml:"use-field-name,multiline,omitempty"`
+ IgnoredFields []string `yaml:"ignored-fields,omitempty" toml:"ignored-fields,multiline,omitempty"`
+}
+
+type TagliatelleExtendedRule struct {
+ Case *string `yaml:"case,omitempty" toml:"case,multiline,omitempty"`
+ ExtraInitialisms *bool `yaml:"extra-initialisms,omitempty" toml:"extra-initialisms,multiline,omitempty"`
+ InitialismOverrides map[string]bool `yaml:"initialism-overrides,omitempty" toml:"initialism-overrides,multiline,omitempty"`
+}
+
+type TestifylintSettings struct {
+ EnableAll *bool `yaml:"enable-all,omitempty" toml:"enable-all,multiline,omitempty"`
+ DisableAll *bool `yaml:"disable-all,omitempty" toml:"disable-all,multiline,omitempty"`
+ EnabledCheckers []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"`
+ DisabledCheckers []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"`
+
+ BoolCompare TestifylintBoolCompare `yaml:"bool-compare,omitempty" toml:"bool-compare,multiline,omitempty"`
+ ExpectedActual TestifylintExpectedActual `yaml:"expected-actual,omitempty" toml:"expected-actual,multiline,omitempty"`
+ Formatter TestifylintFormatter `yaml:"formatter,omitempty" toml:"formatter,multiline,omitempty"`
+ GoRequire TestifylintGoRequire `yaml:"go-require,omitempty" toml:"go-require,multiline,omitempty"`
+ RequireError TestifylintRequireError `yaml:"require-error,omitempty" toml:"require-error,multiline,omitempty"`
+ SuiteExtraAssertCall TestifylintSuiteExtraAssertCall `yaml:"suite-extra-assert-call,omitempty" toml:"suite-extra-assert-call,multiline,omitempty"`
+}
+
+type TestifylintBoolCompare struct {
+ IgnoreCustomTypes *bool `yaml:"ignore-custom-types,omitempty" toml:"ignore-custom-types,multiline,omitempty"`
+}
+
+type TestifylintExpectedActual struct {
+ ExpVarPattern *string `yaml:"pattern,omitempty" toml:"pattern,multiline,omitempty"`
+}
+
+type TestifylintFormatter struct {
+ CheckFormatString *bool `yaml:"check-format-string,omitempty" toml:"check-format-string,multiline,omitempty"`
+ RequireFFuncs *bool `yaml:"require-f-funcs,omitempty" toml:"require-f-funcs,multiline,omitempty"`
+ RequireStringMsg *bool `yaml:"require-string-msg,omitempty" toml:"require-string-msg,multiline,omitempty"`
+}
+
+type TestifylintGoRequire struct {
+ IgnoreHTTPHandlers *bool `yaml:"ignore-http-handlers,omitempty" toml:"ignore-http-handlers,multiline,omitempty"`
+}
+
+type TestifylintRequireError struct {
+ FnPattern *string `yaml:"fn-pattern,omitempty" toml:"fn-pattern,multiline,omitempty"`
+}
+
+type TestifylintSuiteExtraAssertCall struct {
+ Mode *string `yaml:"mode,omitempty" toml:"mode,multiline,omitempty"`
+}
+
+type TestpackageSettings struct {
+ SkipRegexp *string `yaml:"skip-regexp,omitempty" toml:"skip-regexp,multiline,omitempty"`
+ AllowPackages []string `yaml:"allow-packages,omitempty" toml:"allow-packages,multiline,omitempty"`
+}
+
+type ThelperSettings struct {
+ Test ThelperOptions `yaml:"test,omitempty" toml:"test,multiline,omitempty"`
+ Fuzz ThelperOptions `yaml:"fuzz,omitempty" toml:"fuzz,multiline,omitempty"`
+ Benchmark ThelperOptions `yaml:"benchmark,omitempty" toml:"benchmark,multiline,omitempty"`
+ TB ThelperOptions `yaml:"tb,omitempty" toml:"tb,multiline,omitempty"`
+}
+
+type ThelperOptions struct {
+ First *bool `yaml:"first,omitempty" toml:"first,multiline,omitempty"`
+ Name *bool `yaml:"name,omitempty" toml:"name,multiline,omitempty"`
+ Begin *bool `yaml:"begin,omitempty" toml:"begin,multiline,omitempty"`
+}
+
+type UseStdlibVarsSettings struct {
+ HTTPMethod *bool `yaml:"http-method,omitempty" toml:"http-method,multiline,omitempty"`
+ HTTPStatusCode *bool `yaml:"http-status-code,omitempty" toml:"http-status-code,multiline,omitempty"`
+ TimeWeekday *bool `yaml:"time-weekday,omitempty" toml:"time-weekday,multiline,omitempty"`
+ TimeMonth *bool `yaml:"time-month,omitempty" toml:"time-month,multiline,omitempty"`
+ TimeLayout *bool `yaml:"time-layout,omitempty" toml:"time-layout,multiline,omitempty"`
+ CryptoHash *bool `yaml:"crypto-hash,omitempty" toml:"crypto-hash,multiline,omitempty"`
+ DefaultRPCPath *bool `yaml:"default-rpc-path,omitempty" toml:"default-rpc-path,multiline,omitempty"`
+ SQLIsolationLevel *bool `yaml:"sql-isolation-level,omitempty" toml:"sql-isolation-level,multiline,omitempty"`
+ TLSSignatureScheme *bool `yaml:"tls-signature-scheme,omitempty" toml:"tls-signature-scheme,multiline,omitempty"`
+ ConstantKind *bool `yaml:"constant-kind,omitempty" toml:"constant-kind,multiline,omitempty"`
+}
+
+type UseTestingSettings struct {
+ ContextBackground *bool `yaml:"context-background,omitempty" toml:"context-background,multiline,omitempty"`
+ ContextTodo *bool `yaml:"context-todo,omitempty" toml:"context-todo,multiline,omitempty"`
+ OSChdir *bool `yaml:"os-chdir,omitempty" toml:"os-chdir,multiline,omitempty"`
+ OSMkdirTemp *bool `yaml:"os-mkdir-temp,omitempty" toml:"os-mkdir-temp,multiline,omitempty"`
+ OSSetenv *bool `yaml:"os-setenv,omitempty" toml:"os-setenv,multiline,omitempty"`
+ OSTempDir *bool `yaml:"os-temp-dir,omitempty" toml:"os-temp-dir,multiline,omitempty"`
+ OSCreateTemp *bool `yaml:"os-create-temp,omitempty" toml:"os-create-temp,multiline,omitempty"`
+}
+
+type UnconvertSettings struct {
+ FastMath *bool `yaml:"fast-math,omitempty" toml:"fast-math,multiline,omitempty"`
+ Safe *bool `yaml:"safe,omitempty" toml:"safe,multiline,omitempty"`
+}
+
+type UnparamSettings struct {
+ CheckExported *bool `yaml:"check-exported,omitempty" toml:"check-exported,multiline,omitempty"`
+}
+
+type UnusedSettings struct {
+ FieldWritesAreUses *bool `yaml:"field-writes-are-uses,omitempty" toml:"field-writes-are-uses,multiline,omitempty"`
+ PostStatementsAreReads *bool `yaml:"post-statements-are-reads,omitempty" toml:"post-statements-are-reads,multiline,omitempty"`
+ ExportedFieldsAreUsed *bool `yaml:"exported-fields-are-used,omitempty" toml:"exported-fields-are-used,multiline,omitempty"`
+ ParametersAreUsed *bool `yaml:"parameters-are-used,omitempty" toml:"parameters-are-used,multiline,omitempty"`
+ LocalVariablesAreUsed *bool `yaml:"local-variables-are-used,omitempty" toml:"local-variables-are-used,multiline,omitempty"`
+ GeneratedIsUsed *bool `yaml:"generated-is-used,omitempty" toml:"generated-is-used,multiline,omitempty"`
+}
+
+type VarnamelenSettings struct {
+ MaxDistance *int `yaml:"max-distance,omitempty" toml:"max-distance,multiline,omitempty"`
+ MinNameLength *int `yaml:"min-name-length,omitempty" toml:"min-name-length,multiline,omitempty"`
+ CheckReceiver *bool `yaml:"check-receiver,omitempty" toml:"check-receiver,multiline,omitempty"`
+ CheckReturn *bool `yaml:"check-return,omitempty" toml:"check-return,multiline,omitempty"`
+ CheckTypeParam *bool `yaml:"check-type-param,omitempty" toml:"check-type-param,multiline,omitempty"`
+ IgnoreNames []string `yaml:"ignore-names,omitempty" toml:"ignore-names,multiline,omitempty"`
+ IgnoreTypeAssertOk *bool `yaml:"ignore-type-assert-ok,omitempty" toml:"ignore-type-assert-ok,multiline,omitempty"`
+ IgnoreMapIndexOk *bool `yaml:"ignore-map-index-ok,omitempty" toml:"ignore-map-index-ok,multiline,omitempty"`
+ IgnoreChanRecvOk *bool `yaml:"ignore-chan-recv-ok,omitempty" toml:"ignore-chan-recv-ok,multiline,omitempty"`
+ IgnoreDecls []string `yaml:"ignore-decls,omitempty" toml:"ignore-decls,multiline,omitempty"`
+}
+
+type WhitespaceSettings struct {
+ MultiIf *bool `yaml:"multi-if,omitempty" toml:"multi-if,multiline,omitempty"`
+ MultiFunc *bool `yaml:"multi-func,omitempty" toml:"multi-func,multiline,omitempty"`
+}
+
+type WrapcheckSettings struct {
+ ExtraIgnoreSigs []string `yaml:"extra-ignore-sigs,omitempty" toml:"extra-ignore-sigs,multiline,omitempty"`
+ IgnoreSigs []string `yaml:"ignore-sigs,omitempty" toml:"ignore-sigs,multiline,omitempty"`
+ IgnoreSigRegexps []string `yaml:"ignore-sig-regexps,omitempty" toml:"ignore-sig-regexps,multiline,omitempty"`
+ IgnorePackageGlobs []string `yaml:"ignore-package-globs,omitempty" toml:"ignore-package-globs,multiline,omitempty"`
+ IgnoreInterfaceRegexps []string `yaml:"ignore-interface-regexps,omitempty" toml:"ignore-interface-regexps,multiline,omitempty"`
+ ReportInternalErrors *bool `yaml:"report-internal-errors,omitempty" toml:"report-internal-errors,multiline,omitempty"`
+}
+
+type WSLSettings struct {
+ StrictAppend *bool `yaml:"strict-append,omitempty" toml:"strict-append,multiline,omitempty"`
+ AllowAssignAndCallCuddle *bool `yaml:"allow-assign-and-call,omitempty" toml:"allow-assign-and-call,multiline,omitempty"`
+ AllowAssignAndAnythingCuddle *bool `yaml:"allow-assign-and-anything,omitempty" toml:"allow-assign-and-anything,multiline,omitempty"`
+ AllowMultiLineAssignCuddle *bool `yaml:"allow-multiline-assign,omitempty" toml:"allow-multiline-assign,multiline,omitempty"`
+ ForceCaseTrailingWhitespaceLimit *int `yaml:"force-case-trailing-whitespace,omitempty" toml:"force-case-trailing-whitespace,multiline,omitempty"`
+ AllowTrailingComment *bool `yaml:"allow-trailing-comment,omitempty" toml:"allow-trailing-comment,multiline,omitempty"`
+ AllowSeparatedLeadingComment *bool `yaml:"allow-separated-leading-comment,omitempty" toml:"allow-separated-leading-comment,multiline,omitempty"`
+ AllowCuddleDeclaration *bool `yaml:"allow-cuddle-declarations,omitempty" toml:"allow-cuddle-declarations,multiline,omitempty"`
+ AllowCuddleWithCalls []string `yaml:"allow-cuddle-with-calls,omitempty" toml:"allow-cuddle-with-calls,multiline,omitempty"`
+ AllowCuddleWithRHS []string `yaml:"allow-cuddle-with-rhs,omitempty" toml:"allow-cuddle-with-rhs,multiline,omitempty"`
+ AllowCuddleUsedInBlock *bool `yaml:"allow-cuddle-used-in-block,omitempty" toml:"allow-cuddle-used-in-block,multiline,omitempty"`
+ ForceCuddleErrCheckAndAssign *bool `yaml:"force-err-cuddling,omitempty" toml:"force-err-cuddling,multiline,omitempty"`
+ ErrorVariableNames []string `yaml:"error-variable-names,omitempty" toml:"error-variable-names,multiline,omitempty"`
+ ForceExclusiveShortDeclarations *bool `yaml:"force-short-decl-cuddling,omitempty" toml:"force-short-decl-cuddling,multiline,omitempty"`
+}
+
+type CustomLinterSettings struct {
+ Type *string `yaml:"type,omitempty" toml:"type,multiline,omitempty"`
+
+ Path *string `yaml:"path,omitempty" toml:"path,multiline,omitempty"`
+
+ Description *string `yaml:"description,omitempty" toml:"description,multiline,omitempty"`
+
+ OriginalURL *string `yaml:"original-url,omitempty" toml:"original-url,multiline,omitempty"`
+
+ Settings any `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output.go
new file mode 100644
index 00000000..16afb670
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output.go
@@ -0,0 +1,11 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type Output struct {
+ Formats Formats `yaml:"formats,omitempty" toml:"formats,multiline,omitempty"`
+ SortOrder []string `yaml:"sort-order,omitempty" toml:"sort-order,multiline,omitempty"`
+ ShowStats *bool `yaml:"show-stats,omitempty" toml:"show-stats,multiline,omitempty"`
+ PathPrefix *string `yaml:"path-prefix,omitempty" toml:"path-prefix,multiline,omitempty"`
+ PathMode *string `yaml:"path-mode,omitempty" toml:"path-mode,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output_formats.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output_formats.go
new file mode 100644
index 00000000..dbc5665f
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output_formats.go
@@ -0,0 +1,37 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type Formats struct {
+ Text Text `yaml:"text,omitempty" toml:"text,multiline,omitempty"`
+ JSON SimpleFormat `yaml:"json,omitempty" toml:"json,multiline,omitempty"`
+ Tab Tab `yaml:"tab,omitempty" toml:"tab,multiline,omitempty"`
+ HTML SimpleFormat `yaml:"html,omitempty" toml:"html,multiline,omitempty"`
+ Checkstyle SimpleFormat `yaml:"checkstyle,omitempty" toml:"checkstyle,multiline,omitempty"`
+ CodeClimate SimpleFormat `yaml:"code-climate,omitempty" toml:"code-climate,multiline,omitempty"`
+ JUnitXML JUnitXML `yaml:"junit-xml,omitempty" toml:"junit-xml,multiline,omitempty"`
+ TeamCity SimpleFormat `yaml:"teamcity,omitempty" toml:"teamcity,multiline,omitempty"`
+ Sarif SimpleFormat `yaml:"sarif,omitempty" toml:"sarif,multiline,omitempty"`
+}
+
+type SimpleFormat struct {
+ Path *string `yaml:"path,omitempty" toml:"path,multiline,omitempty"`
+}
+
+type Text struct {
+ SimpleFormat `yaml:",inline"`
+ PrintLinterName *bool `yaml:"print-linter-name,omitempty" toml:"print-linter-name,multiline,omitempty"`
+ PrintIssuedLine *bool `yaml:"print-issued-lines,omitempty" toml:"print-issued-lines,multiline,omitempty"`
+ Colors *bool `yaml:"colors,omitempty" toml:"colors,multiline,omitempty"`
+}
+
+type Tab struct {
+ SimpleFormat `yaml:",inline"`
+ PrintLinterName *bool `yaml:"print-linter-name,omitempty" toml:"print-linter-name,multiline,omitempty"`
+ Colors *bool `yaml:"colors,omitempty" toml:"colors,multiline,omitempty"`
+}
+
+type JUnitXML struct {
+ SimpleFormat `yaml:",inline"`
+ Extended *bool `yaml:"extended,omitempty" toml:"extended,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/run.go
new file mode 100644
index 00000000..501d3e9f
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/run.go
@@ -0,0 +1,26 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+import (
+ "time"
+)
+
+type Run struct {
+ Timeout time.Duration `yaml:"timeout,omitempty" toml:"timeout,multiline,omitempty"`
+
+ Concurrency *int `yaml:"concurrency,omitempty" toml:"concurrency,multiline,omitempty"`
+
+ Go *string `yaml:"go,omitempty" toml:"go,multiline,omitempty"`
+
+ RelativePathMode *string `yaml:"relative-path-mode,omitempty" toml:"relative-path-mode,multiline,omitempty"`
+
+ BuildTags []string `yaml:"build-tags,omitempty" toml:"build-tags,multiline,omitempty"`
+ ModulesDownloadMode *string `yaml:"modules-download-mode,omitempty" toml:"modules-download-mode,multiline,omitempty"`
+
+ ExitCodeIfIssuesFound *int `yaml:"issues-exit-code,omitempty" toml:"issues-exit-code,multiline,omitempty"`
+ AnalyzeTests *bool `yaml:"tests,omitempty" toml:"tests,multiline,omitempty"`
+
+ AllowParallelRunners *bool `yaml:"allow-parallel-runners,omitempty" toml:"allow-parallel-runners,multiline,omitempty"`
+ AllowSerialRunners *bool `yaml:"allow-serial-runners,omitempty" toml:"allow-serial-runners,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/severity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/severity.go
new file mode 100644
index 00000000..248ddf1f
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/severity.go
@@ -0,0 +1,13 @@
+// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.
+
+package versiontwo
+
+type Severity struct {
+ Default *string `yaml:"default,omitempty" toml:"default,multiline,omitempty"`
+ Rules []SeverityRule `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"`
+}
+
+type SeverityRule struct {
+ BaseRule `yaml:",inline"`
+ Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/vibra.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/vibra.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/internal/vibra.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/vibra.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/linters.go
similarity index 65%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/linters.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/linters.go
index a93814f0..40036bb8 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/linters.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/linters.go
@@ -1,20 +1,28 @@
package commands
import (
+ "encoding/json"
"fmt"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/spf13/viper"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/lint/lintersdb"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
+type lintersHelp struct {
+ Enabled []linterHelp
+ Disabled []linterHelp
+}
+
type lintersOptions struct {
config.LoaderOptions
+ JSON bool
}
type lintersCommand struct {
@@ -53,13 +61,15 @@ func newLintersCommand(logger logutils.Log) *lintersCommand {
setupConfigFileFlagSet(fs, &c.opts.LoaderOptions)
setupLintersFlagSet(c.viper, fs)
+ fs.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
+
c.cmd = lintersCmd
return c
}
func (c *lintersCommand) preRunE(cmd *cobra.Command, args []string) error {
- loader := config.NewLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args)
+ loader := config.NewLintersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args)
err := loader.Load(config.LoadOptions{Validation: true})
if err != nil {
@@ -84,24 +94,43 @@ func (c *lintersCommand) execute(_ *cobra.Command, _ []string) error {
}
var enabledLinters []*linter.Config
- var disabledLCs []*linter.Config
+ var disabledLinters []*linter.Config
for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
if lc.Internal {
continue
}
+ if goformatters.IsFormatter(lc.Name()) {
+ continue
+ }
+
if enabledLintersMap[lc.Name()] == nil {
- disabledLCs = append(disabledLCs, lc)
+ disabledLinters = append(disabledLinters, lc)
} else {
enabledLinters = append(enabledLinters, lc)
}
}
+ if c.opts.JSON {
+ linters := lintersHelp{}
+
+ for _, lc := range enabledLinters {
+ linters.Enabled = append(linters.Enabled, newLinterHelp(lc))
+ }
+
+ for _, lc := range disabledLinters {
+ linters.Disabled = append(linters.Disabled, newLinterHelp(lc))
+ }
+
+ return json.NewEncoder(c.cmd.OutOrStdout()).Encode(linters)
+ }
+
color.Green("Enabled by your configuration linters:\n")
printLinters(enabledLinters)
+
color.Red("\nDisabled by your configuration linters:\n")
- printLinters(disabledLCs)
+ printLinters(disabledLinters)
return nil
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/migrate.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/migrate.go
new file mode 100644
index 00000000..7c73209e
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/migrate.go
@@ -0,0 +1,243 @@
+package commands
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/charmbracelet/lipgloss"
+ "github.com/fatih/color"
+ "github.com/santhosh-tekuri/jsonschema/v6"
+ "github.com/spf13/cobra"
+ "github.com/spf13/viper"
+
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser"
+ "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/exitcodes"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+)
+
+type migrateOptions struct {
+ config.LoaderOptions
+
+ format string // Flag only.
+ skipValidation bool // Flag only.
+}
+type migrateCommand struct {
+ viper *viper.Viper
+ cmd *cobra.Command
+
+ opts migrateOptions
+
+ cfg *versionone.Config
+
+ buildInfo BuildInfo
+
+ log logutils.Log
+}
+
+func newMigrateCommand(log logutils.Log, info BuildInfo) *migrateCommand {
+ c := &migrateCommand{
+ viper: viper.New(),
+ cfg: versionone.NewConfig(),
+ buildInfo: info,
+ log: log,
+ }
+
+ migrateCmd := &cobra.Command{
+ Use: "migrate",
+ Short: "Migrate configuration file from v1 to v2",
+ SilenceUsage: true,
+ SilenceErrors: true,
+ Args: cobra.NoArgs,
+ RunE: c.execute,
+ PreRunE: c.preRunE,
+ PersistentPreRunE: c.persistentPreRunE,
+ }
+
+ migrateCmd.SetOut(logutils.StdOut) // use custom output to properly color it in Windows terminals
+ migrateCmd.SetErr(logutils.StdErr)
+
+ fs := migrateCmd.Flags()
+ fs.SortFlags = false // sort them as they are defined here
+
+ setupConfigFileFlagSet(fs, &c.opts.LoaderOptions)
+
+ fs.StringVar(&c.opts.format, "format", "",
+ color.GreenString("Output file format.\nBy default, the format of the input configuration file is used.\n"+
+ "It can be 'yml', 'yaml', 'toml', or 'json'."))
+
+ fs.BoolVar(&c.opts.skipValidation, "skip-validation", false,
+ color.GreenString("Skip validation of the configuration file against the JSON Schema for v1."))
+
+ c.cmd = migrateCmd
+
+ return c
+}
+
+func (c *migrateCommand) execute(_ *cobra.Command, _ []string) error {
+ if c.cfg.Version != "" {
+ return fmt.Errorf("configuration version is already set: %s", c.cfg.Version)
+ }
+
+ srcPath := c.viper.ConfigFileUsed()
+ if srcPath == "" {
+ c.log.Warnf("No config file detected")
+ os.Exit(exitcodes.NoConfigFileDetected)
+ }
+
+ err := c.backupConfigurationFile(srcPath)
+ if err != nil {
+ return err
+ }
+
+ c.log.Warnf("The configuration comments are not migrated.")
+ c.log.Warnf("Details about the migration: https://golangci-lint.run/product/migration-guide/")
+
+ c.log.Infof("Migrating v1 configuration file: %s", srcPath)
+
+ ext := filepath.Ext(srcPath)
+
+ if c.opts.format != "" {
+ ext = "." + c.opts.format
+ }
+
+ if !strings.EqualFold(filepath.Ext(srcPath), ext) {
+ defer func() {
+ _ = os.RemoveAll(srcPath)
+ }()
+ }
+
+ if c.cfg.Run.Timeout != 0 {
+ c.log.Warnf("The configuration `run.timeout` is ignored. By default, in v2, the timeout is disabled.")
+ }
+
+ newCfg := migrate.ToConfig(c.cfg)
+
+ dstPath := strings.TrimSuffix(srcPath, filepath.Ext(srcPath)) + ext
+
+ err = saveNewConfiguration(newCfg, dstPath)
+ if err != nil {
+ return fmt.Errorf("saving configuration file: %w", err)
+ }
+
+ c.log.Infof("Migration done: %s", dstPath)
+
+ callForAction(c.cmd)
+
+ return nil
+}
+
+func (c *migrateCommand) preRunE(cmd *cobra.Command, _ []string) error {
+ switch strings.ToLower(c.opts.format) {
+ case "", "yml", "yaml", "toml", "json":
+ // Valid format.
+ default:
+ return fmt.Errorf("unsupported format: %s", c.opts.format)
+ }
+
+ if c.opts.skipValidation {
+ return nil
+ }
+
+ usedConfigFile := c.viper.ConfigFileUsed()
+ if usedConfigFile == "" {
+ c.log.Warnf("No config file detected")
+ os.Exit(exitcodes.NoConfigFileDetected)
+ }
+
+ c.log.Infof("Validating v1 configuration file: %s", usedConfigFile)
+
+ err := validateConfiguration("https://golangci-lint.run/jsonschema/golangci.v1.jsonschema.json", usedConfigFile)
+ if err != nil {
+ var v *jsonschema.ValidationError
+ if !errors.As(err, &v) {
+ return fmt.Errorf("[%s] validate: %w", usedConfigFile, err)
+ }
+
+ printValidationDetail(cmd, v.DetailedOutput())
+
+ return errors.New("the configuration contains invalid elements")
+ }
+
+ return nil
+}
+
+func (c *migrateCommand) persistentPreRunE(_ *cobra.Command, args []string) error {
+ c.log.Infof("%s", c.buildInfo.String())
+
+ loader := config.NewBaseLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, c.opts.LoaderOptions, fakeloader.NewConfig(), args)
+
+ // Loads the configuration just to get the effective path of the configuration.
+ err := loader.Load()
+ if err != nil {
+ return fmt.Errorf("can't load config: %w", err)
+ }
+
+ srcPath := c.viper.ConfigFileUsed()
+ if srcPath == "" {
+ c.log.Warnf("No config file detected")
+ os.Exit(exitcodes.NoConfigFileDetected)
+ }
+
+ return fakeloader.Load(srcPath, c.cfg)
+}
+
+func (c *migrateCommand) backupConfigurationFile(srcPath string) error {
+ filename := strings.TrimSuffix(filepath.Base(srcPath), filepath.Ext(srcPath)) + ".bck" + filepath.Ext(srcPath)
+ dstPath := filepath.Join(filepath.Dir(srcPath), filename)
+
+ c.log.Infof("Saving the v1 configuration to: %s", dstPath)
+
+ stat, err := os.Stat(srcPath)
+ if err != nil {
+ return err
+ }
+
+ data, err := os.ReadFile(srcPath)
+ if err != nil {
+ return err
+ }
+
+ err = os.WriteFile(dstPath, data, stat.Mode())
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func saveNewConfiguration(cfg any, dstPath string) error {
+ dstFile, err := os.Create(dstPath)
+ if err != nil {
+ return err
+ }
+
+ defer func() { _ = dstFile.Close() }()
+
+ return parser.Encode(cfg, dstFile)
+}
+
+func callForAction(cmd *cobra.Command) {
+ pStyle := lipgloss.NewStyle().
+ Padding(1).
+ BorderStyle(lipgloss.RoundedBorder()).
+ BorderForeground(lipgloss.Color("161")).
+ Align(lipgloss.Center)
+
+ hStyle := lipgloss.NewStyle().Bold(true)
+
+ s := fmt.Sprintln(hStyle.Render("We need you!"))
+ s += `
+Donations help fund the ongoing development and maintenance of this tool.
+If golangci-lint has been useful to you, please consider contributing.
+
+Donate now: https://donate.golangci.org`
+
+ cmd.Println(pStyle.Render(s))
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/root.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/root.go
similarity index 96%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/root.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/root.go
index cbb838aa..e3dcc527 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/root.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/root.go
@@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
func Execute(info BuildInfo) error {
@@ -59,7 +59,10 @@ func newRootCommand(info BuildInfo) *rootCommand {
// Each command uses a dedicated configuration structure to avoid side effects of bindings.
rootCmd.AddCommand(
newLintersCommand(log).cmd,
+ newFormattersCommand(log).cmd,
newRunCommand(log, info).cmd,
+ newFmtCommand(log, info).cmd,
+ newMigrateCommand(log, info).cmd,
newCacheCommand().cmd,
newConfigCommand(log, info).cmd,
newVersionCommand(info).cmd,
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/run.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go
index 57f3cdd9..53902eaf 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/run.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go
@@ -21,29 +21,31 @@ import (
"github.com/fatih/color"
"github.com/gofrs/flock"
+ "github.com/ldez/grignotin/goenv"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"go.uber.org/automaxprocs/maxprocs"
+ "golang.org/x/mod/sumdb/dirhash"
"gopkg.in/yaml.v3"
- "github.com/golangci/golangci-lint/internal/cache"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/exitcodes"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/goanalysis/load"
- "github.com/golangci/golangci-lint/pkg/goutil"
- "github.com/golangci/golangci-lint/pkg/lint"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/lint/lintersdb"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/printers"
- "github.com/golangci/golangci-lint/pkg/report"
- "github.com/golangci/golangci-lint/pkg/result"
- "github.com/golangci/golangci-lint/pkg/timeutils"
+ "github.com/golangci/golangci-lint/v2/internal/cache"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/exitcodes"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load"
+ "github.com/golangci/golangci-lint/v2/pkg/goutil"
+ "github.com/golangci/golangci-lint/v2/pkg/lint"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/printers"
+ "github.com/golangci/golangci-lint/v2/pkg/report"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/timeutils"
)
-const defaultTimeout = time.Minute
+const defaultTimeout = 0 * time.Minute
const (
// envFailOnWarnings value: "1"
@@ -53,8 +55,6 @@ const (
)
const (
- // envHelpRun value: "1".
- envHelpRun = "HELP_RUN"
envMemProfileRate = "GL_MEM_PROFILE_RATE"
)
@@ -153,7 +153,7 @@ func (c *runCommand) persistentPreRunE(cmd *cobra.Command, args []string) error
c.log.Infof("%s", c.buildInfo.String())
- loader := config.NewLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args)
+ loader := config.NewLintersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args)
err := loader.Load(config.LoadOptions{CheckDeprecation: true, Validation: true})
if err != nil {
@@ -161,6 +161,7 @@ func (c *runCommand) persistentPreRunE(cmd *cobra.Command, args []string) error
}
if c.cfg.Run.Concurrency == 0 {
+ // `runtime.GOMAXPROCS` defaults to the value of `runtime.NumCPU`.
backup := runtime.GOMAXPROCS(0)
// Automatically set GOMAXPROCS to match Linux container CPU quota.
@@ -186,10 +187,6 @@ func (c *runCommand) persistentPostRunE(_ *cobra.Command, _ []string) error {
}
func (c *runCommand) preRunE(_ *cobra.Command, args []string) error {
- if c.cfg.GetConfigDir() != "" && c.cfg.Version != "" {
- return errors.New("you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2")
- }
-
dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), c.cfg,
lintersdb.NewLinterBuilder(), lintersdb.NewPluginModuleBuilder(c.log), lintersdb.NewPluginGoBuilder(c.log))
if err != nil {
@@ -198,13 +195,11 @@ func (c *runCommand) preRunE(_ *cobra.Command, args []string) error {
c.dbManager = dbManager
- printer, err := printers.NewPrinter(c.log, &c.cfg.Output, c.reportData, c.cfg.GetBasePath())
+ c.printer, err = printers.NewPrinter(c.log, &c.cfg.Output.Formats, c.reportData, c.cfg.GetBasePath())
if err != nil {
return err
}
- c.printer = printer
-
c.goenv = goutil.NewEnv(c.log.Child(logutils.DebugKeyGoEnv))
c.fileCache = fsutils.NewFileCache()
@@ -223,7 +218,7 @@ func (c *runCommand) preRunE(_ *cobra.Command, args []string) error {
c.contextBuilder = lint.NewContextBuilder(c.cfg, pkgLoader, pkgCache, guard)
- if err = initHashSalt(c.buildInfo.Version, c.cfg); err != nil {
+ if err = initHashSalt(c.log.Child(logutils.DebugKeyGoModSalt), c.buildInfo.Version, c.cfg); err != nil {
return fmt.Errorf("failed to init hash salt: %w", err)
}
@@ -238,7 +233,7 @@ func (c *runCommand) postRun(_ *cobra.Command, _ []string) {
c.releaseFileLock()
}
-func (c *runCommand) execute(_ *cobra.Command, args []string) {
+func (c *runCommand) execute(_ *cobra.Command, _ []string) {
needTrackResources := logutils.IsVerbose() || c.opts.PrintResourcesUsage
trackResourcesEndCh := make(chan struct{})
@@ -251,18 +246,17 @@ func (c *runCommand) execute(_ *cobra.Command, args []string) {
}
}()
- ctx := context.Background()
+ ctx, cancel := context.WithCancel(context.Background())
if c.cfg.Run.Timeout > 0 {
- var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, c.cfg.Run.Timeout)
- defer cancel()
}
+ defer cancel()
if needTrackResources {
go watchResources(ctx, trackResourcesEndCh, c.log, c.debugf)
}
- if err := c.runAndPrint(ctx, args); err != nil {
+ if err := c.runAndPrint(ctx); err != nil {
c.log.Errorf("Running error: %s", err)
if c.exitCode == exitcodes.Success {
var exitErr *exitcodes.ExitError
@@ -335,7 +329,7 @@ func (c *runCommand) stopTracing() error {
return nil
}
-func (c *runCommand) runAndPrint(ctx context.Context, args []string) error {
+func (c *runCommand) runAndPrint(ctx context.Context) error {
if err := c.goenv.Discover(ctx); err != nil {
c.log.Warnf("Failed to discover go env: %s", err)
}
@@ -356,7 +350,7 @@ func (c *runCommand) runAndPrint(ctx context.Context, args []string) error {
c.printDeprecatedLinterMessages(enabledLintersMap)
- issues, err := c.runAnalysis(ctx, args)
+ issues, err := c.runAnalysis(ctx)
if err != nil {
return err // XXX: don't lose type
}
@@ -364,7 +358,7 @@ func (c *runCommand) runAndPrint(ctx context.Context, args []string) error {
// Fills linters information for the JSON printer.
for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() {
isEnabled := enabledLintersMap[lc.Name()] != nil
- c.reportData.AddLinter(lc.Name(), isEnabled, lc.EnabledByDefault)
+ c.reportData.AddLinter(lc.Name(), isEnabled)
}
err = c.printer.Print(issues)
@@ -382,7 +376,7 @@ func (c *runCommand) runAndPrint(ctx context.Context, args []string) error {
}
// runAnalysis executes the linters that have been enabled in the configuration.
-func (c *runCommand) runAnalysis(ctx context.Context, args []string) ([]result.Issue, error) {
+func (c *runCommand) runAnalysis(ctx context.Context) ([]result.Issue, error) {
lintersToRun, err := c.dbManager.GetOptimizedLinters()
if err != nil {
return nil, err
@@ -393,7 +387,7 @@ func (c *runCommand) runAnalysis(ctx context.Context, args []string) ([]result.I
return nil, fmt.Errorf("context loading failed: %w", err)
}
- runner, err := lint.NewRunner(c.log.Child(logutils.DebugKeyRunner), c.cfg, args,
+ runner, err := lint.NewRunner(c.log.Child(logutils.DebugKeyRunner), c.cfg,
c.goenv, c.lineCache, c.fileCache, c.dbManager, lintCtx)
if err != nil {
return nil, err
@@ -596,16 +590,6 @@ func setupRunPersistentFlags(fs *pflag.FlagSet, opts *runOptions) {
fs.StringVar(&opts.TracePath, "trace-path", "", color.GreenString("Path to trace output file"))
}
-func getDefaultConcurrency() int {
- if os.Getenv(envHelpRun) == "1" {
- // Make stable concurrency for generating help documentation.
- const prettyConcurrency = 8
- return prettyConcurrency
- }
-
- return runtime.NumCPU()
-}
-
func printMemStats(ms *runtime.MemStats, logger logutils.Log) {
logger.Infof("Mem stats: alloc=%s total_alloc=%s sys=%s "+
"heap_alloc=%s heap_sys=%s heap_idle=%s heap_released=%s heap_in_use=%s "+
@@ -636,7 +620,7 @@ func formatMemory(memBytes uint64) string {
// Related to cache.
-func initHashSalt(version string, cfg *config.Config) error {
+func initHashSalt(logger logutils.Log, version string, cfg *config.Config) error {
binSalt, err := computeBinarySalt(version)
if err != nil {
return fmt.Errorf("failed to calculate binary salt: %w", err)
@@ -647,9 +631,18 @@ func initHashSalt(version string, cfg *config.Config) error {
return fmt.Errorf("failed to calculate config salt: %w", err)
}
+ goModSalt, err := computeGoModSalt()
+ if err != nil {
+ // NOTE: missing go.mod must be ignored.
+ logger.Warnf("Failed to calculate go.mod salt: %v", err)
+ }
+
b := bytes.NewBuffer(binSalt)
b.Write(configSalt)
+ b.WriteString(goModSalt)
+
cache.SetSalt(b)
+
return nil
}
@@ -666,15 +659,19 @@ func computeBinarySalt(version string) ([]byte, error) {
if err != nil {
return nil, err
}
+
f, err := os.Open(p)
if err != nil {
return nil, err
}
+
defer f.Close()
+
h := sha256.New()
if _, err := io.Copy(h, f); err != nil {
return nil, err
}
+
return h.Sum(nil), nil
}
@@ -683,12 +680,12 @@ func computeBinarySalt(version string) ([]byte, error) {
// At least, it has a huge impact on tests speed.
// Fields: `LintersSettings` and `Run.BuildTags`.
func computeConfigSalt(cfg *config.Config) ([]byte, error) {
- lintersSettingsBytes, err := yaml.Marshal(cfg.LintersSettings)
+ lintersSettingsBytes, err := yaml.Marshal(cfg.Linters.Settings)
if err != nil {
return nil, fmt.Errorf("failed to JSON marshal config linter settings: %w", err)
}
- configData := bytes.NewBufferString("linters-settings=")
+ configData := bytes.NewBufferString("linters.settings=")
configData.Write(lintersSettingsBytes)
configData.WriteString("\nbuild-tags=%s" + strings.Join(cfg.Run.BuildTags, ","))
@@ -696,5 +693,29 @@ func computeConfigSalt(cfg *config.Config) ([]byte, error) {
if _, err := h.Write(configData.Bytes()); err != nil {
return nil, err
}
+
return h.Sum(nil), nil
}
+
+func computeGoModSalt() (string, error) {
+ values, err := goenv.Get(context.Background(), goenv.GOMOD)
+ if err != nil {
+ return "", fmt.Errorf("failed to get goenv: %w", err)
+ }
+
+ goModPath := filepath.Clean(values[goenv.GOMOD])
+
+ data, err := os.ReadFile(goModPath)
+ if err != nil {
+ return "", fmt.Errorf("failed to read go.mod: %w", err)
+ }
+
+ sum, err := dirhash.Hash1([]string{goModPath}, func(string) (io.ReadCloser, error) {
+ return io.NopCloser(bytes.NewReader(data)), nil
+ })
+ if err != nil {
+ return "", fmt.Errorf("failed to compute go.sum: %w", err)
+ }
+
+ return sum, nil
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/version.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/version.go
similarity index 65%
rename from vendor/github.com/golangci/golangci-lint/pkg/commands/version.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/commands/version.go
index ac665f4c..2bcb12f4 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/commands/version.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/version.go
@@ -6,17 +6,17 @@ import (
"io"
"os"
"runtime/debug"
- "strings"
"github.com/fatih/color"
"github.com/spf13/cobra"
)
type BuildInfo struct {
- GoVersion string `json:"goVersion"`
- Version string `json:"version"`
- Commit string `json:"commit"`
- Date string `json:"date"`
+ GoVersion string `json:"goVersion"`
+ Version string `json:"version"`
+ Commit string `json:"commit"`
+ Date string `json:"date"`
+ BuildInfo *debug.BuildInfo `json:"buildInfo,omitempty"`
}
func (b BuildInfo) String() string {
@@ -24,14 +24,10 @@ func (b BuildInfo) String() string {
b.Version, b.GoVersion, b.Commit, b.Date)
}
-type versionInfo struct {
- Info BuildInfo
- BuildInfo *debug.BuildInfo
-}
-
type versionOptions struct {
- Format string
- Debug bool
+ Debug bool
+ JSON bool
+ Short bool
}
type versionCommand struct {
@@ -55,8 +51,9 @@ func newVersionCommand(info BuildInfo) *versionCommand {
fs := versionCmd.Flags()
fs.SortFlags = false // sort them as they are defined here
- fs.StringVar(&c.opts.Format, "format", "", color.GreenString("The version's format can be: 'short', 'json'"))
fs.BoolVar(&c.opts.Debug, "debug", false, color.GreenString("Add build information"))
+ fs.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON"))
+ fs.BoolVar(&c.opts.Short, "short", false, color.GreenString("Display only the version number"))
c.cmd = versionCmd
@@ -64,34 +61,26 @@ func newVersionCommand(info BuildInfo) *versionCommand {
}
func (c *versionCommand) execute(_ *cobra.Command, _ []string) error {
+ var info *debug.BuildInfo
if c.opts.Debug {
- info, ok := debug.ReadBuildInfo()
- if !ok {
- return nil
- }
-
- switch strings.ToLower(c.opts.Format) {
- case "json":
- return json.NewEncoder(os.Stdout).Encode(versionInfo{
- Info: c.info,
- BuildInfo: info,
- })
-
- default:
- fmt.Println(info.String())
- return printVersion(os.Stdout, c.info)
- }
+ info, _ = debug.ReadBuildInfo()
}
- switch strings.ToLower(c.opts.Format) {
- case "short":
- fmt.Println(c.info.Version)
- return nil
+ switch {
+ case c.opts.JSON:
+ c.info.BuildInfo = info
- case "json":
return json.NewEncoder(os.Stdout).Encode(c.info)
+ case c.opts.Short:
+ fmt.Println(c.info.Version)
+
+ return nil
default:
+ if info != nil {
+ fmt.Println(info.String())
+ }
+
return printVersion(os.Stdout, c.info)
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_loader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_loader.go
new file mode 100644
index 00000000..9ad332ac
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_loader.go
@@ -0,0 +1,232 @@
+package config
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "slices"
+
+ "github.com/go-viper/mapstructure/v2"
+ "github.com/mitchellh/go-homedir"
+ "github.com/spf13/viper"
+
+ "github.com/golangci/golangci-lint/v2/pkg/exitcodes"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+)
+
+type BaseConfig interface {
+ IsInternalTest() bool
+ SetConfigDir(dir string)
+}
+
+type BaseLoader struct {
+ opts LoaderOptions
+
+ viper *viper.Viper
+
+ log logutils.Log
+
+ cfg BaseConfig
+ args []string
+}
+
+func NewBaseLoader(log logutils.Log, v *viper.Viper, opts LoaderOptions, cfg BaseConfig, args []string) *BaseLoader {
+ return &BaseLoader{
+ opts: opts,
+ viper: v,
+ log: log,
+ cfg: cfg,
+ args: args,
+ }
+}
+
+func (l *BaseLoader) Load() error {
+ err := l.setConfigFile()
+ if err != nil {
+ return err
+ }
+
+ err = l.parseConfig()
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (l *BaseLoader) setConfigFile() error {
+ configFile, err := l.evaluateOptions()
+ if err != nil {
+ if errors.Is(err, errConfigDisabled) {
+ return nil
+ }
+
+ return fmt.Errorf("can't parse --config option: %w", err)
+ }
+
+ if configFile != "" {
+ l.viper.SetConfigFile(configFile)
+
+ // Assume YAML if the file has no extension.
+ if filepath.Ext(configFile) == "" {
+ l.viper.SetConfigType("yaml")
+ }
+ } else {
+ l.setupConfigFileSearch()
+ }
+
+ return nil
+}
+
+func (l *BaseLoader) evaluateOptions() (string, error) {
+ if l.opts.NoConfig && l.opts.Config != "" {
+ return "", errors.New("can't combine option --config and --no-config")
+ }
+
+ if l.opts.NoConfig {
+ return "", errConfigDisabled
+ }
+
+ configFile, err := homedir.Expand(l.opts.Config)
+ if err != nil {
+ return "", errors.New("failed to expand configuration path")
+ }
+
+ return configFile, nil
+}
+
+func (l *BaseLoader) setupConfigFileSearch() {
+ l.viper.SetConfigName(".golangci")
+
+ configSearchPaths := l.getConfigSearchPaths()
+
+ l.log.Infof("Config search paths: %s", configSearchPaths)
+
+ for _, p := range configSearchPaths {
+ l.viper.AddConfigPath(p)
+ }
+}
+
+func (l *BaseLoader) getConfigSearchPaths() []string {
+ firstArg := "./..."
+ if len(l.args) > 0 {
+ firstArg = l.args[0]
+ }
+
+ absPath, err := filepath.Abs(firstArg)
+ if err != nil {
+ l.log.Warnf("Can't make abs path for %q: %s", firstArg, err)
+ absPath = filepath.Clean(firstArg)
+ }
+
+ // start from it
+ var currentDir string
+ if fsutils.IsDir(absPath) {
+ currentDir = absPath
+ } else {
+ currentDir = filepath.Dir(absPath)
+ }
+
+ // find all dirs from it up to the root
+ searchPaths := []string{"./"}
+
+ for {
+ searchPaths = append(searchPaths, currentDir)
+
+ parent := filepath.Dir(currentDir)
+ if currentDir == parent || parent == "" {
+ break
+ }
+
+ currentDir = parent
+ }
+
+ // find home directory for global config
+ if home, err := homedir.Dir(); err != nil {
+ l.log.Warnf("Can't get user's home directory: %v", err)
+ } else if !slices.Contains(searchPaths, home) {
+ searchPaths = append(searchPaths, home)
+ }
+
+ return searchPaths
+}
+
+func (l *BaseLoader) parseConfig() error {
+ if err := l.viper.ReadInConfig(); err != nil {
+ var configFileNotFoundError viper.ConfigFileNotFoundError
+ if errors.As(err, &configFileNotFoundError) {
+ // Load configuration from flags only.
+ err = l.viper.Unmarshal(l.cfg, customDecoderHook())
+ if err != nil {
+ return fmt.Errorf("can't unmarshal config by viper (flags): %w", err)
+ }
+
+ return nil
+ }
+
+ return fmt.Errorf("can't read viper config: %w", err)
+ }
+
+ err := l.setConfigDir()
+ if err != nil {
+ return err
+ }
+
+ // Load configuration from all sources (flags, file).
+ if err := l.viper.Unmarshal(l.cfg, customDecoderHook()); err != nil {
+ return fmt.Errorf("can't unmarshal config by viper (flags, file): %w", err)
+ }
+
+ if l.cfg.IsInternalTest() { // just for testing purposes: to detect config file usage
+ _, _ = fmt.Fprintln(logutils.StdOut, "test")
+ os.Exit(exitcodes.Success)
+ }
+
+ return nil
+}
+
+func (l *BaseLoader) setConfigDir() error {
+ usedConfigFile := l.viper.ConfigFileUsed()
+ if usedConfigFile == "" {
+ return nil
+ }
+
+ if usedConfigFile == os.Stdin.Name() {
+ usedConfigFile = ""
+ l.log.Infof("Reading config file stdin")
+ } else {
+ var err error
+ usedConfigFile, err = fsutils.ShortestRelPath(usedConfigFile, "")
+ if err != nil {
+ l.log.Warnf("Can't pretty print config file path: %v", err)
+ }
+
+ l.log.Infof("Used config file %s", usedConfigFile)
+ }
+
+ usedConfigDir, err := filepath.Abs(filepath.Dir(usedConfigFile))
+ if err != nil {
+ return errors.New("can't get config directory")
+ }
+
+ l.cfg.SetConfigDir(usedConfigDir)
+
+ return nil
+}
+
+func customDecoderHook() viper.DecoderConfigOption {
+ return viper.DecodeHook(DecodeHookFunc())
+}
+
+func DecodeHookFunc() mapstructure.DecodeHookFunc {
+ return mapstructure.ComposeDecodeHookFunc(
+ // Default hooks (https://github.com/spf13/viper/blob/518241257478c557633ab36e474dfcaeb9a3c623/viper.go#L135-L138).
+ mapstructure.StringToTimeDurationHookFunc(),
+ mapstructure.StringToSliceHookFunc(","),
+
+ // Needed for forbidigo, and output.formats.
+ mapstructure.TextUnmarshallerHookFunc(),
+ )
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/base_rule.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_rule.go
similarity index 87%
rename from vendor/github.com/golangci/golangci-lint/pkg/config/base_rule.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_rule.go
index 780c60cd..3a828650 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/config/base_rule.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_rule.go
@@ -7,11 +7,11 @@ import (
)
type BaseRule struct {
- Linters []string
- Path string
- PathExcept string `mapstructure:"path-except"`
- Text string
- Source string
+ Linters []string `mapstructure:"linters"`
+ Path string `mapstructure:"path"`
+ PathExcept string `mapstructure:"path-except"`
+ Text string `mapstructure:"text"`
+ Source string `mapstructure:"source"`
// For compatibility with exclude-use-default/include.
InternalReference string `mapstructure:"-"`
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/config.go
similarity index 76%
rename from vendor/github.com/golangci/golangci-lint/pkg/config/config.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/config/config.go
index ee7a62b7..6d758662 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/config/config.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/config.go
@@ -13,23 +13,31 @@ import (
"github.com/ldez/grignotin/goenv"
"github.com/ldez/grignotin/gomod"
"golang.org/x/mod/modfile"
+
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
+// defaultGoVersion the value should be "oldstable" - 1.
+// If the current stable version is 1.24 then 1.23 - 1 = 1.22.
+const defaultGoVersion = "1.22"
+
// Config encapsulates the config data specified in the golangci-lint YAML config file.
type Config struct {
cfgDir string // Path to the directory containing golangci-lint config file.
basePath string // Path the root directory related to [Run.RelativePathMode].
- Version string `mapstructure:"version"` // From v2, to be able to detect v2 config file.
+ Version string `mapstructure:"version"`
Run Run `mapstructure:"run"`
Output Output `mapstructure:"output"`
- LintersSettings LintersSettings `mapstructure:"linters-settings"`
- Linters Linters `mapstructure:"linters"`
- Issues Issues `mapstructure:"issues"`
- Severity Severity `mapstructure:"severity"`
+ Linters Linters `mapstructure:"linters"`
+
+ Issues Issues `mapstructure:"issues"`
+ Severity Severity `mapstructure:"severity"`
+
+ Formatters Formatters `mapstructure:"formatters"`
InternalCmdTest bool // Option is used only for testing golangci-lint command, don't use it
InternalTest bool // Option is used only for testing golangci-lint code, don't use it
@@ -40,17 +48,25 @@ func (c *Config) GetConfigDir() string {
return c.cfgDir
}
+// SetConfigDir sets the path to directory that contains golangci-lint config file.
+func (c *Config) SetConfigDir(dir string) {
+ c.cfgDir = dir
+}
+
func (c *Config) GetBasePath() string {
return c.basePath
}
+func (c *Config) IsInternalTest() bool {
+ return c.InternalTest
+}
+
func (c *Config) Validate() error {
validators := []func() error{
c.Run.Validate,
c.Output.Validate,
- c.LintersSettings.Validate,
c.Linters.Validate,
- c.Issues.Validate,
+ c.Formatters.Validate,
c.Severity.Validate,
}
@@ -65,15 +81,15 @@ func (c *Config) Validate() error {
func NewDefault() *Config {
return &Config{
- LintersSettings: defaultLintersSettings,
+ Linters: Linters{
+ Settings: defaultLintersSettings,
+ },
+ Formatters: Formatters{
+ Settings: defaultFormatterSettings,
+ },
}
}
-type Version struct {
- Format string `mapstructure:"format"`
- Debug bool `mapstructure:"debug"`
-}
-
func IsGoGreaterThanOrEqual(current, limit string) bool {
v1, err := hcversion.NewVersion(strings.TrimPrefix(current, "go"))
if err != nil {
@@ -88,8 +104,8 @@ func IsGoGreaterThanOrEqual(current, limit string) bool {
return v1.GreaterThanOrEqual(l)
}
-func detectGoVersion(ctx context.Context) string {
- return cmp.Or(detectGoVersionFromGoMod(ctx), "1.17")
+func detectGoVersion(ctx context.Context, log logutils.Log) string {
+ return cmp.Or(detectGoVersionFromGoMod(ctx, log), defaultGoVersion)
}
// detectGoVersionFromGoMod tries to get Go version from go.mod.
@@ -97,7 +113,7 @@ func detectGoVersion(ctx context.Context) string {
// else it returns `go` version if present,
// else it returns `GOVERSION` version if present,
// else it returns empty.
-func detectGoVersionFromGoMod(ctx context.Context) string {
+func detectGoVersionFromGoMod(ctx context.Context, log logutils.Log) string {
values, err := goenv.Get(ctx, goenv.GOMOD, goenv.GOVERSION)
if err != nil {
values = map[string]string{
@@ -114,6 +130,10 @@ func detectGoVersionFromGoMod(ctx context.Context) string {
return parseGoVersion(values[goenv.GOVERSION])
}
+ if file.Module != nil {
+ log.Infof("Module name %q", file.Module.Mod.Path)
+ }
+
// The toolchain exists only if 'toolchain' version > 'go' version.
// If 'toolchain' version <= 'go' version, `go mod tidy` will remove 'toolchain' version from go.mod.
if file.Toolchain != nil && file.Toolchain.Name != "" {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters.go
new file mode 100644
index 00000000..e1723ac1
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters.go
@@ -0,0 +1,28 @@
+package config
+
+import (
+ "fmt"
+ "slices"
+)
+
+type Formatters struct {
+ Enable []string `mapstructure:"enable"`
+ Settings FormatterSettings `mapstructure:"settings"`
+ Exclusions FormatterExclusions `mapstructure:"exclusions"`
+}
+
+func (f *Formatters) Validate() error {
+ for _, n := range f.Enable {
+ if !slices.Contains(getAllFormatterNames(), n) {
+ return fmt.Errorf("%s is not a formatter", n)
+ }
+ }
+
+ return nil
+}
+
+type FormatterExclusions struct {
+ Generated string `mapstructure:"generated"`
+ Paths []string `mapstructure:"paths"`
+ WarnUnused bool `mapstructure:"warn-unused"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters_settings.go
new file mode 100644
index 00000000..d99354ba
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters_settings.go
@@ -0,0 +1,61 @@
+package config
+
+var defaultFormatterSettings = FormatterSettings{
+ GoFmt: GoFmtSettings{
+ Simplify: true,
+ },
+ Gci: GciSettings{
+ Sections: []string{"standard", "default"},
+ },
+ GoLines: GoLinesSettings{
+ MaxLen: 100,
+ TabLen: 4,
+ ReformatTags: true,
+ ChainSplitDots: true,
+ },
+}
+
+type FormatterSettings struct {
+ Gci GciSettings `mapstructure:"gci"`
+ GoFmt GoFmtSettings `mapstructure:"gofmt"`
+ GoFumpt GoFumptSettings `mapstructure:"gofumpt"`
+ GoImports GoImportsSettings `mapstructure:"goimports"`
+ GoLines GoLinesSettings `mapstructure:"golines"`
+}
+
+type GciSettings struct {
+ Sections []string `mapstructure:"sections"`
+ NoInlineComments bool `mapstructure:"no-inline-comments"`
+ NoPrefixComments bool `mapstructure:"no-prefix-comments"`
+ CustomOrder bool `mapstructure:"custom-order"`
+ NoLexOrder bool `mapstructure:"no-lex-order"`
+}
+
+type GoFmtSettings struct {
+ Simplify bool `mapstructure:"simplify"`
+ RewriteRules []GoFmtRewriteRule `mapstructure:"rewrite-rules"`
+}
+
+type GoFmtRewriteRule struct {
+ Pattern string `mapstructure:"pattern"`
+ Replacement string `mapstructure:"replacement"`
+}
+
+type GoFumptSettings struct {
+ ModulePath string `mapstructure:"module-path"`
+ ExtraRules bool `mapstructure:"extra-rules"`
+
+ LangVersion string `mapstructure:"-"`
+}
+
+type GoImportsSettings struct {
+ LocalPrefixes []string `mapstructure:"local-prefixes"`
+}
+
+type GoLinesSettings struct {
+ MaxLen int `mapstructure:"max-len"`
+ TabLen int `mapstructure:"tab-len"`
+ ShortenComments bool `mapstructure:"shorten-comments"`
+ ReformatTags bool `mapstructure:"reformat-tags"`
+ ChainSplitDots bool `mapstructure:"chain-split-dots"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/issues.go
new file mode 100644
index 00000000..5dc630b0
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/issues.go
@@ -0,0 +1,15 @@
+package config
+
+type Issues struct {
+ MaxIssuesPerLinter int `mapstructure:"max-issues-per-linter"`
+ MaxSameIssues int `mapstructure:"max-same-issues"`
+ UniqByLine bool `mapstructure:"uniq-by-line"`
+
+ DiffFromRevision string `mapstructure:"new-from-rev"`
+ DiffFromMergeBase string `mapstructure:"new-from-merge-base"`
+ DiffPatchFilePath string `mapstructure:"new-from-patch"`
+ WholeFiles bool `mapstructure:"whole-files"`
+ Diff bool `mapstructure:"new"`
+
+ NeedFix bool `mapstructure:"fix"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters.go
new file mode 100644
index 00000000..590d9448
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters.go
@@ -0,0 +1,53 @@
+package config
+
+import (
+ "fmt"
+ "slices"
+)
+
+const (
+ GroupStandard = "standard"
+ GroupAll = "all"
+ GroupNone = "none"
+ GroupFast = "fast"
+)
+
+type Linters struct {
+ Default string `mapstructure:"default"`
+ Enable []string `mapstructure:"enable"`
+ Disable []string `mapstructure:"disable"`
+ FastOnly bool `mapstructure:"fast-only"` // Flag only option.
+
+ Settings LintersSettings `mapstructure:"settings"`
+
+ Exclusions LinterExclusions `mapstructure:"exclusions"`
+}
+
+func (l *Linters) Validate() error {
+ validators := []func() error{
+ l.Exclusions.Validate,
+ l.validateNoFormatters,
+ }
+
+ for _, v := range validators {
+ if err := v(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (l *Linters) validateNoFormatters() error {
+ for _, n := range slices.Concat(l.Enable, l.Disable) {
+ if slices.Contains(getAllFormatterNames(), n) {
+ return fmt.Errorf("%s is a formatter", n)
+ }
+ }
+
+ return nil
+}
+
+func getAllFormatterNames() []string {
+ return []string{"gci", "gofmt", "gofumpt", "goimports", "golines"}
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/linters_exclusions.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_exclusions.go
similarity index 80%
rename from vendor/github.com/golangci/golangci-lint/pkg/config/linters_exclusions.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_exclusions.go
index 3bed6dfc..57d08b48 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/config/linters_exclusions.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_exclusions.go
@@ -5,10 +5,16 @@ import (
"slices"
)
+const (
+ GeneratedModeLax = "lax"
+ GeneratedModeStrict = "strict"
+ GeneratedModeDisable = "disable"
+)
+
const (
ExclusionPresetComments = "comments"
- ExclusionPresetStdErrorHandling = "stdErrorHandling"
- ExclusionPresetCommonFalsePositives = "commonFalsePositives"
+ ExclusionPresetStdErrorHandling = "std-error-handling"
+ ExclusionPresetCommonFalsePositives = "common-false-positives"
ExclusionPresetLegacy = "legacy"
)
@@ -17,7 +23,7 @@ const excludeRuleMinConditionsCount = 2
type LinterExclusions struct {
Generated string `mapstructure:"generated"`
WarnUnused bool `mapstructure:"warn-unused"`
- Presets []string `mapstructure:"preset"`
+ Presets []string `mapstructure:"presets"`
Rules []ExcludeRule `mapstructure:"rules"`
Paths []string `mapstructure:"paths"`
PathsExcept []string `mapstructure:"paths-except"`
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/linters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go
similarity index 68%
rename from vendor/github.com/golangci/golangci-lint/pkg/config/linters_settings.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go
index 94650a66..16a8bb95 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/config/linters_settings.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go
@@ -1,15 +1,14 @@
package config
import (
- "encoding"
"errors"
"fmt"
"runtime"
-
- "gopkg.in/yaml.v3"
)
var defaultLintersSettings = LintersSettings{
+ FormatterSettings: defaultFormatterSettings,
+
Asasalint: AsasalintSettings{
UseBuiltinExclusions: true,
},
@@ -33,7 +32,6 @@ var defaultLintersSettings = LintersSettings{
},
Exhaustive: ExhaustiveSettings{
Check: []string{"switch"},
- CheckGenerated: false,
DefaultSignifiesExhaustive: false,
IgnoreEnumMembers: "",
PackageScopeOnly: false,
@@ -43,9 +41,12 @@ var defaultLintersSettings = LintersSettings{
Forbidigo: ForbidigoSettings{
ExcludeGodocExamples: true,
},
- Gci: GciSettings{
- Sections: []string{"standard", "default"},
- SkipGenerated: true,
+ FuncOrder: FuncOrderSettings{
+ Constructor: true,
+ StructMethod: true,
+ },
+ Funlen: FunlenSettings{
+ IgnoreComments: true,
},
GoChecksumType: GoChecksumTypeSettings{
DefaultSignifiesExhaustive: true,
@@ -74,21 +75,12 @@ var defaultLintersSettings = LintersSettings{
Scope: "declarations",
Period: true,
},
- Gofmt: GoFmtSettings{
- Simplify: true,
- },
- Gofumpt: GofumptSettings{
- LangVersion: "",
- ModulePath: "",
- ExtraRules: false,
- },
Gosec: GoSecSettings{
Concurrency: runtime.NumCPU(),
},
Gosmopolitan: GosmopolitanSettings{
AllowTimeLocal: false,
EscapeHatches: []string{},
- IgnoreTests: true,
WatchForScripts: []string{"Han"},
},
Inamedparam: INamedParamSettings{
@@ -143,7 +135,6 @@ var defaultLintersSettings = LintersSettings{
ForLoops: false,
},
Predeclared: PredeclaredSettings{
- Ignore: "",
Qualified: false,
},
SlogLint: SlogLintSettings{
@@ -168,9 +159,6 @@ var defaultLintersSettings = LintersSettings{
SkipRegexp: `(export|internal)_test\.go`,
AllowPackages: []string{"main"},
},
- Unparam: UnparamSettings{
- Algo: "cha",
- },
Unused: UnusedSettings{
FieldWritesAreUses: true,
PostStatementsAreReads: false,
@@ -207,6 +195,7 @@ var defaultLintersSettings = LintersSettings{
AllowCuddleDeclaration: false,
AllowCuddleWithCalls: []string{"Lock", "RLock"},
AllowCuddleWithRHS: []string{"Unlock", "RUnlock"},
+ AllowCuddleUsedInBlock: false,
ForceCuddleErrCheckAndAssign: false,
ErrorVariableNames: []string{"err"},
ForceExclusiveShortDeclarations: false,
@@ -214,92 +203,88 @@ var defaultLintersSettings = LintersSettings{
}
type LintersSettings struct {
- Asasalint AsasalintSettings
- BiDiChk BiDiChkSettings
- CopyLoopVar CopyLoopVarSettings
- Cyclop Cyclop
- Decorder DecorderSettings
- Depguard DepGuardSettings
- Dogsled DogsledSettings
- Dupl DuplSettings
- DupWord DupWordSettings
- Errcheck ErrcheckSettings
- ErrChkJSON ErrChkJSONSettings
- ErrorLint ErrorLintSettings
- Exhaustive ExhaustiveSettings
- Exhaustruct ExhaustructSettings
- Fatcontext FatcontextSettings
- Forbidigo ForbidigoSettings
- Funlen FunlenSettings
- Gci GciSettings
- GinkgoLinter GinkgoLinterSettings
- Gocognit GocognitSettings
- GoChecksumType GoChecksumTypeSettings
- Goconst GoConstSettings
- Gocritic GoCriticSettings
- Gocyclo GoCycloSettings
- Godot GodotSettings
- Godox GodoxSettings
- Gofmt GoFmtSettings
- Gofumpt GofumptSettings
- Goheader GoHeaderSettings
- Goimports GoImportsSettings
- GoModDirectives GoModDirectivesSettings
- Gomodguard GoModGuardSettings
- Gosec GoSecSettings
- Gosimple StaticCheckSettings
- Gosmopolitan GosmopolitanSettings
- Govet GovetSettings
- Grouper GrouperSettings
- Iface IfaceSettings
- ImportAs ImportAsSettings
- Inamedparam INamedParamSettings
- InterfaceBloat InterfaceBloatSettings
- Ireturn IreturnSettings
- Lll LllSettings
- LoggerCheck LoggerCheckSettings
- MaintIdx MaintIdxSettings
- Makezero MakezeroSettings
- Misspell MisspellSettings
- Mnd MndSettings
- MustTag MustTagSettings
- Nakedret NakedretSettings
- Nestif NestifSettings
- NilNil NilNilSettings
- Nlreturn NlreturnSettings
- NoLintLint NoLintLintSettings
- NoNamedReturns NoNamedReturnsSettings
- ParallelTest ParallelTestSettings
- PerfSprint PerfSprintSettings
- Prealloc PreallocSettings
- Predeclared PredeclaredSettings
- Promlinter PromlinterSettings
- ProtoGetter ProtoGetterSettings
- Reassign ReassignSettings
- Recvcheck RecvcheckSettings
- Revive ReviveSettings
- RowsErrCheck RowsErrCheckSettings
- SlogLint SlogLintSettings
- Spancheck SpancheckSettings
- Staticcheck StaticCheckSettings
- Stylecheck StaticCheckSettings
- TagAlign TagAlignSettings
- Tagliatelle TagliatelleSettings
- Tenv TenvSettings
- Testifylint TestifylintSettings
- Testpackage TestpackageSettings
- Thelper ThelperSettings
- Unconvert UnconvertSettings
- Unparam UnparamSettings
- Unused UnusedSettings
- UseStdlibVars UseStdlibVarsSettings
- UseTesting UseTestingSettings
- Varnamelen VarnamelenSettings
- Whitespace WhitespaceSettings
- Wrapcheck WrapcheckSettings
- WSL WSLSettings
-
- Custom map[string]CustomLinterSettings
+ FormatterSettings `mapstructure:"-"`
+
+ Asasalint AsasalintSettings `mapstructure:"asasalint"`
+ BiDiChk BiDiChkSettings `mapstructure:"bidichk"`
+ CopyLoopVar CopyLoopVarSettings `mapstructure:"copyloopvar"`
+ Cyclop CyclopSettings `mapstructure:"cyclop"`
+ Decorder DecorderSettings `mapstructure:"decorder"`
+ Depguard DepGuardSettings `mapstructure:"depguard"`
+ Dogsled DogsledSettings `mapstructure:"dogsled"`
+ Dupl DuplSettings `mapstructure:"dupl"`
+ DupWord DupWordSettings `mapstructure:"dupword"`
+ Errcheck ErrcheckSettings `mapstructure:"errcheck"`
+ ErrChkJSON ErrChkJSONSettings `mapstructure:"errchkjson"`
+ ErrorLint ErrorLintSettings `mapstructure:"errorlint"`
+ Exhaustive ExhaustiveSettings `mapstructure:"exhaustive"`
+ Exhaustruct ExhaustructSettings `mapstructure:"exhaustruct"`
+ Fatcontext FatcontextSettings `mapstructure:"fatcontext"`
+ Forbidigo ForbidigoSettings `mapstructure:"forbidigo"`
+ FuncOrder FuncOrderSettings `mapstructure:"funcorder"`
+ Funlen FunlenSettings `mapstructure:"funlen"`
+ GinkgoLinter GinkgoLinterSettings `mapstructure:"ginkgolinter"`
+ Gocognit GocognitSettings `mapstructure:"gocognit"`
+ GoChecksumType GoChecksumTypeSettings `mapstructure:"gochecksumtype"`
+ Goconst GoConstSettings `mapstructure:"goconst"`
+ Gocritic GoCriticSettings `mapstructure:"gocritic"`
+ Gocyclo GoCycloSettings `mapstructure:"gocyclo"`
+ Godot GodotSettings `mapstructure:"godot"`
+ Godox GodoxSettings `mapstructure:"godox"`
+ Goheader GoHeaderSettings `mapstructure:"goheader"`
+ GoModDirectives GoModDirectivesSettings `mapstructure:"gomoddirectives"`
+ Gomodguard GoModGuardSettings `mapstructure:"gomodguard"`
+ Gosec GoSecSettings `mapstructure:"gosec"`
+ Gosmopolitan GosmopolitanSettings `mapstructure:"gosmopolitan"`
+ Govet GovetSettings `mapstructure:"govet"`
+ Grouper GrouperSettings `mapstructure:"grouper"`
+ Iface IfaceSettings `mapstructure:"iface"`
+ ImportAs ImportAsSettings `mapstructure:"importas"`
+ Inamedparam INamedParamSettings `mapstructure:"inamedparam"`
+ InterfaceBloat InterfaceBloatSettings `mapstructure:"interfacebloat"`
+ Ireturn IreturnSettings `mapstructure:"ireturn"`
+ Lll LllSettings `mapstructure:"lll"`
+ LoggerCheck LoggerCheckSettings `mapstructure:"loggercheck"`
+ MaintIdx MaintIdxSettings `mapstructure:"maintidx"`
+ Makezero MakezeroSettings `mapstructure:"makezero"`
+ Misspell MisspellSettings `mapstructure:"misspell"`
+ Mnd MndSettings `mapstructure:"mnd"`
+ MustTag MustTagSettings `mapstructure:"musttag"`
+ Nakedret NakedretSettings `mapstructure:"nakedret"`
+ Nestif NestifSettings `mapstructure:"nestif"`
+ NilNil NilNilSettings `mapstructure:"nilnil"`
+ Nlreturn NlreturnSettings `mapstructure:"nlreturn"`
+ NoLintLint NoLintLintSettings `mapstructure:"nolintlint"`
+ NoNamedReturns NoNamedReturnsSettings `mapstructure:"nonamedreturns"`
+ ParallelTest ParallelTestSettings `mapstructure:"paralleltest"`
+ PerfSprint PerfSprintSettings `mapstructure:"perfsprint"`
+ Prealloc PreallocSettings `mapstructure:"prealloc"`
+ Predeclared PredeclaredSettings `mapstructure:"predeclared"`
+ Promlinter PromlinterSettings `mapstructure:"promlinter"`
+ ProtoGetter ProtoGetterSettings `mapstructure:"protogetter"`
+ Reassign ReassignSettings `mapstructure:"reassign"`
+ Recvcheck RecvcheckSettings `mapstructure:"recvcheck"`
+ Revive ReviveSettings `mapstructure:"revive"`
+ RowsErrCheck RowsErrCheckSettings `mapstructure:"rowserrcheck"`
+ SlogLint SlogLintSettings `mapstructure:"sloglint"`
+ Spancheck SpancheckSettings `mapstructure:"spancheck"`
+ Staticcheck StaticCheckSettings `mapstructure:"staticcheck"`
+ TagAlign TagAlignSettings `mapstructure:"tagalign"`
+ Tagliatelle TagliatelleSettings `mapstructure:"tagliatelle"`
+ Testifylint TestifylintSettings `mapstructure:"testifylint"`
+ Testpackage TestpackageSettings `mapstructure:"testpackage"`
+ Thelper ThelperSettings `mapstructure:"thelper"`
+ Unconvert UnconvertSettings `mapstructure:"unconvert"`
+ Unparam UnparamSettings `mapstructure:"unparam"`
+ Unused UnusedSettings `mapstructure:"unused"`
+ UseStdlibVars UseStdlibVarsSettings `mapstructure:"usestdlibvars"`
+ UseTesting UseTestingSettings `mapstructure:"usetesting"`
+ Varnamelen VarnamelenSettings `mapstructure:"varnamelen"`
+ Whitespace WhitespaceSettings `mapstructure:"whitespace"`
+ Wrapcheck WrapcheckSettings `mapstructure:"wrapcheck"`
+ WSL WSLSettings `mapstructure:"wsl"`
+
+ Custom map[string]CustomLinterSettings `mapstructure:"custom"`
}
func (s *LintersSettings) Validate() error {
@@ -319,7 +304,6 @@ func (s *LintersSettings) Validate() error {
type AsasalintSettings struct {
Exclude []string `mapstructure:"exclude"`
UseBuiltinExclusions bool `mapstructure:"use-builtin-exclusions"`
- IgnoreTest bool `mapstructure:"ignore-test"`
}
type BiDiChkSettings struct {
@@ -336,15 +320,11 @@ type BiDiChkSettings struct {
type CopyLoopVarSettings struct {
CheckAlias bool `mapstructure:"check-alias"`
-
- // Deprecated: use CheckAlias
- IgnoreAlias *bool `mapstructure:"ignore-alias"`
}
-type Cyclop struct {
+type CyclopSettings struct {
MaxComplexity int `mapstructure:"max-complexity"`
PackageAverage float64 `mapstructure:"package-average"`
- SkipTests bool `mapstructure:"skip-tests"`
}
type DepGuardSettings struct {
@@ -379,7 +359,7 @@ type DogsledSettings struct {
}
type DuplSettings struct {
- Threshold int
+ Threshold int `mapstructure:"threshold"`
}
type DupWordSettings struct {
@@ -392,12 +372,6 @@ type ErrcheckSettings struct {
CheckTypeAssertions bool `mapstructure:"check-type-assertions"`
CheckAssignToBlank bool `mapstructure:"check-blank"`
ExcludeFunctions []string `mapstructure:"exclude-functions"`
-
- // Deprecated: use ExcludeFunctions instead
- Exclude string `mapstructure:"exclude"`
-
- // Deprecated: use ExcludeFunctions instead
- Ignore string `mapstructure:"ignore"`
}
type ErrChkJSONSettings struct {
@@ -421,7 +395,6 @@ type ErrorLintAllowPair struct {
type ExhaustiveSettings struct {
Check []string `mapstructure:"check"`
- CheckGenerated bool `mapstructure:"check-generated"`
DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"`
IgnoreEnumMembers string `mapstructure:"ignore-enum-members"`
IgnoreEnumTypes string `mapstructure:"ignore-enum-types"`
@@ -446,60 +419,23 @@ type ForbidigoSettings struct {
AnalyzeTypes bool `mapstructure:"analyze-types"`
}
-var _ encoding.TextUnmarshaler = &ForbidigoPattern{}
-
-// ForbidigoPattern corresponds to forbidigo.pattern and adds mapstructure support.
-// The YAML field names must match what forbidigo expects.
type ForbidigoPattern struct {
- // patternString gets populated when the config contains a string as entry in ForbidigoSettings.Forbid[]
- // because ForbidigoPattern implements encoding.TextUnmarshaler
- // and the reader uses the mapstructure.TextUnmarshallerHookFunc as decoder hook.
- //
- // If the entry is a map, then the other fields are set as usual by mapstructure.
- patternString string
-
- Pattern string `yaml:"p" mapstructure:"p"`
+ Pattern string `yaml:"p" mapstructure:"pattern"`
Package string `yaml:"pkg,omitempty" mapstructure:"pkg,omitempty"`
Msg string `yaml:"msg,omitempty" mapstructure:"msg,omitempty"`
}
-func (p *ForbidigoPattern) UnmarshalText(text []byte) error {
- // Validation happens when instantiating forbidigo.
- p.patternString = string(text)
- return nil
-}
-
-// MarshalString converts the pattern into a string as needed by forbidigo.NewLinter.
-//
-// MarshalString is intentionally not called MarshalText,
-// although it has the same signature
-// because implementing encoding.TextMarshaler led to infinite recursion when yaml.Marshal called MarshalText.
-func (p *ForbidigoPattern) MarshalString() ([]byte, error) {
- if p.patternString != "" {
- return []byte(p.patternString), nil
- }
-
- return yaml.Marshal(p)
+type FuncOrderSettings struct {
+ Constructor bool `mapstructure:"constructor,omitempty"`
+ StructMethod bool `mapstructure:"struct-method,omitempty"`
}
type FunlenSettings struct {
- Lines int
- Statements int
+ Lines int `mapstructure:"lines"`
+ Statements int `mapstructure:"statements"`
IgnoreComments bool `mapstructure:"ignore-comments"`
}
-type GciSettings struct {
- Sections []string `mapstructure:"sections"`
- NoInlineComments bool `mapstructure:"no-inline-comments"`
- NoPrefixComments bool `mapstructure:"no-prefix-comments"`
- SkipGenerated bool `mapstructure:"skip-generated"`
- CustomOrder bool `mapstructure:"custom-order"`
- NoLexOrder bool `mapstructure:"no-lex-order"`
-
- // Deprecated: use Sections instead.
- LocalPrefixes string `mapstructure:"local-prefixes"`
-}
-
type GinkgoLinterSettings struct {
SuppressLenAssertion bool `mapstructure:"suppress-len-assertion"`
SuppressNilAssertion bool `mapstructure:"suppress-nil-assertion"`
@@ -525,15 +461,19 @@ type GocognitSettings struct {
}
type GoConstSettings struct {
- IgnoreStrings string `mapstructure:"ignore-strings"`
- IgnoreTests bool `mapstructure:"ignore-tests"`
- MatchWithConstants bool `mapstructure:"match-constant"`
- MinStringLen int `mapstructure:"min-len"`
- MinOccurrencesCount int `mapstructure:"min-occurrences"`
- ParseNumbers bool `mapstructure:"numbers"`
- NumberMin int `mapstructure:"min"`
- NumberMax int `mapstructure:"max"`
- IgnoreCalls bool `mapstructure:"ignore-calls"`
+ IgnoreStringValues []string `mapstructure:"ignore-string-values"`
+ MatchWithConstants bool `mapstructure:"match-constant"`
+ MinStringLen int `mapstructure:"min-len"`
+ MinOccurrencesCount int `mapstructure:"min-occurrences"`
+ ParseNumbers bool `mapstructure:"numbers"`
+ NumberMin int `mapstructure:"min"`
+ NumberMax int `mapstructure:"max"`
+ IgnoreCalls bool `mapstructure:"ignore-calls"`
+ FindDuplicates bool `mapstructure:"find-duplicates"`
+ EvalConstExpressions bool `mapstructure:"eval-const-expressions"`
+
+ // Deprecated: use IgnoreStringValues instead.
+ IgnoreStrings string `mapstructure:"ignore-strings"`
}
type GoCriticSettings struct {
@@ -558,31 +498,10 @@ type GodotSettings struct {
Exclude []string `mapstructure:"exclude"`
Capital bool `mapstructure:"capital"`
Period bool `mapstructure:"period"`
-
- // Deprecated: use Scope instead
- CheckAll *bool `mapstructure:"check-all"`
}
type GodoxSettings struct {
- Keywords []string
-}
-
-type GoFmtSettings struct {
- Simplify bool
- RewriteRules []GoFmtRewriteRule `mapstructure:"rewrite-rules"`
-}
-
-type GoFmtRewriteRule struct {
- Pattern string
- Replacement string
-}
-
-type GofumptSettings struct {
- ModulePath string `mapstructure:"module-path"`
- ExtraRules bool `mapstructure:"extra-rules"`
-
- // Deprecated: use the global `run.go` instead.
- LangVersion string `mapstructure:"lang-version"`
+ Keywords []string `mapstructure:"keywords"`
}
type GoHeaderSettings struct {
@@ -591,10 +510,6 @@ type GoHeaderSettings struct {
TemplatePath string `mapstructure:"template-path"`
}
-type GoImportsSettings struct {
- LocalPrefixes string `mapstructure:"local-prefixes"`
-}
-
type GoModDirectivesSettings struct {
ReplaceAllowList []string `mapstructure:"replace-allow-list"`
ReplaceLocal bool `mapstructure:"replace-local"`
@@ -608,52 +523,55 @@ type GoModDirectivesSettings struct {
}
type GoModGuardSettings struct {
- Allowed struct {
- Modules []string `mapstructure:"modules"`
- Domains []string `mapstructure:"domains"`
- } `mapstructure:"allowed"`
- Blocked struct {
- Modules []map[string]struct {
- Recommendations []string `mapstructure:"recommendations"`
- Reason string `mapstructure:"reason"`
- } `mapstructure:"modules"`
- Versions []map[string]struct {
- Version string `mapstructure:"version"`
- Reason string `mapstructure:"reason"`
- } `mapstructure:"versions"`
- LocalReplaceDirectives bool `mapstructure:"local_replace_directives"`
- } `mapstructure:"blocked"`
+ Allowed GoModGuardAllowed `mapstructure:"allowed"`
+ Blocked GoModGuardBlocked `mapstructure:"blocked"`
+}
+
+type GoModGuardAllowed struct {
+ Modules []string `mapstructure:"modules"`
+ Domains []string `mapstructure:"domains"`
+}
+
+type GoModGuardBlocked struct {
+ Modules []map[string]GoModGuardModule `mapstructure:"modules"`
+ Versions []map[string]GoModGuardVersion `mapstructure:"versions"`
+ LocalReplaceDirectives bool `mapstructure:"local-replace-directives"`
+}
+
+type GoModGuardModule struct {
+ Recommendations []string `mapstructure:"recommendations"`
+ Reason string `mapstructure:"reason"`
+}
+
+type GoModGuardVersion struct {
+ Version string `mapstructure:"version"`
+ Reason string `mapstructure:"reason"`
}
type GoSecSettings struct {
- Includes []string `mapstructure:"includes"`
- Excludes []string `mapstructure:"excludes"`
- Severity string `mapstructure:"severity"`
- Confidence string `mapstructure:"confidence"`
- ExcludeGenerated bool `mapstructure:"exclude-generated"`
- Config map[string]any `mapstructure:"config"`
- Concurrency int `mapstructure:"concurrency"`
+ Includes []string `mapstructure:"includes"`
+ Excludes []string `mapstructure:"excludes"`
+ Severity string `mapstructure:"severity"`
+ Confidence string `mapstructure:"confidence"`
+ Config map[string]any `mapstructure:"config"`
+ Concurrency int `mapstructure:"concurrency"`
}
type GosmopolitanSettings struct {
AllowTimeLocal bool `mapstructure:"allow-time-local"`
EscapeHatches []string `mapstructure:"escape-hatches"`
- IgnoreTests bool `mapstructure:"ignore-tests"`
WatchForScripts []string `mapstructure:"watch-for-scripts"`
}
type GovetSettings struct {
Go string `mapstructure:"-"`
- Enable []string
- Disable []string
- EnableAll bool `mapstructure:"enable-all"`
- DisableAll bool `mapstructure:"disable-all"`
-
- Settings map[string]map[string]any
+ Enable []string `mapstructure:"enable"`
+ Disable []string `mapstructure:"disable"`
+ EnableAll bool `mapstructure:"enable-all"`
+ DisableAll bool `mapstructure:"disable-all"`
- // Deprecated: the linter should be enabled inside Enable.
- CheckShadowing *bool `mapstructure:"check-shadowing"`
+ Settings map[string]map[string]any `mapstructure:"settings"`
}
func (cfg *GovetSettings) Validate() error {
@@ -686,14 +604,14 @@ type IfaceSettings struct {
}
type ImportAsSettings struct {
- Alias []ImportAsAlias
- NoUnaliased bool `mapstructure:"no-unaliased"`
- NoExtraAliases bool `mapstructure:"no-extra-aliases"`
+ Alias []ImportAsAlias `mapstructure:"alias"`
+ NoUnaliased bool `mapstructure:"no-unaliased"`
+ NoExtraAliases bool `mapstructure:"no-extra-aliases"`
}
type ImportAsAlias struct {
- Pkg string
- Alias string
+ Pkg string `mapstructure:"pkg"`
+ Alias string `mapstructure:"alias"`
}
type INamedParamSettings struct {
@@ -730,15 +648,14 @@ type MaintIdxSettings struct {
}
type MakezeroSettings struct {
- Always bool
+ Always bool `mapstructure:"always"`
}
type MisspellSettings struct {
- Mode string `mapstructure:"mode"`
- Locale string `mapstructure:"locale"`
- ExtraWords []MisspellExtraWords `mapstructure:"extra-words"`
- // TODO(ldez): v2 the option must be renamed to `IgnoredRules`.
- IgnoreWords []string `mapstructure:"ignore-words"`
+ Mode string `mapstructure:"mode"`
+ Locale string `mapstructure:"locale"`
+ ExtraWords []MisspellExtraWords `mapstructure:"extra-words"`
+ IgnoreRules []string `mapstructure:"ignore-rules"`
}
type MisspellExtraWords struct {
@@ -747,11 +664,13 @@ type MisspellExtraWords struct {
}
type MustTagSettings struct {
- Functions []struct {
- Name string `mapstructure:"name"`
- Tag string `mapstructure:"tag"`
- ArgPos int `mapstructure:"arg-pos"`
- } `mapstructure:"functions"`
+ Functions []MustTagFunction `mapstructure:"functions"`
+}
+
+type MustTagFunction struct {
+ Name string `mapstructure:"name"`
+ Tag string `mapstructure:"tag"`
+ ArgPos int `mapstructure:"arg-pos"`
}
type NakedretSettings struct {
@@ -763,6 +682,7 @@ type NestifSettings struct {
}
type NilNilSettings struct {
+ OnlyTwo *bool `mapstructure:"only-two"`
DetectOpposite bool `mapstructure:"detect-opposite"`
CheckedTypes []string `mapstructure:"checked-types"`
}
@@ -812,14 +732,14 @@ type PerfSprintSettings struct {
}
type PreallocSettings struct {
- Simple bool
+ Simple bool `mapstructure:"simple"`
RangeLoops bool `mapstructure:"range-loops"`
ForLoops bool `mapstructure:"for-loops"`
}
type PredeclaredSettings struct {
- Ignore string `mapstructure:"ignore"`
- Qualified bool `mapstructure:"q"`
+ Ignore []string `mapstructure:"ignore"`
+ Qualified bool `mapstructure:"qualified-name"`
}
type PromlinterSettings struct {
@@ -844,29 +764,32 @@ type RecvcheckSettings struct {
}
type ReviveSettings struct {
- Go string `mapstructure:"-"`
- MaxOpenFiles int `mapstructure:"max-open-files"`
- IgnoreGeneratedHeader bool `mapstructure:"ignore-generated-header"`
- Confidence float64
- Severity string
- EnableAllRules bool `mapstructure:"enable-all-rules"`
- Rules []struct {
- Name string
- Arguments []any
- Severity string
- Disabled bool
- Exclude []string
- }
- ErrorCode int `mapstructure:"error-code"`
- WarningCode int `mapstructure:"warning-code"`
- Directives []struct {
- Name string
- Severity string
- }
+ Go string `mapstructure:"-"`
+ MaxOpenFiles int `mapstructure:"max-open-files"`
+ Confidence float64 `mapstructure:"confidence"`
+ Severity string `mapstructure:"severity"`
+ EnableAllRules bool `mapstructure:"enable-all-rules"`
+ Rules []ReviveRule `mapstructure:"rules"`
+ ErrorCode int `mapstructure:"error-code"`
+ WarningCode int `mapstructure:"warning-code"`
+ Directives []ReviveDirective `mapstructure:"directives"`
+}
+
+type ReviveRule struct {
+ Name string `mapstructure:"name"`
+ Arguments []any `mapstructure:"arguments"`
+ Severity string `mapstructure:"severity"`
+ Disabled bool `mapstructure:"disabled"`
+ Exclude []string `mapstructure:"exclude"`
+}
+
+type ReviveDirective struct {
+ Name string `mapstructure:"name"`
+ Severity string `mapstructure:"severity"`
}
type RowsErrCheckSettings struct {
- Packages []string
+ Packages []string `mapstructure:"packages"`
}
type SlogLintSettings struct {
@@ -876,13 +799,11 @@ type SlogLintSettings struct {
NoGlobal string `mapstructure:"no-global"`
Context string `mapstructure:"context"`
StaticMsg bool `mapstructure:"static-msg"`
+ MsgStyle string `mapstructure:"msg-style"`
NoRawKeys bool `mapstructure:"no-raw-keys"`
KeyNamingCase string `mapstructure:"key-naming-case"`
ForbiddenKeys []string `mapstructure:"forbidden-keys"`
ArgsOnSepLines bool `mapstructure:"args-on-sep-lines"`
-
- // Deprecated: use Context instead.
- ContextOnly *bool `mapstructure:"context-only"`
}
type SpancheckSettings struct {
@@ -896,9 +817,6 @@ type StaticCheckSettings struct {
Initialisms []string `mapstructure:"initialisms"` // only for stylecheck
DotImportWhitelist []string `mapstructure:"dot-import-whitelist"` // only for stylecheck
HTTPStatusCodeWhitelist []string `mapstructure:"http-status-code-whitelist"` // only for stylecheck
-
- // Deprecated: use the global `run.go` instead.
- GoVersion string `mapstructure:"go"`
}
func (s *StaticCheckSettings) HasConfiguration() bool {
@@ -913,12 +831,12 @@ type TagAlignSettings struct {
}
type TagliatelleSettings struct {
- Case TagliatelleCase
+ Case TagliatelleCase `mapstructure:"case"`
}
type TagliatelleCase struct {
TagliatelleBase `mapstructure:",squash"`
- Overrides []TagliatelleOverrides
+ Overrides []TagliatelleOverrides `mapstructure:"overrides"`
}
type TagliatelleOverrides struct {
@@ -935,9 +853,9 @@ type TagliatelleBase struct {
}
type TagliatelleExtendedRule struct {
- Case string
- ExtraInitialisms bool
- InitialismOverrides map[string]bool
+ Case string `mapstructure:"case"`
+ ExtraInitialisms bool `mapstructure:"extra-initialisms"`
+ InitialismOverrides map[string]bool `mapstructure:"initialism-overrides"`
}
type TestifylintSettings struct {
@@ -946,30 +864,38 @@ type TestifylintSettings struct {
EnabledCheckers []string `mapstructure:"enable"`
DisabledCheckers []string `mapstructure:"disable"`
- BoolCompare struct {
- IgnoreCustomTypes bool `mapstructure:"ignore-custom-types"`
- } `mapstructure:"bool-compare"`
+ BoolCompare TestifylintBoolCompare `mapstructure:"bool-compare"`
+ ExpectedActual TestifylintExpectedActual `mapstructure:"expected-actual"`
+ Formatter TestifylintFormatter `mapstructure:"formatter"`
+ GoRequire TestifylintGoRequire `mapstructure:"go-require"`
+ RequireError TestifylintRequireError `mapstructure:"require-error"`
+ SuiteExtraAssertCall TestifylintSuiteExtraAssertCall `mapstructure:"suite-extra-assert-call"`
+}
- ExpectedActual struct {
- ExpVarPattern string `mapstructure:"pattern"`
- } `mapstructure:"expected-actual"`
+type TestifylintBoolCompare struct {
+ IgnoreCustomTypes bool `mapstructure:"ignore-custom-types"`
+}
- Formatter struct {
- CheckFormatString *bool `mapstructure:"check-format-string"`
- RequireFFuncs bool `mapstructure:"require-f-funcs"`
- } `mapstructure:"formatter"`
+type TestifylintExpectedActual struct {
+ ExpVarPattern string `mapstructure:"pattern"`
+}
- GoRequire struct {
- IgnoreHTTPHandlers bool `mapstructure:"ignore-http-handlers"`
- } `mapstructure:"go-require"`
+type TestifylintFormatter struct {
+ CheckFormatString *bool `mapstructure:"check-format-string"`
+ RequireFFuncs bool `mapstructure:"require-f-funcs"`
+ RequireStringMsg bool `mapstructure:"require-string-msg"`
+}
- RequireError struct {
- FnPattern string `mapstructure:"fn-pattern"`
- } `mapstructure:"require-error"`
+type TestifylintGoRequire struct {
+ IgnoreHTTPHandlers bool `mapstructure:"ignore-http-handlers"`
+}
+
+type TestifylintRequireError struct {
+ FnPattern string `mapstructure:"fn-pattern"`
+}
- SuiteExtraAssertCall struct {
- Mode string `mapstructure:"mode"`
- } `mapstructure:"suite-extra-assert-call"`
+type TestifylintSuiteExtraAssertCall struct {
+ Mode string `mapstructure:"mode"`
}
type TestpackageSettings struct {
@@ -990,10 +916,6 @@ type ThelperOptions struct {
Begin *bool `mapstructure:"begin"`
}
-type TenvSettings struct {
- All bool `mapstructure:"all"`
-}
-
type UseStdlibVarsSettings struct {
HTTPMethod bool `mapstructure:"http-method"`
HTTPStatusCode bool `mapstructure:"http-status-code"`
@@ -1005,11 +927,6 @@ type UseStdlibVarsSettings struct {
SQLIsolationLevel bool `mapstructure:"sql-isolation-level"`
TLSSignatureScheme bool `mapstructure:"tls-signature-scheme"`
ConstantKind bool `mapstructure:"constant-kind"`
-
- // Deprecated
- OSDevNull *bool `mapstructure:"os-dev-null"`
- // Deprecated
- SyslogPriority *bool `mapstructure:"syslog-priority"`
}
type UseTestingSettings struct {
@@ -1029,7 +946,6 @@ type UnconvertSettings struct {
type UnparamSettings struct {
CheckExported bool `mapstructure:"check-exported"`
- Algo string
}
type UnusedSettings struct {
@@ -1039,9 +955,6 @@ type UnusedSettings struct {
ParametersAreUsed bool `mapstructure:"parameters-are-used"`
LocalVariablesAreUsed bool `mapstructure:"local-variables-are-used"`
GeneratedIsUsed bool `mapstructure:"generated-is-used"`
-
- // Deprecated
- ExportedIsUsed *bool `mapstructure:"exported-is-used"`
}
type VarnamelenSettings struct {
@@ -1063,12 +976,12 @@ type WhitespaceSettings struct {
}
type WrapcheckSettings struct {
- ExtraIgnoreSigs []string `mapstructure:"extra-ignore-sigs"`
- // TODO(ldez): v2 the options must be renamed to use hyphen.
- IgnoreSigs []string `mapstructure:"ignoreSigs"`
- IgnoreSigRegexps []string `mapstructure:"ignoreSigRegexps"`
- IgnorePackageGlobs []string `mapstructure:"ignorePackageGlobs"`
- IgnoreInterfaceRegexps []string `mapstructure:"ignoreInterfaceRegexps"`
+ ExtraIgnoreSigs []string `mapstructure:"extra-ignore-sigs"`
+ IgnoreSigs []string `mapstructure:"ignore-sigs"`
+ IgnoreSigRegexps []string `mapstructure:"ignore-sig-regexps"`
+ IgnorePackageGlobs []string `mapstructure:"ignore-package-globs"`
+ IgnoreInterfaceRegexps []string `mapstructure:"ignore-interface-regexps"`
+ ReportInternalErrors bool `mapstructure:"report-internal-errors"`
}
type WSLSettings struct {
@@ -1082,6 +995,7 @@ type WSLSettings struct {
AllowCuddleDeclaration bool `mapstructure:"allow-cuddle-declarations"`
AllowCuddleWithCalls []string `mapstructure:"allow-cuddle-with-calls"`
AllowCuddleWithRHS []string `mapstructure:"allow-cuddle-with-rhs"`
+ AllowCuddleUsedInBlock bool `mapstructure:"allow-cuddle-used-in-block"`
ForceCuddleErrCheckAndAssign bool `mapstructure:"force-err-cuddling"`
ErrorVariableNames []string `mapstructure:"error-variable-names"`
ForceExclusiveShortDeclarations bool `mapstructure:"force-short-decl-cuddling"`
@@ -1095,15 +1009,15 @@ type CustomLinterSettings struct {
// Path to a plugin *.so file that implements the private linter.
// Only for Go plugin system.
- Path string
+ Path string `mapstructure:"path"`
// Description describes the purpose of the private linter.
- Description string
+ Description string `mapstructure:"description"`
// OriginalURL The URL containing the source code for the private linter.
OriginalURL string `mapstructure:"original-url"`
// Settings plugin settings only work with linterdb.PluginConstructor symbol.
- Settings any
+ Settings any `mapstructure:"settings"`
}
func (s *CustomLinterSettings) Validate() error {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/loader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/loader.go
new file mode 100644
index 00000000..3ff93064
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/loader.go
@@ -0,0 +1,275 @@
+package config
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "os"
+ "slices"
+
+ "github.com/spf13/pflag"
+ "github.com/spf13/viper"
+
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goutil"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+)
+
+var errConfigDisabled = errors.New("config is disabled by --no-config")
+
+const (
+ modeLinters = "linters"
+ modeFormatters = "formatters"
+)
+
+type LoaderOptions struct {
+ Config string // Flag only. The path to the golangci config file, as specified with the --config argument.
+ NoConfig bool // Flag only.
+}
+
+type LoadOptions struct {
+ CheckDeprecation bool
+ Validation bool
+}
+
+type Loader struct {
+ *BaseLoader
+
+ fs *pflag.FlagSet
+
+ cfg *Config
+
+ mode string
+}
+
+func NewLintersLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader {
+ loader := newLoader(log, v, fs, opts, cfg, args)
+ loader.mode = modeLinters
+
+ return loader
+}
+
+func NewFormattersLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader {
+ loader := newLoader(log, v, fs, opts, cfg, args)
+ loader.mode = modeFormatters
+
+ return loader
+}
+
+func newLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader {
+ return &Loader{
+ BaseLoader: NewBaseLoader(log, v, opts, cfg, args),
+ fs: fs,
+ cfg: cfg,
+ }
+}
+
+func (l *Loader) Load(opts LoadOptions) error {
+ err := l.BaseLoader.Load()
+ if err != nil {
+ return err
+ }
+
+ if l.mode == modeLinters {
+ l.applyStringSliceHack()
+ }
+
+ if l.cfg.Linters.Exclusions.Generated == "" {
+ l.cfg.Linters.Exclusions.Generated = GeneratedModeStrict
+ }
+
+ err = l.checkConfigurationVersion()
+ if err != nil {
+ return err
+ }
+
+ if !l.cfg.InternalCmdTest {
+ for _, n := range slices.Concat(l.cfg.Linters.Enable, l.cfg.Linters.Disable) {
+ if n == "typecheck" {
+ return fmt.Errorf("%s is not a linter, it cannot be enabled or disabled", n)
+ }
+ }
+ }
+
+ l.handleFormatters()
+
+ if opts.CheckDeprecation {
+ err = l.handleDeprecation()
+ if err != nil {
+ return err
+ }
+
+ l.handleFormatterDeprecations()
+ }
+
+ l.handleGoVersion()
+
+ err = goutil.CheckGoVersion(l.cfg.Run.Go)
+ if err != nil {
+ return err
+ }
+
+ l.cfg.basePath, err = fsutils.GetBasePath(context.Background(), l.cfg.Run.RelativePathMode, l.cfg.cfgDir)
+ if err != nil {
+ return fmt.Errorf("get base path: %w", err)
+ }
+
+ err = l.handleEnableOnlyOption()
+ if err != nil {
+ return err
+ }
+
+ if opts.Validation {
+ err = l.cfg.Validate()
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Hack to append values from StringSlice flags.
+// Viper always overrides StringSlice values.
+// https://github.com/spf13/viper/issues/1448
+// So StringSlice flags are not bind to Viper like that their values are obtain via Cobra Flags.
+func (l *Loader) applyStringSliceHack() {
+ if l.fs == nil {
+ return
+ }
+
+ l.appendStringSlice("enable", &l.cfg.Linters.Enable)
+ l.appendStringSlice("disable", &l.cfg.Linters.Disable)
+ l.appendStringSlice("build-tags", &l.cfg.Run.BuildTags)
+}
+
+func (l *Loader) appendStringSlice(name string, current *[]string) {
+ if l.fs.Changed(name) {
+ val, _ := l.fs.GetStringSlice(name)
+ *current = append(*current, val...)
+ }
+}
+
+func (l *Loader) checkConfigurationVersion() error {
+ if l.cfg.GetConfigDir() != "" && l.cfg.Version != "2" {
+ return fmt.Errorf("unsupported version of the configuration: %q "+
+ "See https://golangci-lint.run/product/migration-guide for migration instructions", l.cfg.Version)
+ }
+
+ return nil
+}
+
+func (l *Loader) handleGoVersion() {
+ if l.cfg.Run.Go == "" {
+ l.cfg.Run.Go = detectGoVersion(context.Background(), l.log)
+ }
+
+ l.cfg.Linters.Settings.Govet.Go = l.cfg.Run.Go
+
+ l.cfg.Linters.Settings.ParallelTest.Go = l.cfg.Run.Go
+
+ l.cfg.Linters.Settings.GoFumpt.LangVersion = l.cfg.Run.Go
+ l.cfg.Formatters.Settings.GoFumpt.LangVersion = l.cfg.Run.Go
+
+ trimmedGoVersion := goutil.TrimGoVersion(l.cfg.Run.Go)
+
+ l.cfg.Linters.Settings.Revive.Go = trimmedGoVersion
+
+ l.cfg.Linters.Settings.Gocritic.Go = trimmedGoVersion
+
+ os.Setenv("GOSECGOVERSION", l.cfg.Run.Go)
+}
+
+func (l *Loader) handleDeprecation() error {
+ if l.cfg.InternalTest || l.cfg.InternalCmdTest || os.Getenv(logutils.EnvTestRun) == "1" {
+ return nil
+ }
+
+ l.handleLinterOptionDeprecations()
+
+ return nil
+}
+
+func (l *Loader) handleLinterOptionDeprecations() {
+ // Deprecated since v2.1.0.
+ if l.cfg.Linters.Settings.Goconst.IgnoreStrings != "" {
+ l.log.Warnf("The configuration option `linters.settings.goconst.ignore-strings` is deprecated, " +
+ "please use `linters.settings.goconst.ignore-string-values`.")
+
+ l.cfg.Linters.Settings.Goconst.IgnoreStringValues = append(l.cfg.Linters.Settings.Goconst.IgnoreStringValues,
+ l.cfg.Linters.Settings.Goconst.IgnoreStrings)
+ }
+}
+
+func (l *Loader) handleEnableOnlyOption() error {
+ lookup := l.fs.Lookup("enable-only")
+ if lookup == nil {
+ return nil
+ }
+
+ only, err := l.fs.GetStringSlice("enable-only")
+ if err != nil {
+ return err
+ }
+
+ if len(only) > 0 {
+ l.cfg.Linters = Linters{
+ Default: GroupNone,
+ Enable: only,
+ Settings: l.cfg.Linters.Settings,
+ Exclusions: l.cfg.Linters.Exclusions,
+ }
+
+ l.cfg.Formatters = Formatters{}
+ }
+
+ return nil
+}
+
+func (l *Loader) handleFormatters() {
+ l.handleFormatterOverrides()
+ l.handleFormatterExclusions()
+}
+
+// Overrides linter settings with formatter settings if the formatter is enabled.
+func (l *Loader) handleFormatterOverrides() {
+ if slices.Contains(l.cfg.Formatters.Enable, "gofmt") {
+ l.cfg.Linters.Settings.GoFmt = l.cfg.Formatters.Settings.GoFmt
+ }
+
+ if slices.Contains(l.cfg.Formatters.Enable, "gofumpt") {
+ l.cfg.Linters.Settings.GoFumpt = l.cfg.Formatters.Settings.GoFumpt
+ }
+
+ if slices.Contains(l.cfg.Formatters.Enable, "goimports") {
+ l.cfg.Linters.Settings.GoImports = l.cfg.Formatters.Settings.GoImports
+ }
+
+ if slices.Contains(l.cfg.Formatters.Enable, "gci") {
+ l.cfg.Linters.Settings.Gci = l.cfg.Formatters.Settings.Gci
+ }
+
+ if slices.Contains(l.cfg.Formatters.Enable, "golines") {
+ l.cfg.Linters.Settings.GoLines = l.cfg.Formatters.Settings.GoLines
+ }
+}
+
+// Add formatter exclusions to linters exclusions.
+func (l *Loader) handleFormatterExclusions() {
+ if len(l.cfg.Formatters.Enable) == 0 {
+ return
+ }
+
+ for _, path := range l.cfg.Formatters.Exclusions.Paths {
+ l.cfg.Linters.Exclusions.Rules = append(l.cfg.Linters.Exclusions.Rules, ExcludeRule{
+ BaseRule: BaseRule{
+ Linters: l.cfg.Formatters.Enable,
+ Path: path,
+ },
+ })
+ }
+}
+
+func (*Loader) handleFormatterDeprecations() {
+ // The function is empty but deprecations will happen in the future.
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output.go
new file mode 100644
index 00000000..803dc3ac
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output.go
@@ -0,0 +1,62 @@
+package config
+
+import (
+ "fmt"
+ "slices"
+ "strings"
+
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+)
+
+type Output struct {
+ Formats Formats `mapstructure:"formats"`
+ SortOrder []string `mapstructure:"sort-order"`
+ ShowStats bool `mapstructure:"show-stats"`
+ PathPrefix string `mapstructure:"path-prefix"`
+ PathMode string `mapstructure:"path-mode"`
+}
+
+func (o *Output) Validate() error {
+ validators := []func() error{
+ o.validateSortOrder,
+ o.validatePathMode,
+ }
+
+ for _, v := range validators {
+ if err := v(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (o *Output) validateSortOrder() error {
+ validOrders := []string{"linter", "file", "severity"}
+
+ all := strings.Join(o.SortOrder, " ")
+
+ for _, order := range o.SortOrder {
+ if strings.Count(all, order) > 1 {
+ return fmt.Errorf("the sort-order name %q is repeated several times", order)
+ }
+
+ if !slices.Contains(validOrders, order) {
+ return fmt.Errorf("unsupported sort-order name %q", order)
+ }
+ }
+
+ return nil
+}
+
+func (o *Output) validatePathMode() error {
+ switch o.PathMode {
+ case "", fsutils.OutputPathModeAbsolute:
+ // Valid
+
+ default:
+ return fmt.Errorf("unsupported output path mode %q", o.PathMode)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output_formats.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output_formats.go
new file mode 100644
index 00000000..1c655c1b
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output_formats.go
@@ -0,0 +1,57 @@
+package config
+
+type Formats struct {
+ Text Text `mapstructure:"text"`
+ JSON SimpleFormat `mapstructure:"json"`
+ Tab Tab `mapstructure:"tab"`
+ HTML SimpleFormat `mapstructure:"html"`
+ Checkstyle SimpleFormat `mapstructure:"checkstyle"`
+ CodeClimate SimpleFormat `mapstructure:"code-climate"`
+ JUnitXML JUnitXML `mapstructure:"junit-xml"`
+ TeamCity SimpleFormat `mapstructure:"teamcity"`
+ Sarif SimpleFormat `mapstructure:"sarif"`
+}
+
+func (f *Formats) IsEmpty() bool {
+ formats := []SimpleFormat{
+ f.Text.SimpleFormat,
+ f.JSON,
+ f.Tab.SimpleFormat,
+ f.HTML,
+ f.Checkstyle,
+ f.CodeClimate,
+ f.JUnitXML.SimpleFormat,
+ f.TeamCity,
+ f.Sarif,
+ }
+
+ for _, format := range formats {
+ if format.Path != "" {
+ return false
+ }
+ }
+
+ return true
+}
+
+type SimpleFormat struct {
+ Path string `mapstructure:"path"`
+}
+
+type Text struct {
+ SimpleFormat `mapstructure:",squash"`
+ PrintLinterName bool `mapstructure:"print-linter-name"`
+ PrintIssuedLine bool `mapstructure:"print-issued-lines"`
+ Colors bool `mapstructure:"colors"`
+}
+
+type Tab struct {
+ SimpleFormat `mapstructure:",squash"`
+ PrintLinterName bool `mapstructure:"print-linter-name"`
+ Colors bool `mapstructure:"colors"`
+}
+
+type JUnitXML struct {
+ SimpleFormat `mapstructure:",squash"`
+ Extended bool `mapstructure:"extended"`
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/placeholders.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/placeholders.go
new file mode 100644
index 00000000..b3f35f7b
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/placeholders.go
@@ -0,0 +1,18 @@
+package config
+
+import "strings"
+
+const (
+ // placeholderBasePath used inside linters to evaluate relative paths.
+ placeholderBasePath = "${base-path}"
+
+ // placeholderConfigPath used inside linters to paths relative to configuration.
+ placeholderConfigPath = "${config-path}"
+)
+
+func NewPlaceholderReplacer(cfg *Config) *strings.Replacer {
+ return strings.NewReplacer(
+ placeholderBasePath, cfg.GetBasePath(),
+ placeholderConfigPath, cfg.GetConfigDir(),
+ )
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/run.go
similarity index 74%
rename from vendor/github.com/golangci/golangci-lint/pkg/config/run.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/config/run.go
index 8e00f1e6..dcddf0cb 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/config/run.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/run.go
@@ -6,7 +6,7 @@ import (
"strings"
"time"
- "github.com/golangci/golangci-lint/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
)
// Run encapsulates the config options for running the linter analysis.
@@ -27,16 +27,6 @@ type Run struct {
AllowParallelRunners bool `mapstructure:"allow-parallel-runners"`
AllowSerialRunners bool `mapstructure:"allow-serial-runners"`
-
- // Deprecated: use Issues.ExcludeFiles instead.
- SkipFiles []string `mapstructure:"skip-files"`
- // Deprecated: use Issues.ExcludeDirs instead.
- SkipDirs []string `mapstructure:"skip-dirs"`
- // Deprecated: use Issues.UseDefaultExcludeDirs instead.
- UseDefaultSkipDirs *bool `mapstructure:"skip-dirs-use-default"`
-
- // Deprecated: use Output.ShowStats instead.
- ShowStats *bool `mapstructure:"show-stats"`
}
func (r *Run) Validate() error {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/severity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/severity.go
similarity index 77%
rename from vendor/github.com/golangci/golangci-lint/pkg/config/severity.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/config/severity.go
index a6d2c9ec..f41e17b1 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/config/severity.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/severity.go
@@ -8,9 +8,8 @@ import (
const severityRuleMinConditionsCount = 1
type Severity struct {
- Default string `mapstructure:"default-severity"`
- CaseSensitive bool `mapstructure:"case-sensitive"`
- Rules []SeverityRule `mapstructure:"rules"`
+ Default string `mapstructure:"default"`
+ Rules []SeverityRule `mapstructure:"rules"`
}
func (s *Severity) Validate() error {
@@ -29,7 +28,7 @@ func (s *Severity) Validate() error {
type SeverityRule struct {
BaseRule `mapstructure:",squash"`
- Severity string
+ Severity string `mapstructure:"severity"`
}
func (s *SeverityRule) Validate() error {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/exitcodes/exitcodes.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/exitcodes/exitcodes.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/exitcodes/exitcodes.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/exitcodes/exitcodes.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/basepath.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/basepath.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/fsutils/basepath.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/basepath.go
index 97d6aced..3761fa0e 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/basepath.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/basepath.go
@@ -2,8 +2,8 @@ package fsutils
import (
"bytes"
+ "cmp"
"context"
- "errors"
"fmt"
"os/exec"
"path/filepath"
@@ -19,15 +19,15 @@ const (
RelativePathModeWd = "wd"
)
+// OutputPathModeAbsolute path mode used to show absolute paths in output reports (user-facing).
+const OutputPathModeAbsolute = "abs"
+
func AllRelativePathModes() []string {
return []string{RelativePathModeGoMod, RelativePathModeGitRoot, RelativePathModeCfg, RelativePathModeWd}
}
func GetBasePath(ctx context.Context, mode, cfgDir string) (string, error) {
- if mode == "" {
- // TODO(ldez): v2 the default should be cfg or gomod.
- mode = RelativePathModeWd
- }
+ mode = cmp.Or(mode, RelativePathModeCfg)
switch mode {
case RelativePathModeCfg:
@@ -62,7 +62,7 @@ func GetBasePath(ctx context.Context, mode, cfgDir string) (string, error) {
return wd, nil
default:
- return "", errors.New("unknown relative path mode")
+ return "", fmt.Errorf("unknown relative path mode: %s", mode)
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/filecache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/filecache.go
similarity index 95%
rename from vendor/github.com/golangci/golangci-lint/pkg/fsutils/filecache.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/filecache.go
index e8e5ba19..e91b5874 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/filecache.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/filecache.go
@@ -5,7 +5,7 @@ import (
"os"
"sync"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type FileCache struct {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/fsutils.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/fsutils/fsutils.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/fsutils_unix.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils_unix.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/fsutils/fsutils_unix.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils_unix.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/fsutils_windows.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils_windows.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/fsutils/fsutils_windows.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils_windows.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/linecache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/linecache.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/fsutils/linecache.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/linecache.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/path_unix.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/path_unix.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/fsutils/path_unix.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/path_unix.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/path_windows.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/path_windows.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/fsutils/path_windows.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/path_windows.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/issue.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/issue.go
similarity index 91%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/issue.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/issue.go
index 854e7d15..c4170259 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/issue.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/issue.go
@@ -5,7 +5,7 @@ import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
type Issue struct {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/linter.go
similarity index 97%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/linter.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/linter.go
index 13d3a09a..80ccfe45 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/linter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/linter.go
@@ -9,8 +9,8 @@ import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const (
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/load/guard.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/load/guard.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/load/guard.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/load/guard.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/metalinter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/metalinter.go
similarity index 94%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/metalinter.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/metalinter.go
index c2a79499..4db143ba 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/metalinter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/metalinter.go
@@ -6,8 +6,8 @@ import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
type MetaLinter struct {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/errors.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/errors.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/errors.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/errors.go
index 7da659e8..587e7272 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/errors.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/errors.go
@@ -6,8 +6,8 @@ import (
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
type IllTypedError struct {
@@ -15,7 +15,7 @@ type IllTypedError struct {
}
func (e *IllTypedError) Error() string {
- return fmt.Sprintf("errors in package: %v", e.Pkg.Errors)
+ return fmt.Sprintf("IllTypedError: errors in package: %v", e.Pkg.Errors)
}
func BuildIssuesFromIllTypedError(errs []error, lintCtx *linter.Context) ([]result.Issue, error) {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/extract.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/extract.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/extract.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/extract.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/parse.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/parse.go
similarity index 95%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/parse.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/parse.go
index b25b50f7..8c49a559 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/parse.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/parse.go
@@ -9,7 +9,7 @@ import (
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
func parseError(srcErr packages.Error) (*result.Issue, error) {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/position.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/position.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/position.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/position.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner.go
similarity index 97%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner.go
index 7cff0149..808c9d2a 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner.go
@@ -16,11 +16,11 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/internal/cache"
- "github.com/golangci/golangci-lint/internal/errorutil"
- "github.com/golangci/golangci-lint/pkg/goanalysis/load"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/timeutils"
+ "github.com/golangci/golangci-lint/v2/internal/cache"
+ "github.com/golangci/golangci-lint/v2/internal/errorutil"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/timeutils"
)
var (
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_action.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go
similarity index 97%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_action.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go
index 2e1c4142..2c332d83 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_action.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go
@@ -4,7 +4,7 @@ import (
"fmt"
"runtime/debug"
- "github.com/golangci/golangci-lint/internal/errorutil"
+ "github.com/golangci/golangci-lint/v2/internal/errorutil"
)
type actionAllocator struct {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_action_cache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action_cache.go
similarity index 98%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_action_cache.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action_cache.go
index e06ea297..2cf4dcfc 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_action_cache.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action_cache.go
@@ -8,7 +8,7 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/types/objectpath"
- "github.com/golangci/golangci-lint/internal/cache"
+ "github.com/golangci/golangci-lint/v2/internal/cache"
)
type Fact struct {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_checker.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go
similarity index 98%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_checker.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go
index 376a37f0..569002ed 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_checker.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go
@@ -18,9 +18,9 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/internal/x/tools/analysisflags"
- "github.com/golangci/golangci-lint/internal/x/tools/analysisinternal"
- "github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors"
+ "github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags"
+ "github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors"
)
// NOTE(ldez) altered: custom fields; remove 'once' and 'duration'.
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_loadingpackage.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go
similarity index 95%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_loadingpackage.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go
index fca4b8c3..d22dbea3 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_loadingpackage.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go
@@ -17,13 +17,16 @@ import (
"golang.org/x/tools/go/gcexportdata"
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/pkg/goanalysis/load"
- "github.com/golangci/golangci-lint/pkg/goutil"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load"
+ "github.com/golangci/golangci-lint/v2/pkg/goutil"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
const unsafePkgName = "unsafe"
+// https://github.com/golang/go/blob/go1.23.8/src/internal/types/errors/codes.go#L1484
+const tooNew = 151
+
type loadingPackage struct {
pkg *packages.Package
imports map[string]*loadingPackage
@@ -436,6 +439,14 @@ func (lp *loadingPackage) convertError(err error) []packages.Error {
case types.Error:
// from type checker
+
+ // https://github.com/golang/go/blob/go1.23.8/src/go/types/api.go#L52-L57
+ if int(reflect.ValueOf(err).FieldByName("go116code").Int()) == tooNew {
+ // https://github.com/golang/go/blob/go1.23.8/src/go/types/check.go#L380
+ // https://github.com/golang/go/blob/go1.23.8/src/go/types/check.go#L349
+ panic(err.Msg)
+ }
+
errs = append(errs, packages.Error{
Pos: err.Fset.Position(err.Pos).String(),
Msg: err.Msg,
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runners.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runners.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners.go
index 3a9a35de..fe8d8fe8 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runners.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners.go
@@ -8,11 +8,11 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
- "github.com/golangci/golangci-lint/pkg/timeutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/timeutils"
)
type runAnalyzersConfig interface {
@@ -136,10 +136,16 @@ func buildIssues(diags []Diagnostic, linterNameBuilder func(diag *Diagnostic) st
if len(diag.Related) > 0 {
for _, info := range diag.Related {
+ relatedPos := diag.Pkg.Fset.Position(info.Pos)
+
+ if relatedPos.Filename != diag.Position.Filename {
+ relatedPos = diag.Position
+ }
+
issues = append(issues, result.Issue{
FromLinter: linterName,
Text: fmt.Sprintf("%s(related information): %s", diag.Analyzer.Name, info.Message),
- Pos: diag.Pkg.Fset.Position(info.Pos),
+ Pos: relatedPos,
Pkg: diag.Pkg,
})
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runners_cache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go
similarity index 96%
rename from vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runners_cache.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go
index 4366155b..9673197c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runners_cache.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go
@@ -11,9 +11,9 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/internal/cache"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/internal/cache"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
func saveIssuesToCache(allPkgs []*packages.Package, pkgsFromCache map[*packages.Package]bool,
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformat/runner.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformat/runner.go
new file mode 100644
index 00000000..fa1d1acc
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformat/runner.go
@@ -0,0 +1,258 @@
+package goformat
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "io"
+ "io/fs"
+ "log"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+
+ "github.com/alecthomas/chroma/v2/quick"
+ rpdiff "github.com/rogpeppe/go-internal/diff"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result/processors"
+)
+
+type Runner struct {
+ log logutils.Log
+
+ metaFormatter *goformatters.MetaFormatter
+ matcher *processors.GeneratedFileMatcher
+
+ opts RunnerOptions
+
+ exitCode int
+}
+
+func NewRunner(logger logutils.Log,
+ metaFormatter *goformatters.MetaFormatter, matcher *processors.GeneratedFileMatcher,
+ opts RunnerOptions) *Runner {
+ return &Runner{
+ log: logger,
+ matcher: matcher,
+ metaFormatter: metaFormatter,
+ opts: opts,
+ }
+}
+
+func (c *Runner) Run(paths []string) error {
+ savedStdout, savedStderr := os.Stdout, os.Stderr
+
+ if !logutils.HaveDebugTag(logutils.DebugKeyFormattersOutput) {
+ // Don't allow linters and loader to print anything
+ log.SetOutput(io.Discard)
+ c.setOutputToDevNull()
+ defer func() {
+ os.Stdout, os.Stderr = savedStdout, savedStderr
+ }()
+ }
+
+ if c.opts.stdin {
+ return c.process("", savedStdout, os.Stdin)
+ }
+
+ for _, path := range paths {
+ err := c.walk(path, savedStdout)
+ if err != nil {
+ return err
+ }
+ }
+
+ for pattern, count := range c.opts.excludedPathCounter {
+ if c.opts.warnUnused && count == 0 {
+ c.log.Warnf("The pattern %q match no issues", pattern)
+ } else {
+ c.log.Infof("Skipped %d issues by pattern %q", count, pattern)
+ }
+ }
+
+ return nil
+}
+
+func (c *Runner) walk(root string, stdout *os.File) error {
+ return filepath.Walk(root, func(path string, f fs.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+
+ if f.IsDir() && skipDir(f.Name()) {
+ return fs.SkipDir
+ }
+
+ if !isGoFile(f) {
+ return nil
+ }
+
+ match, err := c.opts.MatchAnyPattern(path)
+ if err != nil || match {
+ return err
+ }
+
+ in, err := os.Open(path)
+ if err != nil {
+ return err
+ }
+
+ defer func() { _ = in.Close() }()
+
+ return c.process(path, stdout, in)
+ })
+}
+
+func (c *Runner) process(path string, stdout io.Writer, in io.Reader) error {
+ input, err := io.ReadAll(in)
+ if err != nil {
+ return err
+ }
+
+ match, err := c.matcher.IsGeneratedFile(path, input)
+ if err != nil || match {
+ return err
+ }
+
+ output := c.metaFormatter.Format(path, input)
+
+ if c.opts.stdin {
+ _, err = stdout.Write(output)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ }
+
+ if bytes.Equal(input, output) {
+ return nil
+ }
+
+ if c.opts.diff {
+ newName := filepath.ToSlash(path)
+ oldName := newName + ".orig"
+
+ patch := rpdiff.Diff(oldName, input, newName, output)
+
+ if c.opts.colors {
+ err = quick.Highlight(stdout, string(patch), "diff", "terminal", "native")
+ if err != nil {
+ return err
+ }
+ } else {
+ _, err = stdout.Write(patch)
+ if err != nil {
+ return err
+ }
+ }
+
+ c.exitCode = 1
+
+ return nil
+ }
+
+ c.log.Infof("format: %s", path)
+
+ // On Windows, we need to re-set the permissions from the file. See golang/go#38225.
+ var perms os.FileMode
+ if fi, err := os.Stat(path); err == nil {
+ perms = fi.Mode() & os.ModePerm
+ }
+
+ return os.WriteFile(path, output, perms)
+}
+
+func (c *Runner) setOutputToDevNull() {
+ devNull, err := os.Open(os.DevNull)
+ if err != nil {
+ c.log.Warnf("Can't open null device %q: %s", os.DevNull, err)
+ return
+ }
+
+ os.Stdout, os.Stderr = devNull, devNull
+}
+
+func (c *Runner) ExitCode() int {
+ return c.exitCode
+}
+
+type RunnerOptions struct {
+ basePath string
+ patterns []*regexp.Regexp
+ generated string
+ diff bool
+ colors bool
+ stdin bool
+
+ warnUnused bool
+ excludedPathCounter map[*regexp.Regexp]int
+}
+
+func NewRunnerOptions(cfg *config.Config, diff, diffColored, stdin bool) (RunnerOptions, error) {
+ basePath, err := fsutils.GetBasePath(context.Background(), cfg.Run.RelativePathMode, cfg.GetConfigDir())
+ if err != nil {
+ return RunnerOptions{}, fmt.Errorf("get base path: %w", err)
+ }
+
+ opts := RunnerOptions{
+ basePath: basePath,
+ generated: cfg.Formatters.Exclusions.Generated,
+ diff: diff || diffColored,
+ colors: diffColored,
+ stdin: stdin,
+ excludedPathCounter: make(map[*regexp.Regexp]int),
+ warnUnused: cfg.Formatters.Exclusions.WarnUnused,
+ }
+
+ for _, pattern := range cfg.Formatters.Exclusions.Paths {
+ exp, err := regexp.Compile(fsutils.NormalizePathInRegex(pattern))
+ if err != nil {
+ return RunnerOptions{}, fmt.Errorf("compile path pattern %q: %w", pattern, err)
+ }
+
+ opts.patterns = append(opts.patterns, exp)
+ opts.excludedPathCounter[exp] = 0
+ }
+
+ return opts, nil
+}
+
+func (o RunnerOptions) MatchAnyPattern(path string) (bool, error) {
+ if len(o.patterns) == 0 {
+ return false, nil
+ }
+
+ rel, err := filepath.Rel(o.basePath, path)
+ if err != nil {
+ return false, err
+ }
+
+ for _, pattern := range o.patterns {
+ if pattern.MatchString(rel) {
+ o.excludedPathCounter[pattern]++
+ return true, nil
+ }
+ }
+
+ return false, nil
+}
+
+func skipDir(name string) bool {
+ switch name {
+ case "vendor", "testdata", "node_modules":
+ return true
+
+ default:
+ return strings.HasPrefix(name, ".")
+ }
+}
+
+func isGoFile(f fs.FileInfo) bool {
+ return !f.IsDir() && !strings.HasPrefix(f.Name(), ".") && strings.HasSuffix(f.Name(), ".go")
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/analyzer.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/analyzer.go
similarity index 88%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/analyzer.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/analyzer.go
index c0ea66e7..d6d92d5b 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/analyzer.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/analyzer.go
@@ -9,9 +9,9 @@ import (
"github.com/rogpeppe/go-internal/diff"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/goformatters/internal"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
// NewAnalyzer converts a [Formatter] to an [analysis.Analyzer].
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/formatters.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/formatters.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/formatters.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/gci.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/gci.go
similarity index 75%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/gci.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/gci.go
index f28b5b98..3eba10f1 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/gci.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/gci.go
@@ -2,16 +2,15 @@ package gci
import (
"context"
- "fmt"
gcicfg "github.com/daixiang0/gci/pkg/config"
"github.com/daixiang0/gci/pkg/gci"
"github.com/daixiang0/gci/pkg/log"
"github.com/ldez/grignotin/gomod"
- "github.com/golangci/golangci-lint/pkg/config"
- gcicfgi "github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/config"
- "github.com/golangci/golangci-lint/pkg/goformatters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ gcicfgi "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/internal"
)
const Name = "gci"
@@ -33,22 +32,16 @@ func New(settings *config.GciSettings) (*Formatter, error) {
Cfg: gcicfg.BoolConfig{
NoInlineComments: settings.NoInlineComments,
NoPrefixComments: settings.NoPrefixComments,
- SkipGenerated: settings.SkipGenerated,
CustomOrder: settings.CustomOrder,
NoLexOrder: settings.NoLexOrder,
+
+ // Should be managed with `formatters.exclusions.generated`.
+ SkipGenerated: false,
},
SectionStrings: settings.Sections,
ModPath: modPath,
}
- if settings.LocalPrefixes != "" {
- cfg.SectionStrings = []string{
- "standard",
- "default",
- fmt.Sprintf("prefix(%s)", settings.LocalPrefixes),
- }
- }
-
parsedCfg, err := cfg.Parse()
if err != nil {
return nil, err
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/LICENSE b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/LICENSE
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/LICENSE
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/LICENSE
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/config/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/config/config.go
similarity index 96%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/config/config.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/config/config.go
index 8140d96b..c859b442 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/config/config.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/config/config.go
@@ -8,7 +8,8 @@ import (
"github.com/daixiang0/gci/pkg/config"
"github.com/daixiang0/gci/pkg/section"
- sectioni "github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/section"
+
+ sectioni "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section"
)
var defaultOrder = map[string]int{
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/section/parser.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/parser.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/section/parser.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/parser.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/section/section.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/section.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/section/section.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/section.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/section/standard.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/section/standard.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/section/standard_list.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard_list.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/section/standard_list.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard_list.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gofmt/gofmt.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt/gofmt.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/gofmt/gofmt.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt/gofmt.go
index 9005c751..4d5ff863 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gofmt/gofmt.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt/gofmt.go
@@ -3,7 +3,7 @@ package gofmt
import (
"github.com/golangci/gofmt/gofmt"
- "github.com/golangci/golangci-lint/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
)
const Name = "gofmt"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gofumpt/gofumpt.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt/gofumpt.go
similarity index 75%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/gofumpt/gofumpt.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt/gofumpt.go
index 7c548a2a..d8f5f2f7 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/gofumpt/gofumpt.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt/gofumpt.go
@@ -5,7 +5,7 @@ import (
gofumpt "mvdan.cc/gofumpt/format"
- "github.com/golangci/golangci-lint/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
)
const Name = "gofumpt"
@@ -14,7 +14,7 @@ type Formatter struct {
options gofumpt.Options
}
-func New(settings *config.GofumptSettings, goVersion string) *Formatter {
+func New(settings *config.GoFumptSettings, goVersion string) *Formatter {
var options gofumpt.Options
if settings != nil {
@@ -37,10 +37,5 @@ func (f *Formatter) Format(_ string, src []byte) ([]byte, error) {
}
func getLangVersion(v string) string {
- if v == "" {
- // TODO: defaults to "1.15", in the future (v2) must be removed.
- return "go1.15"
- }
-
return "go" + strings.TrimPrefix(v, "go")
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/goimports/goimports.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports/goimports.go
similarity index 78%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/goimports/goimports.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports/goimports.go
index fa0f1fc4..5b7edf2e 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/goimports/goimports.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports/goimports.go
@@ -1,9 +1,11 @@
package goimports
import (
+ "strings"
+
"golang.org/x/tools/imports"
- "github.com/golangci/golangci-lint/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
)
const Name = "goimports"
@@ -12,7 +14,7 @@ type Formatter struct{}
func New(settings *config.GoImportsSettings) *Formatter {
if settings != nil {
- imports.LocalPrefix = settings.LocalPrefixes
+ imports.LocalPrefix = strings.Join(settings.LocalPrefixes, ",")
}
return &Formatter{}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/golines/golines.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/golines/golines.go
new file mode 100644
index 00000000..ffd5b5f8
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/golines/golines.go
@@ -0,0 +1,41 @@
+package golines
+
+import (
+ "github.com/golangci/golines"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+)
+
+const Name = "golines"
+
+type Formatter struct {
+ shortener *golines.Shortener
+}
+
+func New(settings *config.GoLinesSettings) *Formatter {
+ options := golines.ShortenerConfig{}
+
+ if settings != nil {
+ options = golines.ShortenerConfig{
+ MaxLen: settings.MaxLen,
+ TabLen: settings.TabLen,
+ KeepAnnotations: false, // golines debug (not usable inside golangci-lint)
+ ShortenComments: settings.ShortenComments,
+ ReformatTags: settings.ReformatTags,
+ IgnoreGenerated: false, // handle globally
+ DotFile: "", // golines debug (not usable inside golangci-lint)
+ ChainSplitDots: settings.ChainSplitDots,
+ BaseFormatterCmd: "go fmt", // fake cmd
+ }
+ }
+
+ return &Formatter{shortener: golines.NewShortener(options)}
+}
+
+func (*Formatter) Name() string {
+ return Name
+}
+
+func (f *Formatter) Format(_ string, src []byte) ([]byte, error) {
+ return f.shortener.Shorten(src)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/internal/commons.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/commons.go
similarity index 74%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/internal/commons.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/commons.go
index 5320e786..f18819e2 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/internal/commons.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/commons.go
@@ -1,6 +1,6 @@
package internal
-import "github.com/golangci/golangci-lint/pkg/logutils"
+import "github.com/golangci/golangci-lint/v2/pkg/logutils"
// FormatterLogger must be used only when the context logger is not available.
var FormatterLogger = logutils.NewStderrLog(logutils.DebugKeyFormatter)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/internal/diff.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/diff.go
similarity index 98%
rename from vendor/github.com/golangci/golangci-lint/pkg/goformatters/internal/diff.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/diff.go
index 75d65b73..7b9f80bc 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goformatters/internal/diff.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/diff.go
@@ -11,8 +11,8 @@ import (
diffpkg "github.com/sourcegraph/go-diff/diff"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type Change struct {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/meta_formatter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/meta_formatter.go
new file mode 100644
index 00000000..718caaa9
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/meta_formatter.go
@@ -0,0 +1,90 @@
+package goformatters
+
+import (
+ "bytes"
+ "fmt"
+ "go/format"
+ "slices"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/golines"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+)
+
+type MetaFormatter struct {
+ log logutils.Log
+ formatters []Formatter
+}
+
+func NewMetaFormatter(log logutils.Log, cfg *config.Formatters, runCfg *config.Run) (*MetaFormatter, error) {
+ for _, formatter := range cfg.Enable {
+ if !IsFormatter(formatter) {
+ return nil, fmt.Errorf("invalid formatter %q", formatter)
+ }
+ }
+
+ m := &MetaFormatter{log: log}
+
+ if slices.Contains(cfg.Enable, gofmt.Name) {
+ m.formatters = append(m.formatters, gofmt.New(&cfg.Settings.GoFmt))
+ }
+
+ if slices.Contains(cfg.Enable, gofumpt.Name) {
+ m.formatters = append(m.formatters, gofumpt.New(&cfg.Settings.GoFumpt, runCfg.Go))
+ }
+
+ if slices.Contains(cfg.Enable, goimports.Name) {
+ m.formatters = append(m.formatters, goimports.New(&cfg.Settings.GoImports))
+ }
+
+ // gci is a last because the only goal of gci is to handle imports.
+ if slices.Contains(cfg.Enable, gci.Name) {
+ formatter, err := gci.New(&cfg.Settings.Gci)
+ if err != nil {
+ return nil, fmt.Errorf("gci: creating formatter: %w", err)
+ }
+
+ m.formatters = append(m.formatters, formatter)
+ }
+
+ // golines calls `format.Source()` internally so no need to format after it.
+ if slices.Contains(cfg.Enable, golines.Name) {
+ m.formatters = append(m.formatters, golines.New(&cfg.Settings.GoLines))
+ }
+
+ return m, nil
+}
+
+func (m *MetaFormatter) Format(filename string, src []byte) []byte {
+ if len(m.formatters) == 0 {
+ data, err := format.Source(src)
+ if err != nil {
+ m.log.Warnf("(fmt) formatting file %s: %v", filename, err)
+ return src
+ }
+
+ return data
+ }
+
+ data := bytes.Clone(src)
+
+ for _, formatter := range m.formatters {
+ formatted, err := formatter.Format(filename, data)
+ if err != nil {
+ m.log.Warnf("(%s) formatting file %s: %v", formatter.Name(), filename, err)
+ continue
+ }
+
+ data = formatted
+ }
+
+ return data
+}
+
+func IsFormatter(name string) bool {
+ return slices.Contains([]string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name, golines.Name}, name)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/asasalint/asasalint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asasalint/asasalint.go
similarity index 69%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/asasalint/asasalint.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asasalint/asasalint.go
index ccc58fee..5f33428c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/asasalint/asasalint.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asasalint/asasalint.go
@@ -4,9 +4,9 @@ import (
"github.com/alingse/asasalint"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New(settings *config.AsasalintSettings) *goanalysis.Linter {
@@ -14,7 +14,9 @@ func New(settings *config.AsasalintSettings) *goanalysis.Linter {
if settings != nil {
cfg.Exclude = settings.Exclude
cfg.NoBuiltinExclusions = !settings.UseBuiltinExclusions
- cfg.IgnoreTest = settings.IgnoreTest
+
+ // Should be managed with `linters.exclusions.rules`.
+ cfg.IgnoreTest = false
}
a, err := asasalint.NewAnalyzer(cfg)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/asciicheck/asciicheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asciicheck/asciicheck.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/asciicheck/asciicheck.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asciicheck/asciicheck.go
index 675dfc47..b5cdaa80 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/asciicheck/asciicheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asciicheck/asciicheck.go
@@ -4,7 +4,7 @@ import (
"github.com/tdakkota/asciicheck"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/bidichk/bidichk.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk/bidichk.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/bidichk/bidichk.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk/bidichk.go
index c6315965..2d2a8d66 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/bidichk/bidichk.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk/bidichk.go
@@ -6,8 +6,8 @@ import (
"github.com/breml/bidichk/pkg/bidichk"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.BiDiChkSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/bodyclose/bodyclose.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose/bodyclose.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/bodyclose/bodyclose.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose/bodyclose.go
index c520e88d..0c86fbe7 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/bodyclose/bodyclose.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose/bodyclose.go
@@ -4,7 +4,7 @@ import (
"github.com/timakin/bodyclose/passes/bodyclose"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/canonicalheader/canonicalheader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader/canonicalheader.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/canonicalheader/canonicalheader.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader/canonicalheader.go
index d721916a..bda1dfbd 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/canonicalheader/canonicalheader.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader/canonicalheader.go
@@ -4,7 +4,7 @@ import (
"github.com/lasiar/canonicalheader"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/containedctx/containedctx.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx/containedctx.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/containedctx/containedctx.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx/containedctx.go
index 6fdb4ea6..6bdb0835 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/containedctx/containedctx.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx/containedctx.go
@@ -4,7 +4,7 @@ import (
"github.com/sivchari/containedctx"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/contextcheck/contextcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck/contextcheck.go
similarity index 80%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/contextcheck/contextcheck.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck/contextcheck.go
index a34c518b..9d01fb7a 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/contextcheck/contextcheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck/contextcheck.go
@@ -4,8 +4,8 @@ import (
"github.com/kkHAIKE/contextcheck"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/copyloopvar/copyloopvar.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/copyloopvar/copyloopvar.go
similarity index 82%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/copyloopvar/copyloopvar.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/copyloopvar/copyloopvar.go
index adb4ee72..f6ca96f9 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/copyloopvar/copyloopvar.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/copyloopvar/copyloopvar.go
@@ -4,8 +4,8 @@ import (
"github.com/karamaru-alpha/copyloopvar"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.CopyLoopVarSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/cyclop/cyclop.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/cyclop/cyclop.go
similarity index 69%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/cyclop/cyclop.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/cyclop/cyclop.go
index 772b5601..41db272c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/cyclop/cyclop.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/cyclop/cyclop.go
@@ -4,17 +4,18 @@ import (
"github.com/bkielbasa/cyclop/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
-func New(settings *config.Cyclop) *goanalysis.Linter {
+func New(settings *config.CyclopSettings) *goanalysis.Linter {
a := analyzer.NewAnalyzer()
var cfg map[string]map[string]any
if settings != nil {
d := map[string]any{
- "skipTests": settings.SkipTests,
+ // Should be managed with `linters.exclusions.rules`.
+ "skipTests": false,
}
if settings.MaxComplexity != 0 {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/decorder/decorder.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/decorder/decorder.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/decorder/decorder.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/decorder/decorder.go
index a05f6a32..03a7853c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/decorder/decorder.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/decorder/decorder.go
@@ -6,8 +6,8 @@ import (
"gitlab.com/bosi/decorder"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.DecorderSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/depguard/depguard.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/depguard/depguard.go
similarity index 73%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/depguard/depguard.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/depguard/depguard.go
index 19440599..c1f66b0c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/depguard/depguard.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/depguard/depguard.go
@@ -6,20 +6,19 @@ import (
"github.com/OpenPeeDeeP/depguard/v2"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
)
-func New(settings *config.DepGuardSettings, basePath string) *goanalysis.Linter {
+func New(settings *config.DepGuardSettings, replacer *strings.Replacer) *goanalysis.Linter {
conf := depguard.LinterSettings{}
if settings != nil {
for s, rule := range settings.Rules {
var extendedPatterns []string
for _, file := range rule.Files {
- extendedPatterns = append(extendedPatterns, strings.ReplaceAll(file, internal.PlaceholderBasePath, basePath))
+ extendedPatterns = append(extendedPatterns, replacer.Replace(file))
}
list := &depguard.List{
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dogsled/dogsled.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dogsled/dogsled.go
similarity index 93%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/dogsled/dogsled.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dogsled/dogsled.go
index afa8152f..23d48ba5 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dogsled/dogsled.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dogsled/dogsled.go
@@ -7,8 +7,8 @@ import (
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
const linterName = "dogsled"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dupl/dupl.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupl/dupl.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/dupl/dupl.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupl/dupl.go
index 6d1a9809..993bfd6f 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dupl/dupl.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupl/dupl.go
@@ -8,12 +8,12 @@ import (
duplAPI "github.com/golangci/dupl/lib"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "dupl"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dupword/dupword.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupword/dupword.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/dupword/dupword.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupword/dupword.go
index a2bcc34d..62851475 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dupword/dupword.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupword/dupword.go
@@ -6,8 +6,8 @@ import (
"github.com/Abirdcfly/dupword"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.DupWordSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/durationcheck/durationcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/durationcheck/durationcheck.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/durationcheck/durationcheck.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/durationcheck/durationcheck.go
index 88f22c27..d3e74231 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/durationcheck/durationcheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/durationcheck/durationcheck.go
@@ -4,7 +4,7 @@ import (
"github.com/charithe/durationcheck"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/err113/err113.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/err113/err113.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/err113/err113.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/err113/err113.go
index 2600128b..78ef99d6 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/err113/err113.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/err113/err113.go
@@ -4,7 +4,7 @@ import (
"github.com/Djarvur/go-err113"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errcheck/errcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errcheck/errcheck.go
new file mode 100644
index 00000000..56d00c35
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errcheck/errcheck.go
@@ -0,0 +1,113 @@
+package errcheck
+
+import (
+ "cmp"
+ "fmt"
+ "regexp"
+ "sync"
+
+ "github.com/kisielk/errcheck/errcheck"
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/packages"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+)
+
+const linterName = "errcheck"
+
+func New(settings *config.ErrcheckSettings) *goanalysis.Linter {
+ var mu sync.Mutex
+ var resIssues []goanalysis.Issue
+
+ analyzer := &analysis.Analyzer{
+ Name: linterName,
+ Doc: goanalysis.TheOnlyanalyzerDoc,
+ Run: goanalysis.DummyRun,
+ }
+
+ return goanalysis.NewLinter(
+ linterName,
+ "errcheck is a program for checking for unchecked errors in Go code. "+
+ "These unchecked errors can be critical bugs in some cases",
+ []*analysis.Analyzer{analyzer},
+ nil,
+ ).WithContextSetter(func(lintCtx *linter.Context) {
+ checker := getChecker(settings)
+ checker.Tags = lintCtx.Cfg.Run.BuildTags
+
+ analyzer.Run = func(pass *analysis.Pass) (any, error) {
+ issues := runErrCheck(lintCtx, pass, checker)
+
+ if len(issues) == 0 {
+ return nil, nil
+ }
+
+ mu.Lock()
+ resIssues = append(resIssues, issues...)
+ mu.Unlock()
+
+ return nil, nil
+ }
+ }).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
+ return resIssues
+ }).WithLoadMode(goanalysis.LoadModeTypesInfo)
+}
+
+func runErrCheck(lintCtx *linter.Context, pass *analysis.Pass, checker *errcheck.Checker) []goanalysis.Issue {
+ pkg := &packages.Package{
+ Fset: pass.Fset,
+ Syntax: pass.Files,
+ Types: pass.Pkg,
+ TypesInfo: pass.TypesInfo,
+ }
+
+ lintIssues := checker.CheckPackage(pkg).Unique()
+ if len(lintIssues.UncheckedErrors) == 0 {
+ return nil
+ }
+
+ issues := make([]goanalysis.Issue, len(lintIssues.UncheckedErrors))
+
+ for i, err := range lintIssues.UncheckedErrors {
+ text := "Error return value is not checked"
+
+ if err.FuncName != "" {
+ code := cmp.Or(err.SelectorName, err.FuncName)
+
+ text = fmt.Sprintf("Error return value of %s is not checked", internal.FormatCode(code, lintCtx.Cfg))
+ }
+
+ issues[i] = goanalysis.NewIssue(
+ &result.Issue{
+ FromLinter: linterName,
+ Text: text,
+ Pos: err.Pos,
+ },
+ pass,
+ )
+ }
+
+ return issues
+}
+
+func getChecker(errCfg *config.ErrcheckSettings) *errcheck.Checker {
+ checker := errcheck.Checker{
+ Exclusions: errcheck.Exclusions{
+ BlankAssignments: !errCfg.CheckAssignToBlank,
+ TypeAssertions: !errCfg.CheckTypeAssertions,
+ SymbolRegexpsByPackage: map[string]*regexp.Regexp{},
+ },
+ }
+
+ if !errCfg.DisableDefaultExclusions {
+ checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, errcheck.DefaultExcludedSymbols...)
+ }
+
+ checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, errCfg.ExcludeFunctions...)
+
+ return &checker
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errchkjson/errchkjson.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errchkjson/errchkjson.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/errchkjson/errchkjson.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errchkjson/errchkjson.go
index 506113d6..a705406e 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errchkjson/errchkjson.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errchkjson/errchkjson.go
@@ -4,8 +4,8 @@ import (
"github.com/breml/errchkjson"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.ErrChkJSONSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errname/errname.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errname/errname.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/errname/errname.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errname/errname.go
index f868854c..36d6f123 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errname/errname.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errname/errname.go
@@ -4,7 +4,7 @@ import (
"github.com/Antonboom/errname/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errorlint/errorlint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errorlint/errorlint.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/errorlint/errorlint.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errorlint/errorlint.go
index 14851adc..7560bc0a 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errorlint/errorlint.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errorlint/errorlint.go
@@ -4,8 +4,8 @@ import (
"github.com/polyfloyd/go-errorlint/errorlint"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.ErrorLintSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustive/exhaustive.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustive/exhaustive.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustive/exhaustive.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustive/exhaustive.go
index 9249efb6..be77e54a 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustive/exhaustive.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustive/exhaustive.go
@@ -4,8 +4,8 @@ import (
"github.com/nishanths/exhaustive"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.ExhaustiveSettings) *goanalysis.Linter {
@@ -16,7 +16,6 @@ func New(settings *config.ExhaustiveSettings) *goanalysis.Linter {
cfg = map[string]map[string]any{
a.Name: {
exhaustive.CheckFlag: settings.Check,
- exhaustive.CheckGeneratedFlag: settings.CheckGenerated,
exhaustive.DefaultSignifiesExhaustiveFlag: settings.DefaultSignifiesExhaustive,
exhaustive.IgnoreEnumMembersFlag: settings.IgnoreEnumMembers,
exhaustive.IgnoreEnumTypesFlag: settings.IgnoreEnumTypes,
@@ -24,6 +23,8 @@ func New(settings *config.ExhaustiveSettings) *goanalysis.Linter {
exhaustive.ExplicitExhaustiveMapFlag: settings.ExplicitExhaustiveMap,
exhaustive.ExplicitExhaustiveSwitchFlag: settings.ExplicitExhaustiveSwitch,
exhaustive.DefaultCaseRequiredFlag: settings.DefaultCaseRequired,
+ // Should be managed with `linters.exclusions.generated`.
+ exhaustive.CheckGeneratedFlag: true,
},
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustruct/exhaustruct.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustruct/exhaustruct.go
similarity index 77%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustruct/exhaustruct.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustruct/exhaustruct.go
index 53ad8715..9b742129 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustruct/exhaustruct.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustruct/exhaustruct.go
@@ -4,9 +4,9 @@ import (
"github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New(settings *config.ExhaustructSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exptostd/exptostd.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exptostd/exptostd.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/exptostd/exptostd.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exptostd/exptostd.go
index 2de8ea98..731a4a0c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exptostd/exptostd.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exptostd/exptostd.go
@@ -4,7 +4,7 @@ import (
"github.com/ldez/exptostd"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/fatcontext/fatcontext.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/fatcontext/fatcontext.go
similarity index 75%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/fatcontext/fatcontext.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/fatcontext/fatcontext.go
index 2ffacacd..e0506259 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/fatcontext/fatcontext.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/fatcontext/fatcontext.go
@@ -1,11 +1,11 @@
package fatcontext
import (
- "github.com/Crocmagnon/fatcontext/pkg/analyzer"
+ "go.augendre.info/fatcontext/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.FatcontextSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/forbidigo/forbidigo.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forbidigo/forbidigo.go
similarity index 90%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/forbidigo/forbidigo.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forbidigo/forbidigo.go
index 3b410359..45f9088f 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/forbidigo/forbidigo.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forbidigo/forbidigo.go
@@ -5,10 +5,11 @@ import (
"github.com/ashanbrown/forbidigo/forbidigo"
"golang.org/x/tools/go/analysis"
+ "gopkg.in/yaml.v3"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
const linterName = "forbidigo"
@@ -49,7 +50,7 @@ func runForbidigo(pass *analysis.Pass, settings *config.ForbidigoSettings) error
// Convert patterns back to strings because that is what NewLinter accepts.
var patterns []string
for _, pattern := range settings.Forbid {
- buffer, err := pattern.MarshalString()
+ buffer, err := yaml.Marshal(pattern)
if err != nil {
return err
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/forcetypeassert/forcetypeassert.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forcetypeassert/forcetypeassert.go
similarity index 86%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/forcetypeassert/forcetypeassert.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forcetypeassert/forcetypeassert.go
index 98abad7e..e8235538 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/forcetypeassert/forcetypeassert.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forcetypeassert/forcetypeassert.go
@@ -4,7 +4,7 @@ import (
"github.com/gostaticanalysis/forcetypeassert"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funcorder/funcorder.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funcorder/funcorder.go
new file mode 100644
index 00000000..7b8e9689
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funcorder/funcorder.go
@@ -0,0 +1,29 @@
+package funcorder
+
+import (
+ "github.com/manuelarte/funcorder/analyzer"
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+)
+
+func New(settings *config.FuncOrderSettings) *goanalysis.Linter {
+ a := analyzer.NewAnalyzer()
+
+ cfg := map[string]map[string]any{}
+
+ if settings != nil {
+ cfg[a.Name] = map[string]any{
+ analyzer.ConstructorCheckName: settings.Constructor,
+ analyzer.StructMethodCheckName: settings.StructMethod,
+ }
+ }
+
+ return goanalysis.NewLinter(
+ a.Name,
+ a.Doc,
+ []*analysis.Analyzer{a},
+ cfg,
+ ).WithLoadMode(goanalysis.LoadModeSyntax)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/funlen/funlen.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funlen/funlen.go
similarity index 78%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/funlen/funlen.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funlen/funlen.go
index bdadcece..541d4fd3 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/funlen/funlen.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funlen/funlen.go
@@ -4,8 +4,8 @@ import (
"github.com/ultraware/funlen"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
type Config struct {
@@ -19,7 +19,7 @@ func New(settings *config.FunlenSettings) *goanalysis.Linter {
if settings != nil {
cfg.lineLimit = settings.Lines
cfg.stmtLimit = settings.Statements
- cfg.ignoreComments = !settings.IgnoreComments
+ cfg.ignoreComments = settings.IgnoreComments
}
a := funlen.NewAnalyzer(cfg.lineLimit, cfg.stmtLimit, cfg.ignoreComments)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gci/gci.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gci/gci.go
similarity index 66%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gci/gci.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gci/gci.go
index b79f1a37..627a4e68 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gci/gci.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gci/gci.go
@@ -3,11 +3,11 @@ package gci
import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/goformatters"
- gcibase "github.com/golangci/golangci-lint/pkg/goformatters/gci"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ gcibase "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
const linterName = "gci"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ginkgolinter/ginkgolinter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ginkgolinter/ginkgolinter.go
similarity index 91%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/ginkgolinter/ginkgolinter.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ginkgolinter/ginkgolinter.go
index 6826b77b..f4521cda 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ginkgolinter/ginkgolinter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ginkgolinter/ginkgolinter.go
@@ -5,8 +5,8 @@ import (
"github.com/nunnatsa/ginkgolinter/types"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.GinkgoLinterSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go
similarity index 86%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go
index be604d80..97534848 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go
@@ -4,7 +4,7 @@ import (
"4d63.com/gocheckcompilerdirectives/checkcompilerdirectives"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoglobals/gochecknoglobals.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoglobals/gochecknoglobals.go
similarity index 86%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoglobals/gochecknoglobals.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoglobals/gochecknoglobals.go
index e893dfcb..8d850a2d 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoglobals/gochecknoglobals.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoglobals/gochecknoglobals.go
@@ -4,7 +4,7 @@ import (
"4d63.com/gochecknoglobals/checknoglobals"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoinits/gochecknoinits.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoinits/gochecknoinits.go
similarity index 90%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoinits/gochecknoinits.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoinits/gochecknoinits.go
index 510a06c9..b5fa6f0d 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoinits/gochecknoinits.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoinits/gochecknoinits.go
@@ -7,8 +7,8 @@ import (
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
const linterName = "gochecknoinits"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecksumtype/gochecksumtype.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecksumtype/gochecksumtype.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecksumtype/gochecksumtype.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecksumtype/gochecksumtype.go
index cbc58731..78cbd574 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecksumtype/gochecksumtype.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecksumtype/gochecksumtype.go
@@ -8,10 +8,10 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gochecksumtype"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocognit/gocognit.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocognit/gocognit.go
similarity index 86%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gocognit/gocognit.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocognit/gocognit.go
index 5fe0f90f..689a70a1 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocognit/gocognit.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocognit/gocognit.go
@@ -8,11 +8,11 @@ import (
"github.com/uudashr/gocognit"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gocognit"
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goconst/goconst.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goconst/goconst.go
new file mode 100644
index 00000000..f3af6462
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goconst/goconst.go
@@ -0,0 +1,117 @@
+package goconst
+
+import (
+ "fmt"
+ "sync"
+
+ goconstAPI "github.com/jgautheron/goconst"
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+)
+
+const linterName = "goconst"
+
+func New(settings *config.GoConstSettings) *goanalysis.Linter {
+ var mu sync.Mutex
+ var resIssues []goanalysis.Issue
+
+ analyzer := &analysis.Analyzer{
+ Name: linterName,
+ Doc: goanalysis.TheOnlyanalyzerDoc,
+ Run: func(pass *analysis.Pass) (any, error) {
+ issues, err := runGoconst(pass, settings)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(issues) == 0 {
+ return nil, nil
+ }
+
+ mu.Lock()
+ resIssues = append(resIssues, issues...)
+ mu.Unlock()
+
+ return nil, nil
+ },
+ }
+
+ return goanalysis.NewLinter(
+ linterName,
+ "Finds repeated strings that could be replaced by a constant",
+ []*analysis.Analyzer{analyzer},
+ nil,
+ ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
+ return resIssues
+ }).WithLoadMode(goanalysis.LoadModeTypesInfo)
+}
+
+func runGoconst(pass *analysis.Pass, settings *config.GoConstSettings) ([]goanalysis.Issue, error) {
+ cfg := goconstAPI.Config{
+ IgnoreStrings: settings.IgnoreStringValues,
+ MatchWithConstants: settings.MatchWithConstants,
+ MinStringLength: settings.MinStringLen,
+ MinOccurrences: settings.MinOccurrencesCount,
+ ParseNumbers: settings.ParseNumbers,
+ NumberMin: settings.NumberMin,
+ NumberMax: settings.NumberMax,
+ ExcludeTypes: map[goconstAPI.Type]bool{},
+ FindDuplicates: settings.FindDuplicates,
+ EvalConstExpressions: settings.EvalConstExpressions,
+
+ // Should be managed with `linters.exclusions.rules`.
+ IgnoreTests: false,
+ }
+
+ if settings.IgnoreCalls {
+ cfg.ExcludeTypes[goconstAPI.Call] = true
+ }
+
+ lintIssues, err := goconstAPI.Run(pass.Files, pass.Fset, pass.TypesInfo, &cfg)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(lintIssues) == 0 {
+ return nil, nil
+ }
+
+ res := make([]goanalysis.Issue, 0, len(lintIssues))
+ for i := range lintIssues {
+ issue := &lintIssues[i]
+
+ var text string
+
+ switch {
+ case issue.OccurrencesCount > 0:
+ text = fmt.Sprintf("string %s has %d occurrences", internal.FormatCode(issue.Str, nil), issue.OccurrencesCount)
+
+ if issue.MatchingConst == "" {
+ text += ", make it a constant"
+ } else {
+ text += fmt.Sprintf(", but such constant %s already exists", internal.FormatCode(issue.MatchingConst, nil))
+ }
+
+ case issue.DuplicateConst != "":
+ text = fmt.Sprintf("This constant is a duplicate of %s at %s",
+ internal.FormatCode(issue.DuplicateConst, nil),
+ issue.DuplicatePos.String())
+
+ default:
+ continue
+ }
+
+ res = append(res, goanalysis.NewIssue(&result.Issue{
+ Pos: issue.Pos,
+ Text: text,
+ FromLinter: linterName,
+ }, pass))
+ }
+
+ return res, nil
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic.go
new file mode 100644
index 00000000..486303da
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic.go
@@ -0,0 +1,172 @@
+package gocritic
+
+import (
+ "errors"
+ "fmt"
+ "go/ast"
+ "go/types"
+ "runtime"
+ "slices"
+ "strings"
+ "sync"
+
+ "github.com/go-critic/go-critic/checkers"
+ gocriticlinter "github.com/go-critic/go-critic/linter"
+ _ "github.com/quasilyte/go-ruleguard/dsl"
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+)
+
+const linterName = "gocritic"
+
+var (
+ debugf = logutils.Debug(logutils.DebugKeyGoCritic)
+ isDebug = logutils.HaveDebugTag(logutils.DebugKeyGoCritic)
+)
+
+func New(settings *config.GoCriticSettings, replacer *strings.Replacer) *goanalysis.Linter {
+ wrapper := &goCriticWrapper{
+ sizes: types.SizesFor("gc", runtime.GOARCH),
+ }
+
+ analyzer := &analysis.Analyzer{
+ Name: linterName,
+ Doc: goanalysis.TheOnlyanalyzerDoc,
+ Run: func(pass *analysis.Pass) (any, error) {
+ err := wrapper.run(pass)
+ if err != nil {
+ return nil, err
+ }
+
+ return nil, nil
+ },
+ }
+
+ return goanalysis.NewLinter(
+ linterName,
+ `Provides diagnostics that check for bugs, performance and style issues.
+Extensible without recompilation through dynamic rules.
+Dynamic rules are written declaratively with AST patterns, filters, report message and optional suggestion.`,
+ []*analysis.Analyzer{analyzer},
+ nil,
+ ).
+ WithContextSetter(func(context *linter.Context) {
+ wrapper.init(context.Log, settings, replacer)
+ }).
+ WithLoadMode(goanalysis.LoadModeTypesInfo)
+}
+
+type goCriticWrapper struct {
+ settingsWrapper *settingsWrapper
+ sizes types.Sizes
+ once sync.Once
+}
+
+func (w *goCriticWrapper) init(logger logutils.Log, settings *config.GoCriticSettings, replacer *strings.Replacer) {
+ if settings == nil {
+ return
+ }
+
+ w.once.Do(func() {
+ err := checkers.InitEmbeddedRules()
+ if err != nil {
+ logger.Fatalf("%s: %v: setting an explicit GOROOT can fix this problem", linterName, err)
+ }
+ })
+
+ settingsWrapper := newSettingsWrapper(logger, settings, replacer)
+
+ if err := settingsWrapper.Load(); err != nil {
+ logger.Fatalf("%s: invalid settings: %s", linterName, err)
+ }
+
+ w.settingsWrapper = settingsWrapper
+}
+
+func (w *goCriticWrapper) run(pass *analysis.Pass) error {
+ if w.settingsWrapper == nil {
+ return errors.New("the settings wrapper is nil")
+ }
+
+ linterCtx := gocriticlinter.NewContext(pass.Fset, w.sizes)
+
+ linterCtx.SetGoVersion(w.settingsWrapper.Go)
+
+ enabledCheckers, err := w.buildEnabledCheckers(linterCtx)
+ if err != nil {
+ return err
+ }
+
+ linterCtx.SetPackageInfo(pass.TypesInfo, pass.Pkg)
+
+ needFileInfo := slices.ContainsFunc(enabledCheckers, func(c *gocriticlinter.Checker) bool {
+ // Related to https://github.com/go-critic/go-critic/blob/440ff466685b41e67d231a1c4a8f5e093374ee93/checkers/importShadow_checker.go#L23
+ return strings.EqualFold(c.Info.Name, "importShadow")
+ })
+
+ for _, f := range pass.Files {
+ if needFileInfo {
+ // Related to https://github.com/go-critic/go-critic/blob/440ff466685b41e67d231a1c4a8f5e093374ee93/checkers/importShadow_checker.go#L23
+ linterCtx.SetFileInfo(f.Name.Name, f)
+ }
+
+ runOnFile(pass, f, enabledCheckers)
+ }
+
+ return nil
+}
+
+func (w *goCriticWrapper) buildEnabledCheckers(linterCtx *gocriticlinter.Context) ([]*gocriticlinter.Checker, error) {
+ allLowerCasedParams := w.settingsWrapper.GetLowerCasedParams()
+
+ var enabledCheckers []*gocriticlinter.Checker
+ for _, info := range gocriticlinter.GetCheckersInfo() {
+ if !w.settingsWrapper.IsCheckEnabled(info.Name) {
+ continue
+ }
+
+ err := w.settingsWrapper.setCheckerParams(info, allLowerCasedParams)
+ if err != nil {
+ return nil, err
+ }
+
+ c, err := gocriticlinter.NewChecker(linterCtx, info)
+ if err != nil {
+ return nil, err
+ }
+
+ enabledCheckers = append(enabledCheckers, c)
+ }
+
+ return enabledCheckers, nil
+}
+
+func runOnFile(pass *analysis.Pass, f *ast.File, checks []*gocriticlinter.Checker) {
+ for _, c := range checks {
+ // All checkers are expected to use *lint.Context
+ // as read-only structure, so no copying is required.
+ for _, warn := range c.Check(f) {
+ diag := analysis.Diagnostic{
+ Pos: warn.Pos,
+ Category: c.Info.Name,
+ Message: fmt.Sprintf("%s: %s", c.Info.Name, warn.Text),
+ }
+
+ if warn.HasQuickFix() {
+ diag.SuggestedFixes = []analysis.SuggestedFix{{
+ TextEdits: []analysis.TextEdit{{
+ Pos: warn.Suggestion.From,
+ End: warn.Suggestion.To,
+ NewText: warn.Suggestion.Replacement,
+ }},
+ }}
+ }
+
+ pass.Report(diag)
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocritic/gocritic.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic_settings.go
similarity index 60%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gocritic/gocritic.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic_settings.go
index 0fa4c63d..e3267eee 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocritic/gocritic.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic_settings.go
@@ -3,241 +3,22 @@ package gocritic
import (
"errors"
"fmt"
- "go/ast"
- "go/types"
"maps"
"reflect"
- "runtime"
"slices"
"strings"
- "sync"
- "github.com/go-critic/go-critic/checkers"
gocriticlinter "github.com/go-critic/go-critic/linter"
- _ "github.com/quasilyte/go-ruleguard/dsl"
- "golang.org/x/tools/go/analysis"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/logutils"
-)
-
-const linterName = "gocritic"
-var (
- debugf = logutils.Debug(logutils.DebugKeyGoCritic)
- isDebug = logutils.HaveDebugTag(logutils.DebugKeyGoCritic)
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
-func New(settings *config.GoCriticSettings) *goanalysis.Linter {
- wrapper := &goCriticWrapper{
- sizes: types.SizesFor("gc", runtime.GOARCH),
- }
-
- analyzer := &analysis.Analyzer{
- Name: linterName,
- Doc: goanalysis.TheOnlyanalyzerDoc,
- Run: func(pass *analysis.Pass) (any, error) {
- err := wrapper.run(pass)
- if err != nil {
- return nil, err
- }
-
- return nil, nil
- },
- }
-
- return goanalysis.NewLinter(
- linterName,
- `Provides diagnostics that check for bugs, performance and style issues.
-Extensible without recompilation through dynamic rules.
-Dynamic rules are written declaratively with AST patterns, filters, report message and optional suggestion.`,
- []*analysis.Analyzer{analyzer},
- nil,
- ).
- WithContextSetter(func(context *linter.Context) {
- wrapper.replacer = strings.NewReplacer(
- internal.PlaceholderBasePath, context.Cfg.GetBasePath(),
- internal.PlaceholderConfigDir, context.Cfg.GetConfigDir(), //nolint:staticcheck // It must be removed in v2.
- )
-
- wrapper.init(context.Log, settings)
- }).
- WithLoadMode(goanalysis.LoadModeTypesInfo)
-}
-
-type goCriticWrapper struct {
- settingsWrapper *settingsWrapper
- replacer *strings.Replacer
- sizes types.Sizes
- once sync.Once
-}
-
-func (w *goCriticWrapper) init(logger logutils.Log, settings *config.GoCriticSettings) {
- if settings == nil {
- return
- }
-
- w.once.Do(func() {
- err := checkers.InitEmbeddedRules()
- if err != nil {
- logger.Fatalf("%s: %v: setting an explicit GOROOT can fix this problem", linterName, err)
- }
- })
-
- settingsWrapper := newSettingsWrapper(settings, logger)
- settingsWrapper.InferEnabledChecks()
- // Validate must be after InferEnabledChecks, not before.
- // Because it uses gathered information about tags set and finally enabled checks.
- if err := settingsWrapper.Validate(); err != nil {
- logger.Fatalf("%s: invalid settings: %s", linterName, err)
- }
-
- w.settingsWrapper = settingsWrapper
-}
-
-func (w *goCriticWrapper) run(pass *analysis.Pass) error {
- if w.settingsWrapper == nil {
- return errors.New("the settings wrapper is nil")
- }
-
- linterCtx := gocriticlinter.NewContext(pass.Fset, w.sizes)
-
- linterCtx.SetGoVersion(w.settingsWrapper.Go)
-
- enabledCheckers, err := w.buildEnabledCheckers(linterCtx)
- if err != nil {
- return err
- }
-
- linterCtx.SetPackageInfo(pass.TypesInfo, pass.Pkg)
-
- runOnPackage(pass, enabledCheckers, pass.Files)
-
- return nil
-}
-
-func (w *goCriticWrapper) buildEnabledCheckers(linterCtx *gocriticlinter.Context) ([]*gocriticlinter.Checker, error) {
- allLowerCasedParams := w.settingsWrapper.GetLowerCasedParams()
-
- var enabledCheckers []*gocriticlinter.Checker
- for _, info := range gocriticlinter.GetCheckersInfo() {
- if !w.settingsWrapper.IsCheckEnabled(info.Name) {
- continue
- }
-
- if err := w.configureCheckerInfo(info, allLowerCasedParams); err != nil {
- return nil, err
- }
-
- c, err := gocriticlinter.NewChecker(linterCtx, info)
- if err != nil {
- return nil, err
- }
-
- enabledCheckers = append(enabledCheckers, c)
- }
-
- return enabledCheckers, nil
-}
-
-func (w *goCriticWrapper) configureCheckerInfo(
- info *gocriticlinter.CheckerInfo,
- allLowerCasedParams map[string]config.GoCriticCheckSettings,
-) error {
- params := allLowerCasedParams[strings.ToLower(info.Name)]
- if params == nil { // no config for this checker
- return nil
- }
-
- // To lowercase info param keys here because golangci-lint's config parser lowercases all strings.
- infoParams := normalizeMap(info.Params)
- for k, p := range params {
- v, ok := infoParams[k]
- if ok {
- v.Value = w.normalizeCheckerParamsValue(p)
- continue
- }
-
- // param `k` isn't supported
- if len(info.Params) == 0 {
- return fmt.Errorf("checker %s config param %s doesn't exist: checker doesn't have params",
- info.Name, k)
- }
-
- supportedKeys := slices.Sorted(maps.Keys(info.Params))
-
- return fmt.Errorf("checker %s config param %s doesn't exist, all existing: %s",
- info.Name, k, supportedKeys)
- }
-
- return nil
-}
-
-// normalizeCheckerParamsValue normalizes value types.
-// go-critic asserts that CheckerParam.Value has some specific types,
-// but the file parsers (TOML, YAML, JSON) don't create the same representation for raw type.
-// then we have to convert value types into the expected value types.
-// Maybe in the future, this kind of conversion will be done in go-critic itself.
-func (w *goCriticWrapper) normalizeCheckerParamsValue(p any) any {
- rv := reflect.ValueOf(p)
- switch rv.Type().Kind() {
- case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
- return int(rv.Int())
- case reflect.Bool:
- return rv.Bool()
- case reflect.String:
- // Perform variable substitution.
- return w.replacer.Replace(rv.String())
- default:
- return p
- }
-}
-
-func runOnPackage(pass *analysis.Pass, checks []*gocriticlinter.Checker, files []*ast.File) {
- for _, f := range files {
- runOnFile(pass, f, checks)
- }
-}
-
-func runOnFile(pass *analysis.Pass, f *ast.File, checks []*gocriticlinter.Checker) {
- for _, c := range checks {
- // All checkers are expected to use *lint.Context
- // as read-only structure, so no copying is required.
- for _, warn := range c.Check(f) {
- diag := analysis.Diagnostic{
- Pos: warn.Pos,
- Category: c.Info.Name,
- Message: fmt.Sprintf("%s: %s", c.Info.Name, warn.Text),
- }
-
- if warn.HasQuickFix() {
- diag.SuggestedFixes = []analysis.SuggestedFix{{
- TextEdits: []analysis.TextEdit{{
- Pos: warn.Suggestion.From,
- End: warn.Suggestion.To,
- NewText: warn.Suggestion.Replacement,
- }},
- }}
- }
-
- pass.Report(diag)
- }
- }
-}
-
-type goCriticChecks[T any] map[string]T
-
-func (m goCriticChecks[T]) has(name string) bool {
- _, ok := m[name]
- return ok
-}
-
type settingsWrapper struct {
*config.GoCriticSettings
+ replacer *strings.Replacer
+
logger logutils.Log
allCheckers []*gocriticlinter.CheckerInfo
@@ -253,12 +34,13 @@ type settingsWrapper struct {
inferredEnabledChecksLowerCased goCriticChecks[struct{}]
}
-func newSettingsWrapper(settings *config.GoCriticSettings, logger logutils.Log) *settingsWrapper {
+func newSettingsWrapper(logger logutils.Log, settings *config.GoCriticSettings, replacer *strings.Replacer) *settingsWrapper {
allCheckers := gocriticlinter.GetCheckersInfo()
allChecks := make(goCriticChecks[struct{}], len(allCheckers))
allChecksLowerCased := make(goCriticChecks[struct{}], len(allCheckers))
allChecksByTag := make(goCriticChecks[[]string])
+
for _, checker := range allCheckers {
allChecks[checker.Name] = struct{}{}
allChecksLowerCased[strings.ToLower(checker.Name)] = struct{}{}
@@ -268,17 +50,18 @@ func newSettingsWrapper(settings *config.GoCriticSettings, logger logutils.Log)
}
}
- allTagsSorted := slices.Sorted(maps.Keys(allChecksByTag))
-
return &settingsWrapper{
- GoCriticSettings: settings,
- logger: logger,
- allCheckers: allCheckers,
- allChecks: allChecks,
+ GoCriticSettings: settings,
+ replacer: replacer,
+ logger: logger,
+
+ allCheckers: allCheckers,
+ allChecks: allChecks,
+ allChecksByTag: allChecksByTag,
+ allTagsSorted: slices.Sorted(maps.Keys(allChecksByTag)),
+ inferredEnabledChecks: make(goCriticChecks[struct{}]),
+
allChecksLowerCased: allChecksLowerCased,
- allChecksByTag: allChecksByTag,
- allTagsSorted: allTagsSorted,
- inferredEnabledChecks: make(goCriticChecks[struct{}]),
inferredEnabledChecksLowerCased: make(goCriticChecks[struct{}]),
}
}
@@ -291,8 +74,15 @@ func (s *settingsWrapper) GetLowerCasedParams() map[string]config.GoCriticCheckS
return normalizeMap(s.SettingsPerCheck)
}
-// InferEnabledChecks tries to be consistent with (lintersdb.Manager).build.
-func (s *settingsWrapper) InferEnabledChecks() {
+func (s *settingsWrapper) Load() error {
+ s.inferEnabledChecks()
+
+ // validate must be after inferEnabledChecks, not before.
+ // Because it uses gathered information about tags set and finally enabled checks.
+ return s.validate()
+}
+
+func (s *settingsWrapper) inferEnabledChecks() {
s.debugChecksInitialState()
enabledByDefaultChecks, disabledByDefaultChecks := s.buildEnabledAndDisabledByDefaultChecks()
@@ -300,22 +90,30 @@ func (s *settingsWrapper) InferEnabledChecks() {
debugChecksListf(enabledByDefaultChecks, "Enabled by default")
debugChecksListf(disabledByDefaultChecks, "Disabled by default")
- enabledChecks := make(goCriticChecks[struct{}])
+ var enabledChecks goCriticChecks[struct{}]
- if s.EnableAll {
+ switch {
+ case s.DisableAll:
+ // disable-all revokes the default settings.
+ enabledChecks = make(goCriticChecks[struct{}])
+
+ case s.EnableAll:
+ // enable-all revokes the default settings.
enabledChecks = make(goCriticChecks[struct{}], len(s.allCheckers))
+
for _, info := range s.allCheckers {
enabledChecks[info.Name] = struct{}{}
}
- } else if !s.DisableAll {
- // enable-all/disable-all revokes the default settings.
+
+ default:
enabledChecks = make(goCriticChecks[struct{}], len(enabledByDefaultChecks))
+
for _, check := range enabledByDefaultChecks {
enabledChecks[check] = struct{}{}
}
}
- if len(s.EnabledTags) != 0 {
+ if len(s.EnabledTags) > 0 {
enabledFromTags := s.expandTagsToChecks(s.EnabledTags)
debugChecksListf(enabledFromTags, "Enabled by config tags %s", s.EnabledTags)
@@ -325,7 +123,7 @@ func (s *settingsWrapper) InferEnabledChecks() {
}
}
- if len(s.EnabledChecks) != 0 {
+ if len(s.EnabledChecks) > 0 {
debugChecksListf(s.EnabledChecks, "Enabled by config")
for _, check := range s.EnabledChecks {
@@ -333,11 +131,12 @@ func (s *settingsWrapper) InferEnabledChecks() {
s.logger.Warnf("%s: no need to enable check %q: it's already enabled", linterName, check)
continue
}
+
enabledChecks[check] = struct{}{}
}
}
- if len(s.DisabledTags) != 0 {
+ if len(s.DisabledTags) > 0 {
disabledFromTags := s.expandTagsToChecks(s.DisabledTags)
debugChecksListf(disabledFromTags, "Disabled by config tags %s", s.DisabledTags)
@@ -347,7 +146,7 @@ func (s *settingsWrapper) InferEnabledChecks() {
}
}
- if len(s.DisabledChecks) != 0 {
+ if len(s.DisabledChecks) > 0 {
debugChecksListf(s.DisabledChecks, "Disabled by config")
for _, check := range s.DisabledChecks {
@@ -355,6 +154,7 @@ func (s *settingsWrapper) InferEnabledChecks() {
s.logger.Warnf("%s: no need to disable check %q: it's already disabled", linterName, check)
continue
}
+
delete(enabledChecks, check)
}
}
@@ -367,29 +167,64 @@ func (s *settingsWrapper) InferEnabledChecks() {
func (s *settingsWrapper) buildEnabledAndDisabledByDefaultChecks() (enabled, disabled []string) {
for _, info := range s.allCheckers {
- if enabledByDef := isEnabledByDefaultGoCriticChecker(info); enabledByDef {
+ if isEnabledByDefaultGoCriticChecker(info) {
enabled = append(enabled, info.Name)
} else {
disabled = append(disabled, info.Name)
}
}
+
return enabled, disabled
}
func (s *settingsWrapper) expandTagsToChecks(tags []string) []string {
var checks []string
+
for _, tag := range tags {
checks = append(checks, s.allChecksByTag[tag]...)
}
+
return checks
}
+func (s *settingsWrapper) setCheckerParams(
+ info *gocriticlinter.CheckerInfo,
+ allLowerCasedParams map[string]config.GoCriticCheckSettings,
+) error {
+ params := allLowerCasedParams[strings.ToLower(info.Name)]
+ if params == nil { // no config for this checker
+ return nil
+ }
+
+ // To lowercase info param keys here because golangci-lint's config parser lowercases all strings.
+ infoParams := normalizeMap(info.Params)
+ for k, p := range params {
+ v, ok := infoParams[k]
+ if ok {
+ v.Value = s.normalizeCheckerParamsValue(p)
+ continue
+ }
+
+ // param `k` isn't supported
+ if len(info.Params) == 0 {
+ return fmt.Errorf("checker %s config param %s doesn't exist: checker doesn't have params",
+ info.Name, k)
+ }
+
+ return fmt.Errorf("checker %s config param %s doesn't exist, all existing: %s",
+ info.Name, k, slices.Sorted(maps.Keys(info.Params)))
+ }
+
+ return nil
+}
+
func (s *settingsWrapper) debugChecksInitialState() {
if !isDebug {
return
}
debugf("All gocritic existing tags and checks:")
+
for _, tag := range s.allTagsSorted {
debugChecksListf(s.allChecksByTag[tag], " tag %q", tag)
}
@@ -404,11 +239,10 @@ func (s *settingsWrapper) debugChecksFinalState() {
var disabledChecks []string
for _, checker := range s.allCheckers {
- check := checker.Name
- if s.inferredEnabledChecks.has(check) {
- enabledChecks = append(enabledChecks, check)
+ if s.IsCheckEnabled(checker.Name) {
+ enabledChecks = append(enabledChecks, checker.Name)
} else {
- disabledChecks = append(disabledChecks, check)
+ disabledChecks = append(disabledChecks, checker.Name)
}
}
@@ -421,8 +255,32 @@ func (s *settingsWrapper) debugChecksFinalState() {
}
}
-// Validate tries to be consistent with (lintersdb.Validator).validateEnabledDisabledLintersConfig.
-func (s *settingsWrapper) Validate() error {
+// normalizeCheckerParamsValue normalizes value types.
+// go-critic asserts that CheckerParam.Value has some specific types,
+// but the file parsers (TOML, YAML, JSON) don't create the same representation for raw type.
+// then we have to convert value types into the expected value types.
+// Maybe in the future, this kind of conversion will be done in go-critic itself.
+func (s *settingsWrapper) normalizeCheckerParamsValue(p any) any {
+ rv := reflect.ValueOf(p)
+
+ switch rv.Type().Kind() {
+ case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
+ return int(rv.Int())
+
+ case reflect.Bool:
+ return rv.Bool()
+
+ case reflect.String:
+ // Perform variable substitution.
+ return s.replacer.Replace(rv.String())
+
+ default:
+ return p
+ }
+}
+
+// validate tries to be consistent with (lintersdb.Validator).validateEnabledDisabledLintersConfig.
+func (s *settingsWrapper) validate() error {
for _, v := range []func() error{
s.validateOptionsCombinations,
s.validateCheckerTags,
@@ -438,26 +296,26 @@ func (s *settingsWrapper) Validate() error {
}
func (s *settingsWrapper) validateOptionsCombinations() error {
- if s.EnableAll {
- if s.DisableAll {
- return errors.New("enable-all and disable-all options must not be combined")
- }
+ if s.EnableAll && s.DisableAll {
+ return errors.New("enable-all and disable-all options must not be combined")
+ }
- if len(s.EnabledTags) != 0 {
+ switch {
+ case s.EnableAll:
+ if len(s.EnabledTags) > 0 {
return errors.New("enable-all and enabled-tags options must not be combined")
}
- if len(s.EnabledChecks) != 0 {
+ if len(s.EnabledChecks) > 0 {
return errors.New("enable-all and enabled-checks options must not be combined")
}
- }
- if s.DisableAll {
- if len(s.DisabledTags) != 0 {
+ case s.DisableAll:
+ if len(s.DisabledTags) > 0 {
return errors.New("disable-all and disabled-tags options must not be combined")
}
- if len(s.DisabledChecks) != 0 {
+ if len(s.DisabledChecks) > 0 {
return errors.New("disable-all and disabled-checks options must not be combined")
}
@@ -500,9 +358,11 @@ func (s *settingsWrapper) validateCheckerNames() error {
for check := range s.SettingsPerCheck {
lcName := strings.ToLower(check)
+
if !s.allChecksLowerCased.has(lcName) {
return fmt.Errorf("invalid check settings: check %q doesn't exist, see %s documentation", check, linterName)
}
+
if !s.inferredEnabledChecksLowerCased.has(lcName) {
s.logger.Warnf("%s: settings were provided for disabled check %q", check, linterName)
}
@@ -531,14 +391,34 @@ func (s *settingsWrapper) validateAtLeastOneCheckerEnabled() error {
if len(s.inferredEnabledChecks) == 0 {
return errors.New("eventually all checks were disabled: at least one must be enabled")
}
+
return nil
}
+type goCriticChecks[T any] map[string]T
+
+func (m goCriticChecks[T]) has(name string) bool {
+ _, ok := m[name]
+ return ok
+}
+
+func debugChecksListf(checks []string, format string, args ...any) {
+ if !isDebug {
+ return
+ }
+
+ v := slices.Sorted(slices.Values(checks))
+
+ debugf("%s checks (%d): %s", fmt.Sprintf(format, args...), len(checks), strings.Join(v, ", "))
+}
+
func normalizeMap[ValueT any](in map[string]ValueT) map[string]ValueT {
ret := make(map[string]ValueT, len(in))
+
for k, v := range in {
ret[strings.ToLower(k)] = v
}
+
return ret
}
@@ -549,13 +429,3 @@ func isEnabledByDefaultGoCriticChecker(info *gocriticlinter.CheckerInfo) bool {
!info.HasTag(gocriticlinter.PerformanceTag) &&
!info.HasTag(gocriticlinter.SecurityTag)
}
-
-func debugChecksListf(checks []string, format string, args ...any) {
- if !isDebug {
- return
- }
-
- v := slices.Sorted(slices.Values(checks))
-
- debugf("%s checks (%d): %s", fmt.Sprintf(format, args...), len(checks), strings.Join(v, ", "))
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocyclo/gocyclo.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocyclo/gocyclo.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gocyclo/gocyclo.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocyclo/gocyclo.go
index 51333dc1..05691695 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocyclo/gocyclo.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocyclo/gocyclo.go
@@ -7,11 +7,11 @@ import (
"github.com/fzipp/gocyclo"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gocyclo"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/godot/godot.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godot/godot.go
similarity index 87%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/godot/godot.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godot/godot.go
index 3194b3d3..04e86211 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/godot/godot.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godot/godot.go
@@ -6,8 +6,8 @@ import (
"github.com/tetafro/godot"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
const linterName = "godot"
@@ -22,11 +22,6 @@ func New(settings *config.GodotSettings) *goanalysis.Linter {
Period: settings.Period,
Capital: settings.Capital,
}
-
- // Convert deprecated setting
- if settings.CheckAll != nil && *settings.CheckAll {
- dotSettings.Scope = godot.AllScope
- }
}
dotSettings.Scope = cmp.Or(dotSettings.Scope, godot.DeclScope)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/godox/godox.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godox/godox.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/godox/godox.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godox/godox.go
index 589789d1..e734c691 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/godox/godox.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godox/godox.go
@@ -7,8 +7,8 @@ import (
"github.com/matoous/godox"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
const linterName = "godox"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gofmt/gofmt.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofmt/gofmt.go
similarity index 60%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gofmt/gofmt.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofmt/gofmt.go
index 22122429..63b69001 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gofmt/gofmt.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofmt/gofmt.go
@@ -3,11 +3,11 @@ package gofmt
import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/goformatters"
- gofmtbase "github.com/golangci/golangci-lint/pkg/goformatters/gofmt"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ gofmtbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
const linterName = "gofmt"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gofumpt/gofumpt.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofumpt/gofumpt.go
similarity index 54%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gofumpt/gofumpt.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofumpt/gofumpt.go
index 878a5c79..d799be7a 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gofumpt/gofumpt.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofumpt/gofumpt.go
@@ -3,16 +3,16 @@ package gofumpt
import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/goformatters"
- gofumptbase "github.com/golangci/golangci-lint/pkg/goformatters/gofumpt"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ gofumptbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
const linterName = "gofumpt"
-func New(settings *config.GofumptSettings) *goanalysis.Linter {
+func New(settings *config.GoFumptSettings) *goanalysis.Linter {
a := goformatters.NewAnalyzer(
internal.LinterLogger.Child(linterName),
"Checks if code and import statements are formatted, with additional rules.",
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goheader/goheader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goheader/goheader.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/goheader/goheader.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goheader/goheader.go
index d24ad453..e03d3277 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goheader/goheader.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goheader/goheader.go
@@ -7,20 +7,19 @@ import (
goheader "github.com/denis-tingaikin/go-header"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
const linterName = "goheader"
-func New(settings *config.GoHeaderSettings, basePath string) *goanalysis.Linter {
+func New(settings *config.GoHeaderSettings, replacer *strings.Replacer) *goanalysis.Linter {
conf := &goheader.Configuration{}
if settings != nil {
conf = &goheader.Configuration{
Values: settings.Values,
Template: settings.Template,
- TemplatePath: strings.ReplaceAll(settings.TemplatePath, internal.PlaceholderBasePath, basePath),
+ TemplatePath: replacer.Replace(settings.TemplatePath),
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goimports/goimports.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goimports/goimports.go
similarity index 61%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/goimports/goimports.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goimports/goimports.go
index d7ba9855..3aa8cde5 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goimports/goimports.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goimports/goimports.go
@@ -3,11 +3,11 @@ package goimports
import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/goformatters"
- goimportsbase "github.com/golangci/golangci-lint/pkg/goformatters/goimports"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ goimportsbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
const linterName = "goimports"
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/golines/golines.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/golines/golines.go
new file mode 100644
index 00000000..0b3acc53
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/golines/golines.go
@@ -0,0 +1,28 @@
+package golines
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ golinesbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/golines"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+)
+
+const linterName = "golines"
+
+func New(settings *config.GoLinesSettings) *goanalysis.Linter {
+ a := goformatters.NewAnalyzer(
+ internal.LinterLogger.Child(linterName),
+ "Checks if code is formatted, and fixes long lines",
+ golinesbase.New(settings),
+ )
+
+ return goanalysis.NewLinter(
+ a.Name,
+ a.Doc,
+ []*analysis.Analyzer{a},
+ nil,
+ ).WithLoadMode(goanalysis.LoadModeSyntax)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gomoddirectives/gomoddirectives.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomoddirectives/gomoddirectives.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gomoddirectives/gomoddirectives.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomoddirectives/gomoddirectives.go
index f8f47ba2..86f94e25 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gomoddirectives/gomoddirectives.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomoddirectives/gomoddirectives.go
@@ -7,11 +7,11 @@ import (
"github.com/ldez/gomoddirectives"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gomoddirectives"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gomodguard/gomodguard.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gomodguard/gomodguard.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard.go
index 8bddebc1..e38a6c9b 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gomodguard/gomodguard.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard.go
@@ -6,11 +6,11 @@ import (
"github.com/ryancurrah/gomodguard"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const (
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goprintffuncname/goprintffuncname.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goprintffuncname/goprintffuncname.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/goprintffuncname/goprintffuncname.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goprintffuncname/goprintffuncname.go
index c206ffaa..b1436347 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goprintffuncname/goprintffuncname.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goprintffuncname/goprintffuncname.go
@@ -4,7 +4,7 @@ import (
"github.com/golangci/go-printf-func-name/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosec/gosec.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosec/gosec.go
similarity index 95%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gosec/gosec.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosec/gosec.go
index 6b46beac..95b445e8 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosec/gosec.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosec/gosec.go
@@ -16,10 +16,10 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "gosec"
@@ -62,7 +62,7 @@ func New(settings *config.GoSecSettings) *goanalysis.Linter {
).WithContextSetter(func(lintCtx *linter.Context) {
analyzer.Run = func(pass *analysis.Pass) (any, error) {
// The `gosecAnalyzer` is here because of concurrency issue.
- gosecAnalyzer := gosec.NewAnalyzer(conf, true, settings.ExcludeGenerated, false, settings.Concurrency, logger)
+ gosecAnalyzer := gosec.NewAnalyzer(conf, true, false, false, settings.Concurrency, logger)
gosecAnalyzer.LoadRules(ruleDefinitions.RulesInfo())
gosecAnalyzer.LoadAnalyzers(analyzerDefinitions.AnalyzersInfo())
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosmopolitan/gosmopolitan.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosmopolitan/gosmopolitan.go
similarity index 76%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/gosmopolitan/gosmopolitan.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosmopolitan/gosmopolitan.go
index bf9b19f1..6c574403 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosmopolitan/gosmopolitan.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosmopolitan/gosmopolitan.go
@@ -6,8 +6,8 @@ import (
"github.com/xen0n/gosmopolitan"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.GosmopolitanSettings) *goanalysis.Linter {
@@ -18,8 +18,10 @@ func New(settings *config.GosmopolitanSettings) *goanalysis.Linter {
cfg[a.Name] = map[string]any{
"allowtimelocal": settings.AllowTimeLocal,
"escapehatches": strings.Join(settings.EscapeHatches, ","),
- "lookattests": !settings.IgnoreTests,
"watchforscripts": strings.Join(settings.WatchForScripts, ","),
+
+ // Should be managed with `linters.exclusions.rules`.
+ "lookattests": true,
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/govet/govet.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/govet/govet.go
similarity index 95%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/govet/govet.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/govet/govet.go
index b970e403..4f338084 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/govet/govet.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/govet/govet.go
@@ -24,6 +24,7 @@ import (
"golang.org/x/tools/go/analysis/passes/fieldalignment"
"golang.org/x/tools/go/analysis/passes/findcall"
"golang.org/x/tools/go/analysis/passes/framepointer"
+ "golang.org/x/tools/go/analysis/passes/httpmux"
"golang.org/x/tools/go/analysis/passes/httpresponse"
"golang.org/x/tools/go/analysis/passes/ifaceassert"
_ "golang.org/x/tools/go/analysis/passes/inspect" // unused internal analyzer
@@ -53,9 +54,9 @@ import (
"golang.org/x/tools/go/analysis/passes/unusedwrite"
"golang.org/x/tools/go/analysis/passes/waitgroup"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
var (
@@ -77,6 +78,7 @@ var (
fieldalignment.Analyzer,
findcall.Analyzer,
framepointer.Analyzer,
+ httpmux.Analyzer,
httpresponse.Analyzer,
ifaceassert.Analyzer,
loopclosure.Analyzer,
@@ -189,11 +191,6 @@ func isAnalyzerEnabled(name string, cfg *config.GovetSettings, defaultAnalyzers
return false
}
- // Keeping for backward compatibility.
- if cfg.CheckShadowing != nil && *cfg.CheckShadowing && name == shadow.Analyzer.Name {
- return true
- }
-
switch {
case cfg.EnableAll:
return !slices.Contains(cfg.Disable, name)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/grouper/grouper.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/grouper/grouper.go
similarity index 90%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/grouper/grouper.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/grouper/grouper.go
index e0a3f794..853e2d3e 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/grouper/grouper.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/grouper/grouper.go
@@ -4,8 +4,8 @@ import (
grouper "github.com/leonklingele/grouper/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.GrouperSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/iface/iface.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/iface/iface.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/iface/iface.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/iface/iface.go
index 31f88160..a3c2816d 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/iface/iface.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/iface/iface.go
@@ -8,8 +8,8 @@ import (
"github.com/uudashr/iface/unused"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.IfaceSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/importas/importas.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/importas/importas.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/importas/importas.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/importas/importas.go
index b7c6c35a..a86db68c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/importas/importas.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/importas/importas.go
@@ -8,9 +8,9 @@ import (
"github.com/julz/importas"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
)
func New(settings *config.ImportAsSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/inamedparam/inamedparam.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/inamedparam/inamedparam.go
similarity index 82%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/inamedparam/inamedparam.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/inamedparam/inamedparam.go
index 5cf06a08..0a67c970 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/inamedparam/inamedparam.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/inamedparam/inamedparam.go
@@ -4,8 +4,8 @@ import (
"github.com/macabu/inamedparam"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.INamedParamSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ineffassign/ineffassign.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ineffassign/ineffassign.go
similarity index 86%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/ineffassign/ineffassign.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ineffassign/ineffassign.go
index ba86fb90..bbe01ba1 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ineffassign/ineffassign.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ineffassign/ineffassign.go
@@ -4,7 +4,7 @@ import (
"github.com/gordonklaus/ineffassign/pkg/ineffassign"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/interfacebloat/interfacebloat.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/interfacebloat/interfacebloat.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/interfacebloat/interfacebloat.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/interfacebloat/interfacebloat.go
index 88927a3d..fbafb3ac 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/interfacebloat/interfacebloat.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/interfacebloat/interfacebloat.go
@@ -4,8 +4,8 @@ import (
"github.com/sashamelentyev/interfacebloat/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.InterfaceBloatSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/commons.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/commons.go
new file mode 100644
index 00000000..d19c1fd4
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/commons.go
@@ -0,0 +1,6 @@
+package internal
+
+import "github.com/golangci/golangci-lint/v2/pkg/logutils"
+
+// LinterLogger must be use only when the context logger is not available.
+var LinterLogger = logutils.NewStderrLog(logutils.DebugKeyLinter)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/util.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/util.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/util.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/util.go
index 7525f2f2..2e5fb29f 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/util.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/util.go
@@ -6,8 +6,8 @@ import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func FormatCode(code string, _ *config.Config) string {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/intrange/intrange.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/intrange/intrange.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/intrange/intrange.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/intrange/intrange.go
index d5ffd434..c75be9b6 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/intrange/intrange.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/intrange/intrange.go
@@ -4,7 +4,7 @@ import (
"github.com/ckaznocha/intrange"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ireturn/ireturn.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ireturn/ireturn.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/ireturn/ireturn.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ireturn/ireturn.go
index 57de5711..44c28700 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ireturn/ireturn.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ireturn/ireturn.go
@@ -6,8 +6,8 @@ import (
"github.com/butuzov/ireturn/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.IreturnSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/lll/lll.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/lll/lll.go
similarity index 96%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/lll/lll.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/lll/lll.go
index bad3b0c4..eb435baa 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/lll/lll.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/lll/lll.go
@@ -11,8 +11,8 @@ import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
const linterName = "lll"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/loggercheck/loggercheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/loggercheck/loggercheck.go
similarity index 90%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/loggercheck/loggercheck.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/loggercheck/loggercheck.go
index 84c8d736..a5dd4da4 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/loggercheck/loggercheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/loggercheck/loggercheck.go
@@ -4,8 +4,8 @@ import (
"github.com/timonwong/loggercheck"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.LoggerCheckSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/maintidx/maintidx.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/maintidx/maintidx.go
similarity index 82%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/maintidx/maintidx.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/maintidx/maintidx.go
index 799c51c8..4e541f88 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/maintidx/maintidx.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/maintidx/maintidx.go
@@ -4,8 +4,8 @@ import (
"github.com/yagipy/maintidx"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.MaintIdxSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/makezero/makezero.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/makezero/makezero.go
similarity index 91%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/makezero/makezero.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/makezero/makezero.go
index b5ab4515..04b4fe93 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/makezero/makezero.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/makezero/makezero.go
@@ -6,8 +6,8 @@ import (
"github.com/ashanbrown/makezero/makezero"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
const linterName = "makezero"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/mirror/mirror.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mirror/mirror.go
similarity index 93%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/mirror/mirror.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mirror/mirror.go
index e15dfa3a..9badb0c1 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/mirror/mirror.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mirror/mirror.go
@@ -4,7 +4,7 @@ import (
"github.com/butuzov/mirror"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/misspell/misspell.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/misspell/misspell.go
similarity index 94%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/misspell/misspell.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/misspell/misspell.go
index 9d19780a..9a170c95 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/misspell/misspell.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/misspell/misspell.go
@@ -10,9 +10,9 @@ import (
"github.com/golangci/misspell"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
const linterName = "misspell"
@@ -68,8 +68,8 @@ func createMisspellReplacer(settings *config.MisspellSettings) (*misspell.Replac
return nil, fmt.Errorf("process extra words: %w", err)
}
- if len(settings.IgnoreWords) != 0 {
- replacer.RemoveRule(settings.IgnoreWords)
+ if len(settings.IgnoreRules) != 0 {
+ replacer.RemoveRule(settings.IgnoreRules)
}
// It can panic.
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/mnd/mnd.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mnd/mnd.go
similarity index 71%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/mnd/mnd.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mnd/mnd.go
index fe64653b..52521e92 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/mnd/mnd.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mnd/mnd.go
@@ -4,16 +4,15 @@ import (
mnd "github.com/tommy-muehle/go-mnd/v2"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.MndSettings) *goanalysis.Linter {
- return newMND(mnd.Analyzer, settings, nil)
-}
+ a := mnd.Analyzer
-func newMND(a *analysis.Analyzer, settings *config.MndSettings, linterCfg map[string]map[string]any) *goanalysis.Linter {
- if len(linterCfg) == 0 && settings != nil {
+ var linterCfg map[string]map[string]any
+ if settings != nil {
cfg := make(map[string]any)
if len(settings.Checks) > 0 {
cfg["checks"] = settings.Checks
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/musttag/musttag.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/musttag/musttag.go
similarity index 82%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/musttag/musttag.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/musttag/musttag.go
index a4e9ceff..03070732 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/musttag/musttag.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/musttag/musttag.go
@@ -4,8 +4,8 @@ import (
"go-simpler.org/musttag"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.MustTagSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nakedret/nakedret.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nakedret/nakedret.go
new file mode 100644
index 00000000..1b769acd
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nakedret/nakedret.go
@@ -0,0 +1,27 @@
+package nakedret
+
+import (
+ "github.com/alexkohler/nakedret/v2"
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+)
+
+func New(settings *config.NakedretSettings) *goanalysis.Linter {
+ cfg := &nakedret.NakedReturnRunner{}
+
+ if settings != nil {
+ // SkipTestFiles is intentionally ignored => should be managed with `linters.exclusions.rules`.
+ cfg.MaxLength = settings.MaxFuncLines
+ }
+
+ a := nakedret.NakedReturnAnalyzer(cfg)
+
+ return goanalysis.NewLinter(
+ a.Name,
+ a.Doc,
+ []*analysis.Analyzer{a},
+ nil,
+ ).WithLoadMode(goanalysis.LoadModeSyntax)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nestif/nestif.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nestif/nestif.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nestif/nestif.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nestif/nestif.go
index b72538fd..1a6b55ca 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nestif/nestif.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nestif/nestif.go
@@ -4,8 +4,8 @@ import (
"github.com/nakabonne/nestif"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
const linterName = "nestif"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilerr/nilerr.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilerr/nilerr.go
similarity index 86%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nilerr/nilerr.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilerr/nilerr.go
index c9e46690..9345b945 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilerr/nilerr.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilerr/nilerr.go
@@ -4,7 +4,7 @@ import (
"github.com/gostaticanalysis/nilerr"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilnesserr/nilnesserr.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnesserr/nilnesserr.go
similarity index 77%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nilnesserr/nilnesserr.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnesserr/nilnesserr.go
index 8349377b..b54992e2 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilnesserr/nilnesserr.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnesserr/nilnesserr.go
@@ -4,8 +4,8 @@ import (
"github.com/alingse/nilnesserr"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilnil/nilnil.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnil/nilnil.go
similarity index 76%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nilnil/nilnil.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnil/nilnil.go
index ed25dec7..5f42e24c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilnil/nilnil.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnil/nilnil.go
@@ -4,8 +4,8 @@ import (
"github.com/Antonboom/nilnil/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.NilNilSettings) *goanalysis.Linter {
@@ -16,6 +16,9 @@ func New(settings *config.NilNilSettings) *goanalysis.Linter {
cfg[a.Name] = map[string]any{
"detect-opposite": settings.DetectOpposite,
}
+ if b := settings.OnlyTwo; b != nil {
+ cfg[a.Name]["only-two"] = *b
+ }
if len(settings.CheckedTypes) != 0 {
cfg[a.Name]["checked-types"] = settings.CheckedTypes
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nlreturn/nlreturn.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nlreturn/nlreturn.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nlreturn/nlreturn.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nlreturn/nlreturn.go
index 50921880..ce2130c5 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nlreturn/nlreturn.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nlreturn/nlreturn.go
@@ -4,8 +4,8 @@ import (
"github.com/ssgreg/nlreturn/v2/pkg/nlreturn"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.NlreturnSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/noctx/noctx.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/noctx/noctx.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/noctx/noctx.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/noctx/noctx.go
index 8a063c61..b0c5f9b5 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/noctx/noctx.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/noctx/noctx.go
@@ -4,7 +4,7 @@ import (
"github.com/sonatard/noctx"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/README.md b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/README.md
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/README.md
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/README.md
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/issues.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/issues.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/issues.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/nolintlint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/nolintlint.go
similarity index 98%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/nolintlint.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/nolintlint.go
index 21cd2012..2be7c5c1 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/nolintlint.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/nolintlint.go
@@ -8,8 +8,8 @@ import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const LinterName = "nolintlint"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/nolintlint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/nolintlint.go
similarity index 81%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/nolintlint.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/nolintlint.go
index e1c87862..f19b8324 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/nolintlint.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/nolintlint.go
@@ -6,12 +6,11 @@ import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
-
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- nolintlint "github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+ nolintlint "github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
)
const LinterName = nolintlint.LinterName
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nonamedreturns/nonamedreturns.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nonamedreturns/nonamedreturns.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nonamedreturns/nonamedreturns.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nonamedreturns/nonamedreturns.go
index 42a618e6..91354f6a 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nonamedreturns/nonamedreturns.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nonamedreturns/nonamedreturns.go
@@ -4,8 +4,8 @@ import (
"github.com/firefart/nonamedreturns/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.NoNamedReturnsSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nosprintfhostport/nosprintfhostport.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nosprintfhostport/nosprintfhostport.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/nosprintfhostport/nosprintfhostport.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nosprintfhostport/nosprintfhostport.go
index 8f06ae1f..cca70680 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nosprintfhostport/nosprintfhostport.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nosprintfhostport/nosprintfhostport.go
@@ -4,7 +4,7 @@ import (
"github.com/stbenjam/no-sprintf-host-port/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/paralleltest/paralleltest.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest/paralleltest.go
similarity index 87%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/paralleltest/paralleltest.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest/paralleltest.go
index 0c908fa3..8c811ca5 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/paralleltest/paralleltest.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest/paralleltest.go
@@ -4,8 +4,8 @@ import (
"github.com/kunwardeep/paralleltest/pkg/paralleltest"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.ParallelTestSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/perfsprint/perfsprint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/perfsprint/perfsprint.go
similarity index 81%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/perfsprint/perfsprint.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/perfsprint/perfsprint.go
index c34f7e4c..f870ee00 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/perfsprint/perfsprint.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/perfsprint/perfsprint.go
@@ -4,8 +4,8 @@ import (
"github.com/catenacyber/perfsprint/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.PerfSprintSettings) *goanalysis.Linter {
@@ -16,6 +16,8 @@ func New(settings *config.PerfSprintSettings) *goanalysis.Linter {
}
if settings != nil {
+ // NOTE: The option `ignore-tests` is not handled because it should be managed with `linters.exclusions.rules`
+
cfg[a.Name]["integer-format"] = settings.IntegerFormat
cfg[a.Name]["int-conversion"] = settings.IntConversion
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/prealloc/prealloc.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc/prealloc.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/prealloc/prealloc.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc/prealloc.go
index 17e86c98..1ceba600 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/prealloc/prealloc.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc/prealloc.go
@@ -6,9 +6,9 @@ import (
"github.com/alexkohler/prealloc/pkg"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
const linterName = "prealloc"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/predeclared/predeclared.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/predeclared/predeclared.go
similarity index 73%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/predeclared/predeclared.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/predeclared/predeclared.go
index b8d189fd..9bde9d2f 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/predeclared/predeclared.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/predeclared/predeclared.go
@@ -1,11 +1,13 @@
package predeclared
import (
+ "strings"
+
"github.com/nishanths/predeclared/passes/predeclared"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.PredeclaredSettings) *goanalysis.Linter {
@@ -15,7 +17,7 @@ func New(settings *config.PredeclaredSettings) *goanalysis.Linter {
if settings != nil {
cfg = map[string]map[string]any{
a.Name: {
- predeclared.IgnoreFlag: settings.Ignore,
+ predeclared.IgnoreFlag: strings.Join(settings.Ignore, ","),
predeclared.QualifiedFlag: settings.Qualified,
},
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/promlinter/promlinter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/promlinter/promlinter.go
similarity index 88%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/promlinter/promlinter.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/promlinter/promlinter.go
index 5decbbc7..ab2c9c56 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/promlinter/promlinter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/promlinter/promlinter.go
@@ -7,10 +7,10 @@ import (
"github.com/yeya24/promlinter"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "promlinter"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/protogetter/protogetter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/protogetter/protogetter.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/protogetter/protogetter.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/protogetter/protogetter.go
index 423e4ca9..c13c98af 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/protogetter/protogetter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/protogetter/protogetter.go
@@ -4,8 +4,8 @@ import (
"github.com/ghostiam/protogetter"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.ProtoGetterSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/reassign/reassign.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/reassign/reassign.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/reassign/reassign.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/reassign/reassign.go
index cfc85635..7d9f8428 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/reassign/reassign.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/reassign/reassign.go
@@ -7,8 +7,8 @@ import (
"github.com/curioswitch/go-reassign"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.ReassignSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/recvcheck/recvcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/recvcheck/recvcheck.go
similarity index 81%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/recvcheck/recvcheck.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/recvcheck/recvcheck.go
index 3af4885b..ed1eb0b7 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/recvcheck/recvcheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/recvcheck/recvcheck.go
@@ -4,8 +4,8 @@ import (
"github.com/raeperd/recvcheck"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.RecvcheckSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/revive/revive.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/revive/revive.go
similarity index 80%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/revive/revive.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/revive/revive.go
index 46028128..5f9b3a90 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/revive/revive.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/revive/revive.go
@@ -3,7 +3,6 @@ package revive
import (
"bytes"
"cmp"
- "encoding/json"
"fmt"
"go/token"
"os"
@@ -19,12 +18,12 @@ import (
"github.com/mgechev/revive/rule"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "revive"
@@ -34,12 +33,6 @@ var (
isDebug = logutils.HaveDebugTag(logutils.DebugKeyRevive)
)
-// jsonObject defines a JSON object of a failure
-type jsonObject struct {
- Severity lint.Severity
- lint.Failure `json:",inline"`
-}
-
func New(settings *config.ReviveSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []goanalysis.Issue
@@ -63,7 +56,7 @@ func New(settings *config.ReviveSettings) *goanalysis.Linter {
}
analyzer.Run = func(pass *analysis.Pass) (any, error) {
- issues, err := w.run(lintCtx, pass)
+ issues, err := w.run(pass)
if err != nil {
return nil, err
}
@@ -85,7 +78,6 @@ func New(settings *config.ReviveSettings) *goanalysis.Linter {
type wrapper struct {
revive lint.Linter
- formatter lint.Formatter
lintingRules []lint.Rule
conf *lint.Config
}
@@ -103,11 +95,6 @@ func newWrapper(settings *config.ReviveSettings) (*wrapper, error) {
return nil, err
}
- formatter, err := reviveConfig.GetFormatter("json")
- if err != nil {
- return nil, err
- }
-
lintingRules, err := reviveConfig.GetLintingRules(conf, []lint.Rule{})
if err != nil {
return nil, err
@@ -115,13 +102,12 @@ func newWrapper(settings *config.ReviveSettings) (*wrapper, error) {
return &wrapper{
revive: lint.New(os.ReadFile, settings.MaxOpenFiles),
- formatter: formatter,
lintingRules: lintingRules,
conf: conf,
}, nil
}
-func (w *wrapper) run(lintCtx *linter.Context, pass *analysis.Pass) ([]goanalysis.Issue, error) {
+func (w *wrapper) run(pass *analysis.Pass) ([]goanalysis.Issue, error) {
packages := [][]string{internal.GetGoFileNames(pass)}
failures, err := w.revive.Lint(packages, w.lintingRules, *w.conf)
@@ -129,75 +115,50 @@ func (w *wrapper) run(lintCtx *linter.Context, pass *analysis.Pass) ([]goanalysi
return nil, err
}
- formatChan := make(chan lint.Failure)
- exitChan := make(chan bool)
-
- var output string
- go func() {
- output, err = w.formatter.Format(formatChan, *w.conf)
- if err != nil {
- lintCtx.Log.Errorf("Format error: %v", err)
- }
- exitChan <- true
- }()
-
- for f := range failures {
- if f.Confidence < w.conf.Confidence {
+ var issues []goanalysis.Issue
+ for failure := range failures {
+ if failure.Confidence < w.conf.Confidence {
continue
}
- formatChan <- f
- }
-
- close(formatChan)
- <-exitChan
-
- var results []jsonObject
- err = json.Unmarshal([]byte(output), &results)
- if err != nil {
- return nil, err
- }
-
- var issues []goanalysis.Issue
- for i := range results {
- issues = append(issues, toIssue(pass, &results[i]))
+ issues = append(issues, w.toIssue(pass, &failure))
}
return issues, nil
}
-func toIssue(pass *analysis.Pass, object *jsonObject) goanalysis.Issue {
- lineRangeTo := object.Position.End.Line
- if object.RuleName == (&rule.ExportedRule{}).Name() {
- lineRangeTo = object.Position.Start.Line
+func (w *wrapper) toIssue(pass *analysis.Pass, failure *lint.Failure) goanalysis.Issue {
+ lineRangeTo := failure.Position.End.Line
+ if failure.RuleName == (&rule.ExportedRule{}).Name() {
+ lineRangeTo = failure.Position.Start.Line
}
issue := &result.Issue{
- Severity: string(object.Severity),
- Text: fmt.Sprintf("%s: %s", object.RuleName, object.Failure.Failure),
+ Severity: string(severity(w.conf, failure)),
+ Text: fmt.Sprintf("%s: %s", failure.RuleName, failure.Failure),
Pos: token.Position{
- Filename: object.Position.Start.Filename,
- Line: object.Position.Start.Line,
- Offset: object.Position.Start.Offset,
- Column: object.Position.Start.Column,
+ Filename: failure.Position.Start.Filename,
+ Line: failure.Position.Start.Line,
+ Offset: failure.Position.Start.Offset,
+ Column: failure.Position.Start.Column,
},
LineRange: &result.Range{
- From: object.Position.Start.Line,
+ From: failure.Position.Start.Line,
To: lineRangeTo,
},
FromLinter: linterName,
}
- if object.ReplacementLine != "" {
- f := pass.Fset.File(token.Pos(object.Position.Start.Offset))
+ if failure.ReplacementLine != "" {
+ f := pass.Fset.File(token.Pos(failure.Position.Start.Offset))
// Skip cgo files because the positions are wrong.
- if object.GetFilename() == f.Name() {
+ if failure.GetFilename() == f.Name() {
issue.SuggestedFixes = []analysis.SuggestedFix{{
TextEdits: []analysis.TextEdit{{
- Pos: f.LineStart(object.Position.Start.Line),
- End: goanalysis.EndOfLinePos(f, object.Position.End.Line),
- NewText: []byte(object.ReplacementLine),
+ Pos: f.LineStart(failure.Position.Start.Line),
+ End: goanalysis.EndOfLinePos(f, failure.Position.End.Line),
+ NewText: []byte(failure.ReplacementLine),
}},
}}
}
@@ -248,12 +209,14 @@ func getConfig(cfg *config.ReviveSettings) (*lint.Config, error) {
func createConfigMap(cfg *config.ReviveSettings) map[string]any {
rawRoot := map[string]any{
- "ignoreGeneratedHeader": cfg.IgnoreGeneratedHeader,
- "confidence": cfg.Confidence,
- "severity": cfg.Severity,
- "errorCode": cfg.ErrorCode,
- "warningCode": cfg.WarningCode,
- "enableAllRules": cfg.EnableAllRules,
+ "confidence": cfg.Confidence,
+ "severity": cfg.Severity,
+ "errorCode": cfg.ErrorCode,
+ "warningCode": cfg.WarningCode,
+ "enableAllRules": cfg.EnableAllRules,
+
+ // Should be managed with `linters.exclusions.generated`.
+ "ignoreGeneratedHeader": false,
}
rawDirectives := map[string]map[string]any{}
@@ -487,3 +450,15 @@ func extractRulesName(rules []lint.Rule) []string {
return names
}
+
+// Extracted from https://github.com/mgechev/revive/blob/v1.7.0/formatter/severity.go
+// Modified to use pointers (related to hugeParam rule).
+func severity(cfg *lint.Config, failure *lint.Failure) lint.Severity {
+ if cfg, ok := cfg.Rules[failure.RuleName]; ok && cfg.Severity == lint.SeverityError {
+ return lint.SeverityError
+ }
+ if cfg, ok := cfg.Directives[failure.RuleName]; ok && cfg.Severity == lint.SeverityError {
+ return lint.SeverityError
+ }
+ return lint.SeverityWarning
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/rowserrcheck/rowserrcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck/rowserrcheck.go
similarity index 81%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/rowserrcheck/rowserrcheck.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck/rowserrcheck.go
index 3fe82446..2bd975dd 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/rowserrcheck/rowserrcheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck/rowserrcheck.go
@@ -4,8 +4,8 @@ import (
"github.com/jingyugao/rowserrcheck/passes/rowserr"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.RowsErrCheckSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/sloglint/sloglint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint/sloglint.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/sloglint/sloglint.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint/sloglint.go
index 48666257..021157dd 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/sloglint/sloglint.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint/sloglint.go
@@ -4,8 +4,8 @@ import (
"go-simpler.org/sloglint"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.SlogLintSettings) *goanalysis.Linter {
@@ -18,6 +18,7 @@ func New(settings *config.SlogLintSettings) *goanalysis.Linter {
NoGlobal: settings.NoGlobal,
ContextOnly: settings.Context,
StaticMsg: settings.StaticMsg,
+ MsgStyle: settings.MsgStyle,
NoRawKeys: settings.NoRawKeys,
KeyNamingCase: settings.KeyNamingCase,
ForbiddenKeys: settings.ForbiddenKeys,
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/spancheck/spancheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/spancheck/spancheck.go
similarity index 87%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/spancheck/spancheck.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/spancheck/spancheck.go
index efdc1d0b..26462305 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/spancheck/spancheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/spancheck/spancheck.go
@@ -4,8 +4,8 @@ import (
"github.com/jjti/go-spancheck"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.SpancheckSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/sqlclosecheck/sqlclosecheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck/sqlclosecheck.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/sqlclosecheck/sqlclosecheck.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck/sqlclosecheck.go
index 5eb32ff9..7f7e70c7 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/sqlclosecheck/sqlclosecheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck/sqlclosecheck.go
@@ -4,7 +4,7 @@ import (
"github.com/ryanrolds/sqlclosecheck/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/staticcheck_common.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/staticcheck/staticcheck.go
similarity index 74%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/staticcheck_common.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/staticcheck/staticcheck.go
index e5a0e33b..1ec39244 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/staticcheck_common.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/staticcheck/staticcheck.go
@@ -1,40 +1,50 @@
-package internal
+package staticcheck
import (
+ "slices"
"strings"
"unicode"
"golang.org/x/tools/go/analysis"
"honnef.co/go/tools/analysis/lint"
scconfig "honnef.co/go/tools/config"
+ "honnef.co/go/tools/quickfix"
+ "honnef.co/go/tools/simple"
+ "honnef.co/go/tools/staticcheck"
+ "honnef.co/go/tools/stylecheck"
- "github.com/golangci/golangci-lint/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
-func SetupStaticCheckAnalyzers(src []*lint.Analyzer, checks []string) []*analysis.Analyzer {
- var names []string
- for _, a := range src {
- names = append(names, a.Analyzer.Name)
+func New(settings *config.StaticCheckSettings) *goanalysis.Linter {
+ cfg := createConfig(settings)
+
+ // `scconfig.Analyzer` is a singleton.
+ scconfig.Analyzer.Run = func(_ *analysis.Pass) (any, error) {
+ return cfg, nil
}
- filter := filterAnalyzerNames(names, checks)
+ allAnalyzers := slices.Concat(staticcheck.Analyzers, stylecheck.Analyzers, simple.Analyzers, quickfix.Analyzers)
- var ret []*analysis.Analyzer
- for _, a := range src {
- if filter[a.Analyzer.Name] {
- ret = append(ret, a.Analyzer)
- }
- }
+ analyzers := setupAnalyzers(allAnalyzers, cfg.Checks)
- return ret
+ return goanalysis.NewLinter(
+ "staticcheck",
+ "It's the set of rules from staticcheck.",
+ analyzers,
+ nil,
+ ).WithLoadMode(goanalysis.LoadModeTypesInfo)
}
-func StaticCheckConfig(settings *config.StaticCheckSettings) *scconfig.Config {
+func createConfig(settings *config.StaticCheckSettings) *scconfig.Config {
+ defaultChecks := []string{"all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"}
+
var cfg *scconfig.Config
if settings == nil || !settings.HasConfiguration() {
return &scconfig.Config{
- Checks: []string{"*"}, // override for compatibility reason. Must drop in the next major version.
+ Checks: defaultChecks,
Initialisms: scconfig.DefaultConfig.Initialisms,
DotImportWhitelist: scconfig.DefaultConfig.DotImportWhitelist,
HTTPStatusCodeWhitelist: scconfig.DefaultConfig.HTTPStatusCodeWhitelist,
@@ -49,7 +59,7 @@ func StaticCheckConfig(settings *config.StaticCheckSettings) *scconfig.Config {
}
if len(cfg.Checks) == 0 {
- cfg.Checks = append(cfg.Checks, "*") // override for compatibility reason. Must drop in the next major version.
+ cfg.Checks = defaultChecks
}
if len(cfg.Initialisms) == 0 {
@@ -72,6 +82,48 @@ func StaticCheckConfig(settings *config.StaticCheckSettings) *scconfig.Config {
return cfg
}
+// https://github.com/dominikh/go-tools/blob/9bf17c0388a65710524ba04c2d821469e639fdc2/config/config.go#L95-L116
+func normalizeList(list []string) []string {
+ if len(list) > 1 {
+ nlist := make([]string, 0, len(list))
+ nlist = append(nlist, list[0])
+ for i, el := range list[1:] {
+ if el != list[i] {
+ nlist = append(nlist, el)
+ }
+ }
+ list = nlist
+ }
+
+ for _, el := range list {
+ if el == "inherit" {
+ // This should never happen, because the default config
+ // should not use "inherit"
+ panic(`unresolved "inherit"`)
+ }
+ }
+
+ return list
+}
+
+func setupAnalyzers(src []*lint.Analyzer, checks []string) []*analysis.Analyzer {
+ var names []string
+ for _, a := range src {
+ names = append(names, a.Analyzer.Name)
+ }
+
+ filter := filterAnalyzerNames(names, checks)
+
+ var ret []*analysis.Analyzer
+ for _, a := range src {
+ if filter[a.Analyzer.Name] {
+ ret = append(ret, a.Analyzer)
+ }
+ }
+
+ return ret
+}
+
// https://github.com/dominikh/go-tools/blob/9bf17c0388a65710524ba04c2d821469e639fdc2/lintcmd/lint.go#L437-L477
//
//nolint:gocritic // Keep the original source code.
@@ -117,27 +169,3 @@ func filterAnalyzerNames(analyzers []string, checks []string) map[string]bool {
}
return allowedChecks
}
-
-// https://github.com/dominikh/go-tools/blob/9bf17c0388a65710524ba04c2d821469e639fdc2/config/config.go#L95-L116
-func normalizeList(list []string) []string {
- if len(list) > 1 {
- nlist := make([]string, 0, len(list))
- nlist = append(nlist, list[0])
- for i, el := range list[1:] {
- if el != list[i] {
- nlist = append(nlist, el)
- }
- }
- list = nlist
- }
-
- for _, el := range list {
- if el == "inherit" {
- // This should never happen, because the default config
- // should not use "inherit"
- panic(`unresolved "inherit"`)
- }
- }
-
- return list
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tagalign/tagalign.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagalign/tagalign.go
similarity index 88%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/tagalign/tagalign.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagalign/tagalign.go
index 7c8a0c8b..412d69b9 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tagalign/tagalign.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagalign/tagalign.go
@@ -4,8 +4,8 @@ import (
"github.com/4meepo/tagalign"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.TagAlignSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tagliatelle/tagliatelle.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagliatelle/tagliatelle.go
similarity index 93%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/tagliatelle/tagliatelle.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagliatelle/tagliatelle.go
index 08215c3a..f6357e0e 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tagliatelle/tagliatelle.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagliatelle/tagliatelle.go
@@ -4,8 +4,8 @@ import (
"github.com/ldez/tagliatelle"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.TagliatelleSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testableexamples/testableexamples.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testableexamples/testableexamples.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/testableexamples/testableexamples.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testableexamples/testableexamples.go
index 6b76271d..38334a09 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testableexamples/testableexamples.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testableexamples/testableexamples.go
@@ -4,7 +4,7 @@ import (
"github.com/maratori/testableexamples/pkg/testableexamples"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testifylint/testifylint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testifylint/testifylint.go
similarity index 88%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/testifylint/testifylint.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testifylint/testifylint.go
index b3f2f0bd..b19471c1 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testifylint/testifylint.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testifylint/testifylint.go
@@ -4,8 +4,8 @@ import (
"github.com/Antonboom/testifylint/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.TestifylintSettings) *goanalysis.Linter {
@@ -19,6 +19,7 @@ func New(settings *config.TestifylintSettings) *goanalysis.Linter {
"bool-compare.ignore-custom-types": settings.BoolCompare.IgnoreCustomTypes,
"formatter.require-f-funcs": settings.Formatter.RequireFFuncs,
+ "formatter.require-string-msg": settings.Formatter.RequireStringMsg,
"go-require.ignore-http-handlers": settings.GoRequire.IgnoreHTTPHandlers,
}
if len(settings.EnabledCheckers) > 0 {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testpackage/testpackage.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testpackage/testpackage.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/testpackage/testpackage.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testpackage/testpackage.go
index f617da55..ddd5ce95 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testpackage/testpackage.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testpackage/testpackage.go
@@ -6,8 +6,8 @@ import (
"github.com/maratori/testpackage/pkg/testpackage"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.TestpackageSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/thelper/thelper.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/thelper/thelper.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/thelper/thelper.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/thelper/thelper.go
index 04503b9c..d9058582 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/thelper/thelper.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/thelper/thelper.go
@@ -8,9 +8,9 @@ import (
"github.com/kulti/thelper/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
)
func New(settings *config.ThelperSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tparallel/tparallel.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tparallel/tparallel.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/tparallel/tparallel.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tparallel/tparallel.go
index 4f7c43a9..f3ce2fcf 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tparallel/tparallel.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tparallel/tparallel.go
@@ -4,7 +4,7 @@ import (
"github.com/moricho/tparallel"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/typecheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/typecheck.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/typecheck.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/typecheck.go
index d0eaa00d..ad51e8d0 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/typecheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/typecheck.go
@@ -3,7 +3,7 @@ package golinters
import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func NewTypecheck() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/unconvert/unconvert.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unconvert/unconvert.go
similarity index 72%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/unconvert/unconvert.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unconvert/unconvert.go
index 954cc9eb..d48cf517 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/unconvert/unconvert.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unconvert/unconvert.go
@@ -6,10 +6,10 @@ import (
"github.com/golangci/unconvert"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "unconvert"
@@ -18,11 +18,14 @@ func New(settings *config.UnconvertSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []goanalysis.Issue
+ unconvert.SetFastMath(settings.FastMath)
+ unconvert.SetSafe(settings.Safe)
+
analyzer := &analysis.Analyzer{
Name: linterName,
Doc: goanalysis.TheOnlyanalyzerDoc,
Run: func(pass *analysis.Pass) (any, error) {
- issues := runUnconvert(pass, settings)
+ issues := runUnconvert(pass)
if len(issues) == 0 {
return nil, nil
@@ -46,8 +49,8 @@ func New(settings *config.UnconvertSettings) *goanalysis.Linter {
}).WithLoadMode(goanalysis.LoadModeTypesInfo)
}
-func runUnconvert(pass *analysis.Pass, settings *config.UnconvertSettings) []goanalysis.Issue {
- positions := unconvert.Run(pass, settings.FastMath, settings.Safe)
+func runUnconvert(pass *analysis.Pass) []goanalysis.Issue {
+ positions := unconvert.Run(pass)
var issues []goanalysis.Issue
for _, position := range positions {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/unparam/unparam.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unparam/unparam.go
similarity index 77%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/unparam/unparam.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unparam/unparam.go
index 04c9a223..5a9bc8a5 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/unparam/unparam.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unparam/unparam.go
@@ -6,9 +6,8 @@ import (
"golang.org/x/tools/go/packages"
"mvdan.cc/unparam/check"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
const linterName = "unparam"
@@ -33,11 +32,7 @@ func New(settings *config.UnparamSettings) *goanalysis.Linter {
"Reports unused function parameters",
[]*analysis.Analyzer{analyzer},
nil,
- ).WithContextSetter(func(lintCtx *linter.Context) {
- if settings.Algo != "cha" {
- lintCtx.Log.Warnf("`linters-settings.unparam.algo` isn't supported by the newest `unparam`")
- }
- }).WithLoadMode(goanalysis.LoadModeTypesInfo)
+ ).WithLoadMode(goanalysis.LoadModeTypesInfo)
}
func runUnparam(pass *analysis.Pass, settings *config.UnparamSettings) error {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/unused/unused.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unused/unused.go
similarity index 93%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/unused/unused.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unused/unused.go
index 7b2b478f..37596225 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/unused/unused.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unused/unused.go
@@ -10,10 +10,10 @@ import (
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/unused"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const linterName = "unused"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/usestdlibvars/usestdlibvars.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usestdlibvars/usestdlibvars.go
similarity index 78%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/usestdlibvars/usestdlibvars.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usestdlibvars/usestdlibvars.go
index 00f7d974..f0b5f542 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/usestdlibvars/usestdlibvars.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usestdlibvars/usestdlibvars.go
@@ -4,8 +4,8 @@ import (
"github.com/sashamelentyev/usestdlibvars/pkg/analyzer"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.UseStdlibVarsSettings) *goanalysis.Linter {
@@ -18,10 +18,10 @@ func New(settings *config.UseStdlibVarsSettings) *goanalysis.Linter {
analyzer.CryptoHashFlag: settings.CryptoHash,
analyzer.HTTPMethodFlag: settings.HTTPMethod,
analyzer.HTTPStatusCodeFlag: settings.HTTPStatusCode,
- analyzer.OSDevNullFlag: settings.OSDevNull != nil && *settings.OSDevNull,
+ analyzer.OSDevNullFlag: false, // Noop because the linter ignore it.
analyzer.RPCDefaultPathFlag: settings.DefaultRPCPath,
analyzer.SQLIsolationLevelFlag: settings.SQLIsolationLevel,
- analyzer.SyslogPriorityFlag: settings.SyslogPriority != nil && *settings.SyslogPriority,
+ analyzer.SyslogPriorityFlag: false, // Noop because the linter ignore it.
analyzer.TimeLayoutFlag: settings.TimeLayout,
analyzer.TimeMonthFlag: settings.TimeMonth,
analyzer.TimeWeekdayFlag: settings.TimeWeekday,
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/usetesting/usetesting.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usetesting/usetesting.go
similarity index 87%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/usetesting/usetesting.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usetesting/usetesting.go
index a21742fb..5dfa9f11 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/usetesting/usetesting.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usetesting/usetesting.go
@@ -4,8 +4,8 @@ import (
"github.com/ldez/usetesting"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.UseTestingSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/varnamelen/varnamelen.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/varnamelen/varnamelen.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/varnamelen/varnamelen.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/varnamelen/varnamelen.go
index 6cb57ffa..dbd8005e 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/varnamelen/varnamelen.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/varnamelen/varnamelen.go
@@ -7,8 +7,8 @@ import (
"github.com/blizzy78/varnamelen"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.VarnamelenSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wastedassign/wastedassign.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wastedassign/wastedassign.go
similarity index 85%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/wastedassign/wastedassign.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wastedassign/wastedassign.go
index 094fa95c..6599f7d4 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wastedassign/wastedassign.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wastedassign/wastedassign.go
@@ -4,7 +4,7 @@ import (
"github.com/sanposhiho/wastedassign/v2"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/whitespace/whitespace.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/whitespace/whitespace.go
similarity index 82%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/whitespace/whitespace.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/whitespace/whitespace.go
index d45969ef..cd7fda1c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/whitespace/whitespace.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/whitespace/whitespace.go
@@ -4,8 +4,8 @@ import (
"github.com/ultraware/whitespace"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.WhitespaceSettings) *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wrapcheck/wrapcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wrapcheck/wrapcheck.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/wrapcheck/wrapcheck.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wrapcheck/wrapcheck.go
index b2f5ec74..8a4427f7 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wrapcheck/wrapcheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wrapcheck/wrapcheck.go
@@ -4,14 +4,16 @@ import (
"github.com/tomarrell/wrapcheck/v2/wrapcheck"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.WrapcheckSettings) *goanalysis.Linter {
cfg := wrapcheck.NewDefaultConfig()
+
if settings != nil {
cfg.ExtraIgnoreSigs = settings.ExtraIgnoreSigs
+ cfg.ReportInternalErrors = settings.ReportInternalErrors
if len(settings.IgnoreSigs) != 0 {
cfg.IgnoreSigs = settings.IgnoreSigs
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wsl/wsl.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/wsl/wsl.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl.go
index c728340e..12148627 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wsl/wsl.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl.go
@@ -4,8 +4,8 @@ import (
"github.com/bombsimon/wsl/v4"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New(settings *config.WSLSettings) *goanalysis.Linter {
@@ -23,6 +23,7 @@ func New(settings *config.WSLSettings) *goanalysis.Linter {
AllowCuddleWithCalls: settings.AllowCuddleWithCalls,
AllowCuddleWithRHS: settings.AllowCuddleWithRHS,
ForceCuddleErrCheckAndAssign: settings.ForceCuddleErrCheckAndAssign,
+ AllowCuddleUsedInBlock: settings.AllowCuddleUsedInBlock,
ErrorVariableNames: settings.ErrorVariableNames,
ForceExclusiveShortDeclarations: settings.ForceExclusiveShortDeclarations,
IncludeGenerated: true, // force to true because golangci-lint already have a way to filter generated files.
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/zerologlint/zerologlint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/zerologlint/zerologlint.go
similarity index 84%
rename from vendor/github.com/golangci/golangci-lint/pkg/golinters/zerologlint/zerologlint.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/zerologlint/zerologlint.go
index 6ca74020..0daf0d48 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/zerologlint/zerologlint.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/zerologlint/zerologlint.go
@@ -4,7 +4,7 @@ import (
"github.com/ykadowak/zerologlint"
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
func New() *goanalysis.Linter {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goutil/env.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/env.go
similarity index 93%
rename from vendor/github.com/golangci/golangci-lint/pkg/goutil/env.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/env.go
index beb71f72..89e1634c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/goutil/env.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/env.go
@@ -8,7 +8,7 @@ import (
"github.com/ldez/grignotin/goenv"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type EnvKey string
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goutil/version.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/version.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/goutil/version.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/version.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/context.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/context.go
similarity index 78%
rename from vendor/github.com/golangci/golangci-lint/pkg/lint/context.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/lint/context.go
index 2ac5a2d2..e8e8cc36 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/context.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/context.go
@@ -4,12 +4,12 @@ import (
"context"
"fmt"
- "github.com/golangci/golangci-lint/internal/cache"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/exitcodes"
- "github.com/golangci/golangci-lint/pkg/goanalysis/load"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/internal/cache"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/exitcodes"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type ContextBuilder struct {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/config.go
similarity index 73%
rename from vendor/github.com/golangci/golangci-lint/pkg/lint/linter/config.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/config.go
index 20bed6a7..a7a9a68d 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/config.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/config.go
@@ -5,23 +5,7 @@ import (
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/pkg/config"
-)
-
-const (
- PresetBugs = "bugs" // Related to bugs detection.
- PresetComment = "comment" // Related to comments analysis.
- PresetComplexity = "complexity" // Related to code complexity analysis.
- PresetError = "error" // Related to error handling analysis.
- PresetFormatting = "format" // Related to code formatting.
- PresetImport = "import" // Related to imports analysis.
- PresetMetaLinter = "metalinter" // Related to linter that contains multiple rules or multiple linters.
- PresetModule = "module" // Related to Go modules analysis.
- PresetPerformance = "performance" // Related to performance.
- PresetSQL = "sql" // Related to SQL.
- PresetStyle = "style" // Related to coding style.
- PresetTest = "test" // Related to the analysis of the code of the tests.
- PresetUnused = "unused" // Related to the detection of unused code.
+ "github.com/golangci/golangci-lint/v2/pkg/config"
)
// LastLinter nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives.
@@ -43,12 +27,11 @@ type Deprecation struct {
}
type Config struct {
- Linter Linter
- EnabledByDefault bool
+ Linter Linter
+ Groups map[string]struct{}
LoadMode packages.LoadMode
- InPresets []string
AlternativeNames []string
OriginalURL string // URL of original (not forked) repo, needed for autogenerated README
@@ -61,9 +44,11 @@ type Config struct {
Deprecation *Deprecation
}
-func (lc *Config) WithEnabledByDefault() *Config {
- lc.EnabledByDefault = true
- return lc
+func NewConfig(linter Linter) *Config {
+ lc := &Config{
+ Linter: linter,
+ }
+ return lc.WithLoadFiles()
}
func (lc *Config) WithInternal() *Config {
@@ -92,11 +77,23 @@ func (lc *Config) WithLoadForGoAnalysis() *Config {
return lc
}
-func (lc *Config) WithPresets(presets ...string) *Config {
- lc.InPresets = presets
+func (lc *Config) WithGroups(names ...string) *Config {
+ if lc.Groups == nil {
+ lc.Groups = make(map[string]struct{})
+ }
+
+ for _, name := range names {
+ lc.Groups[name] = struct{}{}
+ }
+
return lc
}
+func (lc *Config) FromGroup(name string) bool {
+ _, ok := lc.Groups[name]
+ return ok
+}
+
func (lc *Config) WithURL(url string) *Config {
lc.OriginalURL = url
return lc
@@ -176,10 +173,3 @@ func isGoLowerThanGo(v string) func(cfg *config.Config) error {
return fmt.Errorf("this linter is disabled because the Go version (%s) of your project is lower than Go %s", cfg.Run.Go, v)
}
}
-
-func NewConfig(linter Linter) *Config {
- lc := &Config{
- Linter: linter,
- }
- return lc.WithLoadFiles()
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/context.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/context.go
similarity index 74%
rename from vendor/github.com/golangci/golangci-lint/pkg/lint/linter/context.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/context.go
index 6986b623..cf463ea9 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/context.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/context.go
@@ -5,10 +5,10 @@ import (
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/internal/cache"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis/load"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/internal/cache"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type Context struct {
@@ -27,7 +27,7 @@ type Context struct {
}
func (c *Context) Settings() *config.LintersSettings {
- return &c.Cfg.LintersSettings
+ return &c.Cfg.Linters.Settings
}
func (c *Context) ClearTypesInPackages() {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/linter.go
similarity index 91%
rename from vendor/github.com/golangci/golangci-lint/pkg/lint/linter/linter.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/linter.go
index 088aa3d7..7f68545c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/linter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/linter.go
@@ -3,8 +3,8 @@ package linter
import (
"context"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
type Linter interface {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go
new file mode 100644
index 00000000..5ac3e5ba
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go
@@ -0,0 +1,687 @@
+package lintersdb
+
+import (
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/asasalint"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/asciicheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/copyloopvar"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/cyclop"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/decorder"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/depguard"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/dogsled"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/dupl"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/dupword"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/durationcheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/err113"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/errcheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/errchkjson"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/errname"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/errorlint"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustive"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustruct"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/exptostd"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/fatcontext"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/forbidigo"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/forcetypeassert"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/funcorder"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/funlen"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gci"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/ginkgolinter"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckcompilerdirectives"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoglobals"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoinits"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gochecksumtype"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gocognit"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/goconst"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gocyclo"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/godot"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/godox"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gofmt"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gofumpt"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/goheader"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/goimports"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/golines"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gomoddirectives"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/goprintffuncname"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gosec"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/gosmopolitan"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/govet"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/grouper"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/iface"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/importas"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/inamedparam"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/ineffassign"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/interfacebloat"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/intrange"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/ireturn"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/lll"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/loggercheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/maintidx"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/makezero"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/mirror"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/misspell"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/mnd"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/musttag"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/nakedret"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/nestif"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/nilerr"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/nilnesserr"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/nilnil"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/nlreturn"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/noctx"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/nonamedreturns"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/nosprintfhostport"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/perfsprint"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/predeclared"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/promlinter"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/protogetter"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/reassign"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/recvcheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/revive"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/spancheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/staticcheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/tagalign"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/tagliatelle"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/testableexamples"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/testifylint"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/testpackage"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/thelper"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/tparallel"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/unconvert"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/unparam"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/unused"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/usestdlibvars"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/usetesting"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/varnamelen"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/wastedassign"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/whitespace"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/wrapcheck"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/wsl"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/zerologlint"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+)
+
+// LinterBuilder builds the "internal" linters based on the configuration.
+type LinterBuilder struct{}
+
+// NewLinterBuilder creates a new LinterBuilder.
+func NewLinterBuilder() *LinterBuilder {
+ return &LinterBuilder{}
+}
+
+// Build loads all the "internal" linters.
+// The configuration is use for the linter settings.
+func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
+ if cfg == nil {
+ return nil, nil
+ }
+
+ placeholderReplacer := config.NewPlaceholderReplacer(cfg)
+
+ // The linters are sorted in the alphabetical order (case-insensitive).
+ // When a new linter is added the version in `WithSince(...)` must be the next minor version of golangci-lint.
+ return []*linter.Config{
+ linter.NewConfig(asasalint.New(&cfg.Linters.Settings.Asasalint)).
+ WithSince("v1.47.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/alingse/asasalint"),
+
+ linter.NewConfig(asciicheck.New()).
+ WithSince("v1.26.0").
+ WithURL("https://github.com/tdakkota/asciicheck"),
+
+ linter.NewConfig(bidichk.New(&cfg.Linters.Settings.BiDiChk)).
+ WithSince("v1.43.0").
+ WithURL("https://github.com/breml/bidichk"),
+
+ linter.NewConfig(bodyclose.New()).
+ WithSince("v1.18.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/timakin/bodyclose"),
+
+ linter.NewConfig(canonicalheader.New()).
+ WithSince("v1.58.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/lasiar/canonicalheader"),
+
+ linter.NewConfig(containedctx.New()).
+ WithSince("v1.44.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/sivchari/containedctx"),
+
+ linter.NewConfig(contextcheck.New()).
+ WithSince("v1.43.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/kkHAIKE/contextcheck"),
+
+ linter.NewConfig(copyloopvar.New(&cfg.Linters.Settings.CopyLoopVar)).
+ WithSince("v1.57.0").
+ WithAutoFix().
+ WithURL("https://github.com/karamaru-alpha/copyloopvar").
+ WithNoopFallback(cfg, linter.IsGoLowerThanGo122()),
+
+ linter.NewConfig(cyclop.New(&cfg.Linters.Settings.Cyclop)).
+ WithSince("v1.37.0").
+ WithURL("https://github.com/bkielbasa/cyclop"),
+
+ linter.NewConfig(decorder.New(&cfg.Linters.Settings.Decorder)).
+ WithSince("v1.44.0").
+ WithURL("https://gitlab.com/bosi/decorder"),
+
+ linter.NewConfig(depguard.New(&cfg.Linters.Settings.Depguard, placeholderReplacer)).
+ WithSince("v1.4.0").
+ WithURL("https://github.com/OpenPeeDeeP/depguard"),
+
+ linter.NewConfig(dogsled.New(&cfg.Linters.Settings.Dogsled)).
+ WithSince("v1.19.0").
+ WithURL("https://github.com/alexkohler/dogsled"),
+
+ linter.NewConfig(dupl.New(&cfg.Linters.Settings.Dupl)).
+ WithSince("v1.0.0").
+ WithURL("https://github.com/mibk/dupl"),
+
+ linter.NewConfig(dupword.New(&cfg.Linters.Settings.DupWord)).
+ WithSince("v1.50.0").
+ WithAutoFix().
+ WithURL("https://github.com/Abirdcfly/dupword"),
+
+ linter.NewConfig(durationcheck.New()).
+ WithSince("v1.37.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/charithe/durationcheck"),
+
+ linter.NewConfig(errcheck.New(&cfg.Linters.Settings.Errcheck)).
+ WithGroups(config.GroupStandard).
+ WithSince("v1.0.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/kisielk/errcheck"),
+
+ linter.NewConfig(errchkjson.New(&cfg.Linters.Settings.ErrChkJSON)).
+ WithSince("v1.44.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/breml/errchkjson"),
+
+ linter.NewConfig(errname.New()).
+ WithSince("v1.42.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/Antonboom/errname"),
+
+ linter.NewConfig(errorlint.New(&cfg.Linters.Settings.ErrorLint)).
+ WithSince("v1.32.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/polyfloyd/go-errorlint"),
+
+ linter.NewConfig(exhaustive.New(&cfg.Linters.Settings.Exhaustive)).
+ WithSince(" v1.28.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/nishanths/exhaustive"),
+
+ linter.NewConfig(exhaustruct.New(&cfg.Linters.Settings.Exhaustruct)).
+ WithSince("v1.46.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/GaijinEntertainment/go-exhaustruct"),
+
+ linter.NewConfig(exptostd.New()).
+ WithSince("v1.63.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/ldez/exptostd"),
+
+ linter.NewConfig(forbidigo.New(&cfg.Linters.Settings.Forbidigo)).
+ WithSince("v1.34.0").
+ // Strictly speaking,
+ // the additional information is only needed when forbidigoCfg.AnalyzeTypes is chosen by the user.
+ // But we don't know that here in all cases (sometimes config is not loaded),
+ // so we have to assume that it is needed to be on the safe side.
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/ashanbrown/forbidigo"),
+
+ linter.NewConfig(forcetypeassert.New()).
+ WithSince("v1.38.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/gostaticanalysis/forcetypeassert"),
+
+ linter.NewConfig(funcorder.New(&cfg.Linters.Settings.FuncOrder)).
+ WithSince("v2.1.0").
+ WithURL("https://github.com/manuelarte/funcorder"),
+
+ linter.NewConfig(fatcontext.New(&cfg.Linters.Settings.Fatcontext)).
+ WithSince("v1.58.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/Crocmagnon/fatcontext"),
+
+ linter.NewConfig(funlen.New(&cfg.Linters.Settings.Funlen)).
+ WithSince("v1.18.0").
+ WithURL("https://github.com/ultraware/funlen"),
+
+ linter.NewConfig(gci.New(&cfg.Linters.Settings.Gci)).
+ WithSince("v1.30.0").
+ WithAutoFix().
+ WithURL("https://github.com/daixiang0/gci"),
+
+ linter.NewConfig(ginkgolinter.New(&cfg.Linters.Settings.GinkgoLinter)).
+ WithSince("v1.51.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/nunnatsa/ginkgolinter"),
+
+ linter.NewConfig(gocheckcompilerdirectives.New()).
+ WithSince("v1.51.0").
+ WithURL("https://github.com/leighmcculloch/gocheckcompilerdirectives"),
+
+ linter.NewConfig(gochecknoglobals.New()).
+ WithSince("v1.12.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/leighmcculloch/gochecknoglobals"),
+
+ linter.NewConfig(gochecknoinits.New()).
+ WithSince("v1.12.0"),
+
+ linter.NewConfig(gochecksumtype.New(&cfg.Linters.Settings.GoChecksumType)).
+ WithSince("v1.55.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/alecthomas/go-check-sumtype"),
+
+ linter.NewConfig(gocognit.New(&cfg.Linters.Settings.Gocognit)).
+ WithSince("v1.20.0").
+ WithURL("https://github.com/uudashr/gocognit"),
+
+ linter.NewConfig(goconst.New(&cfg.Linters.Settings.Goconst)).
+ WithSince("v1.0.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/jgautheron/goconst"),
+
+ linter.NewConfig(gocritic.New(&cfg.Linters.Settings.Gocritic, placeholderReplacer)).
+ WithSince("v1.12.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/go-critic/go-critic"),
+
+ linter.NewConfig(gocyclo.New(&cfg.Linters.Settings.Gocyclo)).
+ WithSince("v1.0.0").
+ WithURL("https://github.com/fzipp/gocyclo"),
+
+ linter.NewConfig(godot.New(&cfg.Linters.Settings.Godot)).
+ WithSince("v1.25.0").
+ WithAutoFix().
+ WithURL("https://github.com/tetafro/godot"),
+
+ linter.NewConfig(godox.New(&cfg.Linters.Settings.Godox)).
+ WithSince("v1.19.0").
+ WithURL("https://github.com/matoous/godox"),
+
+ linter.NewConfig(err113.New()).
+ WithSince("v1.26.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/Djarvur/go-err113"),
+
+ linter.NewConfig(gofmt.New(&cfg.Linters.Settings.GoFmt)).
+ WithSince("v1.0.0").
+ WithAutoFix().
+ WithURL("https://pkg.go.dev/cmd/gofmt"),
+
+ linter.NewConfig(gofumpt.New(&cfg.Linters.Settings.GoFumpt)).
+ WithSince("v1.28.0").
+ WithAutoFix().
+ WithURL("https://github.com/mvdan/gofumpt"),
+
+ linter.NewConfig(golines.New(&cfg.Linters.Settings.GoLines)).
+ WithSince("v2.0.0").
+ WithAutoFix().
+ WithURL("https://github.com/segmentio/golines"),
+
+ linter.NewConfig(goheader.New(&cfg.Linters.Settings.Goheader, placeholderReplacer)).
+ WithSince("v1.28.0").
+ WithAutoFix().
+ WithURL("https://github.com/denis-tingaikin/go-header"),
+
+ linter.NewConfig(goimports.New(&cfg.Linters.Settings.GoImports)).
+ WithSince("v1.20.0").
+ WithAutoFix().
+ WithURL("https://pkg.go.dev/golang.org/x/tools/cmd/goimports"),
+
+ linter.NewConfig(mnd.New(&cfg.Linters.Settings.Mnd)).
+ WithSince("v1.22.0").
+ WithURL("https://github.com/tommy-muehle/go-mnd"),
+
+ linter.NewConfig(gomoddirectives.New(&cfg.Linters.Settings.GoModDirectives)).
+ WithSince("v1.39.0").
+ WithURL("https://github.com/ldez/gomoddirectives"),
+
+ linter.NewConfig(gomodguard.New(&cfg.Linters.Settings.Gomodguard)).
+ WithSince("v1.25.0").
+ WithURL("https://github.com/ryancurrah/gomodguard"),
+
+ linter.NewConfig(goprintffuncname.New()).
+ WithSince("v1.23.0").
+ WithURL("https://github.com/golangci/go-printf-func-name"),
+
+ linter.NewConfig(gosec.New(&cfg.Linters.Settings.Gosec)).
+ WithSince("v1.0.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/securego/gosec"),
+
+ linter.NewConfig(gosmopolitan.New(&cfg.Linters.Settings.Gosmopolitan)).
+ WithSince("v1.53.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/xen0n/gosmopolitan"),
+
+ linter.NewConfig(govet.New(&cfg.Linters.Settings.Govet)).
+ WithGroups(config.GroupStandard).
+ WithSince("v1.0.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://pkg.go.dev/cmd/vet"),
+
+ linter.NewConfig(grouper.New(&cfg.Linters.Settings.Grouper)).
+ WithSince("v1.44.0").
+ WithURL("https://github.com/leonklingele/grouper"),
+
+ linter.NewConfig(iface.New(&cfg.Linters.Settings.Iface)).
+ WithSince("v1.62.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/uudashr/iface"),
+
+ linter.NewConfig(importas.New(&cfg.Linters.Settings.ImportAs)).
+ WithSince("v1.38.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/julz/importas"),
+
+ linter.NewConfig(inamedparam.New(&cfg.Linters.Settings.Inamedparam)).
+ WithSince("v1.55.0").
+ WithURL("https://github.com/macabu/inamedparam"),
+
+ linter.NewConfig(ineffassign.New()).
+ WithGroups(config.GroupStandard).
+ WithSince("v1.0.0").
+ WithURL("https://github.com/gordonklaus/ineffassign"),
+
+ linter.NewConfig(interfacebloat.New(&cfg.Linters.Settings.InterfaceBloat)).
+ WithSince("v1.49.0").
+ WithURL("https://github.com/sashamelentyev/interfacebloat"),
+
+ linter.NewConfig(intrange.New()).
+ WithSince("v1.57.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/ckaznocha/intrange").
+ WithNoopFallback(cfg, linter.IsGoLowerThanGo122()),
+
+ linter.NewConfig(ireturn.New(&cfg.Linters.Settings.Ireturn)).
+ WithSince("v1.43.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/butuzov/ireturn"),
+
+ linter.NewConfig(lll.New(&cfg.Linters.Settings.Lll)).
+ WithSince("v1.8.0"),
+
+ linter.NewConfig(loggercheck.New(&cfg.Linters.Settings.LoggerCheck)).
+ WithSince("v1.49.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/timonwong/loggercheck"),
+
+ linter.NewConfig(maintidx.New(&cfg.Linters.Settings.MaintIdx)).
+ WithSince("v1.44.0").
+ WithURL("https://github.com/yagipy/maintidx"),
+
+ linter.NewConfig(makezero.New(&cfg.Linters.Settings.Makezero)).
+ WithSince("v1.34.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/ashanbrown/makezero"),
+
+ linter.NewConfig(mirror.New()).
+ WithSince("v1.53.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/butuzov/mirror"),
+
+ linter.NewConfig(misspell.New(&cfg.Linters.Settings.Misspell)).
+ WithSince("v1.8.0").
+ WithAutoFix().
+ WithURL("https://github.com/golangci/misspell"),
+
+ linter.NewConfig(musttag.New(&cfg.Linters.Settings.MustTag)).
+ WithSince("v1.51.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/go-simpler/musttag"),
+
+ linter.NewConfig(nakedret.New(&cfg.Linters.Settings.Nakedret)).
+ WithSince("v1.19.0").
+ WithAutoFix().
+ WithURL("https://github.com/alexkohler/nakedret"),
+
+ linter.NewConfig(nestif.New(&cfg.Linters.Settings.Nestif)).
+ WithSince("v1.25.0").
+ WithURL("https://github.com/nakabonne/nestif"),
+
+ linter.NewConfig(nilerr.New()).
+ WithSince("v1.38.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/gostaticanalysis/nilerr"),
+
+ linter.NewConfig(nilnesserr.New()).
+ WithSince("v1.63.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/alingse/nilnesserr"),
+
+ linter.NewConfig(nilnil.New(&cfg.Linters.Settings.NilNil)).
+ WithSince("v1.43.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/Antonboom/nilnil"),
+
+ linter.NewConfig(nlreturn.New(&cfg.Linters.Settings.Nlreturn)).
+ WithSince("v1.30.0").
+ WithAutoFix().
+ WithURL("https://github.com/ssgreg/nlreturn"),
+
+ linter.NewConfig(noctx.New()).
+ WithSince("v1.28.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/sonatard/noctx"),
+
+ linter.NewConfig(nonamedreturns.New(&cfg.Linters.Settings.NoNamedReturns)).
+ WithSince("v1.46.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/firefart/nonamedreturns"),
+
+ linter.NewConfig(nosprintfhostport.New()).
+ WithSince("v1.46.0").
+ WithURL("https://github.com/stbenjam/no-sprintf-host-port"),
+
+ linter.NewConfig(paralleltest.New(&cfg.Linters.Settings.ParallelTest)).
+ WithSince("v1.33.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/kunwardeep/paralleltest"),
+
+ linter.NewConfig(perfsprint.New(&cfg.Linters.Settings.PerfSprint)).
+ WithSince("v1.55.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/catenacyber/perfsprint"),
+
+ linter.NewConfig(prealloc.New(&cfg.Linters.Settings.Prealloc)).
+ WithSince("v1.19.0").
+ WithURL("https://github.com/alexkohler/prealloc"),
+
+ linter.NewConfig(predeclared.New(&cfg.Linters.Settings.Predeclared)).
+ WithSince("v1.35.0").
+ WithURL("https://github.com/nishanths/predeclared"),
+
+ linter.NewConfig(promlinter.New(&cfg.Linters.Settings.Promlinter)).
+ WithSince("v1.40.0").
+ WithURL("https://github.com/yeya24/promlinter"),
+
+ linter.NewConfig(protogetter.New(&cfg.Linters.Settings.ProtoGetter)).
+ WithSince("v1.55.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/ghostiam/protogetter"),
+
+ linter.NewConfig(reassign.New(&cfg.Linters.Settings.Reassign)).
+ WithSince("v1.49.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/curioswitch/go-reassign"),
+
+ linter.NewConfig(recvcheck.New(&cfg.Linters.Settings.Recvcheck)).
+ WithSince("v1.62.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/raeperd/recvcheck"),
+
+ linter.NewConfig(revive.New(&cfg.Linters.Settings.Revive)).
+ WithSince("v1.37.0").
+ ConsiderSlow().
+ WithAutoFix().
+ WithURL("https://github.com/mgechev/revive"),
+
+ linter.NewConfig(rowserrcheck.New(&cfg.Linters.Settings.RowsErrCheck)).
+ WithSince("v1.23.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/jingyugao/rowserrcheck"),
+
+ linter.NewConfig(sloglint.New(&cfg.Linters.Settings.SlogLint)).
+ WithSince("v1.55.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/go-simpler/sloglint"),
+
+ linter.NewConfig(sqlclosecheck.New()).
+ WithSince("v1.28.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/ryanrolds/sqlclosecheck"),
+
+ linter.NewConfig(spancheck.New(&cfg.Linters.Settings.Spancheck)).
+ WithSince("v1.56.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/jjti/go-spancheck"),
+
+ linter.NewConfig(staticcheck.New(&cfg.Linters.Settings.Staticcheck)).
+ WithGroups(config.GroupStandard).
+ WithSince("v1.0.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://staticcheck.dev/"),
+
+ linter.NewConfig(tagalign.New(&cfg.Linters.Settings.TagAlign)).
+ WithSince("v1.53.0").
+ WithAutoFix().
+ WithURL("https://github.com/4meepo/tagalign"),
+
+ linter.NewConfig(tagliatelle.New(&cfg.Linters.Settings.Tagliatelle)).
+ WithSince("v1.40.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/ldez/tagliatelle"),
+
+ linter.NewConfig(testableexamples.New()).
+ WithSince("v1.50.0").
+ WithURL("https://github.com/maratori/testableexamples"),
+
+ linter.NewConfig(testifylint.New(&cfg.Linters.Settings.Testifylint)).
+ WithSince("v1.55.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/Antonboom/testifylint"),
+
+ linter.NewConfig(testpackage.New(&cfg.Linters.Settings.Testpackage)).
+ WithSince("v1.25.0").
+ WithURL("https://github.com/maratori/testpackage"),
+
+ linter.NewConfig(thelper.New(&cfg.Linters.Settings.Thelper)).
+ WithSince("v1.34.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/kulti/thelper"),
+
+ linter.NewConfig(tparallel.New()).
+ WithSince("v1.32.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/moricho/tparallel"),
+
+ linter.NewConfig(golinters.NewTypecheck()).
+ WithInternal().
+ WithSince("v1.3.0"),
+
+ linter.NewConfig(unconvert.New(&cfg.Linters.Settings.Unconvert)).
+ WithSince("v1.0.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/mdempsky/unconvert"),
+
+ linter.NewConfig(unparam.New(&cfg.Linters.Settings.Unparam)).
+ WithSince("v1.9.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/mvdan/unparam"),
+
+ linter.NewConfig(unused.New(&cfg.Linters.Settings.Unused)).
+ WithGroups(config.GroupStandard).
+ WithSince("v1.20.0").
+ WithLoadForGoAnalysis().
+ ConsiderSlow().
+ WithChangeTypes().
+ WithURL("https://github.com/dominikh/go-tools/tree/HEAD/unused"),
+
+ linter.NewConfig(usestdlibvars.New(&cfg.Linters.Settings.UseStdlibVars)).
+ WithSince("v1.48.0").
+ WithAutoFix().
+ WithURL("https://github.com/sashamelentyev/usestdlibvars"),
+
+ linter.NewConfig(usetesting.New(&cfg.Linters.Settings.UseTesting)).
+ WithSince("v1.63.0").
+ WithLoadForGoAnalysis().
+ WithAutoFix().
+ WithURL("https://github.com/ldez/usetesting"),
+
+ linter.NewConfig(varnamelen.New(&cfg.Linters.Settings.Varnamelen)).
+ WithSince("v1.43.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/blizzy78/varnamelen"),
+
+ linter.NewConfig(wastedassign.New()).
+ WithSince("v1.38.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/sanposhiho/wastedassign"),
+
+ linter.NewConfig(whitespace.New(&cfg.Linters.Settings.Whitespace)).
+ WithSince("v1.19.0").
+ WithAutoFix().
+ WithURL("https://github.com/ultraware/whitespace"),
+
+ linter.NewConfig(wrapcheck.New(&cfg.Linters.Settings.Wrapcheck)).
+ WithSince("v1.32.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/tomarrell/wrapcheck"),
+
+ linter.NewConfig(wsl.New(&cfg.Linters.Settings.WSL)).
+ WithSince("v1.20.0").
+ WithAutoFix().
+ WithURL("https://github.com/bombsimon/wsl"),
+
+ linter.NewConfig(zerologlint.New()).
+ WithSince("v1.53.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/ykadowak/zerologlint"),
+
+ // nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
+ linter.NewConfig(nolintlint.New(&cfg.Linters.Settings.NoLintLint)).
+ WithSince("v1.26.0").
+ WithAutoFix().
+ WithURL("https://github.com/golangci/golangci-lint/tree/HEAD/pkg/golinters/nolintlint/internal"),
+ }, nil
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_go.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_go.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_go.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_go.go
index e9f6931f..00a801ad 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_go.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_go.go
@@ -9,11 +9,11 @@ import (
"golang.org/x/tools/go/analysis"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
const goPluginType = "goplugin"
@@ -40,7 +40,7 @@ func (b *PluginGoBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
var linters []*linter.Config
- for name, settings := range cfg.LintersSettings.Custom {
+ for name, settings := range cfg.Linters.Settings.Custom {
if settings.Type != goPluginType && settings.Type != "" {
continue
}
@@ -69,7 +69,7 @@ func (b *PluginGoBuilder) loadConfig(cfg *config.Config, name string, settings *
WithLoadMode(goanalysis.LoadModeTypesInfo)
linterConfig := linter.NewConfig(customLinter).
- WithEnabledByDefault().
+ WithGroups(config.GroupStandard).
WithLoadForGoAnalysis().
WithURL(settings.OriginalURL)
@@ -83,15 +83,7 @@ func (b *PluginGoBuilder) loadConfig(cfg *config.Config, name string, settings *
// or the linter does not implement the AnalyzerPlugin interface.
func (b *PluginGoBuilder) getAnalyzerPlugin(cfg *config.Config, path string, settings any) ([]*analysis.Analyzer, error) {
if !filepath.IsAbs(path) {
- // Hack for compatibility:
- // the previous default (v1) was `cfg` but `fsutils.GetBasePath` defaults on `wd`.
- // TODO(ldez): should be removed in v2.
- relativePathMode := cfg.Run.RelativePathMode
- if relativePathMode == "" {
- relativePathMode = fsutils.RelativePathModeCfg
- }
-
- basePath, err := fsutils.GetBasePath(context.Background(), relativePathMode, cfg.GetConfigDir())
+ basePath, err := fsutils.GetBasePath(context.Background(), cfg.Run.RelativePathMode, cfg.GetConfigDir())
if err != nil {
return nil, fmt.Errorf("get base path: %w", err)
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_module.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_module.go
similarity index 86%
rename from vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_module.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_module.go
index 60fb58d8..71a01302 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_module.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_module.go
@@ -6,10 +6,10 @@ import (
"github.com/golangci/plugin-module-register/register"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
const modulePluginType = "module"
@@ -32,7 +32,7 @@ func (b *PluginModuleBuilder) Build(cfg *config.Config) ([]*linter.Config, error
var linters []*linter.Config
- for name, settings := range cfg.LintersSettings.Custom {
+ for name, settings := range cfg.Linters.Settings.Custom {
if settings.Type != modulePluginType {
continue
}
@@ -66,7 +66,7 @@ func (b *PluginModuleBuilder) Build(cfg *config.Config) ([]*linter.Config, error
}
lc := linter.NewConfig(customLinter).
- WithEnabledByDefault().
+ WithGroups(config.GroupStandard).
WithURL(settings.OriginalURL)
switch strings.ToLower(p.GetLoadMode()) {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/manager.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/manager.go
similarity index 70%
rename from vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/manager.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/manager.go
index 4fe57a3b..9750301b 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/manager.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/manager.go
@@ -1,6 +1,7 @@
package lintersdb
import (
+ "cmp"
"fmt"
"maps"
"os"
@@ -8,10 +9,11 @@ import (
"sort"
"strings"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/goanalysis"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type Builder interface {
@@ -76,23 +78,11 @@ func (m *Manager) GetAllSupportedLinterConfigs() []*linter.Config {
return m.linters
}
-func (m *Manager) GetAllLinterConfigsForPreset(p string) []*linter.Config {
- var ret []*linter.Config
- for _, lc := range m.linters {
- if lc.IsDeprecated() {
- continue
- }
-
- if slices.Contains(lc.InPresets, p) {
- ret = append(ret, lc)
- }
- }
-
- return ret
-}
-
func (m *Manager) GetEnabledLintersMap() (map[string]*linter.Config, error) {
- enabledLinters := m.build(m.GetAllEnabledByDefaultLinters())
+ enabledLinters, err := m.build()
+ if err != nil {
+ return nil, err
+ }
if os.Getenv(logutils.EnvTestRun) == "1" {
m.verbosePrintLintersStatus(enabledLinters)
@@ -104,7 +94,11 @@ func (m *Manager) GetEnabledLintersMap() (map[string]*linter.Config, error) {
// GetOptimizedLinters returns enabled linters after optimization (merging) of multiple linters into a fewer number of linters.
// E.g. some go/analysis linters can be optimized into one metalinter for data reuse and speed up.
func (m *Manager) GetOptimizedLinters() ([]*linter.Config, error) {
- resultLintersSet := m.build(m.GetAllEnabledByDefaultLinters())
+ resultLintersSet, err := m.build()
+ if err != nil {
+ return nil, err
+ }
+
m.verbosePrintLintersStatus(resultLintersSet)
m.combineGoAnalysisLinters(resultLintersSet)
@@ -133,52 +127,50 @@ func (m *Manager) GetOptimizedLinters() ([]*linter.Config, error) {
return resultLinters, nil
}
-func (m *Manager) GetAllEnabledByDefaultLinters() []*linter.Config {
- var ret []*linter.Config
- for _, lc := range m.linters {
- if lc.EnabledByDefault {
- ret = append(ret, lc)
- }
- }
-
- return ret
-}
-
//nolint:gocyclo // the complexity cannot be reduced.
-func (m *Manager) build(enabledByDefaultLinters []*linter.Config) map[string]*linter.Config {
+func (m *Manager) build() (map[string]*linter.Config, error) {
m.debugf("Linters config: %#v", m.cfg.Linters)
resultLintersSet := map[string]*linter.Config{}
- switch {
- case m.cfg.Linters.DisableAll:
+
+ groupName := cmp.Or(m.cfg.Linters.Default, config.GroupStandard)
+
+ switch groupName {
+ case config.GroupNone:
// no default linters
- case len(m.cfg.Linters.Presets) != 0:
- // imply --disable-all
- case m.cfg.Linters.EnableAll:
+
+ case config.GroupAll:
resultLintersSet = linterConfigsToMap(m.linters)
- default:
- resultLintersSet = linterConfigsToMap(enabledByDefaultLinters)
- }
- // --presets can only add linters to default set
- for _, p := range m.cfg.Linters.Presets {
- for _, lc := range m.GetAllLinterConfigsForPreset(p) {
- resultLintersSet[lc.Name()] = lc
+ case config.GroupFast:
+ var selected []*linter.Config
+ for _, lc := range m.linters {
+ if lc.IsSlowLinter() {
+ continue
+ }
+
+ selected = append(selected, lc)
}
- }
- // --fast removes slow linters from current set.
- // It should be after --presets to be able to run only fast linters in preset.
- // It should be before --enable and --disable to be able to enable or disable specific linter.
- if m.cfg.Linters.Fast {
- for name, lc := range resultLintersSet {
- if lc.IsSlowLinter() {
- delete(resultLintersSet, name)
+ resultLintersSet = linterConfigsToMap(selected)
+
+ case config.GroupStandard:
+ var selected []*linter.Config
+ for _, lc := range m.linters {
+ if !lc.FromGroup(config.GroupStandard) {
+ continue
}
+
+ selected = append(selected, lc)
}
+
+ resultLintersSet = linterConfigsToMap(selected)
+
+ default:
+ return nil, fmt.Errorf("unknown group: %s", groupName)
}
- for _, name := range m.cfg.Linters.Enable {
+ for _, name := range slices.Concat(m.cfg.Linters.Enable, m.cfg.Formatters.Enable) {
for _, lc := range m.GetLinterConfigs(name) {
// it's important to use lc.Name() nor name because name can be alias
resultLintersSet[lc.Name()] = lc
@@ -192,6 +184,15 @@ func (m *Manager) build(enabledByDefaultLinters []*linter.Config) map[string]*li
}
}
+ if m.cfg.Linters.FastOnly {
+ for lc := range maps.Values(resultLintersSet) {
+ if lc.IsSlowLinter() {
+ // it's important to use lc.Name() nor name because name can be alias
+ delete(resultLintersSet, lc.Name())
+ }
+ }
+ }
+
// typecheck is not a real linter and cannot be disabled.
if _, ok := resultLintersSet["typecheck"]; !ok && (m.cfg == nil || !m.cfg.InternalCmdTest) {
for _, lc := range m.GetLinterConfigs("typecheck") {
@@ -200,7 +201,7 @@ func (m *Manager) build(enabledByDefaultLinters []*linter.Config) map[string]*li
}
}
- return resultLintersSet
+ return resultLintersSet, nil
}
func (m *Manager) combineGoAnalysisLinters(linters map[string]*linter.Config) {
@@ -225,8 +226,6 @@ func (m *Manager) combineGoAnalysisLinters(linters map[string]*linter.Config) {
mlConfig.ConsiderSlow()
}
- mlConfig.InPresets = append(mlConfig.InPresets, lc.InPresets...)
-
goanalysisLinters = append(goanalysisLinters, lnt)
}
@@ -256,9 +255,6 @@ func (m *Manager) combineGoAnalysisLinters(linters map[string]*linter.Config) {
mlConfig.Linter = goanalysis.NewMetaLinter(goanalysisLinters)
- sort.Strings(mlConfig.InPresets)
- mlConfig.InPresets = slices.Compact(mlConfig.InPresets)
-
linters[mlConfig.Linter.Name()] = mlConfig
m.debugf("Combined %d go/analysis linters into one metalinter", len(goanalysisLinters))
@@ -275,29 +271,6 @@ func (m *Manager) verbosePrintLintersStatus(lcs map[string]*linter.Config) {
}
sort.Strings(linterNames)
m.log.Infof("Active %d linters: %s", len(linterNames), linterNames)
-
- if len(m.cfg.Linters.Presets) != 0 {
- sort.Strings(m.cfg.Linters.Presets)
- m.log.Infof("Active presets: %s", m.cfg.Linters.Presets)
- }
-}
-
-func AllPresets() []string {
- return []string{
- linter.PresetBugs,
- linter.PresetComment,
- linter.PresetComplexity,
- linter.PresetError,
- linter.PresetFormatting,
- linter.PresetImport,
- linter.PresetMetaLinter,
- linter.PresetModule,
- linter.PresetPerformance,
- linter.PresetSQL,
- linter.PresetStyle,
- linter.PresetTest,
- linter.PresetUnused,
- }
}
func linterConfigsToMap(lcs []*linter.Config) map[string]*linter.Config {
@@ -307,6 +280,10 @@ func linterConfigsToMap(lcs []*linter.Config) map[string]*linter.Config {
continue
}
+ if goformatters.IsFormatter(lc.Name()) {
+ continue
+ }
+
ret[lc.Name()] = lc
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/validator.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/validator.go
similarity index 79%
rename from vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/validator.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/validator.go
index 264d063a..91274825 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/validator.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/validator.go
@@ -1,15 +1,13 @@
package lintersdb
import (
- "errors"
"fmt"
"os"
- "slices"
"strings"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type Validator struct {
@@ -25,7 +23,6 @@ func NewValidator(m *Manager) *Validator {
func (v Validator) Validate(cfg *config.Config) error {
validators := []func(cfg *config.Linters) error{
v.validateLintersNames,
- v.validatePresets,
v.alternativeNamesDeprecation,
}
@@ -71,23 +68,6 @@ func (v Validator) validateLintersNames(cfg *config.Linters) error {
return nil
}
-func (Validator) validatePresets(cfg *config.Linters) error {
- presets := AllPresets()
-
- for _, p := range cfg.Presets {
- if !slices.Contains(presets, p) {
- return fmt.Errorf("no such preset %q: only next presets exist: (%s)",
- p, strings.Join(presets, "|"))
- }
- }
-
- if len(cfg.Presets) != 0 && cfg.EnableAll {
- return errors.New("--presets is incompatible with --enable-all")
- }
-
- return nil
-}
-
func (v Validator) alternativeNamesDeprecation(cfg *config.Linters) error {
if v.m.cfg.InternalTest || v.m.cfg.InternalCmdTest || os.Getenv(logutils.EnvTestRun) == "1" {
return nil
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/package.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/package.go
similarity index 94%
rename from vendor/github.com/golangci/golangci-lint/pkg/lint/package.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/lint/package.go
index 736498b0..3127a24b 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/package.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/package.go
@@ -14,12 +14,12 @@ import (
"github.com/ldez/grignotin/goenv"
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/exitcodes"
- "github.com/golangci/golangci-lint/pkg/goanalysis/load"
- "github.com/golangci/golangci-lint/pkg/goutil"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/exitcodes"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load"
+ "github.com/golangci/golangci-lint/v2/pkg/goutil"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
// PackageLoader loads packages based on [golang.org/x/tools/go/packages.Load].
@@ -39,13 +39,13 @@ type PackageLoader struct {
}
// NewPackageLoader creates a new PackageLoader.
-func NewPackageLoader(log logutils.Log, cfg *config.Config, args []string, goenv *goutil.Env, loadGuard *load.Guard) *PackageLoader {
+func NewPackageLoader(log logutils.Log, cfg *config.Config, args []string, env *goutil.Env, loadGuard *load.Guard) *PackageLoader {
return &PackageLoader{
cfg: cfg,
args: args,
log: log,
debugf: logutils.Debug(logutils.DebugKeyLoader),
- goenv: goenv,
+ goenv: env,
pkgTestIDRe: regexp.MustCompile(`^(.*) \[(.*)\.test\]`),
loadGuard: loadGuard,
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/runner.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/runner.go
similarity index 76%
rename from vendor/github.com/golangci/golangci-lint/pkg/lint/runner.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/lint/runner.go
index 4e6d4692..5ede9b24 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/lint/runner.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/runner.go
@@ -4,20 +4,21 @@ import (
"context"
"errors"
"fmt"
+ "maps"
"runtime/debug"
"strings"
- "github.com/golangci/golangci-lint/internal/errorutil"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/goformatters"
- "github.com/golangci/golangci-lint/pkg/goutil"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/lint/lintersdb"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
- "github.com/golangci/golangci-lint/pkg/result/processors"
- "github.com/golangci/golangci-lint/pkg/timeutils"
+ "github.com/golangci/golangci-lint/v2/internal/errorutil"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ "github.com/golangci/golangci-lint/v2/pkg/goutil"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/result/processors"
+ "github.com/golangci/golangci-lint/v2/pkg/timeutils"
)
type processorStat struct {
@@ -32,46 +33,38 @@ type Runner struct {
Processors []processors.Processor
}
-func NewRunner(log logutils.Log, cfg *config.Config, args []string, goenv *goutil.Env,
+func NewRunner(log logutils.Log, cfg *config.Config, goenv *goutil.Env,
lineCache *fsutils.LineCache, fileCache *fsutils.FileCache,
dbManager *lintersdb.Manager, lintCtx *linter.Context,
) (*Runner, error) {
- // Beware that some processors need to add the path prefix when working with paths
- // because they get invoked before the path prefixer (exclude and severity rules)
- // or process other paths (skip files).
- files := fsutils.NewFiles(lineCache, cfg.Output.PathPrefix)
-
pathRelativity, err := processors.NewPathRelativity(log, cfg.GetBasePath())
if err != nil {
return nil, fmt.Errorf("error creating path relativity processor: %w", err)
}
- exclusionPaths, err := processors.NewExclusionPaths(log, &cfg.Linters.LinterExclusions)
+ exclusionPaths, err := processors.NewExclusionPaths(log, &cfg.Linters.Exclusions)
if err != nil {
return nil, err
}
- skipFilesProcessor, err := processors.NewSkipFiles(cfg.Issues.ExcludeFiles, cfg.Output.PathPrefix)
+ enabledLinters, err := dbManager.GetEnabledLintersMap()
if err != nil {
- return nil, err
- }
-
- skipDirs := cfg.Issues.ExcludeDirs
- if cfg.Issues.UseDefaultExcludeDirs {
- skipDirs = append(skipDirs, processors.StdExcludeDirRegexps...)
+ return nil, fmt.Errorf("failed to get enabled linters: %w", err)
}
- skipDirsProcessor, err := processors.NewSkipDirs(log.Child(logutils.DebugKeySkipDirs), skipDirs, args, cfg.Output.PathPrefix)
- if err != nil {
- return nil, err
+ var enabledFormatters []string
+ for name := range maps.Keys(enabledLinters) {
+ if goformatters.IsFormatter(name) {
+ enabledFormatters = append(enabledFormatters, name)
+ }
}
- enabledLinters, err := dbManager.GetEnabledLintersMap()
- if err != nil {
- return nil, fmt.Errorf("failed to get enabled linters: %w", err)
+ formattersCfg := &config.Formatters{
+ Enable: enabledFormatters,
+ Settings: cfg.Linters.Settings.FormatterSettings,
}
- metaFormatter, err := goformatters.NewMetaFormatter(log, cfg, enabledLinters)
+ metaFormatter, err := goformatters.NewMetaFormatter(log, formattersCfg, &cfg.Run)
if err != nil {
return nil, fmt.Errorf("failed to create meta-formatter: %w", err)
}
@@ -94,16 +87,11 @@ func NewRunner(log logutils.Log, cfg *config.Config, args []string, goenv *gouti
// Must be after PathRelativity.
exclusionPaths,
- skipFilesProcessor,
- skipDirsProcessor,
-
- processors.NewGeneratedFileFilter(cfg.Linters.LinterExclusions.Generated),
- // Must be before exclude because users see already marked output and configure excluding by it.
- processors.NewIdentifierMarker(),
+ processors.NewGeneratedFileFilter(cfg.Linters.Exclusions.Generated),
- processors.NewExclusionRules(log.Child(logutils.DebugKeyExclusionRules), files,
- &cfg.Linters.LinterExclusions, &cfg.Issues),
+ processors.NewExclusionRules(log.Child(logutils.DebugKeyExclusionRules), lineCache,
+ &cfg.Linters.Exclusions),
processors.NewNolintFilter(log.Child(logutils.DebugKeyNolintFilter), dbManager, enabledLinters),
@@ -121,8 +109,8 @@ func NewRunner(log logutils.Log, cfg *config.Config, args []string, goenv *gouti
// Now we can modify the issues for output.
processors.NewSourceCode(lineCache, log.Child(logutils.DebugKeySourceCode)),
processors.NewPathShortener(),
- processors.NewSeverity(log.Child(logutils.DebugKeySeverityRules), files, &cfg.Severity),
- processors.NewPathPrettifier(log, cfg.Output.PathPrefix),
+ processors.NewSeverity(log.Child(logutils.DebugKeySeverityRules), lineCache, &cfg.Severity),
+ processors.NewPathPrettifier(log, &cfg.Output),
processors.NewSortResults(&cfg.Output),
},
lintCtx: lintCtx,
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/logutils/log.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/log.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/logutils/log.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/log.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/logutils/logutils.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/logutils.go
similarity index 79%
rename from vendor/github.com/golangci/golangci-lint/pkg/logutils/logutils.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/logutils.go
index 0454d792..0ee48a36 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/logutils/logutils.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/logutils.go
@@ -16,22 +16,23 @@ const EnvTestRun = "GL_TEST_RUN"
const envDebug = "GL_DEBUG"
const (
- DebugKeyBinSalt = "bin_salt"
- DebugKeyConfigReader = "config_reader"
- DebugKeyEmpty = ""
- DebugKeyEnabledLinters = "enabled_linters"
- DebugKeyExec = "exec"
- DebugKeyFormatter = "formatter"
- DebugKeyGoEnv = "goenv"
- DebugKeyLinter = "linter"
- DebugKeyLintersContext = "linters_context"
- DebugKeyLintersDB = "lintersdb"
- DebugKeyLintersOutput = "linters_output"
- DebugKeyLoader = "loader" // Debugs packages loading (including `go/packages` internal debugging).
- DebugKeyPkgCache = "pkgcache"
- DebugKeyRunner = "runner"
- DebugKeyStopwatch = "stopwatch"
- DebugKeyTest = "test"
+ DebugKeyBinSalt = "bin_salt"
+ DebugKeyGoModSalt = "gomod_salt"
+ DebugKeyConfigReader = "config_reader"
+ DebugKeyEmpty = ""
+ DebugKeyEnabledLinters = "enabled_linters"
+ DebugKeyExec = "exec"
+ DebugKeyFormatter = "formatter"
+ DebugKeyFormattersOutput = "formatters_output"
+ DebugKeyGoEnv = "goenv"
+ DebugKeyLintersContext = "linters_context"
+ DebugKeyLintersDB = "lintersdb"
+ DebugKeyLintersOutput = "linters_output"
+ DebugKeyLoader = "loader" // Debugs packages loading (including `go/packages` internal debugging).
+ DebugKeyPkgCache = "pkgcache"
+ DebugKeyRunner = "runner"
+ DebugKeyStopwatch = "stopwatch"
+ DebugKeyTest = "test"
)
// Printers.
@@ -81,7 +82,8 @@ const (
DebugKeyForbidigo = "forbidigo" // Debugs `forbidigo` linter.
DebugKeyGoCritic = "gocritic" // Debugs `gocritic` linter.
DebugKeyGovet = "govet" // Debugs `govet` linter.
- DebugKeyRevive = "revive" // Debugs `revive` linter.
+ DebugKeyLinter = "linter"
+ DebugKeyRevive = "revive" // Debugs `revive` linter.
)
func getEnabledDebugs() map[string]bool {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/logutils/mock.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/mock.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/logutils/mock.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/mock.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/logutils/out.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/out.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/logutils/out.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/out.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/logutils/stderr_log.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/stderr_log.go
similarity index 98%
rename from vendor/github.com/golangci/golangci-lint/pkg/logutils/stderr_log.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/stderr_log.go
index 569a177a..b47c65ea 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/logutils/stderr_log.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/stderr_log.go
@@ -7,7 +7,7 @@ import (
"github.com/sirupsen/logrus"
- "github.com/golangci/golangci-lint/pkg/exitcodes"
+ "github.com/golangci/golangci-lint/v2/pkg/exitcodes"
)
const (
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/checkstyle.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/checkstyle.go
similarity index 95%
rename from vendor/github.com/golangci/golangci-lint/pkg/printers/checkstyle.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/printers/checkstyle.go
index c31641d2..5a60554b 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/checkstyle.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/checkstyle.go
@@ -10,8 +10,8 @@ import (
"github.com/go-xmlfmt/xmlfmt"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const defaultCheckstyleSeverity = "error"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/codeclimate.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/codeclimate.go
similarity index 95%
rename from vendor/github.com/golangci/golangci-lint/pkg/printers/codeclimate.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/printers/codeclimate.go
index 983dcde3..872d860d 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/codeclimate.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/codeclimate.go
@@ -4,8 +4,8 @@ import (
"encoding/json"
"io"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const defaultCodeClimateSeverity = "critical"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/html.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/html.go
similarity index 99%
rename from vendor/github.com/golangci/golangci-lint/pkg/printers/html.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/printers/html.go
index 6fc6bc62..0f99bb7f 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/html.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/html.go
@@ -6,7 +6,7 @@ import (
"io"
"strings"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const templateContent = `
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/json.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/json.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/printers/json.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/printers/json.go
index 8fc94649..64fd33c7 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/json.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/json.go
@@ -4,8 +4,8 @@ import (
"encoding/json"
"io"
- "github.com/golangci/golangci-lint/pkg/report"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/report"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
// JSON prints issues in a JSON representation.
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/junitxml.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/junitxml.go
similarity index 97%
rename from vendor/github.com/golangci/golangci-lint/pkg/printers/junitxml.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/printers/junitxml.go
index 587cef4e..708f83e5 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/junitxml.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/junitxml.go
@@ -8,7 +8,7 @@ import (
"slices"
"strings"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
// JUnitXML prints issues in the JUnit XML format.
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/printer.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/printer.go
new file mode 100644
index 00000000..575bba75
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/printer.go
@@ -0,0 +1,241 @@
+package printers
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "slices"
+ "strings"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/report"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+)
+
+const (
+ outputStdOut = "stdout"
+ outputStdErr = "stderr"
+)
+
+const defaultFileMode = 0o644
+
+type issuePrinter interface {
+ Print(issues []result.Issue) error
+}
+
+// Printer prints issues.
+type Printer struct {
+ cfg *config.Formats
+ reportData *report.Data
+ basePath string
+
+ log logutils.Log
+
+ stdOut io.Writer
+ stdErr io.Writer
+}
+
+// NewPrinter creates a new Printer.
+func NewPrinter(log logutils.Log, cfg *config.Formats, reportData *report.Data, basePath string) (*Printer, error) {
+ if log == nil {
+ return nil, errors.New("missing log argument in constructor")
+ }
+ if cfg == nil {
+ return nil, errors.New("missing config argument in constructor")
+ }
+ if reportData == nil {
+ return nil, errors.New("missing reportData argument in constructor")
+ }
+
+ return &Printer{
+ cfg: cfg,
+ reportData: reportData,
+ basePath: basePath,
+ log: log,
+ stdOut: logutils.StdOut,
+ stdErr: logutils.StdErr,
+ }, nil
+}
+
+// Print prints issues based on the formats defined.
+//
+//nolint:gocyclo,funlen // the complexity is related to the number of formats.
+func (c *Printer) Print(issues []result.Issue) error {
+ if c.cfg.IsEmpty() {
+ c.cfg.Text.Path = outputStdOut
+ }
+
+ var printers []issuePrinter
+
+ if c.cfg.Text.Path != "" {
+ w, closer, err := c.createWriter(&c.cfg.Text.SimpleFormat)
+ if err != nil {
+ return fmt.Errorf("can't create output for %s: %w", c.cfg.Text.Path, err)
+ }
+
+ defer closer()
+
+ printers = append(printers, NewText(c.log, w, &c.cfg.Text))
+ }
+
+ if c.cfg.JSON.Path != "" {
+ w, closer, err := c.createWriter(&c.cfg.JSON)
+ if err != nil {
+ return fmt.Errorf("can't create output for %s: %w", c.cfg.JSON.Path, err)
+ }
+
+ defer closer()
+
+ printers = append(printers, NewJSON(w, c.reportData))
+ }
+
+ if c.cfg.Tab.Path != "" {
+ w, closer, err := c.createWriter(&c.cfg.Tab.SimpleFormat)
+ if err != nil {
+ return fmt.Errorf("can't create output for %s: %w", c.cfg.Tab.Path, err)
+ }
+
+ defer closer()
+
+ printers = append(printers, NewTab(c.log, w, &c.cfg.Tab))
+ }
+
+ if c.cfg.HTML.Path != "" {
+ w, closer, err := c.createWriter(&c.cfg.HTML)
+ if err != nil {
+ return fmt.Errorf("can't create output for %s: %w", c.cfg.HTML.Path, err)
+ }
+
+ defer closer()
+
+ printers = append(printers, NewHTML(w))
+ }
+
+ if c.cfg.Checkstyle.Path != "" {
+ w, closer, err := c.createWriter(&c.cfg.Checkstyle)
+ if err != nil {
+ return fmt.Errorf("can't create output for %s: %w", c.cfg.Checkstyle.Path, err)
+ }
+
+ defer closer()
+
+ printers = append(printers, NewCheckstyle(c.log, w))
+ }
+
+ if c.cfg.CodeClimate.Path != "" {
+ w, closer, err := c.createWriter(&c.cfg.CodeClimate)
+ if err != nil {
+ return fmt.Errorf("can't create output for %s: %w", c.cfg.CodeClimate.Path, err)
+ }
+
+ defer closer()
+
+ printers = append(printers, NewCodeClimate(c.log, w))
+ }
+
+ if c.cfg.JUnitXML.Path != "" {
+ w, closer, err := c.createWriter(&c.cfg.JUnitXML.SimpleFormat)
+ if err != nil {
+ return fmt.Errorf("can't create output for %s: %w", c.cfg.JUnitXML.Path, err)
+ }
+
+ defer closer()
+
+ printers = append(printers, NewJUnitXML(w, c.cfg.JUnitXML.Extended))
+ }
+
+ if c.cfg.TeamCity.Path != "" {
+ w, closer, err := c.createWriter(&c.cfg.TeamCity)
+ if err != nil {
+ return fmt.Errorf("can't create output for %s: %w", c.cfg.TeamCity.Path, err)
+ }
+
+ defer closer()
+
+ printers = append(printers, NewTeamCity(c.log, w))
+ }
+
+ if c.cfg.Sarif.Path != "" {
+ w, closer, err := c.createWriter(&c.cfg.Sarif)
+ if err != nil {
+ return fmt.Errorf("can't create output for %s: %w", c.cfg.Sarif.Path, err)
+ }
+
+ defer closer()
+
+ printers = append(printers, NewSarif(c.log, w))
+ }
+
+ for _, printer := range printers {
+ err := printer.Print(issues)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (c *Printer) createWriter(cfg *config.SimpleFormat) (io.Writer, func(), error) {
+ if cfg.Path == "" || cfg.Path == outputStdOut {
+ return c.stdOut, func() {}, nil
+ }
+
+ if cfg.Path == outputStdErr {
+ return c.stdErr, func() {}, nil
+ }
+
+ if !filepath.IsAbs(cfg.Path) {
+ cfg.Path = filepath.Join(c.basePath, cfg.Path)
+ }
+
+ err := os.MkdirAll(filepath.Dir(cfg.Path), os.ModePerm)
+ if err != nil {
+ return nil, func() {}, err
+ }
+
+ f, err := os.OpenFile(cfg.Path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, defaultFileMode)
+ if err != nil {
+ return nil, func() {}, err
+ }
+
+ return f, func() { _ = f.Close() }, nil
+}
+
+type severitySanitizer struct {
+ allowedSeverities []string
+ defaultSeverity string
+
+ unsupportedSeverities map[string]struct{}
+}
+
+func (s *severitySanitizer) Sanitize(severity string) string {
+ if slices.Contains(s.allowedSeverities, severity) {
+ return severity
+ }
+
+ if s.unsupportedSeverities == nil {
+ s.unsupportedSeverities = make(map[string]struct{})
+ }
+
+ s.unsupportedSeverities[severity] = struct{}{}
+
+ return s.defaultSeverity
+}
+
+func (s *severitySanitizer) Err() error {
+ if len(s.unsupportedSeverities) == 0 {
+ return nil
+ }
+
+ var names []string
+ for k := range s.unsupportedSeverities {
+ names = append(names, "'"+k+"'")
+ }
+
+ return fmt.Errorf("severities (%v) are not inside supported values (%v), fallback to '%s'",
+ strings.Join(names, ", "), strings.Join(s.allowedSeverities, ", "), s.defaultSeverity)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/sarif.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/sarif.go
similarity index 96%
rename from vendor/github.com/golangci/golangci-lint/pkg/printers/sarif.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/printers/sarif.go
index c06c1162..e8d8c64f 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/sarif.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/sarif.go
@@ -4,8 +4,8 @@ import (
"encoding/json"
"io"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const (
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/tab.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/tab.go
similarity index 77%
rename from vendor/github.com/golangci/golangci-lint/pkg/printers/tab.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/printers/tab.go
index ac04ab0f..0d14593e 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/tab.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/tab.go
@@ -7,23 +7,24 @@ import (
"github.com/fatih/color"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
// Tab prints issues using tabulation as a field separator.
type Tab struct {
printLinterName bool
- useColors bool
+ colors bool
log logutils.Log
w io.Writer
}
-func NewTab(log logutils.Log, w io.Writer, printLinterName, useColors bool) *Tab {
+func NewTab(log logutils.Log, w io.Writer, cfg *config.Tab) *Tab {
return &Tab{
- printLinterName: printLinterName,
- useColors: useColors,
+ printLinterName: cfg.PrintLinterName,
+ colors: cfg.Colors,
log: log.Child(logutils.DebugKeyTabPrinter),
w: w,
}
@@ -32,7 +33,7 @@ func NewTab(log logutils.Log, w io.Writer, printLinterName, useColors bool) *Tab
func (p *Tab) SprintfColored(ca color.Attribute, format string, args ...any) string {
c := color.New(ca)
- if !p.useColors {
+ if !p.colors {
c.DisableColor()
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/teamcity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/teamcity.go
similarity index 97%
rename from vendor/github.com/golangci/golangci-lint/pkg/printers/teamcity.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/printers/teamcity.go
index 9ff5fe5b..a8530772 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/teamcity.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/teamcity.go
@@ -5,8 +5,8 @@ import (
"io"
"strings"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
// Field limits.
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/text.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/text.go
similarity index 83%
rename from vendor/github.com/golangci/golangci-lint/pkg/printers/text.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/printers/text.go
index 9e60408f..545679fb 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/printers/text.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/text.go
@@ -7,25 +7,26 @@ import (
"github.com/fatih/color"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
// Text prints issues with a human friendly representation.
type Text struct {
printLinterName bool
printIssuedLine bool
- useColors bool
+ colors bool
log logutils.Log
w io.Writer
}
-func NewText(log logutils.Log, w io.Writer, printLinterName, printIssuedLine, useColors bool) *Text {
+func NewText(log logutils.Log, w io.Writer, cfg *config.Text) *Text {
return &Text{
- printLinterName: printLinterName,
- printIssuedLine: printIssuedLine,
- useColors: useColors,
+ printLinterName: cfg.PrintLinterName,
+ printIssuedLine: cfg.PrintIssuedLine,
+ colors: cfg.Colors,
log: log.Child(logutils.DebugKeyTextPrinter),
w: w,
}
@@ -34,7 +35,7 @@ func NewText(log logutils.Log, w io.Writer, printLinterName, printIssuedLine, us
func (p *Text) SprintfColored(ca color.Attribute, format string, args ...any) string {
c := color.New(ca)
- if !p.useColors {
+ if !p.colors {
c.DisableColor()
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/report/data.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/report/data.go
similarity index 53%
rename from vendor/github.com/golangci/golangci-lint/pkg/report/data.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/report/data.go
index f083fa9f..7aedc552 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/report/data.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/report/data.go
@@ -6,9 +6,8 @@ type Warning struct {
}
type LinterData struct {
- Name string
- Enabled bool `json:",omitempty"`
- EnabledByDefault bool `json:",omitempty"`
+ Name string
+ Enabled bool `json:",omitempty"`
}
type Data struct {
@@ -17,10 +16,9 @@ type Data struct {
Error string `json:",omitempty"`
}
-func (d *Data) AddLinter(name string, enabled, enabledByDefault bool) {
+func (d *Data) AddLinter(name string, enabled bool) {
d.Linters = append(d.Linters, LinterData{
- Name: name,
- Enabled: enabled,
- EnabledByDefault: enabledByDefault,
+ Name: name,
+ Enabled: enabled,
})
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/report/log.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/report/log.go
similarity index 96%
rename from vendor/github.com/golangci/golangci-lint/pkg/report/log.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/report/log.go
index 61665f28..ad096415 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/report/log.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/report/log.go
@@ -4,7 +4,7 @@ import (
"fmt"
"strings"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
type LogWrapper struct {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/issue.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/issue.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/issue.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/issue.go
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/base_rule.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/base_rule.go
similarity index 77%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/base_rule.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/base_rule.go
index 72dc2028..607886ef 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/base_rule.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/base_rule.go
@@ -3,14 +3,12 @@ package processors
import (
"regexp"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
-const caseInsensitivePrefix = "(?i)"
-
type baseRule struct {
text *regexp.Regexp
source *regexp.Regexp
@@ -49,14 +47,14 @@ func (r *baseRule) isEmpty() bool {
return r.text == nil && r.source == nil && r.path == nil && r.pathExcept == nil && len(r.linters) == 0
}
-func (r *baseRule) match(issue *result.Issue, files *fsutils.Files, log logutils.Log) bool {
+func (r *baseRule) match(issue *result.Issue, lines *fsutils.LineCache, log logutils.Log) bool {
if r.isEmpty() {
return false
}
if r.text != nil && !r.text.MatchString(issue.Text) {
return false
}
- if r.path != nil && !r.path.MatchString(files.WithPathPrefix(issue.RelativePath)) {
+ if r.path != nil && !r.path.MatchString(issue.RelativePath) {
return false
}
if r.pathExcept != nil && r.pathExcept.MatchString(issue.RelativePath) {
@@ -67,7 +65,7 @@ func (r *baseRule) match(issue *result.Issue, files *fsutils.Files, log logutils
}
// the most heavyweight checking last
- if r.source != nil && !r.matchSource(issue, files.LineCache, log) {
+ if r.source != nil && !r.matchSource(issue, lines, log) {
return false
}
@@ -85,9 +83,9 @@ func (r *baseRule) matchLinter(issue *result.Issue) bool {
}
func (r *baseRule) matchSource(issue *result.Issue, lineCache *fsutils.LineCache, log logutils.Log) bool {
- sourceLine, errSourceLine := lineCache.GetLine(issue.RelativePath, issue.Line())
+ sourceLine, errSourceLine := lineCache.GetLine(issue.FilePath(), issue.Line())
if errSourceLine != nil {
- log.Warnf("Failed to get line %s:%d from line cache: %s", issue.RelativePath, issue.Line(), errSourceLine)
+ log.Warnf("Failed to get line %s:%d from line cache: %s", issue.FilePath(), issue.Line(), errSourceLine)
return false // can't properly match
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/cgo.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/cgo.go
similarity index 90%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/cgo.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/cgo.go
index b09b8b72..dea3801e 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/cgo.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/cgo.go
@@ -6,8 +6,8 @@ import (
"github.com/ldez/grignotin/goenv"
- "github.com/golangci/golangci-lint/pkg/goutil"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/goutil"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*Cgo)(nil)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/diff.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/diff.go
similarity index 95%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/diff.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/diff.go
index a7e268b4..a84caf7b 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/diff.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/diff.go
@@ -10,8 +10,8 @@ import (
"github.com/golangci/revgrep"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const envGolangciDiffProcessorPatch = "GOLANGCI_DIFF_PROCESSOR_PATCH"
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_filter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_filter.go
new file mode 100644
index 00000000..6cbde3ae
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_filter.go
@@ -0,0 +1,77 @@
+package processors
+
+import (
+ "fmt"
+ "path/filepath"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+)
+
+var _ Processor = (*GeneratedFileFilter)(nil)
+
+type fileSummary struct {
+ generated bool
+}
+
+// GeneratedFileFilter filters generated files.
+type GeneratedFileFilter struct {
+ debugf logutils.DebugFunc
+
+ mode string
+ matcher *GeneratedFileMatcher
+
+ fileSummaryCache map[string]*fileSummary
+}
+
+func NewGeneratedFileFilter(mode string) *GeneratedFileFilter {
+ return &GeneratedFileFilter{
+ debugf: logutils.Debug(logutils.DebugKeyGeneratedFileFilter),
+
+ mode: mode,
+ matcher: NewGeneratedFileMatcher(mode),
+
+ fileSummaryCache: map[string]*fileSummary{},
+ }
+}
+
+func (*GeneratedFileFilter) Name() string {
+ return "generated_file_filter"
+}
+
+func (p *GeneratedFileFilter) Process(issues []result.Issue) ([]result.Issue, error) {
+ if p.mode == config.GeneratedModeDisable {
+ return issues, nil
+ }
+
+ return filterIssuesErr(issues, p.shouldPassIssue)
+}
+
+func (*GeneratedFileFilter) Finish() {}
+
+func (p *GeneratedFileFilter) shouldPassIssue(issue *result.Issue) (bool, error) {
+ if filepath.Base(issue.FilePath()) == "go.mod" {
+ return true, nil
+ }
+
+ // The file is already known.
+ fs := p.fileSummaryCache[issue.FilePath()]
+ if fs != nil {
+ return !fs.generated, nil
+ }
+
+ fs = &fileSummary{}
+ p.fileSummaryCache[issue.FilePath()] = fs
+
+ var err error
+ fs.generated, err = p.matcher.IsGeneratedFile(issue.FilePath(), nil)
+ if err != nil {
+ return false, fmt.Errorf("failed to get doc (%s) of file %s: %w", p.mode, issue.FilePath(), err)
+ }
+
+ p.debugf("file %q is generated: %t", issue.FilePath(), fs.generated)
+
+ // don't report issues for autogenerated files
+ return !fs.generated, nil
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_matcher.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_matcher.go
new file mode 100644
index 00000000..763ca9e3
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_matcher.go
@@ -0,0 +1,107 @@
+package processors
+
+import (
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "strings"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+)
+
+// The values must be in lowercase.
+const (
+ genCodeGenerated = "code generated"
+ genDoNotEdit = "do not edit"
+
+ // Related to easyjson.
+ genAutoFile = "autogenerated file"
+
+ //nolint:lll // Long URL
+ // Related to Swagger Codegen.
+ // https://github.com/swagger-api/swagger-codegen/blob/61cfeac3b9d855b4eb8bffa0d118bece117bcb7d/modules/swagger-codegen/src/main/resources/go/partial_header.mustache#L16
+ // https://github.com/swagger-api/swagger-codegen/issues/12358
+ genSwaggerCodegen = "* generated by: swagger codegen "
+)
+
+// GeneratedFileMatcher detects generated files.
+// - mode "lax": see `isGeneratedFileLax` documentation.
+// - mode "strict": see `isGeneratedFileStrict` documentation.
+// - mode "disable": skips this processor.
+type GeneratedFileMatcher struct {
+ debugf logutils.DebugFunc
+
+ mode string
+}
+
+func NewGeneratedFileMatcher(mode string) *GeneratedFileMatcher {
+ return &GeneratedFileMatcher{
+ debugf: logutils.Debug(logutils.DebugKeyGeneratedFileFilter),
+ mode: mode,
+ }
+}
+
+func (p *GeneratedFileMatcher) IsGeneratedFile(filepath string, src any) (bool, error) {
+ if p.mode == config.GeneratedModeDisable {
+ return false, nil
+ }
+
+ file, err := parser.ParseFile(token.NewFileSet(), filepath, src, parser.PackageClauseOnly|parser.ParseComments)
+ if err != nil {
+ return false, fmt.Errorf("failed to parse file: %w", err)
+ }
+
+ if p.mode == config.GeneratedModeStrict {
+ return isGeneratedFileStrict(file), nil
+ }
+
+ doc := getComments(file)
+
+ return p.isGeneratedFileLax(doc), nil
+}
+
+// isGeneratedFileLax reports whether the source file is generated code.
+// The function uses a bit laxer rules than isGeneratedFileStrict to match more generated code.
+// See https://github.com/golangci/golangci-lint/issues/48 and https://github.com/golangci/golangci-lint/issues/72.
+func (p *GeneratedFileMatcher) isGeneratedFileLax(doc string) bool {
+ markers := []string{genCodeGenerated, genDoNotEdit, genAutoFile, genSwaggerCodegen}
+
+ doc = strings.ToLower(doc)
+
+ for _, marker := range markers {
+ if strings.Contains(doc, marker) {
+ p.debugf("doc contains marker %q: file is generated", marker)
+
+ return true
+ }
+ }
+
+ p.debugf("doc of len %d doesn't contain any of markers: %s", len(doc), markers)
+
+ return false
+}
+
+// isGeneratedFileStrict returns true if the source file has a line that matches the regular expression:
+//
+// ^// Code generated .* DO NOT EDIT\.$
+//
+// This line must appear before the first non-comment, non-blank text in the file.
+// Based on https://go.dev/s/generatedcode.
+func isGeneratedFileStrict(file *ast.File) bool {
+ if file == nil || len(file.Comments) == 0 {
+ return false
+ }
+
+ return ast.IsGenerated(file)
+}
+
+func getComments(file *ast.File) string {
+ var docLines []string
+ for _, c := range file.Comments {
+ docLines = append(docLines, strings.TrimSpace(c.Text()))
+ }
+
+ return strings.Join(docLines, "\n")
+}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_paths.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_paths.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_paths.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_paths.go
index bd430487..104c33ee 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_paths.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_paths.go
@@ -4,10 +4,10 @@ import (
"fmt"
"regexp"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*ExclusionPaths)(nil)
@@ -79,7 +79,7 @@ func (p *ExclusionPaths) Process(issues []result.Issue) ([]result.Issue, error)
func (p *ExclusionPaths) Finish() {
for pattern, count := range p.excludedPathCounter {
if p.warnUnused && count == 0 {
- p.log.Warnf("The pattern %q match %d issues", pattern, count)
+ p.log.Warnf("The pattern %q match no issues", pattern)
} else {
p.log.Infof("Skipped %d issues by pattern %q", count, pattern)
}
@@ -87,7 +87,7 @@ func (p *ExclusionPaths) Finish() {
for pattern, count := range p.excludedPathExceptCounter {
if p.warnUnused && count == 0 {
- p.log.Warnf("The pattern %q match %d issues", pattern, count)
+ p.log.Warnf("The pattern %q match no issues", pattern)
}
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_presets.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_presets.go
similarity index 93%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_presets.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_presets.go
index 17299b90..4c2fa4c4 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_presets.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_presets.go
@@ -1,15 +1,15 @@
package processors
-import "github.com/golangci/golangci-lint/pkg/config"
+import "github.com/golangci/golangci-lint/v2/pkg/config"
-var linterExclusionPresets = map[string][]config.ExcludeRule{
+var LinterExclusionPresets = map[string][]config.ExcludeRule{
config.ExclusionPresetComments: {
{
// Annoying issue about not having a comment. The rare codebase has such comments.
// CheckPackageComment, CheckExportedFunctionDocs, CheckExportedTypeDocs, CheckExportedVarDocs
BaseRule: config.BaseRule{
Text: "(ST1000|ST1020|ST1021|ST1022)",
- Linters: []string{"stylecheck"},
+ Linters: []string{"staticcheck"},
InternalReference: "EXC0011",
},
},
@@ -54,7 +54,7 @@ var linterExclusionPresets = map[string][]config.ExcludeRule{
{
// Almost all programs ignore errors on these functions and in most cases it's ok.
BaseRule: config.BaseRule{
- Text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close" +
+ Text: "(?i)Error return value of .((os\\.)?std(out|err)\\..*|.*Close" +
"|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked",
Linters: []string{"errcheck"},
InternalReference: "EXC0001",
@@ -129,7 +129,7 @@ func getLinterExclusionPresets(names []string) []config.ExcludeRule {
var rules []config.ExcludeRule
for _, name := range names {
- if p, ok := linterExclusionPresets[name]; ok {
+ if p, ok := LinterExclusionPresets[name]; ok {
rules = append(rules, p...)
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_rules.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_rules.go
similarity index 57%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_rules.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_rules.go
index 7730a53d..064921ae 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclusion_rules.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_rules.go
@@ -5,17 +5,18 @@ import (
"slices"
"strings"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*ExclusionRules)(nil)
type ExclusionRules struct {
- log logutils.Log
- files *fsutils.Files
+ log logutils.Log
+
+ lines *fsutils.LineCache
warnUnused bool
skippedCounter map[string]int
@@ -23,43 +24,17 @@ type ExclusionRules struct {
rules []excludeRule
}
-func NewExclusionRules(log logutils.Log, files *fsutils.Files,
- cfg *config.LinterExclusions, oldCfg *config.Issues) *ExclusionRules {
+func NewExclusionRules(log logutils.Log, lines *fsutils.LineCache, cfg *config.LinterExclusions) *ExclusionRules {
p := &ExclusionRules{
log: log,
- files: files,
+ lines: lines,
warnUnused: cfg.WarnUnused,
skippedCounter: map[string]int{},
}
- // TODO(ldez) remove prefix in v2: the matching must be case sensitive, users can add `(?i)` inside the patterns if needed.
- prefix := caseInsensitivePrefix
- if oldCfg.ExcludeCaseSensitive {
- prefix = ""
- }
-
- excludeRules := slices.Concat(slices.Clone(cfg.Rules),
- filterInclude(getLinterExclusionPresets(cfg.Presets), oldCfg.IncludeDefaultExcludes))
+ excludeRules := slices.Concat(slices.Clone(cfg.Rules), getLinterExclusionPresets(cfg.Presets))
- p.rules = parseRules(excludeRules, prefix, newExcludeRule)
-
- // TODO(ldez): should be removed in v2.
- for _, pattern := range oldCfg.ExcludePatterns {
- if pattern == "" {
- continue
- }
-
- r := &config.ExcludeRule{
- BaseRule: config.BaseRule{
- Path: `.+\.go`,
- Text: pattern,
- },
- }
-
- rule := newExcludeRule(r, prefix)
-
- p.rules = append(p.rules, rule)
- }
+ p.rules = parseRules(excludeRules, "", newExcludeRule)
for _, rule := range p.rules {
if rule.internalReference == "" {
@@ -81,7 +56,7 @@ func (p *ExclusionRules) Process(issues []result.Issue) ([]result.Issue, error)
return filterIssues(issues, func(issue *result.Issue) bool {
for _, rule := range p.rules {
- if !rule.match(issue, p.files, p.log) {
+ if !rule.match(issue, p.lines, p.log) {
continue
}
@@ -146,19 +121,3 @@ func (e excludeRule) String() string {
return strings.Join(msg, ", ")
}
-
-// TODO(ldez): must be removed in v2, only for compatibility with exclude-use-default/include.
-func filterInclude(rules []config.ExcludeRule, refs []string) []config.ExcludeRule {
- if len(refs) == 0 {
- return rules
- }
-
- var filteredRules []config.ExcludeRule
- for _, rule := range rules {
- if !slices.Contains(refs, rule.InternalReference) {
- filteredRules = append(filteredRules, rule)
- }
- }
-
- return filteredRules
-}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/filename_unadjuster.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/filename_unadjuster.go
similarity index 96%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/filename_unadjuster.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/filename_unadjuster.go
index 5f39e064..a3cdd8e6 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/filename_unadjuster.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/filename_unadjuster.go
@@ -9,8 +9,8 @@ import (
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*FilenameUnadjuster)(nil)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/fixer.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/fixer.go
similarity index 91%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/fixer.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/fixer.go
index 610f249e..14dd3454 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/fixer.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/fixer.go
@@ -13,17 +13,18 @@ import (
"os"
"slices"
- "github.com/golangci/golangci-lint/internal/x/tools/diff"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/goformatters"
- "github.com/golangci/golangci-lint/pkg/goformatters/gci"
- "github.com/golangci/golangci-lint/pkg/goformatters/gofmt"
- "github.com/golangci/golangci-lint/pkg/goformatters/gofumpt"
- "github.com/golangci/golangci-lint/pkg/goformatters/goimports"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
- "github.com/golangci/golangci-lint/pkg/timeutils"
+ "github.com/golangci/golangci-lint/v2/internal/x/tools/diff"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/golines"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/timeutils"
)
var _ Processor = (*Fixer)(nil)
@@ -78,7 +79,7 @@ func (p Fixer) process(issues []result.Issue) ([]result.Issue, error) {
// filenames / linters / edits
editsByLinter := make(map[string]map[string][]diff.Edit)
- formatters := []string{gofumpt.Name, goimports.Name, gofmt.Name, gci.Name}
+ formatters := []string{gofumpt.Name, goimports.Name, gofmt.Name, gci.Name, golines.Name}
var notFixableIssues []result.Issue
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/invalid_issue.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/invalid_issue.go
similarity index 92%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/invalid_issue.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/invalid_issue.go
index 042675b5..a7f45d40 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/invalid_issue.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/invalid_issue.go
@@ -3,8 +3,8 @@ package processors
import (
"path/filepath"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*InvalidIssue)(nil)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/issues.go
similarity index 97%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/issues.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/issues.go
index ab443b87..1e76291c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/issues.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/issues.go
@@ -3,7 +3,7 @@ package processors
import (
"fmt"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
func filterIssues(issues []result.Issue, filter func(issue *result.Issue) bool) []result.Issue {
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_from_linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_from_linter.go
similarity index 88%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_from_linter.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_from_linter.go
index ced200af..dec9f3e7 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_from_linter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_from_linter.go
@@ -1,9 +1,9 @@
package processors
import (
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*MaxFromLinter)(nil)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_per_file_from_linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_per_file_from_linter.go
similarity index 74%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_per_file_from_linter.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_per_file_from_linter.go
index 7c59b5dd..fdb6bb02 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_per_file_from_linter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_per_file_from_linter.go
@@ -1,8 +1,13 @@
package processors
import (
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports"
+ "github.com/golangci/golangci-lint/v2/pkg/goformatters/golines"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*MaxPerFileFromLinter)(nil)
@@ -19,9 +24,9 @@ func NewMaxPerFileFromLinter(cfg *config.Config) *MaxPerFileFromLinter {
if !cfg.Issues.NeedFix {
// if we don't fix we do this limiting to not annoy user;
// otherwise we need to fix all issues in the file at once
- maxPerFileFromLinterConfig["gofmt"] = 1
- maxPerFileFromLinterConfig["goimports"] = 1
- maxPerFileFromLinterConfig["gci"] = 1
+ for _, f := range []string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name, golines.Name} {
+ maxPerFileFromLinterConfig[f] = 1
+ }
}
return &MaxPerFileFromLinter{
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_same_issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_same_issues.go
similarity index 90%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_same_issues.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_same_issues.go
index 349f6a9a..06e87586 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_same_issues.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_same_issues.go
@@ -3,9 +3,9 @@ package processors
import (
"sort"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*MaxSameIssues)(nil)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/nolint_filter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/nolint_filter.go
similarity index 96%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/nolint_filter.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/nolint_filter.go
index 99cd7999..96fd6403 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/nolint_filter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/nolint_filter.go
@@ -10,11 +10,11 @@ import (
"sort"
"strings"
- "github.com/golangci/golangci-lint/pkg/golinters/nolintlint"
- "github.com/golangci/golangci-lint/pkg/lint/linter"
- "github.com/golangci/golangci-lint/pkg/lint/lintersdb"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*NolintFilter)(nil)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_absoluter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_absoluter.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_absoluter.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_absoluter.go
index a649716d..99f3de42 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_absoluter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_absoluter.go
@@ -3,8 +3,8 @@ package processors
import (
"path/filepath"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*PathAbsoluter)(nil)
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_prettifier.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_prettifier.go
new file mode 100644
index 00000000..cb6ef8eb
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_prettifier.go
@@ -0,0 +1,51 @@
+package processors
+
+import (
+ "path/filepath"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+)
+
+var _ Processor = (*PathPrettifier)(nil)
+
+// PathPrettifier modifies report file path to be relative to the base path.
+// Also handles the `output.path-prefix` option.
+type PathPrettifier struct {
+ cfg *config.Output
+
+ log logutils.Log
+}
+
+func NewPathPrettifier(log logutils.Log, cfg *config.Output) *PathPrettifier {
+ return &PathPrettifier{
+ cfg: cfg,
+ log: log.Child(logutils.DebugKeyPathPrettifier),
+ }
+}
+
+func (*PathPrettifier) Name() string {
+ return "path_prettifier"
+}
+
+func (p *PathPrettifier) Process(issues []result.Issue) ([]result.Issue, error) {
+ if p.cfg.PathMode == fsutils.OutputPathModeAbsolute {
+ return issues, nil
+ }
+
+ return transformIssues(issues, func(issue *result.Issue) *result.Issue {
+ newIssue := issue
+
+ if p.cfg.PathPrefix == "" {
+ newIssue.Pos.Filename = issue.RelativePath
+ } else {
+ newIssue.Pos.Filename = filepath.Join(p.cfg.PathPrefix, issue.RelativePath)
+ }
+
+ return newIssue
+ }), nil
+}
+
+func (*PathPrettifier) Finish() {}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_relativity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_relativity.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_relativity.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_relativity.go
index bdaf1b98..8b2958a4 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_relativity.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_relativity.go
@@ -4,9 +4,9 @@ import (
"fmt"
"path/filepath"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*PathRelativity)(nil)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_shortener.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_shortener.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_shortener.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_shortener.go
index 0c028826..7a14c39c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_shortener.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_shortener.go
@@ -4,8 +4,8 @@ import (
"fmt"
"strings"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*PathShortener)(nil)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/processor.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/processor.go
similarity index 77%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/processor.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/processor.go
index 13e63d60..1976d6e4 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/processor.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/processor.go
@@ -1,7 +1,7 @@
package processors
import (
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const typeCheckName = "typecheck"
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/severity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/severity.go
similarity index 72%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/severity.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/severity.go
index 2dacf663..035ca80c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/severity.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/severity.go
@@ -3,10 +3,10 @@ package processors
import (
"cmp"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const severityFromLinter = "@linter"
@@ -22,27 +22,21 @@ type Severity struct {
log logutils.Log
- files *fsutils.Files
+ lines *fsutils.LineCache
defaultSeverity string
rules []severityRule
}
-func NewSeverity(log logutils.Log, files *fsutils.Files, cfg *config.Severity) *Severity {
+func NewSeverity(log logutils.Log, lines *fsutils.LineCache, cfg *config.Severity) *Severity {
p := &Severity{
name: "severity-rules",
- files: files,
+ lines: lines,
log: log,
defaultSeverity: cfg.Default,
}
- prefix := caseInsensitivePrefix
- if cfg.CaseSensitive {
- prefix = ""
- p.name = "severity-rules-case-sensitive"
- }
-
- p.rules = parseRules(cfg.Rules, prefix, newSeverityRule)
+ p.rules = parseRules(cfg.Rules, "", newSeverityRule)
return p
}
@@ -61,7 +55,7 @@ func (*Severity) Finish() {}
func (p *Severity) transform(issue *result.Issue) *result.Issue {
for _, rule := range p.rules {
- if rule.match(issue, p.files, p.log) {
+ if rule.match(issue, p.lines, p.log) {
if rule.severity == severityFromLinter || (rule.severity == "" && p.defaultSeverity == severityFromLinter) {
return issue
}
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/sort_results.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/sort_results.go
similarity index 93%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/sort_results.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/sort_results.go
index 96f5574f..033eca9a 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/sort_results.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/sort_results.go
@@ -6,8 +6,8 @@ import (
"slices"
"strings"
- "github.com/golangci/golangci-lint/pkg/config"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const (
@@ -55,12 +55,8 @@ func (SortResults) Name() string { return "sort_results" }
// Process is performing sorting of the result issues.
func (p SortResults) Process(issues []result.Issue) ([]result.Issue, error) {
- if !p.cfg.SortResults {
- return issues, nil
- }
-
if len(p.cfg.SortOrder) == 0 {
- p.cfg.SortOrder = []string{orderNameFile}
+ p.cfg.SortOrder = []string{orderNameLinter, orderNameFile}
}
var cmps []issueComparator
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/source_code.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/source_code.go
similarity index 89%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/source_code.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/source_code.go
index 3f20b2f5..1096269c 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/source_code.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/source_code.go
@@ -1,9 +1,9 @@
package processors
import (
- "github.com/golangci/golangci-lint/pkg/fsutils"
- "github.com/golangci/golangci-lint/pkg/logutils"
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/fsutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
var _ Processor = (*SourceCode)(nil)
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/uniq_by_line.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/uniq_by_line.go
similarity index 96%
rename from vendor/github.com/golangci/golangci-lint/pkg/result/processors/uniq_by_line.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/uniq_by_line.go
index 72984212..113b5814 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/uniq_by_line.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/uniq_by_line.go
@@ -1,7 +1,7 @@
package processors
import (
- "github.com/golangci/golangci-lint/pkg/result"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
)
const uniqByLineLimit = 1
diff --git a/vendor/github.com/golangci/golangci-lint/pkg/timeutils/stopwatch.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/timeutils/stopwatch.go
similarity index 98%
rename from vendor/github.com/golangci/golangci-lint/pkg/timeutils/stopwatch.go
rename to vendor/github.com/golangci/golangci-lint/v2/pkg/timeutils/stopwatch.go
index 95b16de9..332c24c8 100644
--- a/vendor/github.com/golangci/golangci-lint/pkg/timeutils/stopwatch.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/timeutils/stopwatch.go
@@ -7,7 +7,7 @@ import (
"sync"
"time"
- "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/v2/pkg/logutils"
)
const noStagesText = "no stages"
diff --git a/vendor/github.com/golangci/golines/.gitattributes b/vendor/github.com/golangci/golines/.gitattributes
new file mode 100644
index 00000000..148ff868
--- /dev/null
+++ b/vendor/github.com/golangci/golines/.gitattributes
@@ -0,0 +1 @@
+_fixtures/* text eol=lf
diff --git a/vendor/github.com/golangci/golines/.gitignore b/vendor/github.com/golangci/golines/.gitignore
new file mode 100644
index 00000000..48e5593d
--- /dev/null
+++ b/vendor/github.com/golangci/golines/.gitignore
@@ -0,0 +1,20 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+/dist
+
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+vendor
+.vscode
+.idea
+golines
+
+coverage.out
diff --git a/vendor/github.com/golangci/golines/LICENSE b/vendor/github.com/golangci/golines/LICENSE
new file mode 100644
index 00000000..1fbffdf7
--- /dev/null
+++ b/vendor/github.com/golangci/golines/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Segment.io, Inc.
+
+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.
diff --git a/vendor/github.com/golangci/golines/README.md b/vendor/github.com/golangci/golines/README.md
new file mode 100644
index 00000000..24ec221a
--- /dev/null
+++ b/vendor/github.com/golangci/golines/README.md
@@ -0,0 +1,30 @@
+# Fork of golines
+
+This is a fork of [golines](https://github.com/segmentio/golines) to be usable as a library.
+
+## Modifications
+
+- The original code is under the `main` package -> uses `golines` package.
+- Some files have been removed to reduce dependencies:
+ - `main.go`, `main_test.go`
+ - `graph.go`, `graph_generated.go`, `graph.test`
+ - `diff.go`, `diff_test.go`
+ - `doc.go`
+- Some other files have been removed because unused by the fork:
+ - `.goreleaser.yaml`, `.pre-commit-hooks.yaml`
+ - `.github/build.yml`, `.github/release.yml`
+ - `Makefile`
+- The workflow files (`lint.yml` and `test.yml`) are modified to run for this fork.
+- The file `shortener.go` has been modified:
+ - The `baseFormatterCmd` is hardcoded.
+ - The code related to debug logs has been removed.
+ - The code related to graph has been removed.
+- The module name has been changed to `github.com/golangci/golines` to avoid replacement directives inside golangci-lint.
+
+**No modifications will be accepted other than the synchronization of the fork.**
+
+The synchronization of the fork will be done by the golangci-lint maintainers only.
+
+## History
+
+- sync with fc305205784a70b4cfc17397654f4c94e3153ce4 (after v0.12.2)
diff --git a/vendor/github.com/golangci/golines/annotation.go b/vendor/github.com/golangci/golines/annotation.go
new file mode 100644
index 00000000..fc7f92ca
--- /dev/null
+++ b/vendor/github.com/golangci/golines/annotation.go
@@ -0,0 +1,99 @@
+package golines
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/dave/dst"
+)
+
+const annotationPrefix = "// __golines:shorten:"
+
+// CreateAnnotation generates the text of a comment that will annotate long lines.
+func CreateAnnotation(length int) string {
+ return fmt.Sprintf(
+ "%s%d",
+ annotationPrefix,
+ length,
+ )
+}
+
+// IsAnnotation determines whether the given line is an annotation created with CreateAnnotation.
+func IsAnnotation(line string) bool {
+ return strings.HasPrefix(
+ strings.Trim(line, " \t"),
+ annotationPrefix,
+ )
+}
+
+// HasAnnotation determines whether the given AST node has a line length annotation on it.
+func HasAnnotation(node dst.Node) bool {
+ startDecorations := node.Decorations().Start.All()
+ return len(startDecorations) > 0 &&
+ IsAnnotation(startDecorations[len(startDecorations)-1])
+}
+
+// HasTailAnnotation determines whether the given AST node has a line length annotation at its
+// end. This is needed to catch long function declarations with inline interface definitions.
+func HasTailAnnotation(node dst.Node) bool {
+ endDecorations := node.Decorations().End.All()
+ return len(endDecorations) > 0 &&
+ IsAnnotation(endDecorations[len(endDecorations)-1])
+}
+
+// HasAnnotationRecursive determines whether the given node or one of its children has a
+// golines annotation on it. It's currently implemented for function declarations, fields,
+// call expressions, and selector expressions only.
+func HasAnnotationRecursive(node dst.Node) bool {
+ if HasAnnotation(node) {
+ return true
+ }
+
+ switch n := node.(type) {
+ case *dst.FuncDecl:
+ if n.Type != nil && n.Type.Params != nil {
+ for _, item := range n.Type.Params.List {
+ if HasAnnotationRecursive(item) {
+ return true
+ }
+ }
+ }
+ case *dst.Field:
+ return HasTailAnnotation(n) || HasAnnotationRecursive(n.Type)
+ case *dst.SelectorExpr:
+ return HasAnnotation(n.Sel) || HasAnnotation(n.X)
+ case *dst.CallExpr:
+ if HasAnnotationRecursive(n.Fun) {
+ return true
+ }
+
+ for _, arg := range n.Args {
+ if HasAnnotation(arg) {
+ return true
+ }
+ }
+ case *dst.InterfaceType:
+ for _, field := range n.Methods.List {
+ if HasAnnotationRecursive(field) {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+// ParseAnnotation returns the line length encoded in a golines annotation. If none is found,
+// it returns -1.
+func ParseAnnotation(line string) int {
+ if IsAnnotation(line) {
+ components := strings.SplitN(line, ":", 3)
+ val, err := strconv.Atoi(components[2])
+ if err != nil {
+ return -1
+ }
+ return val
+ }
+ return -1
+}
diff --git a/vendor/github.com/golangci/golines/shortener.go b/vendor/github.com/golangci/golines/shortener.go
new file mode 100644
index 00000000..c35b5f35
--- /dev/null
+++ b/vendor/github.com/golangci/golines/shortener.go
@@ -0,0 +1,594 @@
+package golines
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "go/format"
+ "go/token"
+ "os/exec"
+ "reflect"
+ "regexp"
+ "strings"
+
+ "github.com/dave/dst"
+ "github.com/dave/dst/decorator"
+)
+
+var (
+ // Strings to look for to identify generated files
+ generatedTerms = []string{
+ "do not edit",
+ "generated by",
+ "automatically regenerated",
+ }
+ // Go directives (should be ignored)
+ goDirectiveLine = regexp.MustCompile(`\s*//\s*go:.*`)
+)
+
+// The maximum number of shortening "rounds" that we'll allow. The shortening
+// process should converge quickly, but we have this here as a safety mechanism to
+// prevent loops that prevent termination.
+const maxRounds = 20
+
+// ShortenerConfig stores the configuration options exposed by a Shortener instance.
+type ShortenerConfig struct {
+ MaxLen int // Max target width for each line
+ TabLen int // Width of a tab character
+ KeepAnnotations bool // Whether to keep annotations in final result (for debugging only)
+ ShortenComments bool // Whether to shorten comments
+ ReformatTags bool // Whether to reformat struct tags in addition to shortening long lines
+ IgnoreGenerated bool // Whether to ignore generated files
+ DotFile string // Path to write dot-formatted output to (for debugging only)
+ ChainSplitDots bool // Whether to split chain methods by putting dots at ends of lines
+
+ // Formatter that will be run before and after main shortening process. If empty,
+ // defaults to goimports (if found), otherwise gofmt.
+ BaseFormatterCmd string
+}
+
+// Shortener shortens a single go file according to a small set of user style
+// preferences.
+type Shortener struct {
+ config ShortenerConfig
+
+ // Some extra params around the base formatter generated from the BaseFormatterCmd
+ // argument in the config.
+ baseFormatter string
+ baseFormatterArgs []string
+}
+
+// NewShortener creates a new shortener instance from the provided config.
+func NewShortener(config ShortenerConfig) *Shortener {
+ var formatterComponents []string
+
+ // golangci-lint: hardcoded base formatter.
+ // Note:
+ // - the command `gofmt` is not used, it calls `format.Source`.
+ // - the format is related to `go fmt` and not `gofmt`.
+ config.BaseFormatterCmd = "gofmt"
+
+ if config.BaseFormatterCmd == "" {
+ _, err := exec.LookPath("goimports")
+ if err != nil {
+ formatterComponents = []string{"gofmt"}
+ } else {
+ formatterComponents = []string{"goimports"}
+ }
+ } else {
+ formatterComponents = strings.Split(config.BaseFormatterCmd, " ")
+ }
+
+ s := &Shortener{
+ config: config,
+ baseFormatter: formatterComponents[0],
+ }
+
+ if len(formatterComponents) > 1 {
+ s.baseFormatterArgs = formatterComponents[1:]
+ } else {
+ s.baseFormatterArgs = []string{}
+ }
+
+ return s
+}
+
+// Shorten shortens the provided golang file content bytes.
+func (s *Shortener) Shorten(contents []byte) ([]byte, error) {
+ if s.config.IgnoreGenerated && s.isGenerated(contents) {
+ return contents, nil
+ }
+
+ round := 0
+ var err error
+
+ // Do initial, non-line-length-aware formatting
+ contents, err = s.formatSrc(contents)
+ if err != nil {
+ return nil, fmt.Errorf("Error formatting source: %+v", err)
+ }
+
+ for {
+ // Annotate all long lines
+ lines := strings.Split(string(contents), "\n")
+ annotatedLines, linesToShorten := s.annotateLongLines(lines)
+ var stop bool
+
+ if linesToShorten == 0 {
+ if round == 0 {
+ if !s.config.ReformatTags {
+ stop = true
+ } else if !HasMultiKeyTags(lines) {
+ stop = true
+ }
+ } else {
+ stop = true
+ }
+ }
+
+ if stop {
+ break
+ }
+
+ contents = []byte(strings.Join(annotatedLines, "\n"))
+
+ // Generate AST
+ result, err := decorator.Parse(contents)
+ if err != nil {
+ return nil, err
+ }
+
+ // Shorten the file starting at the top-level declarations
+ for _, decl := range result.Decls {
+ s.formatNode(decl)
+ }
+
+ // Materialize output
+ output := bytes.NewBuffer([]byte{})
+ err = decorator.Fprint(output, result)
+ if err != nil {
+ return nil, fmt.Errorf("Error parsing source: %+v", err)
+ }
+ contents = output.Bytes()
+
+ round++
+
+ if round > maxRounds {
+ break
+ }
+ }
+
+ if !s.config.KeepAnnotations {
+ contents = s.removeAnnotations(contents)
+ }
+ if s.config.ShortenComments {
+ contents = s.shortenCommentsFunc(contents)
+ }
+
+ // Do final round of non-line-length-aware formatting after we've fixed up the comments
+ contents, err = s.formatSrc(contents)
+ if err != nil {
+ return nil, fmt.Errorf("Error formatting source: %+v", err)
+ }
+
+ return contents, nil
+}
+
+// formatSrc formats the provided source bytes using the configured "base" formatter (typically
+// goimports or gofmt).
+func (s *Shortener) formatSrc(contents []byte) ([]byte, error) {
+ if s.baseFormatter == "gofmt" {
+ return format.Source(contents)
+ }
+
+ cmd := exec.Command(s.baseFormatter, s.baseFormatterArgs...)
+ stdinPipe, err := cmd.StdinPipe()
+ if err != nil {
+ return nil, err
+ }
+
+ outBuffer := &bytes.Buffer{}
+ cmd.Stdout = outBuffer
+
+ if err = cmd.Start(); err != nil {
+ return nil, err
+ }
+
+ _, err = stdinPipe.Write(contents)
+ if err != nil {
+ return nil, err
+ }
+ stdinPipe.Close()
+
+ err = cmd.Wait()
+ if err != nil {
+ return nil, err
+ }
+
+ return outBuffer.Bytes(), nil
+}
+
+// annotateLongLines adds specially-formatted comments to all eligible lines that are longer than
+// the configured target length. If a line already has one of these comments from a previous
+// shortening round, then the comment contents are updated.
+func (s *Shortener) annotateLongLines(lines []string) ([]string, int) {
+ annotatedLines := []string{}
+ linesToShorten := 0
+ prevLen := -1
+
+ for _, line := range lines {
+ length := s.lineLen(line)
+
+ if prevLen > -1 {
+ if length <= s.config.MaxLen {
+ // Shortening successful, remove previous annotation
+ annotatedLines = annotatedLines[:len(annotatedLines)-1]
+ } else if length < prevLen {
+ // Replace annotation with new length
+ annotatedLines[len(annotatedLines)-1] = CreateAnnotation(length)
+ linesToShorten++
+ }
+ } else if !s.isComment(line) && length > s.config.MaxLen {
+ annotatedLines = append(
+ annotatedLines,
+ CreateAnnotation(length),
+ )
+ linesToShorten++
+ }
+
+ annotatedLines = append(annotatedLines, line)
+ prevLen = ParseAnnotation(line)
+ }
+
+ return annotatedLines, linesToShorten
+}
+
+// removeAnnotations removes all comments that were added by the annotateLongLines
+// function above.
+func (s *Shortener) removeAnnotations(contents []byte) []byte {
+ cleanedLines := []string{}
+ lines := strings.Split(string(contents), "\n")
+
+ for _, line := range lines {
+ if !IsAnnotation(line) {
+ cleanedLines = append(cleanedLines, line)
+ }
+ }
+
+ return []byte(strings.Join(cleanedLines, "\n"))
+}
+
+// shortenCommentsFunc attempts to shorten long comments in the provided source. As noted
+// in the repo README, this functionality has some quirks and is disabled by default.
+func (s *Shortener) shortenCommentsFunc(contents []byte) []byte {
+ cleanedLines := []string{}
+ words := []string{} // all words in a contiguous sequence of long comments
+ prefix := ""
+ lines := strings.Split(string(contents), "\n")
+ for _, line := range lines {
+ if s.isComment(line) && !IsAnnotation(line) &&
+ !s.isGoDirective(line) &&
+ s.lineLen(line) > s.config.MaxLen {
+ start := strings.Index(line, "//")
+ prefix = line[0:(start + 2)]
+ trimmedLine := strings.Trim(line[(start+2):], " ")
+ currLineWords := strings.Split(trimmedLine, " ")
+ words = append(words, currLineWords...)
+ } else {
+ // Reflow the accumulated `words` before appending the unprocessed `line`.
+ currLineLen := 0
+ currLineWords := []string{}
+ maxCommentLen := s.config.MaxLen - s.lineLen(prefix)
+ for _, word := range words {
+ if currLineLen > 0 && currLineLen+1+len(word) > maxCommentLen {
+ cleanedLines = append(
+ cleanedLines,
+ fmt.Sprintf(
+ "%s %s",
+ prefix,
+ strings.Join(currLineWords, " "),
+ ),
+ )
+ currLineWords = []string{}
+ currLineLen = 0
+ }
+ currLineWords = append(currLineWords, word)
+ currLineLen += 1 + len(word)
+ }
+ if currLineLen > 0 {
+ cleanedLines = append(
+ cleanedLines,
+ fmt.Sprintf(
+ "%s %s",
+ prefix,
+ strings.Join(currLineWords, " "),
+ ),
+ )
+ }
+ words = []string{}
+
+ cleanedLines = append(cleanedLines, line)
+ }
+ }
+ return []byte(strings.Join(cleanedLines, "\n"))
+}
+
+// lineLen gets the width of the provided line after tab expansion.
+func (s *Shortener) lineLen(line string) int {
+ length := 0
+
+ for _, char := range line {
+ if char == '\t' {
+ length += s.config.TabLen
+ } else {
+ length++
+ }
+ }
+
+ return length
+}
+
+// isComment determines whether the provided line is a non-block comment.
+func (s *Shortener) isComment(line string) bool {
+ return strings.HasPrefix(strings.Trim(line, " \t"), "//")
+}
+
+// isGoDirective determines whether the provided line is a go directive, e.g. for go generate.
+func (s *Shortener) isGoDirective(line string) bool {
+ return goDirectiveLine.MatchString(line)
+}
+
+// formatNode formats the provided AST node. The appropriate helper function is called
+// based on whether the node is a declaration, expression, statement, or spec.
+func (s *Shortener) formatNode(node dst.Node) {
+ switch n := node.(type) {
+ case dst.Decl:
+ s.formatDecl(n)
+ case dst.Expr:
+ s.formatExpr(n, false, false)
+ case dst.Stmt:
+ s.formatStmt(n)
+ case dst.Spec:
+ s.formatSpec(n, false)
+ default:
+ // noop
+ }
+}
+
+// formatDecl formats an AST declaration node. These include function declarations,
+// imports, and constants.
+func (s *Shortener) formatDecl(decl dst.Decl) {
+ switch d := decl.(type) {
+ case *dst.FuncDecl:
+ if HasAnnotationRecursive(decl) {
+ if d.Type != nil && d.Type.Params != nil {
+ s.formatFieldList(d.Type.Params)
+ }
+ }
+ s.formatStmt(d.Body)
+ case *dst.GenDecl:
+ for _, spec := range d.Specs {
+ s.formatSpec(spec, HasAnnotation(decl))
+ }
+ default:
+ // noop
+ }
+}
+
+// formatFieldList formats a field list in a function declaration.
+func (s *Shortener) formatFieldList(fieldList *dst.FieldList) {
+ for f, field := range fieldList.List {
+ if f == 0 {
+ field.Decorations().Before = dst.NewLine
+ } else {
+ field.Decorations().Before = dst.None
+ }
+
+ field.Decorations().After = dst.NewLine
+ }
+}
+
+// formatStmt formats an AST statement node. Among other examples, these include assignments,
+// case clauses, for statements, if statements, and select statements.
+func (s *Shortener) formatStmt(stmt dst.Stmt) {
+ // Explicitly check for nil statements
+ stmtType := reflect.TypeOf(stmt)
+ if reflect.ValueOf(stmt) == reflect.Zero(stmtType) {
+ return
+ }
+
+ shouldShorten := HasAnnotation(stmt)
+
+ switch st := stmt.(type) {
+ case *dst.AssignStmt:
+ for _, expr := range st.Rhs {
+ s.formatExpr(expr, shouldShorten, false)
+ }
+ case *dst.BlockStmt:
+ for _, stmt := range st.List {
+ s.formatStmt(stmt)
+ }
+ case *dst.CaseClause:
+ if shouldShorten {
+ for _, arg := range st.List {
+ arg.Decorations().After = dst.NewLine
+ s.formatExpr(arg, false, false)
+ }
+ }
+
+ for _, stmt := range st.Body {
+ s.formatStmt(stmt)
+ }
+ case *dst.CommClause:
+ for _, stmt := range st.Body {
+ s.formatStmt(stmt)
+ }
+ case *dst.DeclStmt:
+ s.formatDecl(st.Decl)
+ case *dst.DeferStmt:
+ s.formatExpr(st.Call, shouldShorten, false)
+ case *dst.ExprStmt:
+ s.formatExpr(st.X, shouldShorten, false)
+ case *dst.ForStmt:
+ s.formatStmt(st.Body)
+ case *dst.GoStmt:
+ s.formatExpr(st.Call, shouldShorten, false)
+ case *dst.IfStmt:
+ s.formatExpr(st.Cond, shouldShorten, false)
+ s.formatStmt(st.Body)
+ case *dst.RangeStmt:
+ s.formatStmt(st.Body)
+ case *dst.ReturnStmt:
+ for _, expr := range st.Results {
+ s.formatExpr(expr, shouldShorten, false)
+ }
+ case *dst.SelectStmt:
+ s.formatStmt(st.Body)
+ case *dst.SwitchStmt:
+ s.formatStmt(st.Body)
+ default:
+ // noop
+ }
+}
+
+// formatExpr formats an AST expression node. These include uniary and binary expressions, function
+// literals, and key/value pair statements, among others.
+func (s *Shortener) formatExpr(expr dst.Expr, force bool, isChain bool) {
+ shouldShorten := force || HasAnnotation(expr)
+
+ switch e := expr.(type) {
+ case *dst.BinaryExpr:
+ if (e.Op == token.LAND || e.Op == token.LOR) && shouldShorten {
+ if e.Y.Decorations().Before == dst.NewLine {
+ s.formatExpr(e.X, force, isChain)
+ } else {
+ e.Y.Decorations().Before = dst.NewLine
+ }
+ } else {
+ s.formatExpr(e.X, shouldShorten, isChain)
+ s.formatExpr(e.Y, shouldShorten, isChain)
+ }
+ case *dst.CallExpr:
+ _, ok := e.Fun.(*dst.SelectorExpr)
+
+ if ok &&
+ s.config.ChainSplitDots &&
+ (shouldShorten || HasAnnotationRecursive(e)) &&
+ (isChain || s.chainLength(e) > 1) {
+ e.Decorations().After = dst.NewLine
+
+ for _, arg := range e.Args {
+ s.formatExpr(arg, false, true)
+ }
+
+ s.formatExpr(e.Fun, shouldShorten, true)
+ } else {
+ shortenChildArgs := shouldShorten || HasAnnotationRecursive(e)
+
+ for a, arg := range e.Args {
+ if shortenChildArgs {
+ if a == 0 {
+ arg.Decorations().Before = dst.NewLine
+ } else {
+ arg.Decorations().After = dst.None
+ }
+ arg.Decorations().After = dst.NewLine
+ }
+ s.formatExpr(arg, false, isChain)
+ }
+ s.formatExpr(e.Fun, shouldShorten, isChain)
+ }
+ case *dst.CompositeLit:
+ if shouldShorten {
+ for i, element := range e.Elts {
+ if i == 0 {
+ element.Decorations().Before = dst.NewLine
+ }
+ element.Decorations().After = dst.NewLine
+ }
+ }
+
+ for _, element := range e.Elts {
+ s.formatExpr(element, false, isChain)
+ }
+ case *dst.FuncLit:
+ s.formatStmt(e.Body)
+ case *dst.FuncType:
+ if shouldShorten {
+ s.formatFieldList(e.Params)
+ }
+ case *dst.InterfaceType:
+ for _, method := range e.Methods.List {
+ if HasAnnotation(method) {
+ s.formatExpr(method.Type, true, isChain)
+ }
+ }
+ case *dst.KeyValueExpr:
+ s.formatExpr(e.Value, shouldShorten, isChain)
+ case *dst.SelectorExpr:
+ s.formatExpr(e.X, shouldShorten, isChain)
+ case *dst.StructType:
+ if s.config.ReformatTags {
+ FormatStructTags(e.Fields)
+ }
+ case *dst.UnaryExpr:
+ s.formatExpr(e.X, shouldShorten, isChain)
+ default:
+ // noop
+ }
+}
+
+// formatSpec formats an AST spec node. These include type specifications, among other things.
+func (s *Shortener) formatSpec(spec dst.Spec, force bool) {
+ shouldShorten := HasAnnotation(spec) || force
+ switch sp := spec.(type) {
+ case *dst.ValueSpec:
+ for _, expr := range sp.Values {
+ s.formatExpr(expr, shouldShorten, false)
+ }
+ case *dst.TypeSpec:
+ s.formatExpr(sp.Type, false, false)
+ default:
+ // noop
+ }
+}
+
+// isGenerated checks whether the provided file bytes are from a generated file.
+// This is done by looking for a set of typically-used strings in the first 5 lines.
+func (s *Shortener) isGenerated(contents []byte) bool {
+ scanner := bufio.NewScanner(bytes.NewBuffer(contents))
+
+ for i := 0; scanner.Scan(); i++ {
+ if i >= 5 {
+ return false
+ }
+
+ for _, term := range generatedTerms {
+ if strings.Contains(strings.ToLower(scanner.Text()), term) {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+// chainLength determines the length of the function call chain in an expression.
+func (s *Shortener) chainLength(callExpr *dst.CallExpr) int {
+ numCalls := 1
+ currCall := callExpr
+
+ for {
+ selectorExpr, ok := currCall.Fun.(*dst.SelectorExpr)
+ if !ok {
+ break
+ }
+ currCall, ok = selectorExpr.X.(*dst.CallExpr)
+ if !ok {
+ break
+ }
+ numCalls++
+ }
+
+ return numCalls
+}
diff --git a/vendor/github.com/golangci/golines/tags.go b/vendor/github.com/golangci/golines/tags.go
new file mode 100644
index 00000000..f5321fab
--- /dev/null
+++ b/vendor/github.com/golangci/golines/tags.go
@@ -0,0 +1,217 @@
+package golines
+
+import (
+ "fmt"
+ "reflect"
+ "regexp"
+ "strings"
+
+ "github.com/dave/dst"
+ "github.com/fatih/structtag"
+)
+
+var structTagRegexp = regexp.MustCompile("`([ ]*[a-zA-Z0-9_-]+:\".*\"[ ]*){2,}`")
+
+// HasMultiKeyTags returns whether the given lines have a multikey struct line.
+// It's used as an optimization step to avoid unnnecessary shortening rounds.
+func HasMultiKeyTags(lines []string) bool {
+ for _, line := range lines {
+ if structTagRegexp.MatchString(line) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// FormatStructTags formats struct tags so that the keys within each block of fields are aligned.
+// It's not technically a shortening (and it usually makes these tags longer), so it's being
+// kept separate from the core shortening logic for now.
+//
+// See the struct_tags fixture for examples.
+func FormatStructTags(fieldList *dst.FieldList) {
+ if fieldList == nil || len(fieldList.List) == 0 {
+ return
+ }
+
+ blockFields := []*dst.Field{}
+
+ // Divide fields into "blocks" so that we don't do alignments across blank lines
+ for f, field := range fieldList.List {
+ if f == 0 || field.Decorations().Before == dst.EmptyLine {
+ alignTags(blockFields)
+ blockFields = blockFields[:0]
+ }
+
+ blockFields = append(blockFields, field)
+ }
+
+ alignTags(blockFields)
+}
+
+// alignTags formats the struct tags within a single field block.
+func alignTags(fields []*dst.Field) {
+ if len(fields) == 0 {
+ return
+ }
+
+ maxTagWidths := map[string]int{}
+ tagKeys := []string{}
+ tagKVs := make([]map[string]string, len(fields))
+
+ maxTypeWidth := 0
+ invalidWidths := false
+
+ // First, scan over all field tags so that we can understand their values and widths
+ for f, field := range fields {
+ if len(field.Names) > 0 {
+ typeWidth, err := getWidth(field.Type)
+ if err != nil {
+ // We couldn't figure out the proper width of this field
+ invalidWidths = true
+ } else if typeWidth > maxTypeWidth {
+ maxTypeWidth = typeWidth
+ }
+ }
+
+ if field.Tag == nil {
+ continue
+ }
+
+ tagValue := field.Tag.Value
+
+ // The dst library doesn't strip off the backticks, so we need to do this manually
+ if tagValue[0] != '`' || tagValue[len(tagValue)-1] != '`' {
+ continue
+ }
+ tagValue = tagValue[1 : len(tagValue)-1]
+
+ subTags, err := structtag.Parse(tagValue)
+ if err != nil {
+ return
+ }
+ subTagKeys := subTags.Keys()
+
+ structTag := reflect.StructTag(tagValue)
+
+ for _, key := range subTagKeys {
+ value := structTag.Get(key)
+
+ // Tag is key, value, and some extra chars (two quotes + one colon)
+ width := len(key) + tagValueLen(value) + 3
+
+ if _, ok := maxTagWidths[key]; !ok {
+ maxTagWidths[key] = width
+ tagKeys = append(tagKeys, key)
+ } else if width > maxTagWidths[key] {
+ maxTagWidths[key] = width
+ }
+
+ if tagKVs[f] == nil {
+ tagKVs[f] = map[string]string{}
+ }
+
+ tagKVs[f][key] = value
+ }
+ }
+
+ // Go over all the fields again, replacing each tag with a reformatted one
+ for f, field := range fields {
+ if tagKVs[f] == nil {
+ continue
+ }
+
+ tagComponents := []string{}
+
+ if len(field.Names) == 0 && maxTypeWidth > 0 && !invalidWidths {
+ // Add extra spacing at beginning so that tag aligns with named field tags
+ tagComponents = append(tagComponents, "")
+
+ for i := 0; i < maxTypeWidth; i++ {
+ tagComponents[len(tagComponents)-1] += " "
+ }
+ }
+
+ for _, key := range tagKeys {
+ value, ok := tagKVs[f][key]
+ lenUsed := 0
+
+ if ok {
+ tagComponents = append(tagComponents, fmt.Sprintf("%s:\"%s\"", key, value))
+ lenUsed += len(key) + tagValueLen(value) + 3
+ } else {
+ tagComponents = append(tagComponents, "")
+ }
+
+ if len(field.Names) > 0 || !invalidWidths {
+ lenRemaining := maxTagWidths[key] - lenUsed
+
+ for i := 0; i < lenRemaining; i++ {
+ tagComponents[len(tagComponents)-1] += " "
+ }
+ }
+ }
+
+ updatedTagValue := strings.TrimRight(strings.Join(tagComponents, " "), " ")
+ field.Tag.Value = fmt.Sprintf("`%s`", updatedTagValue)
+ }
+}
+
+// get real tag value's length, fix multi-byte character's length, such as `ï`
+// or `中文`
+func tagValueLen(s string) int {
+ return len([]rune(s))
+}
+
+// getWidth tries to guess the formatted width of a dst node expression. If this isn't (yet)
+// possible, it returns an error.
+func getWidth(node dst.Node) (int, error) {
+ switch n := node.(type) {
+ case *dst.ArrayType:
+ eltWidth, err := getWidth(n.Elt)
+ if err != nil {
+ return 0, err
+ }
+
+ return 2 + eltWidth, nil
+ case *dst.ChanType:
+ valWidth, err := getWidth(n.Value)
+ if err != nil {
+ return 0, err
+ }
+
+ isSend := n.Dir&dst.SEND > 0
+ isRecv := n.Dir&dst.RECV > 0
+
+ if isSend && isRecv {
+ // Channel does not include an arrow
+ return 5 + valWidth, nil
+ }
+
+ // Channel includes an arrow
+ return 7 + valWidth, nil
+ case *dst.Ident:
+ return len(n.Name), nil
+ case *dst.MapType:
+ keyWidth, err := getWidth(n.Key)
+ if err != nil {
+ return 0, err
+ }
+
+ valWidth, err := getWidth(n.Value)
+ if err != nil {
+ return 0, err
+ }
+
+ return 5 + keyWidth + valWidth, nil
+ case *dst.StarExpr:
+ xWidth, err := getWidth(n.X)
+ if err != nil {
+ return 0, err
+ }
+
+ return 1 + xWidth, nil
+ }
+
+ return 0, fmt.Errorf("Could not get width of node %+v", node)
+}
diff --git a/vendor/github.com/golangci/unconvert/golangci.go b/vendor/github.com/golangci/unconvert/golangci.go
index 306c44e5..04e385a0 100644
--- a/vendor/github.com/golangci/unconvert/golangci.go
+++ b/vendor/github.com/golangci/unconvert/golangci.go
@@ -25,15 +25,22 @@ var (
func pointer[T string | int | int32 | int64 | bool](v T) *T { return &v }
-func Run(pass *analysis.Pass, fastMath, safe bool) []token.Position {
+func SetFastMath(fastMath bool) {
+ // To avoid race condition, the settings should not be defined during the Run.
+ flagFastMath = pointer(fastMath)
+}
+
+func SetSafe(safe bool) {
+ // To avoid race condition, the settings should not be defined during the Run.
+ flagSafe = pointer(safe)
+}
+
+func Run(pass *analysis.Pass) []token.Position {
type res struct {
file string
edits editSet
}
- flagFastMath = pointer(fastMath)
- flagSafe = pointer(safe)
-
ch := make(chan res)
var wg sync.WaitGroup
for _, file := range pass.Files {
diff --git a/vendor/github.com/golangci/unconvert/unconvert.go b/vendor/github.com/golangci/unconvert/unconvert.go
index 222aeadf..36c34fa4 100644
--- a/vendor/github.com/golangci/unconvert/unconvert.go
+++ b/vendor/github.com/golangci/unconvert/unconvert.go
@@ -15,7 +15,6 @@ import (
"go/parser"
"go/token"
"go/types"
- "io/ioutil"
"log"
"os"
"os/exec"
@@ -87,7 +86,7 @@ func apply(file string, edits editSet) {
log.Fatal(err)
}
- err = ioutil.WriteFile(file, buf.Bytes(), 0)
+ err = os.WriteFile(file, buf.Bytes(), 0)
if err != nil {
log.Fatal(err)
}
@@ -143,7 +142,7 @@ func print(conversions []token.Position) {
fmt.Printf("%s:%d:%d: unnecessary conversion\n", pos.Filename, pos.Line, pos.Column)
if *flagV {
if pos.Filename != file {
- buf, err := ioutil.ReadFile(pos.Filename)
+ buf, err := os.ReadFile(pos.Filename)
if err != nil {
log.Fatal(err)
}
diff --git a/vendor/github.com/jgautheron/goconst/.gitignore b/vendor/github.com/jgautheron/goconst/.gitignore
new file mode 100644
index 00000000..38dc761f
--- /dev/null
+++ b/vendor/github.com/jgautheron/goconst/.gitignore
@@ -0,0 +1 @@
+/goconst
diff --git a/vendor/github.com/jgautheron/goconst/README.md b/vendor/github.com/jgautheron/goconst/README.md
index c671eb54..3ad33b9c 100644
--- a/vendor/github.com/jgautheron/goconst/README.md
+++ b/vendor/github.com/jgautheron/goconst/README.md
@@ -10,7 +10,7 @@ While this could be considered a beginner mistake, across time, multiple package
### Get Started
- $ go get github.com/jgautheron/goconst/cmd/goconst
+ $ go install github.com/jgautheron/goconst/cmd/goconst@latest
$ goconst ./...
### Usage
@@ -23,11 +23,12 @@ Usage:
Flags:
-ignore exclude files matching the given regular expression
- -ignore-strings exclude strings matching the given regular expression
+ -ignore-strings exclude strings matching the given regular expression
-ignore-tests exclude tests from the search (default: true)
-min-occurrences report from how many occurrences (default: 2)
-min-length only report strings with the minimum given length (default: 3)
-match-constant look for existing constants matching the values
+ -find-duplicates look for constants with identical values
-numbers search also for duplicated numbers
-min minimum value, only works with -numbers
-max maximum value, only works with -numbers
@@ -40,12 +41,46 @@ Examples:
goconst -ignore "yacc|\.pb\." $GOPATH/src/github.com/cockroachdb/cockroach/...
goconst -min-occurrences 3 -output json $GOPATH/src/github.com/cockroachdb/cockroach
goconst -numbers -min 60 -max 512 .
+ goconst -min-occurrences 5 $(go list -m -f '{{.Dir}}')
```
+### Development
+
+#### Running Tests
+
+The project includes a comprehensive test suite. To run the tests:
+
+```bash
+# Run all tests
+go test ./...
+
+# Run tests with verbose output
+go test -v ./...
+
+# Run tests with race detector
+go test -race ./...
+
+# Run benchmarks
+go test -bench=. ./...
+
+# Check test coverage
+go test -cover ./...
+```
+
+#### Contributing
+
+Contributions are welcome! Before submitting a PR:
+
+1. Make sure all tests pass
+2. Add tests for new functionality
+3. Ensure your code passes linting checks
+4. Update documentation as needed
+
### Other static analysis tools
- [gogetimports](https://github.com/jgautheron/gogetimports): Get a JSON-formatted list of imports.
- [usedexports](https://github.com/jgautheron/usedexports): Find exported variables that could be unexported.
### License
+
MIT
diff --git a/vendor/github.com/jgautheron/goconst/api.go b/vendor/github.com/jgautheron/goconst/api.go
index b838e035..10cece15 100644
--- a/vendor/github.com/jgautheron/goconst/api.go
+++ b/vendor/github.com/jgautheron/goconst/api.go
@@ -3,74 +3,253 @@ package goconst
import (
"go/ast"
"go/token"
+ "go/types"
+ "sort"
"strings"
+ "sync"
)
+// Issue represents a finding of duplicated strings, numbers, or constants.
+// Each Issue includes the position where it was found, how many times it occurs,
+// the string itself, and any matching constant name.
type Issue struct {
Pos token.Position
OccurrencesCount int
Str string
MatchingConst string
+ DuplicateConst string
+ DuplicatePos token.Position
}
+// Config contains all configuration options for the goconst analyzer.
type Config struct {
- IgnoreStrings string
- IgnoreTests bool
+ // IgnoreStrings is a list of regular expressions to filter strings
+ IgnoreStrings []string
+ // IgnoreTests indicates whether test files should be excluded
+ IgnoreTests bool
+ // MatchWithConstants enables matching strings with existing constants
MatchWithConstants bool
- MinStringLength int
- MinOccurrences int
- ParseNumbers bool
- NumberMin int
- NumberMax int
- ExcludeTypes map[Type]bool
+ // MinStringLength is the minimum length a string must have to be reported
+ MinStringLength int
+ // MinOccurrences is the minimum number of occurrences required to report a string
+ MinOccurrences int
+ // ParseNumbers enables detection of duplicated numbers
+ ParseNumbers bool
+ // NumberMin sets the minimum value for reported number matches
+ NumberMin int
+ // NumberMax sets the maximum value for reported number matches
+ NumberMax int
+ // ExcludeTypes allows excluding specific types of contexts
+ ExcludeTypes map[Type]bool
+ // FindDuplicates enables finding constants whose values match existing constants in other packages.
+ FindDuplicates bool
+ // EvalConstExpressions enables evaluation of constant expressions like Prefix + "suffix"
+ EvalConstExpressions bool
}
-func Run(files []*ast.File, fset *token.FileSet, cfg *Config) ([]Issue, error) {
- p := New(
+// NewWithIgnorePatterns creates a new instance of the parser with support for multiple ignore patterns.
+// This is an alternative constructor that takes a slice of ignore string patterns.
+func NewWithIgnorePatterns(
+ path, ignore string,
+ ignoreStrings []string,
+ ignoreTests, matchConstant, numbers, findDuplicates, evalConstExpressions bool,
+ numberMin, numberMax, minLength, minOccurrences int,
+ excludeTypes map[Type]bool) *Parser {
+
+ // Join multiple patterns with OR for regex
+ var ignoreStringsPattern string
+ if len(ignoreStrings) > 0 {
+ if len(ignoreStrings) > 1 {
+ // Wrap each pattern in parentheses and join with OR
+ patterns := make([]string, len(ignoreStrings))
+ for i, pattern := range ignoreStrings {
+ patterns[i] = "(" + pattern + ")"
+ }
+ ignoreStringsPattern = strings.Join(patterns, "|")
+ } else {
+ // Single pattern case
+ ignoreStringsPattern = ignoreStrings[0]
+ }
+ }
+
+ return New(
+ path,
+ ignore,
+ ignoreStringsPattern,
+ ignoreTests,
+ matchConstant,
+ numbers,
+ findDuplicates,
+ evalConstExpressions,
+ numberMin,
+ numberMax,
+ minLength,
+ minOccurrences,
+ excludeTypes,
+ )
+}
+
+// RunWithConfig is a convenience function that runs the analysis with a Config object
+// directly supporting multiple ignore patterns.
+func RunWithConfig(files []*ast.File, fset *token.FileSet, typeInfo *types.Info, cfg *Config) ([]Issue, error) {
+ p := NewWithIgnorePatterns(
"",
"",
cfg.IgnoreStrings,
cfg.IgnoreTests,
cfg.MatchWithConstants,
cfg.ParseNumbers,
+ cfg.FindDuplicates,
+ cfg.EvalConstExpressions,
cfg.NumberMin,
cfg.NumberMax,
cfg.MinStringLength,
cfg.MinOccurrences,
cfg.ExcludeTypes,
)
- var issues []Issue
+
+ // Pre-allocate slice based on estimated result size
+ expectedIssues := len(files) * 5 // Assuming average of 5 issues per file
+ if expectedIssues > 1000 {
+ expectedIssues = 1000 // Cap at reasonable maximum
+ }
+
+ // Allocate a new buffer
+ issueBuffer := make([]Issue, 0, expectedIssues)
+
+ // Process files concurrently
+ var wg sync.WaitGroup
+ sem := make(chan struct{}, p.maxConcurrency)
+
+ // Create a filtered files slice with capacity hint
+ filteredFiles := make([]*ast.File, 0, len(files))
+
+ // Filter test files first if needed
for _, f := range files {
if p.ignoreTests {
- if filename := fset.Position(f.Pos()).Filename; strings.HasSuffix(filename, testSuffix) {
+ if filename := fset.Position(f.Pos()).Filename; strings.HasSuffix(filename, "_test.go") {
continue
}
}
- ast.Walk(&treeVisitor{
- fileSet: fset,
- packageName: "",
- fileName: "",
- p: p,
- }, f)
+ filteredFiles = append(filteredFiles, f)
}
+
+ // Process each file in parallel
+ for _, f := range filteredFiles {
+ wg.Add(1)
+ sem <- struct{}{} // acquire semaphore
+
+ go func(f *ast.File) {
+ defer func() {
+ <-sem // release semaphore
+ wg.Done()
+ }()
+
+ // Use empty interned strings for package/file names
+ // The visitor logic will set these appropriately
+ emptyStr := InternString("")
+
+ ast.Walk(&treeVisitor{
+ fileSet: fset,
+ packageName: emptyStr,
+ p: p,
+ ignoreRegex: p.ignoreStringsRegex,
+ typeInfo: typeInfo,
+ }, f)
+ }(f)
+ }
+
+ wg.Wait()
+
p.ProcessResults()
- for str, item := range p.strs {
- fi := item[0]
- i := Issue{
+ // Process each string that passed the filters
+ p.stringMutex.RLock()
+ p.stringCountMutex.RLock()
+
+ // Create a slice to hold the string keys
+ stringKeys := make([]string, 0, len(p.strs))
+
+ // Create an array of strings to sort for stable output
+ for str := range p.strs {
+ if count := p.stringCount[str]; count >= p.minOccurrences {
+ stringKeys = append(stringKeys, str)
+ }
+ }
+
+ sort.Strings(stringKeys)
+
+ // Process strings in a predictable order for stable output
+ for _, str := range stringKeys {
+ positions := p.strs[str]
+ if len(positions) == 0 {
+ continue
+ }
+
+ // Use the first position as representative
+ fi := positions[0]
+
+ // Create issue using the counted value to avoid recounting
+ issue := Issue{
Pos: fi.Position,
- OccurrencesCount: len(item),
+ OccurrencesCount: p.stringCount[str],
Str: str,
}
- if len(p.consts) != 0 {
- if cst, ok := p.consts[str]; ok {
+ // Check for matching constants
+ if len(p.consts) > 0 {
+ p.constMutex.RLock()
+ if csts, ok := p.consts[str]; ok && len(csts) > 0 {
// const should be in the same package and exported
- i.MatchingConst = cst.Name
+ issue.MatchingConst = csts[0].Name
}
+ p.constMutex.RUnlock()
+ }
+
+ issueBuffer = append(issueBuffer, issue)
+ }
+
+ p.stringCountMutex.RUnlock()
+ p.stringMutex.RUnlock()
+
+ // process duplicate constants
+ p.constMutex.RLock()
+
+ // Create a new slice for const keys
+ stringKeys = make([]string, 0, len(p.consts))
+
+ // Create an array of strings and sort for stable output
+ for str := range p.consts {
+ if len(p.consts[str]) > 1 {
+ stringKeys = append(stringKeys, str)
}
- issues = append(issues, i)
}
- return issues, nil
+ sort.Strings(stringKeys)
+
+ // report an issue for every duplicated const
+ for _, str := range stringKeys {
+ positions := p.consts[str]
+
+ for i := 1; i < len(positions); i++ {
+ issueBuffer = append(issueBuffer, Issue{
+ Pos: positions[i].Position,
+ Str: str,
+ DuplicateConst: positions[0].Name,
+ DuplicatePos: positions[0].Position,
+ })
+ }
+ }
+
+ p.constMutex.RUnlock()
+
+ // Don't return the buffer to pool as the caller now owns it
+ return issueBuffer, nil
+}
+
+// Run analyzes the provided AST files for duplicated strings or numbers
+// according to the provided configuration.
+// It returns a slice of Issue objects containing the findings.
+func Run(files []*ast.File, fset *token.FileSet, typeInfo *types.Info, cfg *Config) ([]Issue, error) {
+ return RunWithConfig(files, fset, typeInfo, cfg)
}
diff --git a/vendor/github.com/jgautheron/goconst/parser.go b/vendor/github.com/jgautheron/goconst/parser.go
index 2f32740b..9505d463 100644
--- a/vendor/github.com/jgautheron/goconst/parser.go
+++ b/vendor/github.com/jgautheron/goconst/parser.go
@@ -8,180 +8,877 @@ package goconst
import (
"go/ast"
+ "go/constant"
"go/parser"
"go/token"
+ "go/types"
+ "io"
"log"
"os"
"path/filepath"
"regexp"
+ "runtime"
"strconv"
"strings"
+ "sync"
)
+// StringBuilderPool is a pool of string builders to reduce memory allocations
+var StringBuilderPool = sync.Pool{
+ New: func() interface{} {
+ return new(strings.Builder)
+ },
+}
+
+// FileReaderPool is a pool of byte buffers used for reading files
+var FileReaderPool = sync.Pool{
+ New: func() interface{} {
+ // Start with a 32KB buffer, which is sufficient for most Go files
+ return make([]byte, 32*1024)
+ },
+}
+
+// ByteBufferPool is a pool for temporary byte slices
+var ByteBufferPool = sync.Pool{
+ New: func() interface{} {
+ slice := make([]byte, 0, 8*1024)
+ return &slice
+ },
+}
+
+// ExtendedPosPool is a pool for slices of ExtendedPos
+var ExtendedPosPool = sync.Pool{
+ New: func() interface{} {
+ slice := make([]ExtendedPos, 0, 8)
+ return &slice
+ },
+}
+
+// StringInternPool is a pool for deduplicating strings to reduce memory usage
+var StringInternPool = sync.Map{}
+
+// InternString returns a deduplicated reference to the given string
+// to reduce memory usage when the same string appears multiple times
+func InternString(s string) string {
+ if s == "" {
+ return ""
+ }
+
+ if interned, ok := StringInternPool.Load(s); ok {
+ return interned.(string)
+ }
+ // Store a copy to prevent external modifications
+ interned := string([]byte(s))
+ StringInternPool.Store(interned, interned)
+ return interned
+}
+
+// GetStringBuilder retrieves a string builder from the pool
+func GetStringBuilder() *strings.Builder {
+ return StringBuilderPool.Get().(*strings.Builder)
+}
+
+// PutStringBuilder returns a string builder to the pool after resetting it
+func PutStringBuilder(sb *strings.Builder) {
+ sb.Reset()
+ StringBuilderPool.Put(sb)
+}
+
+// GetByteBuffer retrieves a byte buffer from the pool
+func GetByteBuffer() []byte {
+ return (*ByteBufferPool.Get().(*[]byte))[:0] // Reset length but keep capacity
+}
+
+// PutByteBuffer returns a byte buffer to the pool
+func PutByteBuffer(buf []byte) {
+ bufCopy := make([]byte, 0, cap(buf))
+ ByteBufferPool.Put(&bufCopy)
+}
+
+// GetExtendedPosBuffer retrieves an ExtendedPos slice from the pool
+func GetExtendedPosBuffer() []ExtendedPos {
+ return (*ExtendedPosPool.Get().(*[]ExtendedPos))[:0] // Reset length but keep capacity
+}
+
+// PutExtendedPosBuffer returns an ExtendedPos slice to the pool
+func PutExtendedPosBuffer(slice []ExtendedPos) {
+ sliceCopy := make([]ExtendedPos, 0, cap(slice))
+ ExtendedPosPool.Put(&sliceCopy)
+}
+
const (
testSuffix = "_test.go"
)
+// Parser represents the core analysis engine for finding repeated strings and constants.
+// It holds both configuration options and the internal state during analysis.
type Parser struct {
// Meant to be passed via New()
path, ignore, ignoreStrings string
ignoreTests, matchConstant bool
+ findDuplicates bool
minLength, minOccurrences int
numberMin, numberMax int
excludeTypes map[Type]bool
+ maxConcurrency int
+ evalConstExpressions bool // Whether to evaluate constant expressions
supportedTokens []token.Token
+ supportedKinds []constant.Kind
// Internals
- strs Strings
- consts Constants
+ strs Strings
+ consts Constants
+ stringMutex sync.RWMutex
+ constMutex sync.RWMutex
+
+ // Pre-compiled regexes for efficiency
+ ignoreRegex *regexp.Regexp
+ ignoreStringsRegex *regexp.Regexp
+
+ // String occurrence counter
+ // Using a separate counter map improves performance for
+ // tracking frequency without having to compute len(items) repeatedly
+ stringCount map[string]int
+ stringCountMutex sync.RWMutex
+
+ // Batch processing options
+ batchSize int
+ enableBatching bool
+
+ // FileSet cache to avoid creating multiple fileSets
+ fileSetCache *token.FileSet
+ fileSetMutex sync.Mutex
}
// New creates a new instance of the parser.
// This is your entry point if you'd like to use goconst as an API.
-func New(path, ignore, ignoreStrings string, ignoreTests, matchConstant, numbers bool, numberMin, numberMax, minLength, minOccurrences int, excludeTypes map[Type]bool) *Parser {
+//
+// Parameters:
+// - path: the file or directory path to analyze
+// - ignore: regex pattern to ignore files
+// - ignoreStrings: regex pattern to ignore strings
+// - ignoreTests: whether to ignore test files
+// - matchConstant: whether to match strings with existing constants
+// - numbers: whether to analyze number literals
+// - findDuplicates: whether to find consts with duplicate values
+// - evalConstExpressions: whether to evaluate constant expressions
+// - numberMin/numberMax: range limits for number analysis
+// - minLength: minimum string length to consider
+// - minOccurrences: minimum occurrences to report
+// - excludeTypes: map of context types to exclude
+func New(path, ignore, ignoreStrings string, ignoreTests, matchConstant, numbers, findDuplicates, evalConstExpressions bool, numberMin, numberMax, minLength, minOccurrences int, excludeTypes map[Type]bool) *Parser {
supportedTokens := []token.Token{token.STRING}
+ supportedKinds := []constant.Kind{constant.String}
if numbers {
supportedTokens = append(supportedTokens, token.INT, token.FLOAT)
+ supportedKinds = append(supportedKinds, constant.Complex, constant.Float, constant.Int)
+ }
+
+ // Set default concurrency to number of CPUs
+ maxConcurrency := runtime.NumCPU()
+
+ // Pre-compile regular expressions for efficiency
+ var ignoreRegex, ignoreStringsRegex *regexp.Regexp
+ var err error
+
+ if ignore != "" {
+ ignoreRegex, err = regexp.Compile(ignore)
+ if err != nil {
+ log.Printf("Warning: Invalid ignore regex pattern '%s': %v", ignore, err)
+ }
+ }
+
+ if ignoreStrings != "" {
+ ignoreStringsRegex, err = regexp.Compile(ignoreStrings)
+ if err != nil {
+ log.Printf("Warning: Invalid ignore-strings regex pattern '%s': %v", ignoreStrings, err)
+ }
+ }
+
+ // Estimate capacity based on typical usage patterns
+ stringMapCapacity := 500
+ constMapCapacity := 100
+
+ // For large codebases, increase capacity estimates
+ if numbers {
+ stringMapCapacity *= 2 // Numbers typically increase the result set
}
+ // Intern common strings to reduce memory usage
+ path = InternString(path)
+ ignore = InternString(ignore)
+ ignoreStrings = InternString(ignoreStrings)
+
+ // Create a single FileSet to be reused
+ fileSet := token.NewFileSet()
+
return &Parser{
- path: path,
- ignore: ignore,
- ignoreStrings: ignoreStrings,
- ignoreTests: ignoreTests,
- matchConstant: matchConstant,
- minLength: minLength,
- minOccurrences: minOccurrences,
- numberMin: numberMin,
- numberMax: numberMax,
- supportedTokens: supportedTokens,
- excludeTypes: excludeTypes,
+ path: path,
+ ignore: ignore,
+ ignoreStrings: ignoreStrings,
+ ignoreTests: ignoreTests,
+ matchConstant: matchConstant,
+ findDuplicates: findDuplicates,
+ evalConstExpressions: evalConstExpressions,
+ minLength: minLength,
+ minOccurrences: minOccurrences,
+ numberMin: numberMin,
+ numberMax: numberMax,
+ supportedTokens: supportedTokens,
+ supportedKinds: supportedKinds,
+ excludeTypes: excludeTypes,
+ maxConcurrency: maxConcurrency,
+ ignoreRegex: ignoreRegex,
+ ignoreStringsRegex: ignoreStringsRegex,
+
+ // Initialize the maps with capacity hints
+ strs: make(Strings, stringMapCapacity),
+ consts: make(Constants, constMapCapacity),
+ stringCount: make(map[string]int, stringMapCapacity),
+
+ // Default batch processing settings
+ batchSize: 50,
+ enableBatching: true,
+
+ // Cache a single FileSet for reuse
+ fileSetCache: fileSet,
+ }
+}
+
+// SetConcurrency allows setting the maximum number of goroutines to use
+// for parallel file processing. Default is the number of CPUs.
+func (p *Parser) SetConcurrency(max int) {
+ if max > 0 {
+ p.maxConcurrency = max
+ }
+}
- // Initialize the maps
- strs: Strings{},
- consts: Constants{},
+// EnableBatchProcessing activates batch processing mode for very large codebases.
+// This mode collects files in batches before processing them to reduce memory usage.
+// The batchSize parameter controls how many files to process in each batch.
+func (p *Parser) EnableBatchProcessing(batchSize int) {
+ p.enableBatching = true
+ if batchSize > 0 {
+ p.batchSize = batchSize
}
}
// ParseTree will search the given path for occurrences that could be moved into constants.
// If "..." is appended, the search will be recursive.
+//
+// It returns maps of strings and constants found during the analysis, and any error encountered.
+// Use ProcessResults to filter the results based on configuration before retrieving them.
func (p *Parser) ParseTree() (Strings, Constants, error) {
pathLen := len(p.path)
// Parse recursively the given path if the recursive notation is found
if pathLen >= 5 && p.path[pathLen-3:] == "..." {
- filepath.Walk(p.path[:pathLen-3], func(path string, f os.FileInfo, err error) error {
+ return p.parseTreeConcurrent(p.path[:pathLen-3], true)
+ } else {
+ return p.parseTreeConcurrent(p.path, false)
+ }
+}
+
+const (
+ chanSize = 1000
+)
+
+// parseTreeConcurrent implements an optimized concurrent file traversal
+// that efficiently processes directories and files using worker pools.
+func (p *Parser) parseTreeConcurrent(rootPath string, recursive bool) (Strings, Constants, error) {
+
+ // If batch processing is enabled, use that implementation instead
+ if p.enableBatching {
+ return p.parseTreeBatched(rootPath, recursive)
+ }
+
+ // Process files directly if the input is a single file
+ fi, err := os.Stat(rootPath)
+ if err == nil && !fi.IsDir() {
+ fset := p.getFileSet()
+ src, err := p.readFileEfficiently(rootPath)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ f, err := parser.ParseFile(fset, rootPath, src, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ // run type checker
+ info := &types.Info{
+ Types: make(map[ast.Expr]types.TypeAndValue),
+ }
+
+ chkConfig := &types.Config{
+ Error: func(err error) {}, // type checking is only used to evaluate constant expressions, so we ignore most errors
+ }
+ pkg := types.NewPackage("", f.Name.Name)
+ _ = types.NewChecker(chkConfig, fset, pkg, info).Files([]*ast.File{f})
+
+ // Process the file
+ ast.Walk(&treeVisitor{
+ fileSet: fset,
+ packageName: f.Name.Name,
+ p: p,
+ ignoreRegex: p.ignoreStringsRegex,
+ typeInfo: info,
+ }, f)
+
+ // Post-process and filter results
+ p.ProcessResults()
+ return p.strs, p.consts, nil
+ }
+
+ // Create a channel to collect all files to be processed
+ filesChan := make(chan string, chanSize)
+
+ // Start a goroutine to collect all Go files
+ var wg sync.WaitGroup
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ defer close(filesChan)
+
+ // If not recursive, just handle a single directory
+ if !recursive {
+ entries, err := os.ReadDir(rootPath)
+ if err != nil {
+ log.Printf("Error reading directory %s: %v", rootPath, err)
+ return
+ }
+
+ // Process entries
+ for _, entry := range entries {
+ if entry.IsDir() {
+ continue
+ }
+
+ path := filepath.Join(rootPath, entry.Name())
+ if strings.HasSuffix(path, ".go") {
+ // Skip test files if configured
+ if p.ignoreTests && strings.HasSuffix(path, testSuffix) {
+ continue
+ }
+
+ // Skip files matching ignore pattern
+ if p.shouldSkipPath(path) {
+ continue
+ }
+
+ filesChan <- path
+ }
+ }
+ return
+ }
+
+ // Walk the directory tree recursively
+ err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
- log.Println(err)
- // resume walking
+ log.Printf("Error accessing path %s: %v", path, err)
+ return nil // Continue walking
+ }
+
+ // Skip directories based on ignore patterns
+ if info.IsDir() {
+ if p.shouldSkipPath(path) {
+ return filepath.SkipDir
+ }
return nil
}
- if f.IsDir() {
- p.parseDir(path)
+ // Only process Go files
+ if strings.HasSuffix(path, ".go") {
+ // Skip test files if configured
+ if p.ignoreTests && strings.HasSuffix(path, testSuffix) {
+ return nil
+ }
+
+ // Skip files matching ignore pattern
+ if p.shouldSkipPath(path) {
+ return nil
+ }
+
+ // Send the file path to the channel
+ filesChan <- path
}
+
return nil
})
- } else {
- p.parseDir(p.path)
+
+ if err != nil {
+ log.Printf("Error walking directory tree: %v", err)
+ }
+ }()
+
+ // Read and parse files concurrently
+ fset, filesByPackage := p.parseConcurrently(filesChan)
+
+ wg.Wait()
+
+ // Type checking must be performed serially to avoid data races.
+ info := &types.Info{
+ Types: make(map[ast.Expr]types.TypeAndValue),
+ }
+
+ chkConfig := &types.Config{
+ Error: func(err error) {}, // type checking is only used to evaluate constant expressions, so we ignore most errors
}
+ for pkgName, files := range filesByPackage {
+ chk := types.NewChecker(chkConfig, fset, types.NewPackage("", pkgName), info)
+ _ = chk.Files(files)
+ }
+
+ // Visit all files
+ p.visitConcurrently(fset, info, filesByPackage)
+
+ // Post-process and filter results
p.ProcessResults()
return p.strs, p.consts, nil
}
-// ProcessResults post-processes the raw results.
-func (p *Parser) ProcessResults() {
- for str, item := range p.strs {
- // Filter out items whose occurrences don't match the min value
- if len(item) < p.minOccurrences {
- delete(p.strs, str)
- }
+func (p *Parser) parseConcurrently(filesChan <-chan string) (*token.FileSet, map[string][]*ast.File) {
+ // Start file parser workers
+ var parserWg sync.WaitGroup
- if p.ignoreStrings != "" {
- match, err := regexp.MatchString(p.ignoreStrings, str)
- if err != nil {
- log.Println(err)
- }
- if match {
- delete(p.strs, str)
+ fset := p.getFileSet()
+
+ parsedFilesChan := make(chan parsedFile, chanSize)
+
+ // Add all workers to the WaitGroup before starting any goroutines
+ // This prevents a race condition with the goroutine that waits
+ parserWg.Add(p.maxConcurrency)
+
+ // Start a separate goroutine to close the channel after all parsers are done
+ go func() {
+ parserWg.Wait()
+ close(parsedFilesChan)
+ }()
+
+ for i := 0; i < p.maxConcurrency; i++ {
+ go func() {
+ defer parserWg.Done()
+
+ for filePath := range filesChan {
+ // Parse a single file
+ src, err := p.readFileEfficiently(filePath)
+ if err != nil {
+ log.Printf("Error reading file %s: %v", filePath, err)
+ continue
+ }
+
+ f, err := parser.ParseFile(fset, filePath, src, 0)
+ if err != nil {
+ log.Printf("Error parsing file %s: %v", filePath, err)
+ continue
+ }
+
+ // Process the file
+ pkgName := f.Name.Name
+ parsedFilesChan <- parsedFile{pkgName, f}
}
+ }()
+ }
+
+ // Read all parsed files into packgageFiles map. All packages must be parsed prior to type-checking.
+ fileCount := 0
+ packageFiles := map[string][]*ast.File{}
+
+ var readerWg sync.WaitGroup
+ readerWg.Add(1)
+ go func() {
+ defer readerWg.Done()
+ for parsed := range parsedFilesChan {
+ packageFiles[parsed.pkgName] = append(packageFiles[parsed.pkgName], parsed.f)
+ fileCount++ // safe since this is single-threaded.
}
+ }()
- // If the value is a number
- if i, err := strconv.ParseInt(str, 0, 0); err == nil {
- if p.numberMin != 0 && i < int64(p.numberMin) {
- delete(p.strs, str)
- }
- if p.numberMax != 0 && i > int64(p.numberMax) {
- delete(p.strs, str)
+ // Wait for all file parsing to complete
+ parserWg.Wait()
+ // Wait for collection to complete
+ readerWg.Wait()
+
+ return fset, packageFiles
+}
+
+// visitConcurrently visits all files in filesByPackage on a worker pool goroutines.
+func (p *Parser) visitConcurrently(fset *token.FileSet, info *types.Info, filesByPackage map[string][]*ast.File) {
+ var visitorWg sync.WaitGroup
+
+ parsedFilesChan := make(chan parsedFile, chanSize)
+
+ // Add all workers to the WaitGroup before starting any goroutines
+ visitorWg.Add(p.maxConcurrency)
+
+ for i := 0; i < p.maxConcurrency; i++ {
+ go func() {
+ defer visitorWg.Done()
+ for pf := range parsedFilesChan {
+ ast.Walk(&treeVisitor{
+ fileSet: fset,
+ typeInfo: info,
+ packageName: pf.pkgName,
+ p: p,
+ ignoreRegex: p.ignoreStringsRegex,
+ }, pf.f)
}
+ }()
+ }
+
+ for pkgName, files := range filesByPackage {
+ for _, f := range files {
+ parsedFilesChan <- parsedFile{pkgName, f}
}
}
+ close(parsedFilesChan)
+
+ visitorWg.Wait()
}
-func (p *Parser) parseDir(dir string) error {
- fset := token.NewFileSet()
- pkgs, err := parser.ParseDir(fset, dir, func(info os.FileInfo) bool {
- valid, name := true, info.Name()
+// parseTreeBatched implements batch processing for very large codebases.
+// Instead of processing files immediately as they are found, it collects them
+// in batches and processes each batch completely before moving to the next.
+// This helps manage memory usage for extremely large codebases.
+func (p *Parser) parseTreeBatched(rootPath string, recursive bool) (Strings, Constants, error) {
+ var (
+ allFiles []string
+ allFilesByDir = make(map[string][]string)
+ )
+
+ // First, collect all file paths that need to be processed
+ if recursive {
+ // If recursive, walk the entire directory tree
+ err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ log.Printf("Error accessing path %s: %v", path, err)
+ return nil // Continue walking
+ }
+
+ // Only process Go files
+ if !info.IsDir() && strings.HasSuffix(path, ".go") {
+ // Skip test files if configured to do so
+ if p.ignoreTests && strings.HasSuffix(path, testSuffix) {
+ return nil
+ }
+
+ // Skip files matching ignore pattern
+ if p.shouldSkipPath(path) {
+ return nil
+ }
- if p.ignoreTests {
- if strings.HasSuffix(name, testSuffix) {
- valid = false
+ allFiles = append(allFiles, path)
+ dir := filepath.Dir(path)
+ allFilesByDir[dir] = append(allFilesByDir[dir], path)
}
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, nil, err
+ }
+ } else {
+ // If not recursive, just read the files in the specified directory
+ entries, err := os.ReadDir(rootPath)
+ if err != nil {
+ return nil, nil, err
}
- if len(p.ignore) != 0 {
- match, err := regexp.MatchString(p.ignore, dir+name)
- if err != nil {
- log.Fatal(err)
- return true
+ for _, entry := range entries {
+ if entry.IsDir() {
+ continue
}
- if match {
- valid = false
+
+ path := filepath.Join(rootPath, entry.Name())
+
+ // Only process Go files
+ if strings.HasSuffix(path, ".go") {
+ // Skip test files if configured to do so
+ if p.ignoreTests && strings.HasSuffix(path, testSuffix) {
+ continue
+ }
+
+ // Skip files matching ignore pattern
+ if p.shouldSkipPath(path) {
+ continue
+ }
+
+ allFiles = append(allFiles, path)
+ allFilesByDir[rootPath] = append(allFilesByDir[rootPath], path)
}
}
+ }
+
+ // Split into batches, ensuring each package's files are all in the same batch, since the typechecker requires
+ // entire packages. Some batches may exceed the requested batchSize.
+ totalFiles := 0
+ largeBatches := 0
+ maxBatchSize := 0
+
+ var batches [][]string
+ var currBatch []string
+ for _, pkgFiles := range allFilesByDir {
+ size := len(currBatch)
+ if size >= p.batchSize {
+ batches = append(batches, currBatch)
+ currBatch = nil
+ }
+ currBatch = append(currBatch, pkgFiles...)
+
+ // compute some stats
+ if size >= p.batchSize {
+ largeBatches++
+ }
+ if size >= maxBatchSize {
+ maxBatchSize = size
+ }
+ totalFiles += len(pkgFiles)
+ }
+ if len(currBatch) > 0 {
+ batches = append(batches, currBatch)
+ }
+
+ // Process batches
+ log.Printf("Found %d Go files to process in batches of %d", totalFiles, p.batchSize)
+ if largeBatches > 0 {
+ log.Printf("Warning: %d batches exceed the configured batch size. Largest batch contains %d files", largeBatches, maxBatchSize)
+ }
+
+ for i, batch := range batches {
+ log.Printf("Processing batch %d/%d (%d files)", i+1, len(batches), len(batch))
+
+ // Process this batch concurrently
- return valid
- }, 0)
+ // Queue all files in this batch
+ fileChan := make(chan string, len(batch))
+ for _, filePath := range batch {
+ fileChan <- filePath
+ }
+ close(fileChan) // safe to close since len(fileChan) == len(batch)
+
+ // Parse files concurrently
+ fset, filesByPackage := p.parseConcurrently(fileChan)
+
+ // Type check -- must be processed serially to avoid data races
+ info := &types.Info{
+ Types: make(map[ast.Expr]types.TypeAndValue),
+ }
+
+ chkConfig := &types.Config{
+ Error: func(err error) {}, // type checking is only used to evaluate constant expressions, so we ignore most errors
+ }
+ for pkgName, files := range filesByPackage {
+ chk := types.NewChecker(chkConfig, fset, types.NewPackage("", pkgName), info)
+ _ = chk.Files(files)
+ }
+
+ // Visit all files concurrently
+ p.visitConcurrently(fset, info, filesByPackage)
+
+ // Optional: Run garbage collection between batches for very large codebases
+ if totalFiles > 10000 && len(batch) >= 1000 {
+ runtime.GC()
+ }
+ }
+
+ // Post-process and filter results
+ p.ProcessResults()
+
+ return p.strs, p.consts, nil
+}
+
+// readFileEfficiently reads a file in the most efficient way.
+// Benchmarks showed that for our specific use case, the standard
+// library's ReadFile is already well-optimized.
+func (p *Parser) readFileEfficiently(path string) ([]byte, error) {
+ // Optimized file reading to reduce allocations
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ if closeErr := f.Close(); closeErr != nil {
+ log.Printf("Error closing file: %v", closeErr)
+ }
+ }()
+
+ // Get file size to allocate buffer exactly once
+ info, err := f.Stat()
if err != nil {
- return err
+ return nil, err
}
- for _, pkg := range pkgs {
- for fn, f := range pkg.Files {
- ast.Walk(&treeVisitor{
- fileSet: fset,
- packageName: pkg.Name,
- fileName: fn,
- p: p,
- }, f)
+ // For very small files, use ReadAll
+ if info.Size() < 8192 {
+ return io.ReadAll(f)
+ }
+
+ // For larger files, allocate exact buffer size to avoid resize allocations
+ size := info.Size()
+ buf := make([]byte, size)
+
+ // Read in a single operation
+ n, err := io.ReadFull(f, buf)
+ if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
+ return nil, err
+ }
+
+ return buf[:n], nil
+}
+
+// getFileSet returns a cached FileSet for reuse
+func (p *Parser) getFileSet() *token.FileSet {
+ p.fileSetMutex.Lock()
+ defer p.fileSetMutex.Unlock()
+
+ // Return existing cache if available
+ if p.fileSetCache != nil {
+ return p.fileSetCache
+ }
+
+ // Create a new one if needed
+ p.fileSetCache = token.NewFileSet()
+ return p.fileSetCache
+}
+
+// shouldSkipPath determines if a path should be skipped based on ignore patterns
+func (p *Parser) shouldSkipPath(path string) bool {
+ if p.ignoreRegex != nil {
+ if p.ignoreRegex.MatchString(path) {
+ return true
+ }
+ } else if len(p.ignore) != 0 {
+ // Fallback to non-compiled regex if compilation failed
+ match, err := regexp.MatchString(p.ignore, path)
+ if err != nil {
+ log.Printf("Error matching ignore pattern on %s: %v", path, err)
+ return false
+ }
+ if match {
+ return true
}
}
+ return false
+}
+
+// IncrementStringCount safely increments the count for a string and returns the new count
+func (p *Parser) IncrementStringCount(str string) int {
+ p.stringCountMutex.Lock()
+ defer p.stringCountMutex.Unlock()
- return nil
+ p.stringCount[str]++
+ return p.stringCount[str]
}
+// GetStringCount safely gets the count for a string
+func (p *Parser) GetStringCount(str string) int {
+ p.stringCountMutex.RLock()
+ defer p.stringCountMutex.RUnlock()
+
+ return p.stringCount[str]
+}
+
+// ProcessResults post-processes the raw results.
+// It filters the discovered strings based on the parser's configuration:
+// - Removes strings that don't meet the minimum occurrences threshold
+// - Filters out strings matching the ignore pattern
+// - Applies number range filtering if min/max values are set
+func (p *Parser) ProcessResults() {
+ p.stringMutex.Lock()
+ defer p.stringMutex.Unlock()
+
+ // Also acquire stringCount lock to ensure consistency during processing
+ p.stringCountMutex.Lock()
+ defer p.stringCountMutex.Unlock()
+
+ for str := range p.strs {
+ // Check count first as it's faster than looking at slice length
+ count := p.stringCount[str]
+ if count < p.minOccurrences {
+ delete(p.strs, str)
+ delete(p.stringCount, str)
+ continue
+ }
+
+ // Apply ignoreStrings filter
+ if p.ignoreStrings != "" {
+ if p.ignoreStringsRegex != nil {
+ // Use pre-compiled regex if available
+ if p.ignoreStringsRegex.MatchString(str) {
+ delete(p.strs, str)
+ delete(p.stringCount, str)
+ continue
+ }
+ } else {
+ // Fallback to the non-compiled version
+ match, err := regexp.MatchString(p.ignoreStrings, str)
+ if err != nil {
+ log.Println(err)
+ }
+ if match {
+ delete(p.strs, str)
+ delete(p.stringCount, str)
+ continue
+ }
+ }
+ }
+
+ // Apply number range filtering if applicable
+ if i, err := strconv.ParseInt(str, 0, 0); err == nil {
+ if (p.numberMin != 0 && i < int64(p.numberMin)) ||
+ (p.numberMax != 0 && i > int64(p.numberMax)) {
+ delete(p.strs, str)
+ delete(p.stringCount, str)
+ }
+ }
+ }
+}
+
+type parsedFile struct {
+ pkgName string
+ f *ast.File
+}
+
+// Strings maps string literals to their positions in the code.
type Strings map[string][]ExtendedPos
-type Constants map[string]ConstType
+// Constants maps string values to their constant definitions.
+type Constants map[string][]ConstType
+
+// ConstType holds information about a constant declaration.
type ConstType struct {
+ // Using embedded Position to save memory vs. a separate field
token.Position
- Name, packageName string
+ // Interned strings to reduce memory usage
+ Name string
+ packageName string
}
+// ExtendedPos extends token.Position with package information.
+// This structure is optimized for memory usage in large codebases.
type ExtendedPos struct {
+ // Using embedded Position to save memory vs. a separate field
token.Position
+ // Interned package name to reduce memory usage when many positions
+ // reference the same package
packageName string
}
+// Type represents the context in which a string literal appears.
type Type int
const (
+ // Assignment represents a string in an assignment context (e.g., x := "foo")
Assignment Type = iota
+ // Binary represents a string in a binary expression (e.g., x == "foo")
Binary
+ // Case represents a string in a case clause (e.g., case "foo":)
Case
+ // Return represents a string in a return statement (e.g., return "foo")
Return
+ // Call represents a string passed as an argument to a function call (e.g., f("foo"))
Call
)
diff --git a/vendor/github.com/jgautheron/goconst/visitor.go b/vendor/github.com/jgautheron/goconst/visitor.go
index c0974da8..339723f5 100644
--- a/vendor/github.com/jgautheron/goconst/visitor.go
+++ b/vendor/github.com/jgautheron/goconst/visitor.go
@@ -2,18 +2,21 @@ package goconst
import (
"go/ast"
+ "go/constant"
"go/token"
+ "go/types"
+ "regexp"
"strconv"
"strings"
)
-// treeVisitor carries the package name and file name
-// for passing it to the imports map, and the fileSet for
-// retrieving the token.Position.
+// treeVisitor is used to walk the AST and find strings that could be constants.
type treeVisitor struct {
- p *Parser
- fileSet *token.FileSet
- packageName, fileName string
+ fileSet *token.FileSet
+ typeInfo *types.Info
+ packageName string
+ p *Parser
+ ignoreRegex *regexp.Regexp
}
// Visit browses the AST tree for strings that could be potentially
@@ -30,7 +33,7 @@ func (v *treeVisitor) Visit(node ast.Node) ast.Visitor {
switch t := node.(type) {
// Scan for constants in an attempt to match strings with existing constants
case *ast.GenDecl:
- if !v.p.matchConstant {
+ if !v.p.matchConstant && !v.p.findDuplicates {
return v
}
if t.Tok != token.CONST {
@@ -40,12 +43,20 @@ func (v *treeVisitor) Visit(node ast.Node) ast.Visitor {
for _, spec := range t.Specs {
val := spec.(*ast.ValueSpec)
for i, str := range val.Values {
- lit, ok := str.(*ast.BasicLit)
- if !ok || !v.isSupported(lit.Kind) {
- continue
- }
+ if v.typeInfo != nil && v.p.evalConstExpressions {
+ typedVal, ok := v.typeInfo.Types[str]
+ if !ok || !v.isSupportedKind(typedVal.Value.Kind()) {
+ continue
+ }
- v.addConst(val.Names[i].Name, lit.Value, val.Names[i].Pos())
+ v.addConst(val.Names[i].Name, typedVal.Value.String(), str.Pos())
+ } else {
+ lit, ok := str.(*ast.BasicLit)
+ if !ok || !v.isSupported(lit.Kind) {
+ continue
+ }
+ v.addConst(val.Names[i].Name, lit.Value, val.Names[i].Pos())
+ }
}
}
@@ -112,41 +123,131 @@ func (v *treeVisitor) Visit(node ast.Node) ast.Visitor {
// addString adds a string in the map along with its position in the tree.
func (v *treeVisitor) addString(str string, pos token.Pos, typ Type) {
+ // Early type exclusion check
ok, excluded := v.p.excludeTypes[typ]
if ok && excluded {
return
}
+
// Drop quotes if any
+ var unquotedStr string
if strings.HasPrefix(str, `"`) || strings.HasPrefix(str, "`") {
- str, _ = strconv.Unquote(str)
+ var err error
+ // Reuse strings from pool if possible to avoid allocations
+ sb := GetStringBuilder()
+ defer PutStringBuilder(sb)
+
+ unquotedStr, err = strconv.Unquote(str)
+ if err != nil {
+ // If unquoting fails, manually strip quotes
+ // This avoids additional temporary strings
+ if len(str) >= 2 {
+ sb.WriteString(str[1 : len(str)-1])
+ unquotedStr = sb.String()
+ } else {
+ unquotedStr = str
+ }
+ }
+ } else {
+ unquotedStr = str
}
- // Ignore empty strings
- if len(str) == 0 {
+ // Early length check
+ if len(unquotedStr) == 0 || len(unquotedStr) < v.p.minLength {
return
}
- if len(str) < v.p.minLength {
+ // Early regex filtering - pre-compiled for efficiency
+ if v.ignoreRegex != nil && v.ignoreRegex.MatchString(unquotedStr) {
return
}
- _, ok = v.p.strs[str]
- if !ok {
- v.p.strs[str] = make([]ExtendedPos, 0)
+ // Early number range filtering
+ if v.p.numberMin != 0 || v.p.numberMax != 0 {
+ if i, err := strconv.ParseInt(unquotedStr, 0, 0); err == nil {
+ if (v.p.numberMin != 0 && i < int64(v.p.numberMin)) ||
+ (v.p.numberMax != 0 && i > int64(v.p.numberMax)) {
+ return
+ }
+ }
+ }
+
+ // Use interned string to reduce memory usage - identical strings share the same memory
+ internedStr := InternString(unquotedStr)
+
+ // Update the count first, this is faster than appending to slices
+ count := v.p.IncrementStringCount(internedStr)
+
+ // Only continue if we're still adding the position to the map
+ // or if count has reached threshold
+ if count == 1 || count == v.p.minOccurrences {
+ // Lock to safely update the shared map
+ v.p.stringMutex.Lock()
+ defer v.p.stringMutex.Unlock()
+
+ _, exists := v.p.strs[internedStr]
+ if !exists {
+ v.p.strs[internedStr] = make([]ExtendedPos, 0, v.p.minOccurrences) // Preallocate with expected size
+ }
+
+ // Create an optimized position record
+ newPos := ExtendedPos{
+ packageName: InternString(v.packageName), // Intern the package name to reduce memory
+ Position: v.fileSet.Position(pos),
+ }
+
+ v.p.strs[internedStr] = append(v.p.strs[internedStr], newPos)
}
- v.p.strs[str] = append(v.p.strs[str], ExtendedPos{
- packageName: v.packageName,
- Position: v.fileSet.Position(pos),
- })
}
// addConst adds a const in the map along with its position in the tree.
func (v *treeVisitor) addConst(name string, val string, pos token.Pos) {
- val = strings.Replace(val, `"`, "", 2)
- v.p.consts[val] = ConstType{
- Name: name,
- packageName: v.packageName,
- Position: v.fileSet.Position(pos),
+ // Early filtering using the same criteria as for strings
+ var unquotedVal string
+ if strings.HasPrefix(val, `"`) || strings.HasPrefix(val, "`") {
+ var err error
+ // Use string builder from pool to reduce allocations
+ sb := GetStringBuilder()
+ defer PutStringBuilder(sb)
+
+ if unquotedVal, err = strconv.Unquote(val); err != nil {
+ // If unquoting fails, manually strip quotes without allocations
+ if len(val) >= 2 {
+ sb.WriteString(val[1 : len(val)-1])
+ unquotedVal = sb.String()
+ } else {
+ unquotedVal = val
+ }
+ }
+ } else {
+ unquotedVal = val
+ }
+
+ // Skip constants with values that would be filtered anyway
+ if len(unquotedVal) < v.p.minLength {
+ return
+ }
+
+ if v.ignoreRegex != nil && v.ignoreRegex.MatchString(unquotedVal) {
+ return
+ }
+
+ // Use interned string to reduce memory usage
+ internedVal := InternString(unquotedVal)
+ internedName := InternString(name)
+ internedPkg := InternString(v.packageName)
+
+ // Lock to safely update the shared map
+ v.p.constMutex.Lock()
+ defer v.p.constMutex.Unlock()
+
+ // track this const if this is a new const, or if we are searching for duplicate consts
+ if _, ok := v.p.consts[internedVal]; !ok || v.p.findDuplicates {
+ v.p.consts[internedVal] = append(v.p.consts[internedVal], ConstType{
+ Name: internedName,
+ packageName: internedPkg,
+ Position: v.fileSet.Position(pos),
+ })
}
}
@@ -158,3 +259,12 @@ func (v *treeVisitor) isSupported(tk token.Token) bool {
}
return false
}
+
+func (v *treeVisitor) isSupportedKind(kind constant.Kind) bool {
+ for _, s := range v.p.supportedKinds {
+ if kind == s {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/kunwardeep/paralleltest/pkg/paralleltest/paralleltest.go b/vendor/github.com/kunwardeep/paralleltest/pkg/paralleltest/paralleltest.go
index e9187d6f..aebbe70e 100644
--- a/vendor/github.com/kunwardeep/paralleltest/pkg/paralleltest/paralleltest.go
+++ b/vendor/github.com/kunwardeep/paralleltest/pkg/paralleltest/paralleltest.go
@@ -12,7 +12,7 @@ import (
const Doc = `check that tests use t.Parallel() method
It also checks that the t.Parallel is used if multiple tests cases are run as part of single test.
-As part of ensuring parallel tests works as expected it checks for reinitialising of the range value
+As part of ensuring parallel tests works as expected it checks for reinitializing of the range value
over the test cases.(https://tinyurl.com/y6555cy6)`
func NewAnalyzer() *analysis.Analyzer {
@@ -46,138 +46,187 @@ func newParallelAnalyzer() *parallelAnalyzer {
return a
}
-func (a *parallelAnalyzer) run(pass *analysis.Pass) (interface{}, error) {
- inspector := inspector.New(pass.Files)
+type testFunctionAnalysis struct {
+ funcHasParallelMethod,
+ funcCantParallelMethod,
+ rangeStatementOverTestCasesExists,
+ rangeStatementHasParallelMethod,
+ rangeStatementCantParallelMethod bool
+ loopVariableUsedInRun *string
+ numberOfTestRun int
+ positionOfTestRunNode []ast.Node
+ rangeNode ast.Node
+}
- nodeFilter := []ast.Node{
- (*ast.FuncDecl)(nil),
- }
+type testRunAnalysis struct {
+ hasParallel bool
+ cantParallel bool
+ numberOfTestRun int
+ positionOfTestRunNode []ast.Node
+}
- inspector.Preorder(nodeFilter, func(node ast.Node) {
- funcDecl := node.(*ast.FuncDecl)
- var funcHasParallelMethod,
- funcCantParallelMethod,
- rangeStatementOverTestCasesExists,
- rangeStatementHasParallelMethod,
- rangeStatementCantParallelMethod bool
- var loopVariableUsedInRun *string
- var numberOfTestRun int
- var positionOfTestRunNode []ast.Node
- var rangeNode ast.Node
-
- // Check runs for test functions only
- isTest, testVar := isTestFunction(funcDecl)
- if !isTest {
- return
- }
+func (a *parallelAnalyzer) analyzeTestRun(pass *analysis.Pass, n ast.Node, testVar string) testRunAnalysis {
+ var analysis testRunAnalysis
- for _, l := range funcDecl.Body.List {
- switch v := l.(type) {
+ if methodRunIsCalledInTestFunction(n, testVar) {
+ innerTestVar := getRunCallbackParameterName(n)
+ analysis.numberOfTestRun++
- case *ast.ExprStmt:
- ast.Inspect(v, func(n ast.Node) bool {
- // Check if the test method is calling t.Parallel
- if !funcHasParallelMethod {
- funcHasParallelMethod = methodParallelIsCalledInTestFunction(n, testVar)
+ if callExpr, ok := n.(*ast.CallExpr); ok && len(callExpr.Args) > 1 {
+ if funcLit, ok := callExpr.Args[1].(*ast.FuncLit); ok {
+ ast.Inspect(funcLit, func(p ast.Node) bool {
+ if !analysis.hasParallel {
+ analysis.hasParallel = methodParallelIsCalledInTestFunction(p, innerTestVar)
}
-
- // Check if the test calls t.Setenv, cannot be used in parallel tests or tests with parallel ancestors
- if !funcCantParallelMethod {
- funcCantParallelMethod = methodSetenvIsCalledInTestFunction(n, testVar)
+ if !analysis.cantParallel {
+ analysis.cantParallel = methodSetenvIsCalledInTestFunction(p, innerTestVar)
}
-
- // Check if the t.Run within the test function is calling t.Parallel
- if methodRunIsCalledInTestFunction(n, testVar) {
- // n is a call to t.Run; find out the name of the subtest's *testing.T parameter.
- innerTestVar := getRunCallbackParameterName(n)
-
- hasParallel := false
- cantParallel := false
- numberOfTestRun++
- ast.Inspect(v, func(p ast.Node) bool {
- if !hasParallel {
- hasParallel = methodParallelIsCalledInTestFunction(p, innerTestVar)
- }
- if !cantParallel {
- cantParallel = methodSetenvIsCalledInTestFunction(p, innerTestVar)
+ return true
+ })
+ } else if ident, ok := callExpr.Args[1].(*ast.Ident); ok {
+ foundFunc := false
+ for _, file := range pass.Files {
+ for _, decl := range file.Decls {
+ if funcDecl, ok := decl.(*ast.FuncDecl); ok && funcDecl.Name.Name == ident.Name {
+ foundFunc = true
+ isReceivingTestContext, testParamName := isFunctionReceivingTestContext(funcDecl)
+ if isReceivingTestContext {
+ ast.Inspect(funcDecl, func(p ast.Node) bool {
+ if !analysis.hasParallel {
+ analysis.hasParallel = methodParallelIsCalledInTestFunction(p, testParamName)
+ }
+ return true
+ })
}
- return true
- })
- if !hasParallel && !cantParallel {
- positionOfTestRunNode = append(positionOfTestRunNode, n)
}
}
- return true
- })
+ }
+ if !foundFunc {
+ analysis.hasParallel = false
+ }
+ }
+ }
- // Check if the range over testcases is calling t.Parallel
- case *ast.RangeStmt:
- rangeNode = v
+ if !analysis.hasParallel && !analysis.cantParallel {
+ analysis.positionOfTestRunNode = append(analysis.positionOfTestRunNode, n)
+ }
+ }
- var loopVars []types.Object
- for _, expr := range []ast.Expr{v.Key, v.Value} {
- if id, ok := expr.(*ast.Ident); ok {
- loopVars = append(loopVars, pass.TypesInfo.ObjectOf(id))
- }
- }
+ return analysis
+}
- ast.Inspect(v, func(n ast.Node) bool {
- // nolint: gocritic
- switch r := n.(type) {
- case *ast.ExprStmt:
- if methodRunIsCalledInRangeStatement(r.X, testVar) {
- // r.X is a call to t.Run; find out the name of the subtest's *testing.T parameter.
- innerTestVar := getRunCallbackParameterName(r.X)
+func (a *parallelAnalyzer) analyzeTestFunction(pass *analysis.Pass, funcDecl *ast.FuncDecl) {
+ var analysis testFunctionAnalysis
- rangeStatementOverTestCasesExists = true
+ // Check runs for test functions only
+ isTest, testVar := isTestFunction(funcDecl)
+ if !isTest {
+ return
+ }
- if !rangeStatementHasParallelMethod {
- rangeStatementHasParallelMethod = methodParallelIsCalledInMethodRun(r.X, innerTestVar)
- }
+ for _, l := range funcDecl.Body.List {
+ switch v := l.(type) {
+ case *ast.ExprStmt:
+ ast.Inspect(v, func(n ast.Node) bool {
+ if !analysis.funcHasParallelMethod {
+ analysis.funcHasParallelMethod = methodParallelIsCalledInTestFunction(n, testVar)
+ }
+ if !analysis.funcCantParallelMethod {
+ analysis.funcCantParallelMethod = methodSetenvIsCalledInTestFunction(n, testVar)
+ }
+ runAnalysis := a.analyzeTestRun(pass, n, testVar)
+ analysis.numberOfTestRun += runAnalysis.numberOfTestRun
+ analysis.positionOfTestRunNode = append(analysis.positionOfTestRunNode, runAnalysis.positionOfTestRunNode...)
+ return true
+ })
+
+ case *ast.RangeStmt:
+ analysis.rangeNode = v
+
+ var loopVars []types.Object
+ for _, expr := range []ast.Expr{v.Key, v.Value} {
+ if id, ok := expr.(*ast.Ident); ok {
+ loopVars = append(loopVars, pass.TypesInfo.ObjectOf(id))
+ }
+ }
+
+ ast.Inspect(v, func(n ast.Node) bool {
+ if r, ok := n.(*ast.ExprStmt); ok {
+ if methodRunIsCalledInRangeStatement(r.X, testVar) {
+ innerTestVar := getRunCallbackParameterName(r.X)
+ analysis.rangeStatementOverTestCasesExists = true
- if !rangeStatementCantParallelMethod {
- rangeStatementCantParallelMethod = methodSetenvIsCalledInMethodRun(r.X, innerTestVar)
+ if !analysis.rangeStatementHasParallelMethod {
+ analysis.rangeStatementHasParallelMethod = methodParallelIsCalledInMethodRun(r.X, innerTestVar)
+ }
+ if !analysis.rangeStatementCantParallelMethod {
+ analysis.rangeStatementCantParallelMethod = methodSetenvIsCalledInMethodRun(r.X, innerTestVar)
+ }
+ if !a.ignoreLoopVar && analysis.loopVariableUsedInRun == nil {
+ if run, ok := r.X.(*ast.CallExpr); ok {
+ analysis.loopVariableUsedInRun = loopVarReferencedInRun(run, loopVars, pass.TypesInfo)
}
+ }
- if !a.ignoreLoopVar && loopVariableUsedInRun == nil {
- if run, ok := r.X.(*ast.CallExpr); ok {
- loopVariableUsedInRun = loopVarReferencedInRun(run, loopVars, pass.TypesInfo)
- }
+ // Check nested test runs
+ if callExpr, ok := r.X.(*ast.CallExpr); ok && len(callExpr.Args) > 1 {
+ if funcLit, ok := callExpr.Args[1].(*ast.FuncLit); ok {
+ ast.Inspect(funcLit, func(p ast.Node) bool {
+ runAnalysis := a.analyzeTestRun(pass, p, innerTestVar)
+ analysis.numberOfTestRun += runAnalysis.numberOfTestRun
+ analysis.positionOfTestRunNode = append(analysis.positionOfTestRunNode, runAnalysis.positionOfTestRunNode...)
+ return true
+ })
}
}
}
- return true
- })
- }
+ }
+ return true
+ })
}
+ }
- // Descendents which call Setenv, also prevent tests from calling Parallel
- if rangeStatementCantParallelMethod {
- funcCantParallelMethod = true
- }
+ if analysis.rangeStatementCantParallelMethod {
+ analysis.funcCantParallelMethod = true
+ }
- if !a.ignoreMissing && !funcHasParallelMethod && !funcCantParallelMethod {
- pass.Reportf(node.Pos(), "Function %s missing the call to method parallel\n", funcDecl.Name.Name)
- }
+ if !a.ignoreMissing && !analysis.funcHasParallelMethod && !analysis.funcCantParallelMethod {
+ pass.Reportf(funcDecl.Pos(), "Function %s missing the call to method parallel\n", funcDecl.Name.Name)
+ }
- if rangeStatementOverTestCasesExists && rangeNode != nil {
- if !rangeStatementHasParallelMethod && !rangeStatementCantParallelMethod {
- if !a.ignoreMissing && !a.ignoreMissingSubtests {
- pass.Reportf(rangeNode.Pos(), "Range statement for test %s missing the call to method parallel in test Run\n", funcDecl.Name.Name)
- }
- } else if loopVariableUsedInRun != nil {
- pass.Reportf(rangeNode.Pos(), "Range statement for test %s does not reinitialise the variable %s\n", funcDecl.Name.Name, *loopVariableUsedInRun)
+ if analysis.rangeStatementOverTestCasesExists && analysis.rangeNode != nil {
+ if !analysis.rangeStatementHasParallelMethod && !analysis.rangeStatementCantParallelMethod {
+ if !a.ignoreMissing && !a.ignoreMissingSubtests {
+ pass.Reportf(analysis.rangeNode.Pos(), "Range statement for test %s missing the call to method parallel in test Run\n", funcDecl.Name.Name)
}
+ } else if analysis.loopVariableUsedInRun != nil && !a.ignoreLoopVar {
+ pass.Reportf(analysis.rangeNode.Pos(), "Range statement for test %s does not reinitialise the variable %s\n", funcDecl.Name.Name, *analysis.loopVariableUsedInRun)
}
+ }
- // Check if the t.Run is more than one as there is no point making one test parallel
- if !a.ignoreMissing && !a.ignoreMissingSubtests {
- if numberOfTestRun > 1 && len(positionOfTestRunNode) > 0 {
- for _, n := range positionOfTestRunNode {
- pass.Reportf(n.Pos(), "Function %s missing the call to method parallel in the test run\n", funcDecl.Name.Name)
- }
+ if !a.ignoreMissing && !a.ignoreMissingSubtests {
+ if analysis.numberOfTestRun > 1 && len(analysis.positionOfTestRunNode) > 0 {
+ for _, n := range analysis.positionOfTestRunNode {
+ pass.Reportf(n.Pos(), "Function %s missing the call to method parallel in the test run\n", funcDecl.Name.Name)
}
}
+ }
+}
+
+func (a *parallelAnalyzer) run(pass *analysis.Pass) (interface{}, error) {
+ inspector := inspector.New(pass.Files)
+
+ nodeFilter := []ast.Node{
+ (*ast.FuncDecl)(nil),
+ }
+
+ inspector.Preorder(nodeFilter, func(node ast.Node) {
+ funcDecl := node.(*ast.FuncDecl)
+ // Only process _test.go files
+ if !strings.HasSuffix(pass.Fset.File(funcDecl.Pos()).Name(), "_test.go") {
+ return
+ }
+ a.analyzeTestFunction(pass, funcDecl)
})
return nil, nil
@@ -267,8 +316,38 @@ func getRunCallbackParameterName(node ast.Node) string {
return ""
}
-// Checks if the function has the param type *testing.T; if it does, then the
-// parameter name is returned, too.
+// isFunctionReceivingTestContext checks if a function declaration receives a *testing.T parameter
+// Returns (true, paramName) if it does, (false, "") if it doesn't
+func isFunctionReceivingTestContext(funcDecl *ast.FuncDecl) (bool, string) {
+ testMethodPackageType := "testing"
+ testMethodStruct := "T"
+
+ if funcDecl.Type.Params != nil && len(funcDecl.Type.Params.List) != 1 {
+ return false, ""
+ }
+
+ param := funcDecl.Type.Params.List[0]
+ if starExp, ok := param.Type.(*ast.StarExpr); ok {
+ if selectExpr, ok := starExp.X.(*ast.SelectorExpr); ok {
+ if selectExpr.Sel.Name == testMethodStruct {
+ if s, ok := selectExpr.X.(*ast.Ident); ok {
+ if len(param.Names) > 0 {
+ return s.Name == testMethodPackageType, param.Names[0].Name
+ }
+ }
+ }
+ }
+ }
+
+ return false, ""
+}
+
+// isTestFunction checks if a function declaration is a test function
+// A test function must:
+// 1. Start with "Test"
+// 2. Have exactly one parameter
+// 3. Have that parameter be of type *testing.T
+// Returns (true, paramName) if it is a test function, (false, "") if it isn't
func isTestFunction(funcDecl *ast.FuncDecl) (bool, string) {
testMethodPackageType := "testing"
testMethodStruct := "T"
@@ -298,6 +377,8 @@ func isTestFunction(funcDecl *ast.FuncDecl) (bool, string) {
return false, ""
}
+// loopVarReferencedInRun checks if a loop variable is referenced within a test run
+// This is important for detecting potential race conditions in parallel tests
func loopVarReferencedInRun(call *ast.CallExpr, vars []types.Object, typeInfo *types.Info) (found *string) {
if len(call.Args) != 2 {
return
diff --git a/vendor/github.com/ldez/exptostd/.golangci.yml b/vendor/github.com/ldez/exptostd/.golangci.yml
index e615d3e5..e45135c6 100644
--- a/vendor/github.com/ldez/exptostd/.golangci.yml
+++ b/vendor/github.com/ldez/exptostd/.golangci.yml
@@ -1,83 +1,78 @@
+version: "2"
+
+formatters:
+ enable:
+ - gci
+ - gofumpt
+ settings:
+ gofumpt:
+ extra-rules: true
+
linters:
- enable-all: true
+ default: all
disable:
- - exportloopref # deprecated
- - sqlclosecheck # not relevant (SQL)
- - rowserrcheck # not relevant (SQL)
- cyclop # duplicate of gocyclo
- - lll
- dupl
- - nlreturn
+ - errchkjson
- exhaustive
- exhaustruct
- - testpackage
- - tparallel
+ - lll
+ - nilnil
+ - nlreturn
+ - nonamedreturns
- paralleltest
- prealloc
+ - rowserrcheck # not relevant (SQL)
+ - sqlclosecheck # not relevant (SQL)
+ - testpackage
+ - tparallel
- varnamelen
- - nilnil
- - errchkjson
- - nonamedreturns
-
-linters-settings:
- govet:
- enable-all: true
- disable:
- - fieldalignment
- gocyclo:
- min-complexity: 20
- goconst:
- min-len: 5
- min-occurrences: 3
- misspell:
- locale: US
- funlen:
- lines: -1
- statements: 40
- godox:
- keywords:
- - FIXME
- gofumpt:
- extra-rules: true
- depguard:
- rules:
- main:
- deny:
- - pkg: "github.com/instana/testify"
- desc: not allowed
- - pkg: "github.com/pkg/errors"
- desc: Should be replaced by standard lib errors package
- wsl:
- force-case-trailing-whitespace: 1
- allow-trailing-comment: true
- gocritic:
- enabled-tags:
- - diagnostic
- - style
- - performance
- disabled-checks:
- - sloppyReassign
- - rangeValCopy
- - octalLiteral
- - paramTypeCombine # already handle by gofumpt.extra-rules
- settings:
- hugeParam:
- sizeThreshold: 100
- nolintlint:
- require-specific: true
- require-explanation: true
+ settings:
+ depguard:
+ rules:
+ main:
+ deny:
+ - pkg: github.com/instana/testify
+ desc: not allowed
+ - pkg: github.com/pkg/errors
+ desc: Should be replaced by standard lib errors package
+ funlen:
+ lines: -1
+ statements: 40
+ goconst:
+ min-len: 5
+ min-occurrences: 3
+ gocritic:
+ disabled-checks:
+ - sloppyReassign
+ - rangeValCopy
+ - octalLiteral
+ - paramTypeCombine # already handle by gofumpt.extra-rules
+ enabled-tags:
+ - diagnostic
+ - style
+ - performance
+ settings:
+ hugeParam:
+ sizeThreshold: 100
+ gocyclo:
+ min-complexity: 20
+ godox:
+ keywords:
+ - FIXME
+ govet:
+ disable:
+ - fieldalignment
+ enable-all: true
+ misspell:
+ locale: US
+ nolintlint:
+ require-explanation: true
+ require-specific: true
+ wsl:
+ force-case-trailing-whitespace: 1
+ allow-trailing-comment: true
issues:
- exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0
-
-output:
- show-stats: true
- sort-results: true
- sort-order:
- - linter
- - file
-
-run:
- timeout: 5m
diff --git a/vendor/github.com/ldez/exptostd/exptostd.go b/vendor/github.com/ldez/exptostd/exptostd.go
index cf6c5e84..036f9236 100644
--- a/vendor/github.com/ldez/exptostd/exptostd.go
+++ b/vendor/github.com/ldez/exptostd/exptostd.go
@@ -55,7 +55,6 @@ type analyzer struct {
constraintsPkgReplacements map[string]stdReplacement[*ast.SelectorExpr]
skipGoVersionDetection bool
- goVersion int
}
// NewAnalyzer create a new Analyzer.
@@ -126,7 +125,7 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
return nil, nil
}
- a.goVersion = getGoVersion(pass)
+ goVersion := getGoVersion(pass)
nodeFilter := []ast.Node{
(*ast.CallExpr)(nil),
@@ -166,7 +165,7 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
switch ident.Name {
case pkgMaps:
- diagnostic, usage := a.detectPackageUsage(pass, a.mapsPkgReplacements, selExpr, ident, node, pkgExpMaps)
+ diagnostic, usage := a.detectPackageUsage(pass, a.mapsPkgReplacements, selExpr, ident, node, pkgExpMaps, goVersion)
if usage {
pass.Report(diagnostic)
}
@@ -174,7 +173,7 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
shouldKeepExpMaps = shouldKeepExpMaps || !usage
case pkgSlices:
- diagnostic, usage := a.detectPackageUsage(pass, a.slicesPkgReplacements, selExpr, ident, node, pkgExpSlices)
+ diagnostic, usage := a.detectPackageUsage(pass, a.slicesPkgReplacements, selExpr, ident, node, pkgExpSlices, goVersion)
if usage {
resultExpSlices.Diagnostics = append(resultExpSlices.Diagnostics, diagnostic)
}
@@ -185,14 +184,14 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
case *ast.FuncDecl:
if node.Type.TypeParams != nil {
for _, field := range node.Type.TypeParams.List {
- a.detectConstraintsUsage(pass, field.Type, resultExpConstraints)
+ a.detectConstraintsUsage(pass, field.Type, resultExpConstraints, goVersion)
}
}
case *ast.TypeSpec:
if node.TypeParams != nil {
for _, field := range node.TypeParams.List {
- a.detectConstraintsUsage(pass, field.Type, resultExpConstraints)
+ a.detectConstraintsUsage(pass, field.Type, resultExpConstraints, goVersion)
}
}
@@ -204,11 +203,11 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
for _, method := range interfaceType.Methods.List {
switch exp := method.Type.(type) {
case *ast.BinaryExpr:
- a.detectConstraintsUsage(pass, exp.X, resultExpConstraints)
- a.detectConstraintsUsage(pass, exp.Y, resultExpConstraints)
+ a.detectConstraintsUsage(pass, exp.X, resultExpConstraints, goVersion)
+ a.detectConstraintsUsage(pass, exp.Y, resultExpConstraints, goVersion)
case *ast.SelectorExpr:
- a.detectConstraintsUsage(pass, exp, resultExpConstraints)
+ a.detectConstraintsUsage(pass, exp, resultExpConstraints, goVersion)
}
}
}
@@ -235,14 +234,14 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
func (a *analyzer) detectPackageUsage(pass *analysis.Pass,
replacements map[string]stdReplacement[*ast.CallExpr],
selExpr *ast.SelectorExpr, ident *ast.Ident, callExpr *ast.CallExpr,
- importPath string,
+ importPath string, goVersion int,
) (analysis.Diagnostic, bool) {
rp, ok := replacements[selExpr.Sel.Name]
if !ok {
return analysis.Diagnostic{}, false
}
- if !a.skipGoVersionDetection && rp.MinGo > a.goVersion {
+ if !a.skipGoVersionDetection && rp.MinGo > goVersion {
return analysis.Diagnostic{}, false
}
@@ -267,7 +266,7 @@ func (a *analyzer) detectPackageUsage(pass *analysis.Pass,
return diagnostic, true
}
-func (a *analyzer) detectConstraintsUsage(pass *analysis.Pass, expr ast.Expr, result *Result) {
+func (a *analyzer) detectConstraintsUsage(pass *analysis.Pass, expr ast.Expr, result *Result, goVersion int) {
selExpr, ok := expr.(*ast.SelectorExpr)
if !ok {
return
@@ -288,7 +287,7 @@ func (a *analyzer) detectConstraintsUsage(pass *analysis.Pass, expr ast.Expr, re
return
}
- if !a.skipGoVersionDetection && rp.MinGo > a.goVersion {
+ if !a.skipGoVersionDetection && rp.MinGo > goVersion {
result.shouldKeepImport = true
return
}
diff --git a/vendor/github.com/ldez/usetesting/.golangci.yml b/vendor/github.com/ldez/usetesting/.golangci.yml
index 597647d2..1c66174e 100644
--- a/vendor/github.com/ldez/usetesting/.golangci.yml
+++ b/vendor/github.com/ldez/usetesting/.golangci.yml
@@ -1,83 +1,78 @@
+version: "2"
+
+formatters:
+ enable:
+ - gci
+ - gofumpt
+ settings:
+ gofumpt:
+ extra-rules: true
+
linters:
- enable-all: true
+ default: all
disable:
- - exportloopref # deprecated
- - sqlclosecheck # not relevant (SQL)
- - rowserrcheck # not relevant (SQL)
- cyclop # duplicate of gocyclo
- - lll
- dupl
- - nlreturn
+ - errchkjson
- exhaustive
- exhaustruct
- - testpackage
- - tparallel
+ - lll
+ - nilnil
+ - nlreturn
+ - nonamedreturns
- paralleltest
- prealloc
+ - rowserrcheck # not relevant (SQL)
+ - sqlclosecheck # not relevant (SQL)
+ - testpackage
+ - tparallel
- varnamelen
- - nilnil
- - errchkjson
- - nonamedreturns
-
-linters-settings:
- govet:
- enable-all: true
- disable:
- - fieldalignment
- mnd:
- ignored-numbers:
- - "124"
- gocyclo:
- min-complexity: 20
- goconst:
- min-len: 5
- min-occurrences: 3
- misspell:
- locale: US
- funlen:
- lines: -1
- statements: 40
- godox:
- keywords:
- - FIXME
- gofumpt:
- extra-rules: true
- depguard:
- rules:
- main:
- deny:
- - pkg: "github.com/instana/testify"
- desc: not allowed
- - pkg: "github.com/pkg/errors"
- desc: Should be replaced by standard lib errors package
- wsl:
- force-case-trailing-whitespace: 1
- allow-trailing-comment: true
- gocritic:
- enabled-tags:
- - diagnostic
- - style
- - performance
- disabled-checks:
- - sloppyReassign
- - rangeValCopy
- - octalLiteral
- - paramTypeCombine # already handle by gofumpt.extra-rules
- settings:
- hugeParam:
- sizeThreshold: 100
+ settings:
+ depguard:
+ rules:
+ main:
+ deny:
+ - pkg: github.com/instana/testify
+ desc: not allowed
+ - pkg: github.com/pkg/errors
+ desc: Should be replaced by standard lib errors package
+ funlen:
+ lines: -1
+ statements: 40
+ goconst:
+ min-len: 5
+ min-occurrences: 3
+ gocritic:
+ disabled-checks:
+ - sloppyReassign
+ - rangeValCopy
+ - octalLiteral
+ - paramTypeCombine # already handle by gofumpt.extra-rules
+ enabled-tags:
+ - diagnostic
+ - style
+ - performance
+ settings:
+ hugeParam:
+ sizeThreshold: 100
+ gocyclo:
+ min-complexity: 20
+ godox:
+ keywords:
+ - FIXME
+ govet:
+ disable:
+ - fieldalignment
+ enable-all: true
+ misspell:
+ locale: US
+ mnd:
+ ignored-numbers:
+ - "124"
+ wsl:
+ force-case-trailing-whitespace: 1
+ allow-trailing-comment: true
issues:
- exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0
-
-output:
- show-stats: true
- sort-results: true
- sort-order:
- - linter
- - file
-
-run:
- timeout: 5m
diff --git a/vendor/github.com/ldez/usetesting/readme.md b/vendor/github.com/ldez/usetesting/readme.md
index e21ba06e..0da8c8d1 100644
--- a/vendor/github.com/ldez/usetesting/readme.md
+++ b/vendor/github.com/ldez/usetesting/readme.md
@@ -11,38 +11,42 @@ Detects when some calls can be replaced by methods from the testing package.
Recommended.
```yml
-linters-settings:
- usetesting:
- # Enable/disable `os.CreateTemp("", ...)` detections.
- # Default: true
- os-create-temp: false
-
- # Enable/disable `os.MkdirTemp()` detections.
- # Default: true
- os-mkdir-temp: false
-
- # Enable/disable `os.Setenv()` detections.
- # Default: false
- os-setenv: true
-
- # Enable/disable `os.TempDir()` detections.
- # Default: false
- os-temp-dir: true
+linters:
+ enable:
+ - usetesting
+
+ settings:
+ usetesting:
+ # Enable/disable `os.CreateTemp("", ...)` detections.
+ # Default: true
+ os-create-temp: false
- # Enable/disable `os.Chdir()` detections.
- # Disabled if Go < 1.24.
- # Default: true
- os-chdir: false
-
- # Enable/disable `context.Background()` detections.
- # Disabled if Go < 1.24.
- # Default: true
- context-background: false
-
- # Enable/disable `context.TODO()` detections.
- # Disabled if Go < 1.24.
- # Default: true
- context-todo: false
+ # Enable/disable `os.MkdirTemp()` detections.
+ # Default: true
+ os-mkdir-temp: false
+
+ # Enable/disable `os.Setenv()` detections.
+ # Default: true
+ os-setenv: false
+
+ # Enable/disable `os.TempDir()` detections.
+ # Default: false
+ os-temp-dir: true
+
+ # Enable/disable `os.Chdir()` detections.
+ # Disabled if Go < 1.24.
+ # Default: true
+ os-chdir: false
+
+ # Enable/disable `context.Background()` detections.
+ # Disabled if Go < 1.24.
+ # Default: true
+ context-background: false
+
+ # Enable/disable `context.TODO()` detections.
+ # Disabled if Go < 1.24.
+ # Default: true
+ context-todo: false
```
### As a CLI
diff --git a/vendor/github.com/ldez/usetesting/report.go b/vendor/github.com/ldez/usetesting/report.go
index 3c90b6ba..333931c3 100644
--- a/vendor/github.com/ldez/usetesting/report.go
+++ b/vendor/github.com/ldez/usetesting/report.go
@@ -102,7 +102,7 @@ func diagnosticOSCreateTemp(ce *ast.CallExpr, fnInfo *FuncInfo) analysis.Diagnos
return diagnostic
}
-func (a *analyzer) reportSelector(pass *analysis.Pass, se *ast.SelectorExpr, fnInfo *FuncInfo) bool {
+func (a *analyzer) reportSelector(pass *analysis.Pass, se *ast.SelectorExpr, fnInfo *FuncInfo, geGo124 bool) bool {
if se.Sel == nil || !se.Sel.IsExported() {
return false
}
@@ -112,10 +112,10 @@ func (a *analyzer) reportSelector(pass *analysis.Pass, se *ast.SelectorExpr, fnI
return false
}
- return a.report(pass, se, ident.Name, se.Sel.Name, fnInfo)
+ return a.report(pass, se, ident.Name, se.Sel.Name, fnInfo, geGo124)
}
-func (a *analyzer) reportIdent(pass *analysis.Pass, ident *ast.Ident, fnInfo *FuncInfo) bool {
+func (a *analyzer) reportIdent(pass *analysis.Pass, ident *ast.Ident, fnInfo *FuncInfo, geGo124 bool) bool {
if !ident.IsExported() {
return false
}
@@ -126,11 +126,11 @@ func (a *analyzer) reportIdent(pass *analysis.Pass, ident *ast.Ident, fnInfo *Fu
pkgName := getPkgNameFromType(pass, ident)
- return a.report(pass, ident, pkgName, ident.Name, fnInfo)
+ return a.report(pass, ident, pkgName, ident.Name, fnInfo, geGo124)
}
//nolint:gocyclo // The complexity is expected by the number of cases to check.
-func (a *analyzer) report(pass *analysis.Pass, rg analysis.Range, origPkgName, origName string, fnInfo *FuncInfo) bool {
+func (a *analyzer) report(pass *analysis.Pass, rg analysis.Range, origPkgName, origName string, fnInfo *FuncInfo, geGo124 bool) bool {
switch {
case a.osMkdirTemp && origPkgName == osPkgName && origName == mkdirTempName:
report(pass, rg, origPkgName, origName, tempDirName, fnInfo)
@@ -141,13 +141,13 @@ func (a *analyzer) report(pass *analysis.Pass, rg analysis.Range, origPkgName, o
case a.osSetenv && origPkgName == osPkgName && origName == setenvName:
report(pass, rg, origPkgName, origName, setenvName, fnInfo)
- case a.geGo124 && a.osChdir && origPkgName == osPkgName && origName == chdirName:
+ case geGo124 && a.osChdir && origPkgName == osPkgName && origName == chdirName:
report(pass, rg, origPkgName, origName, chdirName, fnInfo)
- case a.geGo124 && a.contextBackground && origPkgName == contextPkgName && origName == backgroundName:
+ case geGo124 && a.contextBackground && origPkgName == contextPkgName && origName == backgroundName:
report(pass, rg, origPkgName, origName, contextName, fnInfo)
- case a.geGo124 && a.contextTodo && origPkgName == contextPkgName && origName == todoName:
+ case geGo124 && a.contextTodo && origPkgName == contextPkgName && origName == todoName:
report(pass, rg, origPkgName, origName, contextName, fnInfo)
default:
diff --git a/vendor/github.com/ldez/usetesting/usetesting.go b/vendor/github.com/ldez/usetesting/usetesting.go
index 72582783..6ff18f9a 100644
--- a/vendor/github.com/ldez/usetesting/usetesting.go
+++ b/vendor/github.com/ldez/usetesting/usetesting.go
@@ -50,7 +50,6 @@ type analyzer struct {
fieldNames []string
skipGoVersionDetection bool
- geGo124 bool
}
// NewAnalyzer create a new UseTesting.
@@ -93,7 +92,7 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
return nil, nil
}
- a.geGo124 = a.isGoSupported(pass)
+ geGo124 := a.isGoSupported(pass)
insp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
if !ok {
@@ -112,14 +111,14 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
switch fn := node.(type) {
case *ast.FuncDecl:
- a.checkFunc(pass, fn.Type, fn.Body, fn.Name.Name)
+ a.checkFunc(pass, fn.Type, fn.Body, fn.Name.Name, geGo124)
case *ast.FuncLit:
if hasParentFunc(stack) {
return true
}
- a.checkFunc(pass, fn.Type, fn.Body, "anonymous function")
+ a.checkFunc(pass, fn.Type, fn.Body, "anonymous function", geGo124)
}
return true
@@ -128,7 +127,7 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
return nil, nil
}
-func (a *analyzer) checkFunc(pass *analysis.Pass, ft *ast.FuncType, block *ast.BlockStmt, fnName string) {
+func (a *analyzer) checkFunc(pass *analysis.Pass, ft *ast.FuncType, block *ast.BlockStmt, fnName string, geGo124 bool) {
if len(ft.Params.List) < 1 {
return
}
@@ -141,10 +140,10 @@ func (a *analyzer) checkFunc(pass *analysis.Pass, ft *ast.FuncType, block *ast.B
ast.Inspect(block, func(n ast.Node) bool {
switch v := n.(type) {
case *ast.SelectorExpr:
- return !a.reportSelector(pass, v, fnInfo)
+ return !a.reportSelector(pass, v, fnInfo, geGo124)
case *ast.Ident:
- return !a.reportIdent(pass, v, fnInfo)
+ return !a.reportIdent(pass, v, fnInfo, geGo124)
case *ast.CallExpr:
return !a.reportCallExpr(pass, v, fnInfo)
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/.gitignore b/vendor/github.com/lucasb-eyer/go-colorful/.gitignore
new file mode 100644
index 00000000..0aa2c922
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/.gitignore
@@ -0,0 +1,101 @@
+# Created by https://www.toptal.com/developers/gitignore/api/code,go,linux,macos,windows
+# Edit at https://www.toptal.com/developers/gitignore?templates=code,go,linux,macos,windows
+
+### Code ###
+.vscode/*
+!.vscode/tasks.json
+!.vscode/launch.json
+*.code-workspace
+
+### Go ###
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
+
+### Go Patch ###
+/vendor/
+/Godeps/
+
+### Linux ###
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### macOS ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# End of https://www.toptal.com/developers/gitignore/api/code,go,linux,macos,windows
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md b/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md
new file mode 100644
index 00000000..84f9c7b2
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md
@@ -0,0 +1,42 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+The format of this file is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+but only releases after v1.0.3 properly adhere to it.
+
+
+## [1.2.0] - 2021-01-27
+### Added
+- HSLuv and HPLuv color spaces (#41, #51)
+- CIE LCh(uv) color space, called `LuvLCh` in code (#51)
+- JSON and envconfig serialization support for `HexColor` (#42)
+- `DistanceLinearRGB` (#53)
+
+### Fixed
+- RGB to/from XYZ conversion is more accurate (#51)
+- A bug in `XYZToLuvWhiteRef` that only applied to very small values was fixed (#51)
+- `BlendHCL` output is clamped so that it's not invalid (#46)
+- Properly documented `DistanceCIE76` (#40)
+- Some small godoc fixes
+
+
+## [1.0.3] - 2019-11-11
+- Remove SQLMock dependency
+
+
+## [1.0.2] - 2019-04-07
+- Fixes SQLMock dependency
+
+
+## [1.0.1] - 2019-03-24
+- Adds support for Go Modules
+
+
+## [1.0.0] - 2018-05-26
+- API Breaking change in `MakeColor`: instead of `panic`ing when alpha is zero, it now returns a secondary, boolean return value indicating success. See [the color.Color interface](#the-colorcolor-interface) section and [this FAQ entry](#q-why-would-makecolor-ever-fail) for details.
+
+
+## [0.9.0] - 2018-05-26
+- Initial version number after having ignored versioning for a long time :)
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/LICENSE b/vendor/github.com/lucasb-eyer/go-colorful/LICENSE
new file mode 100644
index 00000000..4e402a00
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/LICENSE
@@ -0,0 +1,7 @@
+Copyright (c) 2013 Lucas Beyer
+
+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.
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/README.md b/vendor/github.com/lucasb-eyer/go-colorful/README.md
new file mode 100644
index 00000000..8b9bd499
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/README.md
@@ -0,0 +1,482 @@
+go-colorful
+===========
+
+[](https://goreportcard.com/report/github.com/lucasb-eyer/go-colorful)
+
+A library for playing with colors in Go. Supports Go 1.13 onwards.
+
+Why?
+====
+I love games. I make games. I love detail and I get lost in detail.
+One such detail popped up during the development of [Memory Which Does Not Suck](https://github.com/lucasb-eyer/mwdns/),
+when we wanted the server to assign the players random colors. Sometimes
+two players got very similar colors, which bugged me. The very same evening,
+[I want hue](http://tools.medialab.sciences-po.fr/iwanthue/) was the top post
+on HackerNews' frontpage and showed me how to Do It Right™. Last but not
+least, there was no library for handling color spaces available in go. Colorful
+does just that and implements Go's `color.Color` interface.
+
+What?
+=====
+Go-Colorful stores colors in RGB and provides methods from converting these to various color-spaces. Currently supported colorspaces are:
+
+- **RGB:** All three of Red, Green and Blue in [0..1].
+- **HSL:** Hue in [0..360], Saturation and Luminance in [0..1]. For legacy reasons; please forget that it exists.
+- **HSV:** Hue in [0..360], Saturation and Value in [0..1]. You're better off using HCL, see below.
+- **Hex RGB:** The "internet" color format, as in #FF00FF.
+- **Linear RGB:** See [gamma correct rendering](http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/).
+- **CIE-XYZ:** CIE's standard color space, almost in [0..1].
+- **CIE-xyY:** encodes chromacity in x and y and luminance in Y, all in [0..1]
+- **CIE-L\*a\*b\*:** A *perceptually uniform* color space, i.e. distances are meaningful. L\* in [0..1] and a\*, b\* almost in [-1..1].
+- **CIE-L\*u\*v\*:** Very similar to CIE-L\*a\*b\*, there is [no consensus](http://en.wikipedia.org/wiki/CIELUV#Historical_background) on which one is "better".
+- **CIE-L\*C\*h° (HCL):** This is generally the [most useful](http://vis4.net/blog/posts/avoid-equidistant-hsv-colors/) one; CIE-L\*a\*b\* space in polar coordinates, i.e. a *better* HSV. H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*a\*b\*.
+- **CIE LCh(uv):** Called `LuvLCh` in code, this is a cylindrical transformation of the CIE-L\*u\*v\* color space. Like HCL above: H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*u\*v\*.
+- **HSLuv:** The better alternative to HSL, see [here](https://www.hsluv.org/) and [here](https://www.kuon.ch/post/2020-03-08-hsluv/). Hue in [0..360], Saturation and Luminance in [0..1].
+- **HPLuv:** A variant of HSLuv. The color space is smoother, but only pastel colors can be included. Because the valid colors are limited, it's easy to get invalid Saturation values way above 1.0, indicating the color can't be represented in HPLuv beccause it's not pastel.
+
+For the colorspaces where it makes sense (XYZ, Lab, Luv, HCl), the
+[D65](http://en.wikipedia.org/wiki/Illuminant_D65) is used as reference white
+by default but methods for using your own reference white are provided.
+
+A coordinate being *almost in* a range means that generally it is, but for very
+bright colors and depending on the reference white, it might overflow this
+range slightly. For example, C\* of #0000ff is 1.338.
+
+Unit-tests are provided.
+
+Nice, but what's it useful for?
+-------------------------------
+
+- Converting color spaces. Some people like to do that.
+- Blending (interpolating) between colors in a "natural" look by using the right colorspace.
+- Generating random colors under some constraints (e.g. colors of the same shade, or shades of one color.)
+- Generating gorgeous random palettes with distinct colors of a same temperature.
+
+What not (yet)?
+===============
+There are a few features which are currently missing and might be useful.
+I just haven't implemented them yet because I didn't have the need for it.
+Pull requests welcome.
+
+- Sorting colors (potentially using above mentioned distances)
+
+So which colorspace should I use?
+=================================
+It depends on what you want to do. I think the folks from *I want hue* are
+on-spot when they say that RGB fits to how *screens produce* color, CIE L\*a\*b\*
+fits how *humans perceive* color and HCL fits how *humans think* colors.
+
+Whenever you'd use HSV, rather go for CIE-L\*C\*h°. for fixed lightness L\* and
+chroma C\* values, the hue angle h° rotates through colors of the same
+perceived brightness and intensity.
+
+How?
+====
+
+### Installing
+Installing the library is as easy as
+
+```bash
+$ go get github.com/lucasb-eyer/go-colorful
+```
+
+The package can then be used through an
+
+```go
+import "github.com/lucasb-eyer/go-colorful"
+```
+
+### Basic usage
+
+Create a beautiful blue color using different source space:
+
+```go
+// Any of the following should be the same
+c := colorful.Color{0.313725, 0.478431, 0.721569}
+c, err := colorful.Hex("#517AB8")
+if err != nil {
+ log.Fatal(err)
+}
+c = colorful.Hsv(216.0, 0.56, 0.722)
+c = colorful.Xyz(0.189165, 0.190837, 0.480248)
+c = colorful.Xyy(0.219895, 0.221839, 0.190837)
+c = colorful.Lab(0.507850, 0.040585,-0.370945)
+c = colorful.Luv(0.507849,-0.194172,-0.567924)
+c = colorful.Hcl(276.2440, 0.373160, 0.507849)
+fmt.Printf("RGB values: %v, %v, %v", c.R, c.G, c.B)
+```
+
+And then converting this color back into various color spaces:
+
+```go
+hex := c.Hex()
+h, s, v := c.Hsv()
+x, y, z := c.Xyz()
+x, y, Y := c.Xyy()
+l, a, b := c.Lab()
+l, u, v := c.Luv()
+h, c, l := c.Hcl()
+```
+
+Note that, because of Go's unfortunate choice of requiring an initial uppercase,
+the name of the functions relating to the xyY space are just off. If you have
+any good suggestion, please open an issue. (I don't consider XyY good.)
+
+### The `color.Color` interface
+Because a `colorful.Color` implements Go's `color.Color` interface (found in the
+`image/color` package), it can be used anywhere that expects a `color.Color`.
+
+Furthermore, you can convert anything that implements the `color.Color` interface
+into a `colorful.Color` using the `MakeColor` function:
+
+```go
+c, ok := colorful.MakeColor(color.Gray16{12345})
+```
+
+**Caveat:** Be aware that this latter conversion (using `MakeColor`) hits a
+corner-case when alpha is exactly zero. Because `color.Color` uses pre-multiplied
+alpha colors, this means the RGB values are lost (set to 0) and it's impossible
+to recover them. In such a case `MakeColor` will return `false` as its second value.
+
+### Comparing colors
+In the RGB color space, the Euclidian distance between colors *doesn't* correspond
+to visual/perceptual distance. This means that two pairs of colors which have the
+same distance in RGB space can look much further apart. This is fixed by the
+CIE-L\*a\*b\*, CIE-L\*u\*v\* and CIE-L\*C\*h° color spaces.
+Thus you should only compare colors in any of these space.
+(Note that the distance in CIE-L\*a\*b\* and CIE-L\*C\*h° are the same, since it's the same space but in cylindrical coordinates)
+
+
+
+The two colors shown on the top look much more different than the two shown on
+the bottom. Still, in RGB space, their distance is the same.
+Here is a little example program which shows the distances between the top two
+and bottom two colors in RGB, CIE-L\*a\*b\* and CIE-L\*u\*v\* space. You can find it in `doc/colordist/colordist.go`.
+
+```go
+package main
+
+import "fmt"
+import "github.com/lucasb-eyer/go-colorful"
+
+func main() {
+ c1a := colorful.Color{150.0 / 255.0, 10.0 / 255.0, 150.0 / 255.0}
+ c1b := colorful.Color{53.0 / 255.0, 10.0 / 255.0, 150.0 / 255.0}
+ c2a := colorful.Color{10.0 / 255.0, 150.0 / 255.0, 50.0 / 255.0}
+ c2b := colorful.Color{99.9 / 255.0, 150.0 / 255.0, 10.0 / 255.0}
+
+ fmt.Printf("DistanceRgb: c1: %v\tand c2: %v\n", c1a.DistanceRgb(c1b), c2a.DistanceRgb(c2b))
+ fmt.Printf("DistanceLab: c1: %v\tand c2: %v\n", c1a.DistanceLab(c1b), c2a.DistanceLab(c2b))
+ fmt.Printf("DistanceLuv: c1: %v\tand c2: %v\n", c1a.DistanceLuv(c1b), c2a.DistanceLuv(c2b))
+ fmt.Printf("DistanceCIE76: c1: %v\tand c2: %v\n", c1a.DistanceCIE76(c1b), c2a.DistanceCIE76(c2b))
+ fmt.Printf("DistanceCIE94: c1: %v\tand c2: %v\n", c1a.DistanceCIE94(c1b), c2a.DistanceCIE94(c2b))
+ fmt.Printf("DistanceCIEDE2000: c1: %v\tand c2: %v\n", c1a.DistanceCIEDE2000(c1b), c2a.DistanceCIEDE2000(c2b))
+}
+```
+
+Running the above program shows that you should always prefer any of the CIE distances:
+
+```bash
+$ go run colordist.go
+DistanceRgb: c1: 0.3803921568627451 and c2: 0.3858713931171159
+DistanceLab: c1: 0.32048458312798056 and c2: 0.24397151758565272
+DistanceLuv: c1: 0.5134369614199698 and c2: 0.2568692839860636
+DistanceCIE76: c1: 0.32048458312798056 and c2: 0.24397151758565272
+DistanceCIE94: c1: 0.19799168128511324 and c2: 0.12207136371167401
+DistanceCIEDE2000: c1: 0.17274551120971166 and c2: 0.10665210031428465
+```
+
+It also shows that `DistanceLab` is more formally known as `DistanceCIE76` and
+has been superseded by the slightly more accurate, but much more expensive
+`DistanceCIE94` and `DistanceCIEDE2000`.
+
+Note that `AlmostEqualRgb` is provided mainly for (unit-)testing purposes. Use
+it only if you really know what you're doing. It will eat your cat.
+
+### Blending colors
+Blending is highly connected to distance, since it basically "walks through" the
+colorspace thus, if the colorspace maps distances well, the walk is "smooth".
+
+Colorful comes with blending functions in RGB, HSV and any of the LAB spaces.
+Of course, you'd rather want to use the blending functions of the LAB spaces since
+these spaces map distances well but, just in case, here is an example showing
+you how the blendings (`#fdffcc` to `#242a42`) are done in the various spaces:
+
+
+
+What you see is that HSV is really bad: it adds some green, which is not present
+in the original colors at all! RGB is much better, but it stays light a little
+too long. LUV and LAB both hit the right lightness but LAB has a little more
+color. HCL works in the same vein as HSV (both cylindrical interpolations) but
+it does it right in that there is no green appearing and the lighthness changes
+in a linear manner.
+
+While this seems all good, you need to know one thing: When interpolating in any
+of the CIE color spaces, you might get invalid RGB colors! This is important if
+the starting and ending colors are user-input or random. An example of where this
+happens is when blending between `#eeef61` and `#1e3140`:
+
+
+
+You can test whether a color is a valid RGB color by calling the `IsValid` method
+and indeed, calling IsValid will return false for the redish colors on the bottom.
+One way to "fix" this is to get a valid color close to the invalid one by calling
+`Clamped`, which always returns a nearby valid color. Doing this, we get the
+following result, which is satisfactory:
+
+
+
+The following is the code creating the above three images; it can be found in `doc/colorblend/colorblend.go`
+
+```go
+package main
+
+import "fmt"
+import "github.com/lucasb-eyer/go-colorful"
+import "image"
+import "image/draw"
+import "image/png"
+import "os"
+
+func main() {
+ blocks := 10
+ blockw := 40
+ img := image.NewRGBA(image.Rect(0,0,blocks*blockw,200))
+
+ c1, _ := colorful.Hex("#fdffcc")
+ c2, _ := colorful.Hex("#242a42")
+
+ // Use these colors to get invalid RGB in the gradient.
+ //c1, _ := colorful.Hex("#EEEF61")
+ //c2, _ := colorful.Hex("#1E3140")
+
+ for i := 0 ; i < blocks ; i++ {
+ draw.Draw(img, image.Rect(i*blockw, 0,(i+1)*blockw, 40), &image.Uniform{c1.BlendHsv(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
+ draw.Draw(img, image.Rect(i*blockw, 40,(i+1)*blockw, 80), &image.Uniform{c1.BlendLuv(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
+ draw.Draw(img, image.Rect(i*blockw, 80,(i+1)*blockw,120), &image.Uniform{c1.BlendRgb(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
+ draw.Draw(img, image.Rect(i*blockw,120,(i+1)*blockw,160), &image.Uniform{c1.BlendLab(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
+ draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
+
+ // This can be used to "fix" invalid colors in the gradient.
+ //draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1)).Clamped()}, image.Point{}, draw.Src)
+ }
+
+ toimg, err := os.Create("colorblend.png")
+ if err != nil {
+ fmt.Printf("Error: %v", err)
+ return
+ }
+ defer toimg.Close()
+
+ png.Encode(toimg, img)
+}
+```
+
+#### Generating color gradients
+A very common reason to blend colors is creating gradients. There is an example
+program in [doc/gradientgen.go](doc/gradientgen/gradientgen.go); it doesn't use any API
+which hasn't been used in the previous example code, so I won't bother pasting
+the code in here. Just look at that gorgeous gradient it generated in HCL space:
+
+
+
+### Getting random colors
+It is sometimes necessary to generate random colors. You could simply do this
+on your own by generating colors with random values. By restricting the random
+values to a range smaller than [0..1] and using a space such as CIE-H\*C\*l° or
+HSV, you can generate both random shades of a color or random colors of a
+lightness:
+
+```go
+random_blue := colorful.Hcl(180.0+rand.Float64()*50.0, 0.2+rand.Float64()*0.8, 0.3+rand.Float64()*0.7)
+random_dark := colorful.Hcl(rand.Float64()*360.0, rand.Float64(), rand.Float64()*0.4)
+random_light := colorful.Hcl(rand.Float64()*360.0, rand.Float64(), 0.6+rand.Float64()*0.4)
+```
+
+Since getting random "warm" and "happy" colors is quite a common task, there
+are some helper functions:
+
+```go
+colorful.WarmColor()
+colorful.HappyColor()
+colorful.FastWarmColor()
+colorful.FastHappyColor()
+```
+
+The ones prefixed by `Fast` are faster but less coherent since they use the HSV
+space as opposed to the regular ones which use CIE-L\*C\*h° space. The
+following picture shows the warm colors in the top two rows and happy colors
+in the bottom two rows. Within these, the first is the regular one and the
+second is the fast one.
+
+
+
+Don't forget to initialize the random seed! You can see the code used for
+generating this picture in `doc/colorgens/colorgens.go`.
+
+### Getting random palettes
+As soon as you need to generate more than one random color, you probably want
+them to be distinguishible. Playing against an opponent which has almost the
+same blue as I do is not fun. This is where random palettes can help.
+
+These palettes are generated using an algorithm which ensures that all colors
+on the palette are as distinguishible as possible. Again, there is a `Fast`
+method which works in HSV and is less perceptually uniform and a non-`Fast`
+method which works in CIE spaces. For more theory on `SoftPalette`, check out
+[I want hue](http://tools.medialab.sciences-po.fr/iwanthue/theory.php). Yet
+again, there is a `Happy` and a `Warm` version, which do what you expect, but
+now there is an additional `Soft` version, which is more configurable: you can
+give a constraint on the color space in order to get colors within a certain *feel*.
+
+Let's start with the simple methods first, all they take is the amount of
+colors to generate, which could, for example, be the player count. They return
+an array of `colorful.Color` objects:
+
+```go
+pal1, err1 := colorful.WarmPalette(10)
+pal2 := colorful.FastWarmPalette(10)
+pal3, err3 := colorful.HappyPalette(10)
+pal4 := colorful.FastHappyPalette(10)
+pal5, err5 := colorful.SoftPalette(10)
+```
+
+Note that the non-fast methods *may* fail if you ask for way too many colors.
+Let's move on to the advanced one, namely `SoftPaletteEx`. Besides the color
+count, this function takes a `SoftPaletteSettings` object as argument. The
+interesting part here is its `CheckColor` member, which is a boolean function
+taking three floating points as arguments: `l`, `a` and `b`. This function
+should return `true` for colors which lie within the region you want and `false`
+otherwise. The other members are `Iteration`, which should be within [5..100]
+where higher means slower but more exact palette, and `ManySamples` which you
+should set to `true` in case your `CheckColor` constraint rejects a large part
+of the color space.
+
+For example, to create a palette of 10 brownish colors, you'd call it like this:
+
+```go
+func isbrowny(l, a, b float64) bool {
+ h, c, L := colorful.LabToHcl(l, a, b)
+ return 10.0 < h && h < 50.0 && 0.1 < c && c < 0.5 && L < 0.5
+}
+// Since the above function is pretty restrictive, we set ManySamples to true.
+brownies := colorful.SoftPaletteEx(10, colorful.SoftPaletteSettings{isbrowny, 50, true})
+```
+
+The following picture shows the palettes generated by all of these methods
+(sourcecode in `doc/palettegens/palettegens.go`), in the order they were presented, i.e.
+from top to bottom: `Warm`, `FastWarm`, `Happy`, `FastHappy`, `Soft`,
+`SoftEx(isbrowny)`. All of them contain some randomness, so YMMV.
+
+
+
+Again, the code used for generating the above image is available as [doc/palettegens/palettegens.go](https://github.com/lucasb-eyer/go-colorful/blob/master/doc/palettegens/palettegens.go).
+
+### Sorting colors
+TODO: Sort using dist fn.
+
+### Using linear RGB for computations
+There are two methods for transforming RGB<->Linear RGB: a fast and almost precise one,
+and a slow and precise one.
+
+```go
+r, g, b := colorful.Hex("#FF0000").FastLinearRgb()
+```
+
+TODO: describe some more.
+
+### Want to use some other reference point?
+
+```go
+c := colorful.LabWhiteRef(0.507850, 0.040585,-0.370945, colorful.D50)
+l, a, b := c.LabWhiteRef(colorful.D50)
+```
+
+### Reading and writing colors from databases
+
+The type `HexColor` makes it easy to store colors as strings in a database. It
+implements the [https://godoc.org/database/sql#Scanner](database/sql.Scanner)
+and [database/sql/driver.Value](https://godoc.org/database/sql/driver.Value)
+interfaces which provide automatic type conversion.
+
+Example:
+
+```go
+var hc HexColor
+_, err := db.QueryRow("SELECT '#ff0000';").Scan(&hc)
+// hc == HexColor{R: 1, G: 0, B: 0}; err == nil
+```
+
+FAQ
+===
+
+### Q: I get all f!@#ed up values! Your library sucks!
+A: You probably provided values in the wrong range. For example, RGB values are
+expected to reside between 0 and 1, *not* between 0 and 255. Normalize your colors.
+
+### Q: Lab/Luv/HCl seem broken! Your library sucks!
+They look like this:
+
+
+
+A: You're likely trying to generate and display colors that can't be represented by RGB,
+and thus monitors. When you're trying to convert, say, `HCL(190.0, 1.0, 1.0).RGB255()`,
+you're asking for RGB values of `(-2105.254 300.680 286.185)`, which clearly don't exist,
+and the `RGB255` function just casts these numbers to `uint8`, creating wrap-around and
+what looks like a completely broken gradient. What you want to do, is either use more
+reasonable values of colors which actually exist in RGB, or just `Clamp()` the resulting
+color to its nearest existing one, living with the consequences:
+`HCL(190.0, 1.0, 1.0).Clamp().RGB255()`. It will look something like this:
+
+
+
+[Here's an issue going in-depth about this](https://github.com/lucasb-eyer/go-colorful/issues/14),
+as well as [my answer](https://github.com/lucasb-eyer/go-colorful/issues/14#issuecomment-324205385),
+both with code and pretty pictures. Also note that this was somewhat covered above in the
+["Blending colors" section](https://github.com/lucasb-eyer/go-colorful#blending-colors).
+
+### Q: In a tight loop, conversion to Lab/Luv/HCl/... are slooooow!
+A: Yes, they are.
+This library aims for correctness, readability, and modularity; it wasn't written with speed in mind.
+A large part of the slowness comes from these conversions going through `LinearRgb` which uses powers.
+I implemented a fast approximation to `LinearRgb` called `FastLinearRgb` by using Taylor approximations.
+The approximation is roughly 5x faster and precise up to roughly 0.5%,
+the major caveat being that if the input values are outside the range 0-1, accuracy drops dramatically.
+You can use these in your conversions as follows:
+
+```go
+col := // Get your color somehow
+l, a, b := XyzToLab(LinearRgbToXyz(col.LinearRgb()))
+```
+
+If you need faster versions of `Distance*` and `Blend*` that make use of this fast approximation,
+feel free to implement them and open a pull-request, I'll happily accept.
+
+The derivation of these functions can be followed in [this Jupyter notebook](doc/LinearRGB Approximations.ipynb).
+Here's the main figure showing the approximation quality:
+
+
+
+More speed could be gained by using SIMD instructions in many places.
+You can also get more speed for specific conversions by approximating the full conversion function,
+but that is outside the scope of this library.
+Thanks to [@ZirconiumX](https://github.com/ZirconiumX) for starting this investigation,
+see [issue #18](https://github.com/lucasb-eyer/go-colorful/issues/18) for details.
+
+### Q: Why would `MakeColor` ever fail!?
+A: `MakeColor` fails when the alpha channel is zero. In that case, the
+conversion is undefined. See [issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21)
+as well as the short caveat note in the ["The `color.Color` interface"](README.md#the-colorcolor-interface)
+section above.
+
+Who?
+====
+
+This library was developed by Lucas Beyer with contributions from
+Bastien Dejean (@baskerville), Phil Kulak (@pkulak) and Christian Muehlhaeuser (@muesli).
+
+It is now maintained by makeworld (@makeworld-the-better-one).
+
+
+## License
+
+This repo is under the MIT license, see [LICENSE](LICENSE) for details.
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go b/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go
new file mode 100644
index 00000000..2e2e49e1
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go
@@ -0,0 +1,55 @@
+// Various ways to generate single random colors
+
+package colorful
+
+import (
+ "math/rand"
+)
+
+// Creates a random dark, "warm" color through a restricted HSV space.
+func FastWarmColor() Color {
+ return Hsv(
+ rand.Float64()*360.0,
+ 0.5+rand.Float64()*0.3,
+ 0.3+rand.Float64()*0.3)
+}
+
+// Creates a random dark, "warm" color through restricted HCL space.
+// This is slower than FastWarmColor but will likely give you colors which have
+// the same "warmness" if you run it many times.
+func WarmColor() (c Color) {
+ for c = randomWarm(); !c.IsValid(); c = randomWarm() {
+ }
+ return
+}
+
+func randomWarm() Color {
+ return Hcl(
+ rand.Float64()*360.0,
+ 0.1+rand.Float64()*0.3,
+ 0.2+rand.Float64()*0.3)
+}
+
+// Creates a random bright, "pimpy" color through a restricted HSV space.
+func FastHappyColor() Color {
+ return Hsv(
+ rand.Float64()*360.0,
+ 0.7+rand.Float64()*0.3,
+ 0.6+rand.Float64()*0.3)
+}
+
+// Creates a random bright, "pimpy" color through restricted HCL space.
+// This is slower than FastHappyColor but will likely give you colors which
+// have the same "brightness" if you run it many times.
+func HappyColor() (c Color) {
+ for c = randomPimp(); !c.IsValid(); c = randomPimp() {
+ }
+ return
+}
+
+func randomPimp() Color {
+ return Hcl(
+ rand.Float64()*360.0,
+ 0.5+rand.Float64()*0.3,
+ 0.5+rand.Float64()*0.3)
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/colors.go b/vendor/github.com/lucasb-eyer/go-colorful/colors.go
new file mode 100644
index 00000000..0d5bffe5
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/colors.go
@@ -0,0 +1,979 @@
+// The colorful package provides all kinds of functions for working with colors.
+package colorful
+
+import (
+ "fmt"
+ "image/color"
+ "math"
+)
+
+// A color is stored internally using sRGB (standard RGB) values in the range 0-1
+type Color struct {
+ R, G, B float64
+}
+
+// Implement the Go color.Color interface.
+func (col Color) RGBA() (r, g, b, a uint32) {
+ r = uint32(col.R*65535.0 + 0.5)
+ g = uint32(col.G*65535.0 + 0.5)
+ b = uint32(col.B*65535.0 + 0.5)
+ a = 0xFFFF
+ return
+}
+
+// Constructs a colorful.Color from something implementing color.Color
+func MakeColor(col color.Color) (Color, bool) {
+ r, g, b, a := col.RGBA()
+ if a == 0 {
+ return Color{0, 0, 0}, false
+ }
+
+ // Since color.Color is alpha pre-multiplied, we need to divide the
+ // RGB values by alpha again in order to get back the original RGB.
+ r *= 0xffff
+ r /= a
+ g *= 0xffff
+ g /= a
+ b *= 0xffff
+ b /= a
+
+ return Color{float64(r) / 65535.0, float64(g) / 65535.0, float64(b) / 65535.0}, true
+}
+
+// Might come in handy sometimes to reduce boilerplate code.
+func (col Color) RGB255() (r, g, b uint8) {
+ r = uint8(col.R*255.0 + 0.5)
+ g = uint8(col.G*255.0 + 0.5)
+ b = uint8(col.B*255.0 + 0.5)
+ return
+}
+
+// Used to simplify HSLuv testing.
+func (col Color) values() (float64, float64, float64) {
+ return col.R, col.G, col.B
+}
+
+// This is the tolerance used when comparing colors using AlmostEqualRgb.
+const Delta = 1.0 / 255.0
+
+// This is the default reference white point.
+var D65 = [3]float64{0.95047, 1.00000, 1.08883}
+
+// And another one.
+var D50 = [3]float64{0.96422, 1.00000, 0.82521}
+
+// Checks whether the color exists in RGB space, i.e. all values are in [0..1]
+func (c Color) IsValid() bool {
+ return 0.0 <= c.R && c.R <= 1.0 &&
+ 0.0 <= c.G && c.G <= 1.0 &&
+ 0.0 <= c.B && c.B <= 1.0
+}
+
+// clamp01 clamps from 0 to 1.
+func clamp01(v float64) float64 {
+ return math.Max(0.0, math.Min(v, 1.0))
+}
+
+// Returns Clamps the color into valid range, clamping each value to [0..1]
+// If the color is valid already, this is a no-op.
+func (c Color) Clamped() Color {
+ return Color{clamp01(c.R), clamp01(c.G), clamp01(c.B)}
+}
+
+func sq(v float64) float64 {
+ return v * v
+}
+
+func cub(v float64) float64 {
+ return v * v * v
+}
+
+// DistanceRgb computes the distance between two colors in RGB space.
+// This is not a good measure! Rather do it in Lab space.
+func (c1 Color) DistanceRgb(c2 Color) float64 {
+ return math.Sqrt(sq(c1.R-c2.R) + sq(c1.G-c2.G) + sq(c1.B-c2.B))
+}
+
+// DistanceLinearRGB computes the distance between two colors in linear RGB
+// space. This is not useful for measuring how humans perceive color, but
+// might be useful for other things, like dithering.
+func (c1 Color) DistanceLinearRGB(c2 Color) float64 {
+ r1, g1, b1 := c1.LinearRgb()
+ r2, g2, b2 := c2.LinearRgb()
+ return math.Sqrt(sq(r1-r2) + sq(g1-g2) + sq(b1-b2))
+}
+
+// Check for equality between colors within the tolerance Delta (1/255).
+func (c1 Color) AlmostEqualRgb(c2 Color) bool {
+ return math.Abs(c1.R-c2.R)+
+ math.Abs(c1.G-c2.G)+
+ math.Abs(c1.B-c2.B) < 3.0*Delta
+}
+
+// You don't really want to use this, do you? Go for BlendLab, BlendLuv or BlendHcl.
+func (c1 Color) BlendRgb(c2 Color, t float64) Color {
+ return Color{c1.R + t*(c2.R-c1.R),
+ c1.G + t*(c2.G-c1.G),
+ c1.B + t*(c2.B-c1.B)}
+}
+
+// Utility used by Hxx color-spaces for interpolating between two angles in [0,360].
+func interp_angle(a0, a1, t float64) float64 {
+ // Based on the answer here: http://stackoverflow.com/a/14498790/2366315
+ // With potential proof that it works here: http://math.stackexchange.com/a/2144499
+ delta := math.Mod(math.Mod(a1-a0, 360.0)+540, 360.0) - 180.0
+ return math.Mod(a0+t*delta+360.0, 360.0)
+}
+
+/// HSV ///
+///////////
+// From http://en.wikipedia.org/wiki/HSL_and_HSV
+// Note that h is in [0..360] and s,v in [0..1]
+
+// Hsv returns the Hue [0..360], Saturation and Value [0..1] of the color.
+func (col Color) Hsv() (h, s, v float64) {
+ min := math.Min(math.Min(col.R, col.G), col.B)
+ v = math.Max(math.Max(col.R, col.G), col.B)
+ C := v - min
+
+ s = 0.0
+ if v != 0.0 {
+ s = C / v
+ }
+
+ h = 0.0 // We use 0 instead of undefined as in wp.
+ if min != v {
+ if v == col.R {
+ h = math.Mod((col.G-col.B)/C, 6.0)
+ }
+ if v == col.G {
+ h = (col.B-col.R)/C + 2.0
+ }
+ if v == col.B {
+ h = (col.R-col.G)/C + 4.0
+ }
+ h *= 60.0
+ if h < 0.0 {
+ h += 360.0
+ }
+ }
+ return
+}
+
+// Hsv creates a new Color given a Hue in [0..360], a Saturation and a Value in [0..1]
+func Hsv(H, S, V float64) Color {
+ Hp := H / 60.0
+ C := V * S
+ X := C * (1.0 - math.Abs(math.Mod(Hp, 2.0)-1.0))
+
+ m := V - C
+ r, g, b := 0.0, 0.0, 0.0
+
+ switch {
+ case 0.0 <= Hp && Hp < 1.0:
+ r = C
+ g = X
+ case 1.0 <= Hp && Hp < 2.0:
+ r = X
+ g = C
+ case 2.0 <= Hp && Hp < 3.0:
+ g = C
+ b = X
+ case 3.0 <= Hp && Hp < 4.0:
+ g = X
+ b = C
+ case 4.0 <= Hp && Hp < 5.0:
+ r = X
+ b = C
+ case 5.0 <= Hp && Hp < 6.0:
+ r = C
+ b = X
+ }
+
+ return Color{m + r, m + g, m + b}
+}
+
+// You don't really want to use this, do you? Go for BlendLab, BlendLuv or BlendHcl.
+func (c1 Color) BlendHsv(c2 Color, t float64) Color {
+ h1, s1, v1 := c1.Hsv()
+ h2, s2, v2 := c2.Hsv()
+
+ // We know that h are both in [0..360]
+ return Hsv(interp_angle(h1, h2, t), s1+t*(s2-s1), v1+t*(v2-v1))
+}
+
+/// HSL ///
+///////////
+
+// Hsl returns the Hue [0..360], Saturation [0..1], and Luminance (lightness) [0..1] of the color.
+func (col Color) Hsl() (h, s, l float64) {
+ min := math.Min(math.Min(col.R, col.G), col.B)
+ max := math.Max(math.Max(col.R, col.G), col.B)
+
+ l = (max + min) / 2
+
+ if min == max {
+ s = 0
+ h = 0
+ } else {
+ if l < 0.5 {
+ s = (max - min) / (max + min)
+ } else {
+ s = (max - min) / (2.0 - max - min)
+ }
+
+ if max == col.R {
+ h = (col.G - col.B) / (max - min)
+ } else if max == col.G {
+ h = 2.0 + (col.B-col.R)/(max-min)
+ } else {
+ h = 4.0 + (col.R-col.G)/(max-min)
+ }
+
+ h *= 60
+
+ if h < 0 {
+ h += 360
+ }
+ }
+
+ return
+}
+
+// Hsl creates a new Color given a Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1]
+func Hsl(h, s, l float64) Color {
+ if s == 0 {
+ return Color{l, l, l}
+ }
+
+ var r, g, b float64
+ var t1 float64
+ var t2 float64
+ var tr float64
+ var tg float64
+ var tb float64
+
+ if l < 0.5 {
+ t1 = l * (1.0 + s)
+ } else {
+ t1 = l + s - l*s
+ }
+
+ t2 = 2*l - t1
+ h /= 360
+ tr = h + 1.0/3.0
+ tg = h
+ tb = h - 1.0/3.0
+
+ if tr < 0 {
+ tr++
+ }
+ if tr > 1 {
+ tr--
+ }
+ if tg < 0 {
+ tg++
+ }
+ if tg > 1 {
+ tg--
+ }
+ if tb < 0 {
+ tb++
+ }
+ if tb > 1 {
+ tb--
+ }
+
+ // Red
+ if 6*tr < 1 {
+ r = t2 + (t1-t2)*6*tr
+ } else if 2*tr < 1 {
+ r = t1
+ } else if 3*tr < 2 {
+ r = t2 + (t1-t2)*(2.0/3.0-tr)*6
+ } else {
+ r = t2
+ }
+
+ // Green
+ if 6*tg < 1 {
+ g = t2 + (t1-t2)*6*tg
+ } else if 2*tg < 1 {
+ g = t1
+ } else if 3*tg < 2 {
+ g = t2 + (t1-t2)*(2.0/3.0-tg)*6
+ } else {
+ g = t2
+ }
+
+ // Blue
+ if 6*tb < 1 {
+ b = t2 + (t1-t2)*6*tb
+ } else if 2*tb < 1 {
+ b = t1
+ } else if 3*tb < 2 {
+ b = t2 + (t1-t2)*(2.0/3.0-tb)*6
+ } else {
+ b = t2
+ }
+
+ return Color{r, g, b}
+}
+
+/// Hex ///
+///////////
+
+// Hex returns the hex "html" representation of the color, as in #ff0080.
+func (col Color) Hex() string {
+ // Add 0.5 for rounding
+ return fmt.Sprintf("#%02x%02x%02x", uint8(col.R*255.0+0.5), uint8(col.G*255.0+0.5), uint8(col.B*255.0+0.5))
+}
+
+// Hex parses a "html" hex color-string, either in the 3 "#f0c" or 6 "#ff1034" digits form.
+func Hex(scol string) (Color, error) {
+ format := "#%02x%02x%02x"
+ factor := 1.0 / 255.0
+ if len(scol) == 4 {
+ format = "#%1x%1x%1x"
+ factor = 1.0 / 15.0
+ }
+
+ var r, g, b uint8
+ n, err := fmt.Sscanf(scol, format, &r, &g, &b)
+ if err != nil {
+ return Color{}, err
+ }
+ if n != 3 {
+ return Color{}, fmt.Errorf("color: %v is not a hex-color", scol)
+ }
+
+ return Color{float64(r) * factor, float64(g) * factor, float64(b) * factor}, nil
+}
+
+/// Linear ///
+//////////////
+// http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/
+// http://www.brucelindbloom.com/Eqn_RGB_to_XYZ.html
+
+func linearize(v float64) float64 {
+ if v <= 0.04045 {
+ return v / 12.92
+ }
+ return math.Pow((v+0.055)/1.055, 2.4)
+}
+
+// LinearRgb converts the color into the linear RGB space (see http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/).
+func (col Color) LinearRgb() (r, g, b float64) {
+ r = linearize(col.R)
+ g = linearize(col.G)
+ b = linearize(col.B)
+ return
+}
+
+// A much faster and still quite precise linearization using a 6th-order Taylor approximation.
+// See the accompanying Jupyter notebook for derivation of the constants.
+func linearize_fast(v float64) float64 {
+ v1 := v - 0.5
+ v2 := v1 * v1
+ v3 := v2 * v1
+ v4 := v2 * v2
+ //v5 := v3*v2
+ return -0.248750514614486 + 0.925583310193438*v + 1.16740237321695*v2 + 0.280457026598666*v3 - 0.0757991963780179*v4 //+ 0.0437040411548932*v5
+}
+
+// FastLinearRgb is much faster than and almost as accurate as LinearRgb.
+// BUT it is important to NOTE that they only produce good results for valid colors r,g,b in [0,1].
+func (col Color) FastLinearRgb() (r, g, b float64) {
+ r = linearize_fast(col.R)
+ g = linearize_fast(col.G)
+ b = linearize_fast(col.B)
+ return
+}
+
+func delinearize(v float64) float64 {
+ if v <= 0.0031308 {
+ return 12.92 * v
+ }
+ return 1.055*math.Pow(v, 1.0/2.4) - 0.055
+}
+
+// LinearRgb creates an sRGB color out of the given linear RGB color (see http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/).
+func LinearRgb(r, g, b float64) Color {
+ return Color{delinearize(r), delinearize(g), delinearize(b)}
+}
+
+func delinearize_fast(v float64) float64 {
+ // This function (fractional root) is much harder to linearize, so we need to split.
+ if v > 0.2 {
+ v1 := v - 0.6
+ v2 := v1 * v1
+ v3 := v2 * v1
+ v4 := v2 * v2
+ v5 := v3 * v2
+ return 0.442430344268235 + 0.592178981271708*v - 0.287864782562636*v2 + 0.253214392068985*v3 - 0.272557158129811*v4 + 0.325554383321718*v5
+ } else if v > 0.03 {
+ v1 := v - 0.115
+ v2 := v1 * v1
+ v3 := v2 * v1
+ v4 := v2 * v2
+ v5 := v3 * v2
+ return 0.194915592891669 + 1.55227076330229*v - 3.93691860257828*v2 + 18.0679839248761*v3 - 101.468750302746*v4 + 632.341487393927*v5
+ } else {
+ v1 := v - 0.015
+ v2 := v1 * v1
+ v3 := v2 * v1
+ v4 := v2 * v2
+ v5 := v3 * v2
+ // You can clearly see from the involved constants that the low-end is highly nonlinear.
+ return 0.0519565234928877 + 5.09316778537561*v - 99.0338180489702*v2 + 3484.52322764895*v3 - 150028.083412663*v4 + 7168008.42971613*v5
+ }
+}
+
+// FastLinearRgb is much faster than and almost as accurate as LinearRgb.
+// BUT it is important to NOTE that they only produce good results for valid inputs r,g,b in [0,1].
+func FastLinearRgb(r, g, b float64) Color {
+ return Color{delinearize_fast(r), delinearize_fast(g), delinearize_fast(b)}
+}
+
+// XyzToLinearRgb converts from CIE XYZ-space to Linear RGB space.
+func XyzToLinearRgb(x, y, z float64) (r, g, b float64) {
+ r = 3.2409699419045214*x - 1.5373831775700935*y - 0.49861076029300328*z
+ g = -0.96924363628087983*x + 1.8759675015077207*y + 0.041555057407175613*z
+ b = 0.055630079696993609*x - 0.20397695888897657*y + 1.0569715142428786*z
+ return
+}
+
+func LinearRgbToXyz(r, g, b float64) (x, y, z float64) {
+ x = 0.41239079926595948*r + 0.35758433938387796*g + 0.18048078840183429*b
+ y = 0.21263900587151036*r + 0.71516867876775593*g + 0.072192315360733715*b
+ z = 0.019330818715591851*r + 0.11919477979462599*g + 0.95053215224966058*b
+ return
+}
+
+/// XYZ ///
+///////////
+// http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/
+
+func (col Color) Xyz() (x, y, z float64) {
+ return LinearRgbToXyz(col.LinearRgb())
+}
+
+func Xyz(x, y, z float64) Color {
+ return LinearRgb(XyzToLinearRgb(x, y, z))
+}
+
+/// xyY ///
+///////////
+// http://www.brucelindbloom.com/Eqn_XYZ_to_xyY.html
+
+// Well, the name is bad, since it's xyY but Golang needs me to start with a
+// capital letter to make the method public.
+func XyzToXyy(X, Y, Z float64) (x, y, Yout float64) {
+ return XyzToXyyWhiteRef(X, Y, Z, D65)
+}
+
+func XyzToXyyWhiteRef(X, Y, Z float64, wref [3]float64) (x, y, Yout float64) {
+ Yout = Y
+ N := X + Y + Z
+ if math.Abs(N) < 1e-14 {
+ // When we have black, Bruce Lindbloom recommends to use
+ // the reference white's chromacity for x and y.
+ x = wref[0] / (wref[0] + wref[1] + wref[2])
+ y = wref[1] / (wref[0] + wref[1] + wref[2])
+ } else {
+ x = X / N
+ y = Y / N
+ }
+ return
+}
+
+func XyyToXyz(x, y, Y float64) (X, Yout, Z float64) {
+ Yout = Y
+
+ if -1e-14 < y && y < 1e-14 {
+ X = 0.0
+ Z = 0.0
+ } else {
+ X = Y / y * x
+ Z = Y / y * (1.0 - x - y)
+ }
+
+ return
+}
+
+// Converts the given color to CIE xyY space using D65 as reference white.
+// (Note that the reference white is only used for black input.)
+// x, y and Y are in [0..1]
+func (col Color) Xyy() (x, y, Y float64) {
+ return XyzToXyy(col.Xyz())
+}
+
+// Converts the given color to CIE xyY space, taking into account
+// a given reference white. (i.e. the monitor's white)
+// (Note that the reference white is only used for black input.)
+// x, y and Y are in [0..1]
+func (col Color) XyyWhiteRef(wref [3]float64) (x, y, Y float64) {
+ X, Y2, Z := col.Xyz()
+ return XyzToXyyWhiteRef(X, Y2, Z, wref)
+}
+
+// Generates a color by using data given in CIE xyY space.
+// x, y and Y are in [0..1]
+func Xyy(x, y, Y float64) Color {
+ return Xyz(XyyToXyz(x, y, Y))
+}
+
+/// L*a*b* ///
+//////////////
+// http://en.wikipedia.org/wiki/Lab_color_space#CIELAB-CIEXYZ_conversions
+// For L*a*b*, we need to L*a*b*<->XYZ->RGB and the first one is device dependent.
+
+func lab_f(t float64) float64 {
+ if t > 6.0/29.0*6.0/29.0*6.0/29.0 {
+ return math.Cbrt(t)
+ }
+ return t/3.0*29.0/6.0*29.0/6.0 + 4.0/29.0
+}
+
+func XyzToLab(x, y, z float64) (l, a, b float64) {
+ // Use D65 white as reference point by default.
+ // http://www.fredmiranda.com/forum/topic/1035332
+ // http://en.wikipedia.org/wiki/Standard_illuminant
+ return XyzToLabWhiteRef(x, y, z, D65)
+}
+
+func XyzToLabWhiteRef(x, y, z float64, wref [3]float64) (l, a, b float64) {
+ fy := lab_f(y / wref[1])
+ l = 1.16*fy - 0.16
+ a = 5.0 * (lab_f(x/wref[0]) - fy)
+ b = 2.0 * (fy - lab_f(z/wref[2]))
+ return
+}
+
+func lab_finv(t float64) float64 {
+ if t > 6.0/29.0 {
+ return t * t * t
+ }
+ return 3.0 * 6.0 / 29.0 * 6.0 / 29.0 * (t - 4.0/29.0)
+}
+
+func LabToXyz(l, a, b float64) (x, y, z float64) {
+ // D65 white (see above).
+ return LabToXyzWhiteRef(l, a, b, D65)
+}
+
+func LabToXyzWhiteRef(l, a, b float64, wref [3]float64) (x, y, z float64) {
+ l2 := (l + 0.16) / 1.16
+ x = wref[0] * lab_finv(l2+a/5.0)
+ y = wref[1] * lab_finv(l2)
+ z = wref[2] * lab_finv(l2-b/2.0)
+ return
+}
+
+// Converts the given color to CIE L*a*b* space using D65 as reference white.
+func (col Color) Lab() (l, a, b float64) {
+ return XyzToLab(col.Xyz())
+}
+
+// Converts the given color to CIE L*a*b* space, taking into account
+// a given reference white. (i.e. the monitor's white)
+func (col Color) LabWhiteRef(wref [3]float64) (l, a, b float64) {
+ x, y, z := col.Xyz()
+ return XyzToLabWhiteRef(x, y, z, wref)
+}
+
+// Generates a color by using data given in CIE L*a*b* space using D65 as reference white.
+// WARNING: many combinations of `l`, `a`, and `b` values do not have corresponding
+// valid RGB values, check the FAQ in the README if you're unsure.
+func Lab(l, a, b float64) Color {
+ return Xyz(LabToXyz(l, a, b))
+}
+
+// Generates a color by using data given in CIE L*a*b* space, taking
+// into account a given reference white. (i.e. the monitor's white)
+func LabWhiteRef(l, a, b float64, wref [3]float64) Color {
+ return Xyz(LabToXyzWhiteRef(l, a, b, wref))
+}
+
+// DistanceLab is a good measure of visual similarity between two colors!
+// A result of 0 would mean identical colors, while a result of 1 or higher
+// means the colors differ a lot.
+func (c1 Color) DistanceLab(c2 Color) float64 {
+ l1, a1, b1 := c1.Lab()
+ l2, a2, b2 := c2.Lab()
+ return math.Sqrt(sq(l1-l2) + sq(a1-a2) + sq(b1-b2))
+}
+
+// DistanceCIE76 is the same as DistanceLab.
+func (c1 Color) DistanceCIE76(c2 Color) float64 {
+ return c1.DistanceLab(c2)
+}
+
+// Uses the CIE94 formula to calculate color distance. More accurate than
+// DistanceLab, but also more work.
+func (cl Color) DistanceCIE94(cr Color) float64 {
+ l1, a1, b1 := cl.Lab()
+ l2, a2, b2 := cr.Lab()
+
+ // NOTE: Since all those formulas expect L,a,b values 100x larger than we
+ // have them in this library, we either need to adjust all constants
+ // in the formula, or convert the ranges of L,a,b before, and then
+ // scale the distances down again. The latter is less error-prone.
+ l1, a1, b1 = l1*100.0, a1*100.0, b1*100.0
+ l2, a2, b2 = l2*100.0, a2*100.0, b2*100.0
+
+ kl := 1.0 // 2.0 for textiles
+ kc := 1.0
+ kh := 1.0
+ k1 := 0.045 // 0.048 for textiles
+ k2 := 0.015 // 0.014 for textiles.
+
+ deltaL := l1 - l2
+ c1 := math.Sqrt(sq(a1) + sq(b1))
+ c2 := math.Sqrt(sq(a2) + sq(b2))
+ deltaCab := c1 - c2
+
+ // Not taking Sqrt here for stability, and it's unnecessary.
+ deltaHab2 := sq(a1-a2) + sq(b1-b2) - sq(deltaCab)
+ sl := 1.0
+ sc := 1.0 + k1*c1
+ sh := 1.0 + k2*c1
+
+ vL2 := sq(deltaL / (kl * sl))
+ vC2 := sq(deltaCab / (kc * sc))
+ vH2 := deltaHab2 / sq(kh*sh)
+
+ return math.Sqrt(vL2+vC2+vH2) * 0.01 // See above.
+}
+
+// DistanceCIEDE2000 uses the Delta E 2000 formula to calculate color
+// distance. It is more expensive but more accurate than both DistanceLab
+// and DistanceCIE94.
+func (cl Color) DistanceCIEDE2000(cr Color) float64 {
+ return cl.DistanceCIEDE2000klch(cr, 1.0, 1.0, 1.0)
+}
+
+// DistanceCIEDE2000klch uses the Delta E 2000 formula with custom values
+// for the weighting factors kL, kC, and kH.
+func (cl Color) DistanceCIEDE2000klch(cr Color, kl, kc, kh float64) float64 {
+ l1, a1, b1 := cl.Lab()
+ l2, a2, b2 := cr.Lab()
+
+ // As with CIE94, we scale up the ranges of L,a,b beforehand and scale
+ // them down again afterwards.
+ l1, a1, b1 = l1*100.0, a1*100.0, b1*100.0
+ l2, a2, b2 = l2*100.0, a2*100.0, b2*100.0
+
+ cab1 := math.Sqrt(sq(a1) + sq(b1))
+ cab2 := math.Sqrt(sq(a2) + sq(b2))
+ cabmean := (cab1 + cab2) / 2
+
+ g := 0.5 * (1 - math.Sqrt(math.Pow(cabmean, 7)/(math.Pow(cabmean, 7)+math.Pow(25, 7))))
+ ap1 := (1 + g) * a1
+ ap2 := (1 + g) * a2
+ cp1 := math.Sqrt(sq(ap1) + sq(b1))
+ cp2 := math.Sqrt(sq(ap2) + sq(b2))
+
+ hp1 := 0.0
+ if b1 != ap1 || ap1 != 0 {
+ hp1 = math.Atan2(b1, ap1)
+ if hp1 < 0 {
+ hp1 += math.Pi * 2
+ }
+ hp1 *= 180 / math.Pi
+ }
+ hp2 := 0.0
+ if b2 != ap2 || ap2 != 0 {
+ hp2 = math.Atan2(b2, ap2)
+ if hp2 < 0 {
+ hp2 += math.Pi * 2
+ }
+ hp2 *= 180 / math.Pi
+ }
+
+ deltaLp := l2 - l1
+ deltaCp := cp2 - cp1
+ dhp := 0.0
+ cpProduct := cp1 * cp2
+ if cpProduct != 0 {
+ dhp = hp2 - hp1
+ if dhp > 180 {
+ dhp -= 360
+ } else if dhp < -180 {
+ dhp += 360
+ }
+ }
+ deltaHp := 2 * math.Sqrt(cpProduct) * math.Sin(dhp/2*math.Pi/180)
+
+ lpmean := (l1 + l2) / 2
+ cpmean := (cp1 + cp2) / 2
+ hpmean := hp1 + hp2
+ if cpProduct != 0 {
+ hpmean /= 2
+ if math.Abs(hp1-hp2) > 180 {
+ if hp1+hp2 < 360 {
+ hpmean += 180
+ } else {
+ hpmean -= 180
+ }
+ }
+ }
+
+ t := 1 - 0.17*math.Cos((hpmean-30)*math.Pi/180) + 0.24*math.Cos(2*hpmean*math.Pi/180) + 0.32*math.Cos((3*hpmean+6)*math.Pi/180) - 0.2*math.Cos((4*hpmean-63)*math.Pi/180)
+ deltaTheta := 30 * math.Exp(-sq((hpmean-275)/25))
+ rc := 2 * math.Sqrt(math.Pow(cpmean, 7)/(math.Pow(cpmean, 7)+math.Pow(25, 7)))
+ sl := 1 + (0.015*sq(lpmean-50))/math.Sqrt(20+sq(lpmean-50))
+ sc := 1 + 0.045*cpmean
+ sh := 1 + 0.015*cpmean*t
+ rt := -math.Sin(2*deltaTheta*math.Pi/180) * rc
+
+ return math.Sqrt(sq(deltaLp/(kl*sl))+sq(deltaCp/(kc*sc))+sq(deltaHp/(kh*sh))+rt*(deltaCp/(kc*sc))*(deltaHp/(kh*sh))) * 0.01
+}
+
+// BlendLab blends two colors in the L*a*b* color-space, which should result in a smoother blend.
+// t == 0 results in c1, t == 1 results in c2
+func (c1 Color) BlendLab(c2 Color, t float64) Color {
+ l1, a1, b1 := c1.Lab()
+ l2, a2, b2 := c2.Lab()
+ return Lab(l1+t*(l2-l1),
+ a1+t*(a2-a1),
+ b1+t*(b2-b1))
+}
+
+/// L*u*v* ///
+//////////////
+// http://en.wikipedia.org/wiki/CIELUV#XYZ_.E2.86.92_CIELUV_and_CIELUV_.E2.86.92_XYZ_conversions
+// For L*u*v*, we need to L*u*v*<->XYZ<->RGB and the first one is device dependent.
+
+func XyzToLuv(x, y, z float64) (l, a, b float64) {
+ // Use D65 white as reference point by default.
+ // http://www.fredmiranda.com/forum/topic/1035332
+ // http://en.wikipedia.org/wiki/Standard_illuminant
+ return XyzToLuvWhiteRef(x, y, z, D65)
+}
+
+func XyzToLuvWhiteRef(x, y, z float64, wref [3]float64) (l, u, v float64) {
+ if y/wref[1] <= 6.0/29.0*6.0/29.0*6.0/29.0 {
+ l = y / wref[1] * (29.0 / 3.0 * 29.0 / 3.0 * 29.0 / 3.0) / 100.0
+ } else {
+ l = 1.16*math.Cbrt(y/wref[1]) - 0.16
+ }
+ ubis, vbis := xyz_to_uv(x, y, z)
+ un, vn := xyz_to_uv(wref[0], wref[1], wref[2])
+ u = 13.0 * l * (ubis - un)
+ v = 13.0 * l * (vbis - vn)
+ return
+}
+
+// For this part, we do as R's graphics.hcl does, not as wikipedia does.
+// Or is it the same?
+func xyz_to_uv(x, y, z float64) (u, v float64) {
+ denom := x + 15.0*y + 3.0*z
+ if denom == 0.0 {
+ u, v = 0.0, 0.0
+ } else {
+ u = 4.0 * x / denom
+ v = 9.0 * y / denom
+ }
+ return
+}
+
+func LuvToXyz(l, u, v float64) (x, y, z float64) {
+ // D65 white (see above).
+ return LuvToXyzWhiteRef(l, u, v, D65)
+}
+
+func LuvToXyzWhiteRef(l, u, v float64, wref [3]float64) (x, y, z float64) {
+ //y = wref[1] * lab_finv((l + 0.16) / 1.16)
+ if l <= 0.08 {
+ y = wref[1] * l * 100.0 * 3.0 / 29.0 * 3.0 / 29.0 * 3.0 / 29.0
+ } else {
+ y = wref[1] * cub((l+0.16)/1.16)
+ }
+ un, vn := xyz_to_uv(wref[0], wref[1], wref[2])
+ if l != 0.0 {
+ ubis := u/(13.0*l) + un
+ vbis := v/(13.0*l) + vn
+ x = y * 9.0 * ubis / (4.0 * vbis)
+ z = y * (12.0 - 3.0*ubis - 20.0*vbis) / (4.0 * vbis)
+ } else {
+ x, y = 0.0, 0.0
+ }
+ return
+}
+
+// Converts the given color to CIE L*u*v* space using D65 as reference white.
+// L* is in [0..1] and both u* and v* are in about [-1..1]
+func (col Color) Luv() (l, u, v float64) {
+ return XyzToLuv(col.Xyz())
+}
+
+// Converts the given color to CIE L*u*v* space, taking into account
+// a given reference white. (i.e. the monitor's white)
+// L* is in [0..1] and both u* and v* are in about [-1..1]
+func (col Color) LuvWhiteRef(wref [3]float64) (l, u, v float64) {
+ x, y, z := col.Xyz()
+ return XyzToLuvWhiteRef(x, y, z, wref)
+}
+
+// Generates a color by using data given in CIE L*u*v* space using D65 as reference white.
+// L* is in [0..1] and both u* and v* are in about [-1..1]
+// WARNING: many combinations of `l`, `u`, and `v` values do not have corresponding
+// valid RGB values, check the FAQ in the README if you're unsure.
+func Luv(l, u, v float64) Color {
+ return Xyz(LuvToXyz(l, u, v))
+}
+
+// Generates a color by using data given in CIE L*u*v* space, taking
+// into account a given reference white. (i.e. the monitor's white)
+// L* is in [0..1] and both u* and v* are in about [-1..1]
+func LuvWhiteRef(l, u, v float64, wref [3]float64) Color {
+ return Xyz(LuvToXyzWhiteRef(l, u, v, wref))
+}
+
+// DistanceLuv is a good measure of visual similarity between two colors!
+// A result of 0 would mean identical colors, while a result of 1 or higher
+// means the colors differ a lot.
+func (c1 Color) DistanceLuv(c2 Color) float64 {
+ l1, u1, v1 := c1.Luv()
+ l2, u2, v2 := c2.Luv()
+ return math.Sqrt(sq(l1-l2) + sq(u1-u2) + sq(v1-v2))
+}
+
+// BlendLuv blends two colors in the CIE-L*u*v* color-space, which should result in a smoother blend.
+// t == 0 results in c1, t == 1 results in c2
+func (c1 Color) BlendLuv(c2 Color, t float64) Color {
+ l1, u1, v1 := c1.Luv()
+ l2, u2, v2 := c2.Luv()
+ return Luv(l1+t*(l2-l1),
+ u1+t*(u2-u1),
+ v1+t*(v2-v1))
+}
+
+/// HCL ///
+///////////
+// HCL is nothing else than L*a*b* in cylindrical coordinates!
+// (this was wrong on English wikipedia, I fixed it, let's hope the fix stays.)
+// But it is widely popular since it is a "correct HSV"
+// http://www.hunterlab.com/appnotes/an09_96a.pdf
+
+// Converts the given color to HCL space using D65 as reference white.
+// H values are in [0..360], C and L values are in [0..1] although C can overshoot 1.0
+func (col Color) Hcl() (h, c, l float64) {
+ return col.HclWhiteRef(D65)
+}
+
+func LabToHcl(L, a, b float64) (h, c, l float64) {
+ // Oops, floating point workaround necessary if a ~= b and both are very small (i.e. almost zero).
+ if math.Abs(b-a) > 1e-4 && math.Abs(a) > 1e-4 {
+ h = math.Mod(57.29577951308232087721*math.Atan2(b, a)+360.0, 360.0) // Rad2Deg
+ } else {
+ h = 0.0
+ }
+ c = math.Sqrt(sq(a) + sq(b))
+ l = L
+ return
+}
+
+// Converts the given color to HCL space, taking into account
+// a given reference white. (i.e. the monitor's white)
+// H values are in [0..360], C and L values are in [0..1]
+func (col Color) HclWhiteRef(wref [3]float64) (h, c, l float64) {
+ L, a, b := col.LabWhiteRef(wref)
+ return LabToHcl(L, a, b)
+}
+
+// Generates a color by using data given in HCL space using D65 as reference white.
+// H values are in [0..360], C and L values are in [0..1]
+// WARNING: many combinations of `h`, `c`, and `l` values do not have corresponding
+// valid RGB values, check the FAQ in the README if you're unsure.
+func Hcl(h, c, l float64) Color {
+ return HclWhiteRef(h, c, l, D65)
+}
+
+func HclToLab(h, c, l float64) (L, a, b float64) {
+ H := 0.01745329251994329576 * h // Deg2Rad
+ a = c * math.Cos(H)
+ b = c * math.Sin(H)
+ L = l
+ return
+}
+
+// Generates a color by using data given in HCL space, taking
+// into account a given reference white. (i.e. the monitor's white)
+// H values are in [0..360], C and L values are in [0..1]
+func HclWhiteRef(h, c, l float64, wref [3]float64) Color {
+ L, a, b := HclToLab(h, c, l)
+ return LabWhiteRef(L, a, b, wref)
+}
+
+// BlendHcl blends two colors in the CIE-L*C*h° color-space, which should result in a smoother blend.
+// t == 0 results in c1, t == 1 results in c2
+func (col1 Color) BlendHcl(col2 Color, t float64) Color {
+ h1, c1, l1 := col1.Hcl()
+ h2, c2, l2 := col2.Hcl()
+
+ // We know that h are both in [0..360]
+ return Hcl(interp_angle(h1, h2, t), c1+t*(c2-c1), l1+t*(l2-l1)).Clamped()
+}
+
+// LuvLch
+
+// Converts the given color to LuvLCh space using D65 as reference white.
+// h values are in [0..360], C and L values are in [0..1] although C can overshoot 1.0
+func (col Color) LuvLCh() (l, c, h float64) {
+ return col.LuvLChWhiteRef(D65)
+}
+
+func LuvToLuvLCh(L, u, v float64) (l, c, h float64) {
+ // Oops, floating point workaround necessary if u ~= v and both are very small (i.e. almost zero).
+ if math.Abs(v-u) > 1e-4 && math.Abs(u) > 1e-4 {
+ h = math.Mod(57.29577951308232087721*math.Atan2(v, u)+360.0, 360.0) // Rad2Deg
+ } else {
+ h = 0.0
+ }
+ l = L
+ c = math.Sqrt(sq(u) + sq(v))
+ return
+}
+
+// Converts the given color to LuvLCh space, taking into account
+// a given reference white. (i.e. the monitor's white)
+// h values are in [0..360], c and l values are in [0..1]
+func (col Color) LuvLChWhiteRef(wref [3]float64) (l, c, h float64) {
+ return LuvToLuvLCh(col.LuvWhiteRef(wref))
+}
+
+// Generates a color by using data given in LuvLCh space using D65 as reference white.
+// h values are in [0..360], C and L values are in [0..1]
+// WARNING: many combinations of `l`, `c`, and `h` values do not have corresponding
+// valid RGB values, check the FAQ in the README if you're unsure.
+func LuvLCh(l, c, h float64) Color {
+ return LuvLChWhiteRef(l, c, h, D65)
+}
+
+func LuvLChToLuv(l, c, h float64) (L, u, v float64) {
+ H := 0.01745329251994329576 * h // Deg2Rad
+ u = c * math.Cos(H)
+ v = c * math.Sin(H)
+ L = l
+ return
+}
+
+// Generates a color by using data given in LuvLCh space, taking
+// into account a given reference white. (i.e. the monitor's white)
+// h values are in [0..360], C and L values are in [0..1]
+func LuvLChWhiteRef(l, c, h float64, wref [3]float64) Color {
+ L, u, v := LuvLChToLuv(l, c, h)
+ return LuvWhiteRef(L, u, v, wref)
+}
+
+// BlendLuvLCh blends two colors in the cylindrical CIELUV color space.
+// t == 0 results in c1, t == 1 results in c2
+func (col1 Color) BlendLuvLCh(col2 Color, t float64) Color {
+ l1, c1, h1 := col1.LuvLCh()
+ l2, c2, h2 := col2.LuvLCh()
+
+ // We know that h are both in [0..360]
+ return LuvLCh(l1+t*(l2-l1), c1+t*(c2-c1), interp_angle(h1, h2, t))
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go
new file mode 100644
index 00000000..bb66dfa4
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go
@@ -0,0 +1,25 @@
+package colorful
+
+import (
+ "math/rand"
+)
+
+// Uses the HSV color space to generate colors with similar S,V but distributed
+// evenly along their Hue. This is fast but not always pretty.
+// If you've got time to spare, use Lab (the non-fast below).
+func FastHappyPalette(colorsCount int) (colors []Color) {
+ colors = make([]Color, colorsCount)
+
+ for i := 0; i < colorsCount; i++ {
+ colors[i] = Hsv(float64(i)*(360.0/float64(colorsCount)), 0.8+rand.Float64()*0.2, 0.65+rand.Float64()*0.2)
+ }
+ return
+}
+
+func HappyPalette(colorsCount int) ([]Color, error) {
+ pimpy := func(l, a, b float64) bool {
+ _, c, _ := LabToHcl(l, a, b)
+ return 0.3 <= c && 0.4 <= l && l <= 0.8
+ }
+ return SoftPaletteEx(colorsCount, SoftPaletteSettings{pimpy, 50, true})
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go b/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go
new file mode 100644
index 00000000..76f31d8f
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go
@@ -0,0 +1,67 @@
+package colorful
+
+import (
+ "database/sql/driver"
+ "encoding/json"
+ "fmt"
+ "reflect"
+)
+
+// A HexColor is a Color stored as a hex string "#rrggbb". It implements the
+// database/sql.Scanner, database/sql/driver.Value,
+// encoding/json.Unmarshaler and encoding/json.Marshaler interfaces.
+type HexColor Color
+
+type errUnsupportedType struct {
+ got interface{}
+ want reflect.Type
+}
+
+func (hc *HexColor) Scan(value interface{}) error {
+ s, ok := value.(string)
+ if !ok {
+ return errUnsupportedType{got: reflect.TypeOf(value), want: reflect.TypeOf("")}
+ }
+ c, err := Hex(s)
+ if err != nil {
+ return err
+ }
+ *hc = HexColor(c)
+ return nil
+}
+
+func (hc *HexColor) Value() (driver.Value, error) {
+ return Color(*hc).Hex(), nil
+}
+
+func (e errUnsupportedType) Error() string {
+ return fmt.Sprintf("unsupported type: got %v, want a %s", e.got, e.want)
+}
+
+func (hc *HexColor) UnmarshalJSON(data []byte) error {
+ var hexCode string
+ if err := json.Unmarshal(data, &hexCode); err != nil {
+ return err
+ }
+
+ var col, err = Hex(hexCode)
+ if err != nil {
+ return err
+ }
+ *hc = HexColor(col)
+ return nil
+}
+
+func (hc HexColor) MarshalJSON() ([]byte, error) {
+ return json.Marshal(Color(hc).Hex())
+}
+
+// Decode - deserialize function for https://github.com/kelseyhightower/envconfig
+func (hc *HexColor) Decode(hexCode string) error {
+ var col, err = Hex(hexCode)
+ if err != nil {
+ return err
+ }
+ *hc = HexColor(col)
+ return nil
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hsluv-snapshot-rev4.json b/vendor/github.com/lucasb-eyer/go-colorful/hsluv-snapshot-rev4.json
new file mode 100644
index 00000000..16354abf
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/hsluv-snapshot-rev4.json
@@ -0,0 +1 @@
+{"#11ee00":{"lch":[82.5213119008325577,127.202882727266427,127.478988192005161],"luv":[82.5213119008325577,-77.3991947082883627,100.945222931227221],"rgb":[0.0666666666666666657,0.933333333333333348,0],"xyz":[0.308043578886299796,0.612655858810891907,0.102019012460713238],"hpluv":[127.478988192005161,308.195222762673438,82.5213119008325577],"hsluv":[127.478988192005161,100.000000000002416,82.5213119008325577]},"#11ee11":{"lch":[82.5429986110943759,126.352581314528209,127.715012949240403],"luv":[82.5429986110943759,-77.2942129186682,99.9528861720763473],"rgb":[0.0666666666666666657,0.933333333333333348,0.0666666666666666657],"xyz":[0.3090552443859369,0.613060525010746815,0.107347117425468874],"hpluv":[127.715012949240403,306.573296560288782,82.5429986110943759],"hsluv":[127.715012949240403,98.9038130800949205,82.5429986110943759]},"#11ee22":{"lch":[82.5831747617793184,124.791738379333623,128.158354445562821],"luv":[82.5831747617793184,-77.1009570540098,98.1245147202868253],"rgb":[0.0666666666666666657,0.933333333333333348,0.133333333333333331],"xyz":[0.310930602524413957,0.613810668266137616,0.117224003621448067],"hpluv":[128.158354445562821,303.59085997924285,82.5831747617793184],"hsluv":[128.158354445562821,98.9085620232469864,82.5831747617793184]},"#11ee33":{"lch":[82.6492529720821381,122.265269823008623,128.905098358231896],"luv":[82.6492529720821381,-76.7865393115689301,95.1452762119380537],"rgb":[0.0666666666666666657,0.933333333333333348,0.2],"xyz":[0.314018353256871663,0.615045768559120742,0.133486157479059203],"hpluv":[128.905098358231896,298.749143147736106,82.6492529720821381],"hsluv":[128.905098358231896,98.916292078887,82.6492529720821381]},"#11ee44":{"lch":[82.7444986901015511,118.712635154498344,130.021230388522838],"luv":[82.7444986901015511,-76.3407023620842,90.9108734321077],"rgb":[0.0666666666666666657,0.933333333333333348,0.266666666666666663],"xyz":[0.318476348501090578,0.616828966656808308,0.156964932431945842],"hpluv":[130.021230388522838,291.911386756693616,82.7444986901015511],"hsluv":[130.021230388522838,98.9272612770947148,82.7444986901015511]},"#11ee55":{"lch":[82.8716000285422894,114.135934527262179,131.587310643629934],"luv":[82.8716000285422894,-75.758934185545,85.3674144008224],"rgb":[0.0666666666666666657,0.933333333333333348,0.333333333333333315],"xyz":[0.324438762540452563,0.619213932272553058,0.188366979705919757],"hpluv":[131.587310643629934,283.052591495130912,82.8716000285422894],"hsluv":[131.587310643629934,98.941589727101146,82.8716000285422894]},"#11ee66":{"lch":[83.0328193013522622,108.602333046050703,133.707640253052432],"luv":[83.0328193013522622,-75.0419109433949103,78.5059128028513697],"rgb":[0.0666666666666666657,0.933333333333333348,0.4],"xyz":[0.332023758313960748,0.622247930581956377,0.228314624113063719],"hpluv":[133.707640253052432,272.269449526145593,83.0328193013522622],"hsluv":[133.707640253052432,98.9592735060659,83.0328193013522622]},"#11ee77":{"lch":[83.2300736177455747,102.250357200027821,136.520544097163679],"luv":[83.2300736177455747,-74.1950209885278866,70.3579022430685228],"rgb":[0.0666666666666666657,0.933333333333333348,0.466666666666666674],"xyz":[0.341337771334162654,0.625973535790037228,0.277368426019461656],"hpluv":[136.520544097163679,259.803949175129901,83.2300736177455747],"hsluv":[136.520544097163679,98.9801962733070155,83.2300736177455747]},"#11ee88":{"lch":[83.4649827070576151,95.3003261118453651,140.209511574476238],"luv":[83.4649827070576151,-73.2277962837693082,60.990507527375577],"rgb":[0.0666666666666666657,0.933333333333333348,0.533333333333333326],"xyz":[0.352478188436106454,0.63042970263081477,0.336041289423033795],"hpluv":[140.209511574476238,246.084644167270028,83.4649827070576151],"hsluv":[140.209511574476238,99.0041428894333109,83.4649827070576151]},"#11ee99":{"lch":[83.7388997377875626,88.07037792773761,145.011549795441141],"luv":[83.7388997377875626,-72.1532115864445416,50.5005497603372433],"rgb":[0.0666666666666666657,0.933333333333333348,0.6],"xyz":[0.365535152545179209,0.635652488274444,0.404807967064151675],"hpluv":[145.011549795441141,231.793725377578141,83.7388997377875626],"hsluv":[145.011549795441141,99.0308160530368582,83.7388997377875626]},"#11eeaa":{"lch":[84.0529327571252907,80.9984265129003802,151.210882439188083],"luv":[84.0529327571252907,-70.9868724309634729,39.0078074241021824],"rgb":[0.0666666666666666657,0.933333333333333348,0.66666666666666663],"xyz":[0.38059284551043171,0.641675565460545,0.484111816681150331],"hpluv":[151.210882439188083,217.967504021816438,84.0529327571252907],"hsluv":[151.210882439188083,99.0598554997167895,84.0529327571252907]},"#11eebb":{"lch":[84.4079608499599914,74.6634505604909435,159.089705667287262],"luv":[84.4079608499599914,-69.7461428935043273,26.6478216947980826],"rgb":[0.0666666666666666657,0.933333333333333348,0.733333333333333282],"xyz":[0.397730437617768384,0.648530602303479808,0.574369801779792],"hpluv":[159.089705667287262,206.122134265545043,84.4079608499599914],"hsluv":[159.089705667287262,99.0908585861444209,84.4079608499599914]},"#11eecc":{"lch":[84.8046473826435,69.7804076798411,168.790807110150524],"luv":[84.8046473826435,-68.449275126866155,13.5647348138992196],"rgb":[0.0666666666666666657,0.933333333333333348,0.8],"xyz":[0.417022813061490139,0.656247552480968666,0.675976312450062178],"hpluv":[168.790807110150524,198.342538571842852,84.8046473826435],"hsluv":[168.790807110150524,99.123400814408285,84.8046473826435]},"#11eedd":{"lch":[85.2434517572140749,67.1146678094459,180.081412911690762],"luv":[85.2434517572140749,-67.114600056421537,-0.0953647673755886743],"rgb":[0.0666666666666666657,0.933333333333333348,0.866666666666666696],"xyz":[0.438541138612123627,0.664854882701222172,0.789306160350068176],"hpluv":[180.081412911690762,197.173954094180345,85.2434517572140749],"hsluv":[180.081412911690762,99.1570549081779546,85.2434517572140749]},"#11eeee":{"lch":[85.7246405502341275,67.2734484234975,192.17705063006116],"luv":[85.7246405502341275,-65.759826803247222,-14.1902093570146306],"rgb":[0.0666666666666666657,0.933333333333333348,0.933333333333333348],"xyz":[0.462353318878298392,0.674379754807692189,0.914716976418591399],"hpluv":[192.17705063006116,205.138082793863816,85.7246405502341275],"hsluv":[192.17705063006116,99.1914073274009098,85.7246405502341275]},"#11eeff":{"lch":[86.2482985645723517,70.4606934075819282,203.935071880927921],"luv":[86.2482985645723517,-64.401481656171029,-28.585983907627277],"rgb":[0.0666666666666666657,0.933333333333333348,1],"xyz":[0.488524367288129757,0.684848174171624913,1.05255116471037335],"hpluv":[203.935071880927921,224.026806300523,86.2482985645723517],"hsluv":[203.935071880927921,99.9999999999942304,86.2482985645723517]},"#11ff00":{"lch":[87.7931168603164,135.408535196841626,127.513270797457935],"luv":[87.7931168603164,-82.4563732780469,107.407718111808407],"rgb":[0.0666666666666666657,1,0],"xyz":[0.359895951315973628,0.716360603670241,0.119303136603937349],"hpluv":[127.513270797457935,491.310985978769054,87.7931168603164],"hsluv":[127.513270797457935,100.000000000002373,87.7931168603164]},"#11ff11":{"lch":[87.8126571401035108,134.634318462908169,127.715012949240432],"luv":[87.8126571401035108,-82.3604359259359313,106.50426424355777],"rgb":[0.0666666666666666657,1,0.0666666666666666657],"xyz":[0.360907616815610732,0.716765269870095922,0.124631241568692985],"hpluv":[127.715012949240432,489.364334505449051,87.8126571401035108],"hsluv":[127.715012949240432,99.999999999991914,87.8126571401035108]},"#11ff22":{"lch":[87.848860165327963,133.211117719966126,128.093229681784152],"luv":[87.848860165327963,-82.1836510367646,104.838205757586152],"rgb":[0.0666666666666666657,1,0.133333333333333331],"xyz":[0.362782974954087789,0.717515413125486723,0.134508127764672164],"hpluv":[128.093229681784152,485.7796458877379,87.848860165327963],"hsluv":[128.093229681784152,99.9999999999918572,87.848860165327963]},"#11ff33":{"lch":[87.9084130007832698,130.901693692038833,128.728166832562891],"luv":[87.9084130007832698,-81.8955348861488659,102.119414300885666],"rgb":[0.0666666666666666657,1,0.2],"xyz":[0.365870725686545495,0.71875051341846985,0.150770281622283314],"hpluv":[128.728166832562891,479.945632467831388,87.9084130007832698],"hsluv":[128.728166832562891,99.9999999999919567,87.9084130007832698]},"#11ff44":{"lch":[87.9942732352876,127.641489512823171,129.672386074694657],"luv":[87.9942732352876,-81.4859348177847806,98.2465891108891185],"rgb":[0.0666666666666666657,1,0.266666666666666663],"xyz":[0.37032872093076441,0.720533711516157416,0.174249056575169953],"hpluv":[129.672386074694657,471.674193406224788,87.9942732352876],"hsluv":[129.672386074694657,99.9999999999918856,87.9942732352876]},"#11ff55":{"lch":[88.1088871723243727,123.41738800901625,130.987994113812931],"luv":[88.1088871723243727,-80.9495722978130772,93.1612494966077662],"rgb":[0.0666666666666666657,1,0.333333333333333315],"xyz":[0.376291134970126395,0.722918677131902165,0.205651103849143868],"hpluv":[130.987994113812931,460.897243009671797,88.1088871723243727],"hsluv":[130.987994113812931,99.9999999999917,88.1088871723243727]},"#11ff66":{"lch":[88.2543278429396,118.268592142924746,132.753132104158254],"luv":[88.2543278429396,-80.2855559529031382,86.8429006471038],"rgb":[0.0666666666666666657,1,0.4],"xyz":[0.38387613074363458,0.725952675441305484,0.24559874825628783],"hpluv":[132.753132104158254,447.675525940365219,88.2543278429396],"hsluv":[132.753132104158254,99.9999999999916724,88.2543278429396]},"#11ff77":{"lch":[88.4323687925046613,112.290518027227137,135.069051083024959],"luv":[88.4323687925046613,-79.4970211443964558,79.3056370505300521],"rgb":[0.0666666666666666657,1,0.466666666666666674],"xyz":[0.393190143763836486,0.729678280649386335,0.294652550162685767],"hpluv":[135.069051083024959,432.222948715922314,88.4323687925046613],"hsluv":[135.069051083024959,99.999999999991644,88.4323687925046613]},"#11ff88":{"lch":[88.6445280109338825,105.641380676940045,138.068036362648229],"luv":[88.6445280109338825,-78.5907289650887577,70.5946076698930369],"rgb":[0.0666666666666666657,1,0.533333333333333326],"xyz":[0.404330560865780286,0.734134447490163877,0.353325413566257907],"hpluv":[138.068036362648229,414.95023459347243,88.6445280109338825],"hsluv":[138.068036362648229,99.9999999999915,88.6445280109338825]},"#11ff99":{"lch":[88.8920961876840465,98.552301258979881,141.921030988541872],"luv":[88.8920961876840465,-77.5765731609304225,60.7818342932124338],"rgb":[0.0666666666666666657,1,0.6],"xyz":[0.417387524974853,0.73935723313379309,0.422092091207375786],"hpluv":[141.921030988541872,396.537381185702543,88.8920961876840465],"hsluv":[141.921030988541872,99.9999999999913456,88.8920961876840465]},"#11ffaa":{"lch":[89.1761561490339147,91.3418654410923523,146.840553381528281],"luv":[89.1761561490339147,-76.4669946123218,49.9613362233014158],"rgb":[0.0666666666666666657,1,0.66666666666666663],"xyz":[0.432445217940105542,0.745380310319894157,0.501395940824374442],"hpluv":[146.840553381528281,378.048392077141443,89.1761561490339147],"hsluv":[146.840553381528281,99.9999999999913,89.1761561490339147]},"#11ffbb":{"lch":[89.4975971674113,84.4340589142561413,153.067388238784645],"luv":[89.4975971674113,-75.2763296710648859,38.2437510711127],"rgb":[0.0666666666666666657,1,0.733333333333333282],"xyz":[0.449582810047442216,0.752235347162828916,0.591653925923016133],"hpluv":[153.067388238784645,361.099415032935838,89.4975971674113],"hsluv":[153.067388238784645,99.9999999999909335,89.4975971674113]},"#11ffcc":{"lch":[89.8571262823018628,78.3714319324892159,160.817799258328876],"luv":[89.8571262823018628,-74.0201316086282901,25.7507564896672143],"rgb":[0.0666666666666666657,1,0.8],"xyz":[0.468875185491163915,0.759952297340317773,0.693260436593286289],"hpluv":[160.817799258328876,348.067615225706845,89.8571262823018628],"hsluv":[160.817799258328876,99.999999999991,89.8571262823018628]},"#11ffdd":{"lch":[90.2552779380141317,73.7997451229305,170.162013498752287],"luv":[90.2552779380141317,-72.7145076797264238,12.6096293801408788],"rgb":[0.0666666666666666657,1,0.866666666666666696],"xyz":[0.490393511041797514,0.768559627560571279,0.806590284493292287],"hpluv":[170.162013498752287,342.256686666565315,90.2552779380141317],"hsluv":[170.162013498752287,99.999999999990834,90.2552779380141317]},"#11ffee":{"lch":[90.6924227584195819,71.3832589696730793,180.844217403257659],"luv":[90.6924227584195819,-71.3755103944163665,-1.05174952720347981],"rgb":[0.0666666666666666657,1,0.933333333333333348],"xyz":[0.514205691307972224,0.778084499667041296,0.93200110056181551],"hpluv":[180.844217403257659,347.82122947809512,90.6924227584195819],"hsluv":[180.844217403257659,99.9999999999901803,90.6924227584195819]},"#11ffff":{"lch":[91.1687759776689859,71.6302608322469467,192.17705063006116],"luv":[91.1687759776689859,-70.0186129384549361,-15.1092061032524665],"rgb":[0.0666666666666666657,1,1],"xyz":[0.540376739717803645,0.788552919030974,1.06983528885359735],"hpluv":[192.17705063006116,369.258709956275879,91.1687759776689859],"hsluv":[192.17705063006116,99.9999999999898108,91.1687759776689859]},"#00aa00":{"lch":[60.5587499434736287,93.727653253516209,127.71501294924046],"luv":[60.5587499434736287,-57.3364240886418415,74.1445038903004559],"rgb":[0,0.66666666666666663,0],"xyz":[0.143740958848290495,0.287481917696585,0.0479136529494288144],"hpluv":[127.71501294924046,196.394882900214554,60.5587499434736287],"hsluv":[127.71501294924046,100.000000000002359,60.5587499434736287]},"#00aa11":{"lch":[60.5946550577951939,92.4075267438518182,128.220974416403209],"luv":[60.5946550577951939,-57.1721703645967665,72.5981675713458543],"rgb":[0,0.66666666666666663,0.0666666666666666657],"xyz":[0.144752624347927628,0.28788658389643984,0.0532417579141844441],"hpluv":[128.220974416403209,193.513984665985475,60.5946550577951939],"hsluv":[128.220974416403209,99.9999999999907772,60.5946550577951939]},"#00aa22":{"lch":[60.661124672570665,90.0113827545795715,129.185497299711983],"luv":[60.661124672570665,-56.8721735728637725,69.7682226983709199],"rgb":[0,0.66666666666666663,0.133333333333333331],"xyz":[0.146627982486404629,0.288636727151830641,0.0631186441101636436],"hpluv":[129.185497299711983,188.289586599726533,60.661124672570665],"hsluv":[129.185497299711983,99.9999999999908624,60.661124672570665]},"#00aa33":{"lch":[60.7703154938824355,86.2098857925288513,130.852037745481823],"luv":[60.7703154938824355,-56.3905639077229353,65.2092685937350751],"rgb":[0,0.66666666666666663,0.2],"xyz":[0.14971573321886239,0.289871827444813768,0.0793807979677747799],"hpluv":[130.852037745481823,180.013429236819462,60.7703154938824355],"hsluv":[130.852037745481823,99.9999999999908,60.7703154938824355]},"#00aa44":{"lch":[60.9274158721733841,81.0355822964375108,133.441426631804489],"luv":[60.9274158721733841,-55.7210928860807044,58.8381288426430444],"rgb":[0,0.66666666666666663,0.266666666666666663],"xyz":[0.15417372846308125,0.291655025542501334,0.102859572920661418],"hpluv":[133.441426631804489,168.77274926729055,60.9274158721733841],"hsluv":[133.441426631804489,99.9999999999908908,60.9274158721733841]},"#00aa55":{"lch":[61.1365343944832915,74.6960845180523592,137.272019015051796],"luv":[61.1365343944832915,-54.8704978500827636,50.6826746335676717],"rgb":[0,0.66666666666666663,0.333333333333333315],"xyz":[0.160136142502443235,0.294039991158246194,0.134261620194635334],"hpluv":[137.272019015051796,155.037353806827582,61.1365343944832915],"hsluv":[137.272019015051796,99.9999999999910614,61.1365343944832915]},"#00aa66":{"lch":[61.4009335299549264,67.6053275851037512,142.80970662058607],"luv":[61.4009335299549264,-53.8565898531593703,40.8649978254956139],"rgb":[0,0.66666666666666663,0.4],"xyz":[0.16772113827595142,0.297073989467649513,0.174209264601779296],"hpluv":[142.80970662058607,139.715720243970395,61.4009335299549264],"hsluv":[142.80970662058607,99.9999999999911893,61.4009335299549264]},"#00aa77":{"lch":[61.7231520087844814,60.4394033477847188,150.696962972825474],"luv":[61.7231520087844814,-52.7057786154446859,29.5807771631501382],"rgb":[0,0.66666666666666663,0.466666666666666674],"xyz":[0.177035151296153326,0.300799594675730309,0.223263066508177205],"hpluv":[150.696962972825474,124.254291935777843,61.7231520087844814],"hsluv":[150.696962972825474,99.9999999999911893,61.7231520087844814]},"#00aa88":{"lch":[62.1050795642419615,54.2095218153359397,161.640221068188367],"luv":[62.1050795642419615,-51.4501140589855126,17.0750700954568337],"rgb":[0,0.66666666666666663,0.533333333333333326],"xyz":[0.188175568398097182,0.305255761516507906,0.281935929911749372],"hpluv":[161.640221068188367,110.761232665855573,62.1050795642419615],"hsluv":[161.640221068188367,99.9999999999911466,62.1050795642419615]},"#00aa99":{"lch":[62.5480102999456307,50.2545412813378576,175.872445658321794],"luv":[62.5480102999456307,-50.1241952468173793,3.61717711159146882],"rgb":[0,0.66666666666666663,0.6],"xyz":[0.201232532507169881,0.310478547160137064,0.350702607552867307],"hpluv":[175.872445658321794,101.95326553071466,62.5480102999456307],"hsluv":[175.872445658321794,99.9999999999913314,62.5480102999456307]},"#00aaaa":{"lch":[63.0526871437625829,49.8847230087107931,192.17705063006116],"luv":[63.0526871437625829,-48.762339705407328,-10.5223484123201398],"rgb":[0,0.66666666666666663,0.66666666666666663],"xyz":[0.216290225472422437,0.316501624346238186,0.430006457169865852],"hpluv":[192.17705063006116,100.392967527320806,63.0526871437625829],"hsluv":[192.17705063006116,99.9999999999914451,63.0526871437625829]},"#00aabb":{"lch":[63.6193436646561565,53.6276681768737,207.895374658889665],"luv":[63.6193436646561565,-47.3963155750249143,-25.0901587081772526],"rgb":[0,0.66666666666666663,0.733333333333333282],"xyz":[0.233427817579759056,0.323356661189172945,0.520264442268507654],"hpluv":[207.895374658889665,106.964349821245364,63.6193436646561565],"hsluv":[207.895374658889665,99.9999999999916,63.6193436646561565]},"#00aacc":{"lch":[64.2477463386430259,60.9097449106327886,220.878520684721707],"luv":[64.2477463386430259,-46.0537892020538,-39.8628338833449],"rgb":[0,0.66666666666666663,0.8],"xyz":[0.25272019302348081,0.331073611366661746,0.62187095293877781],"hpluv":[220.878520684721707,120.300715116377788,64.2477463386430259],"hsluv":[220.878520684721707,99.9999999999916298,64.2477463386430259]},"#00aadd":{"lch":[64.9372385342214926,70.6418801813473465,230.685034316882962],"luv":[64.9372385342214926,-44.7574928469198525,-54.6538385624811625],"rgb":[0,0.66666666666666663,0.866666666666666696],"xyz":[0.274238518574114354,0.339680941586915253,0.735200800838783808],"hpluv":[230.685034316882962,138.04089297290011,64.9372385342214926],"hsluv":[230.685034316882962,99.9999999999918145,64.9372385342214926]},"#00aaee":{"lch":[65.6867863979168618,81.8478503674051,237.87423205753521],"luv":[65.6867863979168618,-43.5250094774703129,-69.3155405356638283],"rgb":[0,0.66666666666666663,0.933333333333333348],"xyz":[0.298050698840289119,0.34920581369338527,0.860611616907307],"hpluv":[237.87423205753521,158.11336767521891,65.6867863979168618],"hsluv":[237.87423205753521,99.999999999991843,65.6867863979168618]},"#00aaff":{"lch":[66.4950261675888,93.8462134827344,243.161780722675303],"luv":[66.4950261675888,-42.369016683119284,-83.7375555551541],"rgb":[0,0.66666666666666663,1],"xyz":[0.324221747250120484,0.359674233057318,0.998445805199088876],"hpluv":[243.161780722675303,179.088178632175044,66.4950261675888],"hsluv":[243.161780722675303,99.9999999999982805,66.4950261675888]},"#00bb00":{"lch":[66.1662429166961772,102.406451239047826,127.71501294924046],"luv":[66.1662429166961772,-62.6455428450044352,81.0099822060849135],"rgb":[0,0.733333333333333282,0],"xyz":[0.177695456756889275,0.355390913513783546,0.0592318189189614333],"hpluv":[127.71501294924046,196.39488290021464,66.1662429166961772],"hsluv":[127.71501294924046,100.000000000002373,66.1662429166961772]},"#00bb11":{"lch":[66.1974173108447559,101.237205455569821,128.123527834983577],"luv":[66.1974173108447559,-62.4996967519340956,79.6414444518024425],"rgb":[0,0.733333333333333282,0.0666666666666666657],"xyz":[0.178707122256526407,0.355795579713638399,0.064559923883717063],"hpluv":[128.123527834983577,194.061073356438868,66.1974173108447559],"hsluv":[128.123527834983577,99.9999999999909335,66.1974173108447559]},"#00bb22":{"lch":[66.2551438620851911,99.1062916374383747,128.898124119483072],"luv":[66.2551438620851911,-62.232564676438038,77.1308299962987718],"rgb":[0,0.733333333333333282,0.133333333333333331],"xyz":[0.180582480395003409,0.3565457229690292,0.0744368100796962556],"hpluv":[128.898124119483072,189.810813804630897,66.2551438620851911],"hsluv":[128.898124119483072,99.9999999999908624,66.2551438620851911]},"#00bb33":{"lch":[66.3500136661217255,95.7008075372637137,130.224174268563928],"luv":[66.3500136661217255,-61.8016571104716235,73.0698278476423155],"rgb":[0,0.733333333333333282,0.2],"xyz":[0.18367023112746117,0.357780823262012326,0.0906989639373074],"hpluv":[130.224174268563928,183.02647365261987,66.3500136661217255],"hsluv":[130.224174268563928,99.9999999999909335,66.3500136661217255]},"#00bb44":{"lch":[66.4865992404304,91.0092453899789859,132.255785626190885],"luv":[66.4865992404304,-61.1983980271068,67.3605138443080875],"rgb":[0,0.733333333333333282,0.266666666666666663],"xyz":[0.18812822637168003,0.359564021359699892,0.114177738890194044],"hpluv":[132.255785626190885,173.696361176634838,66.4865992404304],"hsluv":[132.255785626190885,99.9999999999909619,66.4865992404304]},"#00bb55":{"lch":[66.6685736373934219,85.1496193371524,135.204737263674588],"luv":[66.6685736373934219,-60.4246386982598,59.9943389949978751],"rgb":[0,0.733333333333333282,0.333333333333333315],"xyz":[0.194090640411042015,0.361948986975444753,0.145579786164167946],"hpluv":[135.204737263674588,162.069343805127659,66.6685736373934219],"hsluv":[135.204737263674588,99.9999999999909477,66.6685736373934219]},"#00bb66":{"lch":[66.8989180170192412,78.3861452968700689,139.371990675590268],"luv":[66.8989180170192412,-59.4914065933894,51.0407711152765629],"rgb":[0,0.733333333333333282,0.4],"xyz":[0.2016756361845502,0.364982985284848072,0.185527430571311908],"hpluv":[139.371990675590268,148.682392510907704,66.8989180170192412],"hsluv":[139.371990675590268,99.9999999999911182,66.8989180170192412]},"#00bb77":{"lch":[67.1800303821267448,71.1598447269708316,145.178146497089472],"luv":[67.1800303821267448,-58.4173559625633061,40.6341731047866617],"rgb":[0,0.733333333333333282,0.466666666666666674],"xyz":[0.210989649204752105,0.368708590492928867,0.234581232477709817],"hpluv":[145.178146497089472,134.410786503463328,67.1800303821267448],"hsluv":[145.178146497089472,99.9999999999910898,67.1800303821267448]},"#00bb88":{"lch":[67.5137905946342,64.1363411600919,153.159702568813543],"luv":[67.5137905946342,-57.2268359754185525,28.9578918715820954],"rgb":[0,0.733333333333333282,0.533333333333333326],"xyz":[0.222130066306695961,0.373164757333706465,0.293254095881282],"hpluv":[153.159702568813543,120.545503395456095,67.5137905946342],"hsluv":[153.159702568813543,99.9999999999911608,67.5137905946342]},"#00bb99":{"lch":[67.9016044714860811,58.2533417764790187,163.826150797364875],"luv":[67.9016044714860811,-55.9477282230567141,16.2266304205851419],"rgb":[0,0.733333333333333282,0.6],"xyz":[0.235187030415768661,0.378387542977335622,0.362020773522399919],"hpluv":[163.826150797364875,108.862958898475256,67.9016044714860811],"hsluv":[163.826150797364875,99.9999999999912461,67.9016044714860811]},"#00bbaa":{"lch":[68.3444379186728384,54.6744668749029543,177.202021912208522],"luv":[68.3444379186728384,-54.6092872876890922,2.66890801368250408],"rgb":[0,0.733333333333333282,0.66666666666666663],"xyz":[0.250244723381021217,0.384410620163436745,0.44132462313939852],"hpluv":[177.202021912208522,101.512776720033713,68.3444379186728384],"hsluv":[177.202021912208522,99.9999999999913598,68.3444379186728384]},"#00bbbb":{"lch":[68.8428468315880338,54.4656619866929645,192.177050630061132],"luv":[68.8428468315880338,-53.2402096652165113,-11.4886209116881091],"rgb":[0,0.733333333333333282,0.733333333333333282],"xyz":[0.267382315488357836,0.391265657006371503,0.531582608238040266],"hpluv":[192.177050630061132,100.392967527320806,68.8428468315880338],"hsluv":[192.177050630061132,99.9999999999914451,68.8428468315880338]},"#00bbcc":{"lch":[69.3970058395379397,58.0340346662075675,206.653495587531239],"luv":[69.3970058395379397,-51.8670935918889384,-26.0337047299998297],"rgb":[0,0.733333333333333282,0.8],"xyz":[0.28667469093207959,0.398982607183860305,0.633189118908310422],"hpluv":[206.653495587531239,106.116119046155191,69.3970058395379397],"hsluv":[206.653495587531239,99.9999999999915161,69.3970058395379397]},"#00bbdd":{"lch":[70.0067374807312461,64.9183055759271923,218.91244904401708],"luv":[70.0067374807312461,-50.5133677649133119,-40.7772740125682844],"rgb":[0,0.733333333333333282,0.866666666666666696],"xyz":[0.308193016482713134,0.407589937404113811,0.74651896680831642],"hpluv":[218.91244904401708,117.670246608059514,70.0067374807312461],"hsluv":[218.91244904401708,99.999999999991644,70.0067374807312461]},"#00bbee":{"lch":[70.6715424904064236,74.2108860535778,228.474155043258463],"luv":[70.6715424904064236,-49.1986871961444336,-55.5584807840624819],"rgb":[0,0.733333333333333282,0.933333333333333348],"xyz":[0.332005196748887843,0.417114809510583828,0.871929782876839643],"hpluv":[228.474155043258463,133.248513578578667,70.6715424904064236],"hsluv":[228.474155043258463,99.9999999999918288,70.6715424904064236]},"#00bbff":{"lch":[71.3906313155650167,85.0452269855302,235.688960914523477],"luv":[71.3906313155650167,-47.9387359102869155,-70.246481992653],"rgb":[0,0.733333333333333282,1],"xyz":[0.358176245158719264,0.427583228874516552,1.00976397116862149],"hpluv":[235.688960914523477,151.163886263776277,71.3906313155650167],"hsluv":[235.688960914523477,99.9999999999978,71.3906313155650167]},"#00cc00":{"lch":[71.6795694698327139,110.939506494120423,127.71501294924046],"luv":[71.6795694698327139,-67.8655057683618566,87.7601688009055181],"rgb":[0,0.8,0],"xyz":[0.215919200066506195,0.431838400133018441,0.0719730666888333814],"hpluv":[127.71501294924046,196.394882900214611,71.6795694698327139],"hsluv":[127.71501294924046,100.000000000002359,71.6795694698327139]},"#00cc11":{"lch":[71.7069484470386698,109.895339051400697,128.05073784188761],"luv":[71.7069484470386698,-67.7349868616780668,86.5387606802328548],"rgb":[0,0.8,0.0666666666666666657],"xyz":[0.216930865566143327,0.432243066332873294,0.0773011716535890181],"hpluv":[128.05073784188761,194.472124503698296,71.7069484470386698],"hsluv":[128.05073784188761,99.9999999999908766,71.7069484470386698]},"#00cc22":{"lch":[71.7576566073484,107.986601617430239,128.68476606632143],"luv":[71.7576566073484,-67.4954197535952289,84.2939763041676287],"rgb":[0,0.8,0.133333333333333331],"xyz":[0.218806223704620328,0.432993209588264094,0.0871780578495682107],"hpluv":[128.68476606632143,190.959361108477,71.7576566073484],"hsluv":[128.68476606632143,99.9999999999909193,71.7576566073484]},"#00cc33":{"lch":[71.8410194320707,104.91966800737103,129.762682813168567],"luv":[71.8410194320707,-67.1075822658835364,80.6517770244687853],"rgb":[0,0.8,0.2],"xyz":[0.22189397443707809,0.434228309881247221,0.103440211707179347],"hpluv":[129.762682813168567,185.320621425294917,71.8410194320707],"hsluv":[129.762682813168567,99.9999999999909761,71.8410194320707]},"#00cc44":{"lch":[71.9610975929873717,100.65733905537941,131.396818004218431],"luv":[71.9610975929873717,-66.561699323308261,75.5078809721416491],"rgb":[0,0.8,0.266666666666666663],"xyz":[0.226351969681296949,0.436011507978934787,0.126918986660065986],"hpluv":[131.396818004218431,177.495355343216744,71.9610975929873717],"hsluv":[131.396818004218431,99.9999999999909903,71.9610975929873717]},"#00cc55":{"lch":[72.1211872877728837,95.2615727691762828,133.734892870047815],"luv":[72.1211872877728837,-65.8564749898269639,68.8308938513177],"rgb":[0,0.8,0.333333333333333315],"xyz":[0.232314383720658935,0.438396473594679648,0.158321033934039901],"hpluv":[133.734892870047815,167.607792551030144,72.1211872877728837],"hsluv":[133.734892870047815,99.999999999991033,72.1211872877728837]},"#00cc66":{"lch":[72.3240060759138,88.9026050634798821,136.980115521422647],"luv":[72.3240060759138,-64.9982032665013207,60.6539921126355495],"rgb":[0,0.8,0.4],"xyz":[0.23989937949416712,0.441430471904082966,0.198268678341183863],"hpluv":[136.980115521422647,155.980870440536961,72.3240060759138],"hsluv":[136.980115521422647,99.9999999999910614,72.3240060759138]},"#00cc77":{"lch":[72.5717906268391459,81.8763194870781206,141.413175407098493],"luv":[72.5717906268391459,-63.9997644777707464,51.066249515114805],"rgb":[0,0.8,0.466666666666666674],"xyz":[0.249213392514369025,0.445156077112163762,0.247322480247581772],"hpluv":[141.413175407098493,143.162673336571032,72.5717906268391459],"hsluv":[141.413175407098493,99.9999999999910756,72.5717906268391459]},"#00cc88":{"lch":[72.8663546950801,74.6325704710961162,147.40707881161012],"luv":[72.8663546950801,-62.8793552775828672,40.2020802322297683],"rgb":[0,0.8,0.533333333333333326],"xyz":[0.260353809616312881,0.449612243952941359,0.305995343651153939],"hpluv":[147.40707881161012,129.969270924532168,72.8663546950801],"hsluv":[147.40707881161012,99.9999999999911608,72.8663546950801]},"#00cc99":{"lch":[73.2091273059676695,67.813783770663278,155.40051707617576],"luv":[73.2091273059676695,-61.6589956558222809,28.2290191825639418],"rgb":[0,0.8,0.6],"xyz":[0.273410773725385581,0.454835029596570517,0.374762021292271874],"hpluv":[155.40051707617576,117.541728748843539,73.2091273059676695],"hsluv":[155.40051707617576,99.9999999999911893,73.2091273059676695]},"#00ccaa":{"lch":[73.6011808048110368,62.2803364521242102,165.745935171574274],"luv":[73.6011808048110368,-60.3629393869259374,15.3347923742089414],"rgb":[0,0.8,0.66666666666666663],"xyz":[0.288468466690638137,0.460858106782671639,0.454065870909270419],"hpluv":[165.745935171574274,107.375573062224,73.6011808048110368],"hsluv":[165.745935171574274,99.9999999999912887,73.6011808048110368]},"#00ccbb":{"lch":[74.043253901593,59.041045922693165,178.335616576813749],"luv":[74.043253901593,-59.0161369965186395,1.7148404163965667],"rgb":[0,0.8,0.733333333333333282],"xyz":[0.305606058797974756,0.467713143625606398,0.544323856007912221],"hpluv":[178.335616576813749,101.183074845522739,74.043253901593],"hsluv":[178.335616576813749,99.9999999999913882,74.043253901593]},"#00cccc":{"lch":[74.5357725840108714,58.9696734274942429,192.177050630061132],"luv":[74.5357725840108714,-57.64288292201784,-12.4386668330598962],"rgb":[0,0.8,0.8],"xyz":[0.32489843424169651,0.4754300938030952,0.645930366678182377],"hpluv":[192.177050630061132,100.392967527320835,74.5357725840108714],"hsluv":[192.177050630061132,99.9999999999914877,74.5357725840108714]},"#00ccdd":{"lch":[75.0788705190671,62.3850861111967063,205.58971515357635],"luv":[75.0788705190671,-56.2657375800620656,-26.9456071312750254],"rgb":[0,0.8,0.866666666666666696],"xyz":[0.346416759792330053,0.484037424023348706,0.759260214578188375],"hpluv":[205.58971515357635,105.439266222061761,75.0788705190671],"hsluv":[205.58971515357635,99.9999999999915588,75.0788705190671]},"#00ccee":{"lch":[75.672409810316779,68.9113069897593,217.179575991302841],"luv":[75.672409810316779,-54.9047659259632326,-41.6441461630807765],"rgb":[0,0.8,0.933333333333333348],"xyz":[0.370228940058504818,0.493562296129818723,0.884671030646711598],"hpluv":[217.179575991302841,115.555933163518176,75.672409810316779],"hsluv":[217.179575991302841,99.9999999999916,75.672409810316779]},"#00ccff":{"lch":[76.3160024985922263,77.7871508482342193,226.46755023570978],"luv":[76.3160024985922263,-53.5770891110031471,-56.3944710009551713],"rgb":[0,0.8,1],"xyz":[0.396399988468336184,0.504030715493751447,1.02250521893849333],"hpluv":[226.46755023570978,131.600547876461974,76.3160024985922263],"hsluv":[226.46755023570978,99.9999999999969731,76.3160024985922263]},"#00dd00":{"lch":[77.1074905447145369,119.34037845513086,127.715012949240503],"luv":[77.1074905447145369,-73.004607631587163,94.4057900468603],"rgb":[0,0.866666666666666696,0],"xyz":[0.258553190613681372,0.51710638122737,0.0861843968712247],"hpluv":[127.715012949240503,210.385995725156505,77.1074905447145369],"hsluv":[127.715012949240503,100.000000000002203,77.1074905447145369]},"#00dd11":{"lch":[77.1317715771024268,118.40111864948102,127.995077421524911],"luv":[77.1317715771024268,-72.8869911141770359,93.3076171797906255],"rgb":[0,0.866666666666666696,0.0666666666666666657],"xyz":[0.259564856113318476,0.517511047427224868,0.0915125018359803366],"hpluv":[127.995077421524911,208.997725019578468,77.1317715771024268],"hsluv":[127.995077421524911,99.9999999999909193,77.1317715771024268]},"#00dd22":{"lch":[77.1767486793617081,116.680170458435171,128.522366120948305],"luv":[77.1767486793617081,-72.6707542705971434,91.2864921658838568],"rgb":[0,0.866666666666666696,0.133333333333333331],"xyz":[0.261440214251795533,0.518261190682615669,0.101389388031959529],"hpluv":[128.522366120948305,206.449864525990506,77.1767486793617081],"hsluv":[128.522366120948305,99.9999999999909335,77.1767486793617081]},"#00dd33":{"lch":[77.2507083817471312,113.903613467858165,129.414072915332611],"luv":[77.2507083817471312,-72.3197155087496668,87.9993858488157485],"rgb":[0,0.866666666666666696,0.2],"xyz":[0.264527964984253239,0.519496290975598796,0.117651541889570666],"hpluv":[129.414072915332611,202.327676795977681,77.2507083817471312],"hsluv":[129.414072915332611,99.9999999999909335,77.2507083817471312]},"#00dd44":{"lch":[77.3572825066044,110.019432359123073,130.755032484191332],"luv":[77.3572825066044,-71.8235777962907633,83.3405613681826907],"rgb":[0,0.866666666666666696,0.266666666666666663],"xyz":[0.268985960228472154,0.521279489073286362,0.141130316842457304],"hpluv":[130.755032484191332,196.537344059934071,77.3572825066044],"hsluv":[130.755032484191332,99.9999999999909193,77.3572825066044]},"#00dd55":{"lch":[77.499442461574418,105.05363654061,132.652443872197409],"luv":[77.499442461574418,-71.1790335676869717,77.2645567564888],"rgb":[0,0.866666666666666696,0.333333333333333315],"xyz":[0.274948374267834139,0.523664454689031111,0.172532364116431219],"hpluv":[132.652443872197409,189.094972829508237,77.499442461574418],"hsluv":[132.652443872197409,99.9999999999909477,77.499442461574418]},"#00dd66":{"lch":[77.6796666807438,99.1151742217995,135.249123061333165],"luv":[77.6796666807438,-70.3890792332532413,69.7796194150732276],"rgb":[0,0.866666666666666696,0.4],"xyz":[0.282533370041342324,0.52669845299843443,0.212480008523575181],"hpluv":[135.249123061333165,180.139247328423863,77.6796666807438],"hsluv":[135.249123061333165,99.9999999999909903,77.6796666807438]},"#00dd77":{"lch":[77.9000291762011301,92.4061998396230138,138.73841210181584],"luv":[77.9000291762011301,-69.4623356452591878,60.9416909472136155],"rgb":[0,0.866666666666666696,0.466666666666666674],"xyz":[0.29184738306154423,0.530424058206515281,0.26153381042997309],"hpluv":[138.73841210181584,169.957910917592017,77.9000291762011301],"hsluv":[138.73841210181584,99.9999999999910187,77.9000291762011301]},"#00dd88":{"lch":[78.1622519856154,85.2389230174627386,143.3784757437721],"luv":[78.1622519856154,-68.4122000424903,50.8472701580255091],"rgb":[0,0.866666666666666696,0.533333333333333326],"xyz":[0.30298780016348803,0.534880225047292823,0.320206673833545286],"hpluv":[143.3784757437721,159.033158409305884,78.1622519856154],"hsluv":[143.3784757437721,99.9999999999911608,78.1622519856154]},"#00dd99":{"lch":[78.4677391993035798,78.0607504013048583,149.494791226300919],"luv":[78.4677391993035798,-67.2558167964087801,39.6249398770864545],"rgb":[0,0.866666666666666696,0.6],"xyz":[0.316044764272560785,0.540103010690922,0.388973351474663165],"hpluv":[149.494791226300919,148.113090063328627,78.4677391993035798],"hsluv":[149.494791226300919,99.9999999999911466,78.4677391993035798]},"#00ddaa":{"lch":[78.8176011215583401,71.4835041270533225,157.438879868811341],"luv":[78.8176011215583401,-66.0129273361177,27.4259874352573583],"rgb":[0,0.866666666666666696,0.66666666666666663],"xyz":[0.331102457237813286,0.546126087877023103,0.468277201091661766],"hpluv":[157.438879868811341,138.307036304413771,78.8176011215583401],"hsluv":[157.438879868811341,99.9999999999912319,78.8176011215583401]},"#00ddbb":{"lch":[79.21267314937,66.2909050184163675,167.440816272526462],"luv":[79.21267314937,-64.7046905962200896,14.4148223370296193],"rgb":[0,0.866666666666666696,0.733333333333333282],"xyz":[0.34824004934514996,0.552981124719957862,0.558535186190303512],"hpluv":[167.440816272526462,131.160951364069831,79.21267314937],"hsluv":[167.440816272526462,99.9999999999912319,79.21267314937]},"#00ddcc":{"lch":[79.6535319864315738,63.3571261830985,179.312753048293331],"luv":[79.6535319864315738,-63.3525685364998381,0.759932897798095253],"rgb":[0,0.866666666666666696,0.8],"xyz":[0.367532424788871714,0.560698074897446719,0.660141696860573668],"hpluv":[179.312753048293331,128.577362979680402,79.6535319864315738],"hsluv":[179.312753048293331,99.9999999999913314,79.6535319864315738]},"#00dddd":{"lch":[80.1405107346531338,63.4039144225475795,192.177050630061245],"luv":[80.1405107346531338,-61.9773555359817649,-13.3739958452306631],"rgb":[0,0.866666666666666696,0.866666666666666696],"xyz":[0.389050750339505202,0.569305405117700225,0.773471544760579666],"hpluv":[192.177050630061245,132.399857962191078,80.1405107346531338],"hsluv":[192.177050630061245,99.9999999999915,80.1405107346531338]},"#00ddee":{"lch":[80.6737137665329,66.6843941199945078,204.668960845135786],"luv":[80.6737137665329,-60.59840405426975,-27.8323884211582282],"rgb":[0,0.866666666666666696,0.933333333333333348],"xyz":[0.412862930605679967,0.578830277224170242,0.898882360829102889],"hpluv":[204.668960845135786,143.769811077134563,80.6737137665329],"hsluv":[204.668960845135786,99.9999999999914735,80.6737137665329]},"#00ddff":{"lch":[81.2530318771427,72.8883394631876627,215.643856178856652],"luv":[81.2530318771427,-59.2330695533496296,-42.475328144570291],"rgb":[0,0.866666666666666696,1],"xyz":[0.439033979015511333,0.589298696588103,1.03671654912088473],"hpluv":[215.643856178856652,162.831862460855405,81.2530318771427],"hsluv":[215.643856178856652,99.9999999999960636,81.2530318771427]},"#00ee00":{"lch":[82.4573791946470749,127.620478503329409,127.715012949240503],"luv":[82.4573791946470749,-78.0698291684561241,100.955873068518613],"rgb":[0,0.933333333333333348,0],"xyz":[0.305731966954196188,0.611463933908400925,0.101910655651395884],"hpluv":[127.715012949240503,307.908475174189959,82.4573791946470749],"hsluv":[127.715012949240503,100.000000000002217,82.4573791946470749]},"#00ee11":{"lch":[82.4790940690076582,126.770138643430457,127.951660682688043],"luv":[82.4790940690076582,-77.963182339567652,99.9620440525398],"rgb":[0,0.933333333333333348,0.0666666666666666657],"xyz":[0.306743632453833293,0.611868600108255833,0.107238760616151521],"hpluv":[127.951660682688043,306.293921948395678,82.4790940690076582],"hsluv":[127.951660682688043,99.9999999999909193,82.4790940690076582]},"#00ee22":{"lch":[82.5193223464761729,125.209295581045268,128.396138884075839],"luv":[82.5193223464761729,-77.7668632323815814,98.1309466116455],"rgb":[0,0.933333333333333348,0.133333333333333331],"xyz":[0.308618990592310349,0.612618743363646634,0.117115646812130714],"hpluv":[128.396138884075839,303.325246698320768,82.5193223464761729],"hsluv":[128.396138884075839,99.9999999999907914,82.5193223464761729]},"#00ee33":{"lch":[82.5854861516441616,122.683025615083068,129.144698003447559],"luv":[82.5854861516441616,-77.4474668310457304,95.1473313105795881],"rgb":[0,0.933333333333333348,0.2],"xyz":[0.311706741324768055,0.613853843656629761,0.133377800669741864],"hpluv":[129.144698003447559,298.506449004286878,82.5854861516441616],"hsluv":[129.144698003447559,99.9999999999910187,82.5854861516441616]},"#00ee44":{"lch":[82.680854944152216,119.131104912681948,130.263308305441626],"luv":[82.680854944152216,-76.994580956063885,90.9068460629701889],"rgb":[0,0.933333333333333348,0.266666666666666663],"xyz":[0.31616473656898697,0.615637041754317327,0.156856575622628502],"hpluv":[130.263308305441626,291.702339981024693,82.680854944152216],"hsluv":[130.263308305441626,99.9999999999908624,82.680854944152216]},"#00ee55":{"lch":[82.8081199656530913,114.556122924925475,131.832385242542614],"luv":[82.8081199656530913,-76.4036333062175572,85.3556683366704192],"rgb":[0,0.933333333333333348,0.333333333333333315],"xyz":[0.322127150608348956,0.618022007370062076,0.18825862289660239],"hpluv":[131.832385242542614,282.889526663711365,82.8081199656530913],"hsluv":[131.832385242542614,99.9999999999908908,82.8081199656530913]},"#00ee66":{"lch":[82.9695459516691756,109.025909834785097,133.955863991345211],"luv":[82.9695459516691756,-75.6753248662734137,78.4849936082476347],"rgb":[0,0.933333333333333348,0.4],"xyz":[0.329712146381857141,0.621056005679465395,0.22820626730374638],"hpluv":[133.955863991345211,272.166364406401044,82.9695459516691756],"hsluv":[133.955863991345211,99.9999999999909193,82.9695459516691756]},"#00ee77":{"lch":[83.167051813506589,102.679799146220446,136.771308753659213],"luv":[83.167051813506589,-74.8151450958190338,70.3266323450776127],"rgb":[0,0.933333333333333348,0.466666666666666674],"xyz":[0.339026159402059046,0.624781610887546246,0.277260069210144289],"hpluv":[136.771308753659213,259.776444306911685,83.167051813506589],"hsluv":[136.771308753659213,99.9999999999910898,83.167051813506589]},"#00ee88":{"lch":[83.4022585136551839,95.7389522528198427,140.46074817536558],"luv":[83.4022585136551839,-73.8327925713246742,60.9480575538504],"rgb":[0,0.933333333333333348,0.533333333333333326],"xyz":[0.350166576504002847,0.629237777728323788,0.335932932613716428],"hpluv":[140.46074817536558,246.149488794882956,83.4022585136551839],"hsluv":[140.46074817536558,99.999999999991033,83.4022585136551839]},"#00ee99":{"lch":[83.6765199188301096,88.5221307628359142,145.258543938418427],"luv":[83.6765199188301096,-72.7414610621927,50.4464813176313],"rgb":[0,0.933333333333333348,0.6],"xyz":[0.363223540613075602,0.634460563371953,0.404699610254834363],"hpluv":[145.258543938418427,231.96752956627526,83.6765199188301096],"hsluv":[145.258543938418427,99.9999999999911,83.6765199188301096]},"#00eeaa":{"lch":[83.9909442670452364,81.4671227341597159,151.444498676017645],"luv":[83.9909442670452364,-71.557012704351564,38.9420854527837363],"rgb":[0,0.933333333333333348,0.66666666666666663],"xyz":[0.378281233578328102,0.640483640558054068,0.484003459871832964],"hpluv":[151.444498676017645,218.263507316576721,83.9909442670452364],"hsluv":[151.444498676017645,99.9999999999911893,83.9909442670452364]},"#00eebb":{"lch":[84.3464103530465366,75.1511025294100392,159.294479220170871],"luv":[84.3464103530465366,-70.2970903476626319,26.5707978811035801],"rgb":[0,0.933333333333333348,0.733333333333333282],"xyz":[0.395418825685664777,0.647338677400988827,0.57426144497047471],"hpluv":[159.294479220170871,206.543608310772072,84.3464103530465366],"hsluv":[159.294479220170871,99.9999999999912,84.3464103530465366]},"#00eecc":{"lch":[84.743580800257746,70.2844566194431195,168.945018717488722],"luv":[84.743580800257746,-68.9802322625990456,13.4771064879770393],"rgb":[0,0.933333333333333348,0.8],"xyz":[0.414711201129386531,0.655055627578477684,0.675867955640744866],"hpluv":[168.945018717488722,198.871854707918374,84.743580800257746],"hsluv":[168.945018717488722,99.9999999999913,84.743580800257746]},"#00eedd":{"lch":[85.1829138464002114,67.6253239558150625,180.163192871920216],"luv":[85.1829138464002114,-67.6250496492668418,-0.192613766721418916],"rgb":[0,0.933333333333333348,0.866666666666666696],"xyz":[0.43622952668002,0.66366295779873119,0.789197803540750864],"hpluv":[180.163192871920216,197.760624486431198,85.1829138464002114],"hsluv":[180.163192871920216,99.9999999999913882,85.1829138464002114]},"#00eeee":{"lch":[85.6646745174910507,67.7744082531008303,192.177050630061217],"luv":[85.6646745174910507,-66.2495152673009358,-14.2958784586901881],"rgb":[0,0.933333333333333348,0.933333333333333348],"xyz":[0.460041706946194784,0.673187829905201207,0.914608619609274087],"hpluv":[192.177050630061217,205.696714727687493,85.6646745174910507],"hsluv":[192.177050630061217,99.9999999999914309,85.6646745174910507]},"#00eeff":{"lch":[86.1889457184888,70.9350767712842867,203.864647638418489],"luv":[86.1889457184888,-64.8703943995767247,-28.6987290135183635],"rgb":[0,0.933333333333333348,1],"xyz":[0.486212755356026149,0.683656249269133931,1.05244280790105593],"hpluv":[203.864647638418489,224.453619733699583,86.1889457184888],"hsluv":[203.864647638418489,99.9999999999939888,86.1889457184888]},"#00ff00":{"lch":[87.7355191096597338,135.789531996666284,127.715012949240474],"luv":[87.7355191096597338,-83.0671197143942663,107.418111239344327],"rgb":[0,1,0],"xyz":[0.35758433938387,0.71516867876775,0.11919477979462],"hpluv":[127.715012949240474,490.145375063702204,87.7355191096597338],"hsluv":[127.715012949240474,100.000000000002217,87.7355191096597338]},"#00ff11":{"lch":[87.7550810882892165,135.01527678270574,127.917210072153054],"luv":[87.7550810882892165,-82.9698837721702915,106.513489059100834],"rgb":[0,1,0.0666666666666666657],"xyz":[0.358596004883507125,0.715573344967604941,0.124522884759375632],"hpluv":[127.917210072153054,488.208403570135204,87.7550810882892165],"hsluv":[127.917210072153054,99.9999999999917719,87.7550810882892165]},"#00ff22":{"lch":[87.7913242833811864,133.592052176160422,128.296258949772664],"luv":[87.7913242833811864,-82.7907071985999892,104.845291769319132],"rgb":[0,1,0.133333333333333331],"xyz":[0.360471363021984181,0.716323488222995741,0.134399770955354825],"hpluv":[128.296258949772664,484.641757887342919,87.7913242833811864],"hsluv":[128.296258949772664,99.9999999999919,87.7913242833811864]},"#00ff33":{"lch":[87.850943105558116,131.282721750620482,128.932531697131338],"luv":[87.850943105558116,-82.4986966230128616,102.123053644879462],"rgb":[0,1,0.2],"xyz":[0.363559113754441887,0.717558588515978868,0.150661924812965975],"hpluv":[128.932531697131338,478.837727878060548,87.850943105558116],"hsluv":[128.932531697131338,99.999999999991843,87.850943105558116]},"#00ff44":{"lch":[87.9368982766027756,128.022939247233296,129.878593634905172],"luv":[87.9368982766027756,-82.0835673214571528,98.245411848516369],"rgb":[0,1,0.266666666666666663],"xyz":[0.368017108998660802,0.719341786613666434,0.174140699765852613],"hpluv":[129.878593634905172,470.610169071279643,87.9368982766027756],"hsluv":[129.878593634905172,99.9999999999916724,87.9368982766027756]},"#00ff55":{"lch":[88.0516385770734189,123.799916713223595,131.196479790431113],"luv":[88.0516385770734189,-81.5399771501718362,93.1539129857171133],"rgb":[0,1,0.333333333333333315],"xyz":[0.373979523038022788,0.721726752229411184,0.205542747039826501],"hpluv":[131.196479790431113,459.892953467552729,88.0516385770734189],"hsluv":[131.196479790431113,99.9999999999917719,88.0516385770734189]},"#00ff66":{"lch":[88.197238997611,118.653311588493224,132.964137709394919],"luv":[88.197238997611,-80.8670327043222557,86.8281715373192498],"rgb":[0,1,0.4],"xyz":[0.381564518811531,0.724760750538814502,0.245490391446970491],"hpluv":[132.964137709394919,446.748834194207859,88.197238997611],"hsluv":[132.964137709394919,99.9999999999917719,88.197238997611]},"#00ff77":{"lch":[88.3754745956423164,112.679107800887323,135.2824164931273],"luv":[88.3754745956423164,-80.0679233099649537,79.2824633297525452],"rgb":[0,1,0.466666666666666674],"xyz":[0.390878531831732878,0.728486355746895353,0.2945441933533684],"hpluv":[135.2824164931273,431.3936933951166,88.3754745956423164],"hsluv":[135.2824164931273,99.9999999999915445,88.3754745956423164]},"#00ff88":{"lch":[88.587864465470858,106.036155512425779,138.2828406903445],"luv":[88.587864465470858,-79.1495135423216425,70.5621767086956311],"rgb":[0,1,0.533333333333333326],"xyz":[0.402018948933676679,0.732942522587672896,0.353217056756940539],"hpluv":[138.2828406903445,414.239888157084465,88.587864465470858],"hsluv":[138.2828406903445,99.9999999999914,88.587864465470858]},"#00ff99":{"lch":[88.8357000190422,98.9561663203651278,142.1349886621461],"luv":[88.8357000190422,-78.1218422027535695,60.739613298668921],"rgb":[0,1,0.6],"xyz":[0.415075913042749378,0.738165308231302109,0.421983734398058474],"hpluv":[142.1349886621461,395.967958147281365,88.8357000190422],"hsluv":[142.1349886621461,99.9999999999915303,88.8357000190422]},"#00ffaa":{"lch":[89.1200644426462674,91.7580340339716258,147.049061977519528],"luv":[89.1200644426462674,-76.997527549554917,49.9090929694682828],"rgb":[0,1,0.66666666666666663],"xyz":[0.430133606008001934,0.744188385417403175,0.501287584015057],"hpluv":[147.049061977519528,377.639750156066668,89.1200644426462674],"hsluv":[147.049061977519528,99.9999999999913,89.1200644426462674]},"#00ffbb":{"lch":[89.4418470234824241,84.8653215767476468,153.262243037154207],"luv":[89.4418470234824241,-75.791105608661141,38.1815546689964407],"rgb":[0,1,0.733333333333333282],"xyz":[0.447271198115338608,0.751043422260337934,0.591545569113698821],"hpluv":[153.262243037154207,360.863433446149145,89.4418470234824241],"hsluv":[153.262243037154207,99.9999999999912,89.4418470234824241]},"#00ffcc":{"lch":[89.801754487955634,78.8187300060100569,160.986090443114392],"luv":[89.801754487955634,-74.5183415032407197,25.6789598575702236],"rgb":[0,1,0.8],"xyz":[0.466563573559060307,0.758760372437826791,0.693152079783969],"hpluv":[160.986090443114392,347.997153451554084,89.801754487955634],"hsluv":[160.986090443114392,99.9999999999912461,89.801754487955634]},"#00ffdd":{"lch":[90.2003206582774339,74.260092310928,170.286849800478649],"luv":[90.2003206582774339,-73.1955569867131572,12.5288366352336915],"rgb":[0,1,0.866666666666666696],"xyz":[0.488081899109693906,0.767367702658080297,0.806481927683975],"hpluv":[170.286849800478649,342.308208972166483,90.2003206582774339],"hsluv":[170.286849800478649,99.9999999999913314,90.2003206582774339]},"#00ffee":{"lch":[90.6379152481429458,71.8480695265374294,180.909719109957],"luv":[90.6379152481429458,-71.8390133400929898,-1.14072652818200426],"rgb":[0,1,0.933333333333333348],"xyz":[0.511894079375868616,0.776892574764550314,0.931892743752498198],"hpluv":[180.909719109957,347.895283980605143,90.6379152481429458],"hsluv":[180.909719109957,99.999999999991374,90.6379152481429458]},"#00ffff":{"lch":[91.114752316705065,72.0862882649682,192.17705063006116],"luv":[91.114752316705065,-70.4643799638718207,-15.205397466925735],"rgb":[0,1,1],"xyz":[0.5380651277857,0.787360994128483,1.06972693204428],"hpluv":[192.17705063006116,369.190533917051368,91.114752316705065],"hsluv":[192.17705063006116,99.9999999999914877,91.114752316705065]},"#ff0000":{"lch":[53.23711559542933,179.038096923620287,12.1770506300617765],"luv":[53.23711559542933,175.009822162883836,37.7650936255616],"rgb":[1,0,0],"xyz":[0.41239079926595,0.21263900587151,0.019330818715591],"hpluv":[12.1770506300617765,426.746789183125202,53.23711559542933],"hsluv":[12.1770506300617765,100.000000000002203,53.23711559542933]},"#ff0011":{"lch":[53.2810087118185294,177.689248384364731,11.7592124156573554],"luv":[53.2810087118185294,173.960033822228979,36.2129206771479346],"rgb":[1,0,0.0666666666666666657],"xyz":[0.413402464765587119,0.213043672071364848,0.0246589236803466325],"hpluv":[11.7592124156573554,423.182830024727082,53.2810087118185294],"hsluv":[11.7592124156573554,99.9999999999986073,53.2810087118185294]},"#ff0022":{"lch":[53.362228057366309,175.255817292919801,10.9800713678561319],"luv":[53.362228057366309,172.047495148921342,33.3805468497921751],"rgb":[1,0,0.133333333333333331],"xyz":[0.415277822904064176,0.213793815326755676,0.0345358098763258251],"hpluv":[10.9800713678561319,416.75211680728853,53.362228057366309],"hsluv":[10.9800713678561319,99.9999999999986215,53.362228057366309]},"#ff0033":{"lch":[53.4955416476677499,171.43316235878109,9.68478250033725],"luv":[53.4955416476677499,168.989928530586468,28.8397852204116347],"rgb":[1,0,0.2],"xyz":[0.418365573636521881,0.215028915619738775,0.0507979637339369683],"hpluv":[9.68478250033725,406.646064741178918,53.4955416476677499],"hsluv":[9.68478250033725,99.9999999999986215,53.4955416476677499]},"#ff0044":{"lch":[53.6871179383659722,166.29954793496961,7.78930386328567259],"luv":[53.6871179383659722,164.765128442936401,22.5386799204815809],"rgb":[1,0,0.266666666666666663],"xyz":[0.422823568880740797,0.216812113717426369,0.0742767386868236],"hpluv":[7.78930386328567259,393.061316669856922,53.6871179383659722],"hsluv":[7.78930386328567259,99.9999999999987637,53.6871179383659722]},"#ff0055":{"lch":[53.9417095924386558,160.100368719231,5.2128969892355661],"luv":[53.9417095924386558,159.438189183864722,14.5461986032050437],"rgb":[1,0,0.333333333333333315],"xyz":[0.428785982920102782,0.219197079333171202,0.105678785960797522],"hpluv":[5.2128969892355661,376.623098544524225,53.9417095924386558],"hsluv":[5.2128969892355661,99.9999999999988,53.9417095924386558]},"#ff0066":{"lch":[54.2629295430466669,153.227313284557312,1.88082466234467849],"luv":[54.2629295430466669,153.144763004983872,5.02902580538230204],"rgb":[1,0,0.4],"xyz":[0.436370978693610967,0.222231077642574493,0.145626430367941484],"hpluv":[1.88082466234467849,358.321012364802243,54.2629295430466669],"hsluv":[1.88082466234467849,99.99999999999892,54.2629295430466669]},"#ff0077":{"lch":[54.6533978532017244,146.184101175375929,357.735148851436577],"luv":[54.6533978532017244,146.06990602550718,-5.77702260269427281],"rgb":[1,0,0.466666666666666674],"xyz":[0.445684991713812872,0.225956682850655316,0.194680232274339393],"hpluv":[357.735148851436577,339.408176675868503,54.6533978532017244],"hsluv":[357.735148851436577,99.9999999999990479,54.6533978532017244]},"#ff0088":{"lch":[55.1148373309560782,139.538803635294983,352.754628092234327],"luv":[55.1148373309560782,138.424605854630585,-17.5984719211521572],"rgb":[1,0,0.533333333333333326],"xyz":[0.456825408815756673,0.230412849691432914,0.253353095677911533],"hpluv":[352.754628092234327,321.26675874055752,55.1148373309560782],"hsluv":[352.754628092234327,99.9999999999991616,55.1148373309560782]},"#ff0099":{"lch":[55.6481496721619493,133.863929319774144,346.981903482220218],"luv":[55.6481496721619493,130.423488026195145,-30.1540269949209758],"rgb":[1,0,0.6],"xyz":[0.469882372924829372,0.235635635335062071,0.322119773319029468],"hpluv":[346.981903482220218,305.247535929832054,55.6481496721619493],"hsluv":[346.981903482220218,99.9999999999993463,55.6481496721619493]},"#ff00aa":{"lch":[56.2534865150640258,129.667114810270476,340.549180922221581],"luv":[56.2534865150640258,122.266710865918853,-43.1788383036143273],"rgb":[1,0,0.66666666666666663],"xyz":[0.484940065890081928,0.241658712521163166,0.401423622936028068],"hpluv":[340.549180922221581,292.495864077812769,56.2534865150640258],"hsluv":[340.549180922221581,99.9999999999994742,56.2534865150640258]},"#ff00bb":{"lch":[56.9303217870161689,127.321325924901956,333.685619315648239],"luv":[56.9303217870161689,114.127678427447606,-56.4410582115202928],"rgb":[1,0,0.733333333333333282],"xyz":[0.502077657997418547,0.248513749364097924,0.491681608034669815],"hpluv":[333.685619315648239,283.789838362024682,56.9303217870161689],"hsluv":[333.685619315648239,99.9999999999995879,56.9303217870161689]},"#ff00cc":{"lch":[57.6775275187384153,127.012826563172382,326.690520651062286],"luv":[57.6775275187384153,106.146716951325558,-69.7505024499586312],"rgb":[1,0,0.8],"xyz":[0.521370033441140301,0.256230699541586726,0.593288118704939915],"hpluv":[326.690520651062286,279.434659423159303,57.6775275187384153],"hsluv":[326.690520651062286,99.9999999999997726,57.6775275187384153]},"#ff00dd":{"lch":[58.4934529509690151,128.727977043064641,319.874434183361473],"luv":[58.4934529509690151,98.4297766537384149,-82.9606602040687],"rgb":[1,0,0.866666666666666696],"xyz":[0.542888358991773901,0.264838029761840288,0.706617966604945913],"hpluv":[319.874434183361473,279.257606739571429,58.4934529509690151],"hsluv":[319.874434183361473,99.9999999999999716,58.4934529509690151]},"#ff00ee":{"lch":[59.3760054748790367,132.286429048213932,313.494468670954461],"luv":[59.3760054748790367,91.0507046157626,-95.9659757377649214],"rgb":[1,0,0.933333333333333348],"xyz":[0.56670053925794861,0.274362901868310305,0.832028782673469136],"hpluv":[313.494468670954461,282.711609251625362,59.3760054748790367],"hsluv":[313.494468670954461,100.000000000000156,59.3760054748790367]},"#ff00ff":{"lch":[60.3227313545512942,137.405400537897037,307.715012949243601],"luv":[60.3227313545512942,84.0556019897527875,-108.696365491768773],"rgb":[1,0,1],"xyz":[0.59287158766778,0.284831321232243,0.969862970965251],"hpluv":[307.715012949243601,289.042783730483336,60.3227313545512942],"hsluv":[307.715012949243601,100.000000000000384,60.3227313545512942]},"#ff1100":{"lch":[53.6695097624616864,176.771562285449363,12.5954542867932275],"luv":[53.6695097624616864,172.517389506501019,38.5478345786208934],"rgb":[1,0.0666666666666666657,0],"xyz":[0.414395199526878422,0.216647806393366865,0.019998952135900451],"hpluv":[12.5954542867932275,417.949777534481484,53.6695097624616864],"hsluv":[12.5954542867932275,100.000000000002245,53.6695097624616864]},"#ff1111":{"lch":[53.7128602445647658,175.445128796306847,12.1770506300617765],"luv":[53.7128602445647658,171.497694164414924,37.0072170615611569],"rgb":[1,0.0666666666666666657,0.0666666666666666657],"xyz":[0.415406865026515526,0.217052472593221718,0.0253270571006560807],"hpluv":[12.1770506300617765,414.478837946685644,53.7128602445647658],"hsluv":[12.1770506300617765,99.9999999999986215,53.7128602445647658]},"#ff1122":{"lch":[53.7930781791116743,173.051572118951754,11.3967197916969329],"luv":[53.7930781791116743,169.639425839354459,34.1952016185739538],"rgb":[1,0.0666666666666666657,0.133333333333333331],"xyz":[0.417282223164992583,0.217802615848612546,0.0352039432966352803],"hpluv":[11.3967197916969329,408.214548988049671,53.7930781791116743],"hsluv":[11.3967197916969329,99.9999999999987,53.7930781791116743]},"#ff1133":{"lch":[53.9247555399676912,169.290109899416,10.0990648343251674],"luv":[53.9247555399676912,166.667136068812482,29.6851320424264138],"rgb":[1,0.0666666666666666657,0.2],"xyz":[0.420369973897450289,0.219037716141595645,0.0514660971542464235],"hpluv":[10.0990648343251674,398.366425235699353,53.9247555399676912],"hsluv":[10.0990648343251674,99.9999999999987,53.9247555399676912]},"#ff1144":{"lch":[54.1139966850166445,164.235972949617775,8.19925898659400154],"luv":[54.1139966850166445,162.55716522781,23.4226993279181244],"rgb":[1,0.0666666666666666657,0.266666666666666663],"xyz":[0.424827969141669204,0.220820914239283239,0.074944872107133062],"hpluv":[8.19925898659400154,385.121711929848118,54.1139966850166445],"hsluv":[8.19925898659400154,99.9999999999988489,54.1139966850166445]},"#ff1155":{"lch":[54.365514290002,158.12888296709221,5.61535385404219856],"luv":[54.365514290002,157.370056367003059,15.4728467796533362],"rgb":[1,0.0666666666666666657,0.333333333333333315],"xyz":[0.430790383181031189,0.223205879855028072,0.106346919381106964],"hpluv":[5.61535385404219856,369.085538340858477,54.365514290002],"hsluv":[5.61535385404219856,99.9999999999988916,54.365514290002]},"#ff1166":{"lch":[54.6829025612910442,151.353597545298243,2.27091305216541839],"luv":[54.6829025612910442,151.234730451097789,5.99731567352495443],"rgb":[1,0.0666666666666666657,0.4],"xyz":[0.438375378954539374,0.226239878164431363,0.146294563788250925],"hpluv":[2.27091305216541839,351.221033033747858,54.6829025612910442],"hsluv":[2.27091305216541839,99.999999999999,54.6829025612910442]},"#ff1177":{"lch":[55.0687823252034292,144.407362773795285,358.105880212246802],"luv":[55.0687823252034292,144.328460520523464,-4.77303960367160496],"rgb":[1,0.0666666666666666657,0.466666666666666674],"xyz":[0.44768939197474128,0.229965483372512186,0.195348365694648834],"hpluv":[358.105880212246802,332.753927221166919,55.0687823252034292],"hsluv":[358.105880212246802,99.9999999999990905,55.0687823252034292]},"#ff1188":{"lch":[55.5248949860500716,137.85386672349216,353.096828842063303],"luv":[55.5248949860500716,136.85452147125136,-16.5689023019976744],"rgb":[1,0.0666666666666666657,0.533333333333333326],"xyz":[0.45882980907668508,0.234421650213289784,0.254021229098221],"hpluv":[353.096828842063303,315.043506786171235,55.5248949860500716],"hsluv":[353.096828842063303,99.9999999999992,55.5248949860500716]},"#ff1199":{"lch":[56.0521767726019249,132.264360312052816,347.28491936957397],"luv":[56.0521767726019249,129.020794472918823,-29.1117777254046715],"rgb":[1,0.0666666666666666657,0.6],"xyz":[0.47188677318575778,0.239644435856918941,0.322787906739338937],"hpluv":[347.28491936957397,299.426117704125659,56.0521767726019249],"hsluv":[347.28491936957397,99.9999999999993605,56.0521767726019249]},"#ff11aa":{"lch":[56.6508275614924912,128.148315107741439,340.802676353967],"luv":[56.6508275614924912,121.022209124101792,-42.1380536294115586],"rgb":[1,0.0666666666666666657,0.66666666666666663],"xyz":[0.486944466151010336,0.245667513043020036,0.402091756356337537],"hpluv":[340.802676353967,287.042344439162662,56.6508275614924912],"hsluv":[340.802676353967,99.9999999999995168,56.6508275614924912]},"#ff11bb":{"lch":[57.3203806938084455,125.882364893771992,333.882217516525884],"luv":[57.3203806938084455,113.02864145467457,-55.4156656746030762],"rgb":[1,0.0666666666666666657,0.733333333333333282],"xyz":[0.504082058258347,0.252522549885954795,0.492349741454979284],"hpluv":[333.882217516525884,278.673167271969135,57.3203806938084455],"hsluv":[333.882217516525884,99.9999999999996163,57.3203806938084455]},"#ff11cc":{"lch":[58.0597760671947754,125.656277294901628,326.828156543045054],"luv":[58.0597760671947754,105.178488239830273,-68.7530772780178694],"rgb":[1,0.0666666666666666657,0.8],"xyz":[0.523374433702068709,0.260239500063443596,0.593956252125249384],"hpluv":[326.828156543045054,274.630115267561905,58.0597760671947754],"hsluv":[326.828156543045054,99.9999999999997868,58.0597760671947754]},"#ff11dd":{"lch":[58.8674364673636177,127.458097444326981,319.957026901825429],"luv":[58.8674364673636177,97.5770916499376568,-82.0016938195011846],"rgb":[1,0.0666666666666666657,0.866666666666666696],"xyz":[0.544892759252702308,0.268846830283697158,0.707286100025255382],"hpluv":[319.957026901825429,274.746161939823423,58.8674364673636177],"hsluv":[319.957026901825429,100.000000000000028,58.8674364673636177]},"#ff11ee":{"lch":[59.7413458233107519,131.106916258937218,313.5305052972667],"luv":[59.7413458233107519,90.2986667085849319,-95.0535337669245877],"rgb":[1,0.0666666666666666657,0.933333333333333348],"xyz":[0.568704939518877,0.278371702390167175,0.832696916093778605],"hpluv":[313.5305052972667,278.477381794919836,59.7413458233107519],"hsluv":[313.5305052972667,100.000000000000199,59.7413458233107519]},"#ff11ff":{"lch":[60.6791274610807534,136.317870534400242,307.715012949243601],"luv":[60.6791274610807534,83.3903225409976,-107.83606045076894],"rgb":[1,0.0666666666666666657,1],"xyz":[0.594875987928708438,0.288840121754099899,0.97053110438556045],"hpluv":[307.715012949243601,285.070838096226908,60.6791274610807534],"hsluv":[307.715012949243601,100.000000000000398,60.6791274610807534]},"#ff2200":{"lch":[54.4571507543770679,172.725520469573979,13.3786813235288875],"luv":[54.4571507543770679,168.038102184023103,39.9662562154253393],"rgb":[1,0.133333333333333331,0],"xyz":[0.418110823261646336,0.224079053862902833,0.0212374933808230602],"hpluv":[13.3786813235288875,402.476865089738737,54.4571507543770679],"hsluv":[13.3786813235288875,100.00000000000216,54.4571507543770679]},"#ff2211":{"lch":[54.4995382972682876,171.437527349711331,12.9593558016228254],"luv":[54.4995382972682876,167.070909686171433,38.446546274251638],"rgb":[1,0.133333333333333331,0.0666666666666666657],"xyz":[0.41912248876128344,0.224483720062757686,0.0265655983455786934],"hpluv":[12.9593558016228254,399.164948195999784,54.4995382972682876],"hsluv":[12.9593558016228254,99.999999999998721,54.4995382972682876]},"#ff2222":{"lch":[54.5779789595956117,169.112342257331477,12.1770506300617924],"luv":[54.5779789595956117,165.307392407273255,35.6714216042562171],"rgb":[1,0.133333333333333331,0.133333333333333331],"xyz":[0.420997846899760497,0.225233863318148514,0.036442484541557886],"hpluv":[12.1770506300617924,393.185217729465933,54.5779789595956117],"hsluv":[12.1770506300617924,99.9999999999987494,54.5779789595956117]},"#ff2233":{"lch":[54.7067518227456,165.455769736233549,10.8753803895539445],"luv":[54.7067518227456,162.484163442906947,31.2171166072114978],"rgb":[1,0.133333333333333331,0.2],"xyz":[0.424085597632218203,0.226468963611131613,0.0527046383991690293],"hpluv":[10.8753803895539445,383.778210348001721,54.7067518227456],"hsluv":[10.8753803895539445,99.9999999999987779,54.7067518227456]},"#ff2244":{"lch":[54.8918465894738148,160.537768894747074,8.96806115251763103],"luv":[54.8918465894738148,158.575257224785304,25.0252480066910863],"rgb":[1,0.133333333333333331,0.266666666666666663],"xyz":[0.428543592876437118,0.228252161708819207,0.0761834133520556678],"hpluv":[8.96806115251763103,371.115171122776133,54.8918465894738148],"hsluv":[8.96806115251763103,99.9999999999988347,54.8918465894738148]},"#ff2255":{"lch":[55.1379036013317432,154.588213330392733,6.3708707633682522],"luv":[55.1379036013317432,153.633547891150499,17.1536778289841081],"rgb":[1,0.133333333333333331,0.333333333333333315],"xyz":[0.434506006915799103,0.23063712732456404,0.107585460626029583],"hpluv":[6.3708707633682522,355.76683037739258,55.1379036013317432],"hsluv":[6.3708707633682522,99.9999999999989342,55.1379036013317432]},"#ff2266":{"lch":[55.4484819892530254,147.979820726080618,3.00414546296194196],"luv":[55.4484819892530254,147.776458796099433,7.75535736170059753],"rgb":[1,0.133333333333333331,0.4],"xyz":[0.442091002689307289,0.23367112563396733,0.147533105033173545],"hpluv":[3.00414546296194196,338.650844053811227,55.4484819892530254],"hsluv":[3.00414546296194196,99.9999999999990763,55.4484819892530254]},"#ff2277":{"lch":[55.8262016697843961,141.198613687408425,358.803757025958646],"luv":[55.8262016697843961,141.167840095073672,-2.94778393674187145],"rgb":[1,0.133333333333333331,0.466666666666666674],"xyz":[0.451405015709509194,0.237396730842048154,0.196586906939571454],"hpluv":[358.803757025958646,320.945787006908631,55.8262016697843961],"hsluv":[358.803757025958646,99.9999999999991616,55.8262016697843961]},"#ff2288":{"lch":[56.2728344602164299,134.800794021339357,353.742009538390391],"luv":[56.2728344602164299,133.997535770156077,-14.694028593592142],"rgb":[1,0.133333333333333331,0.533333333333333326],"xyz":[0.462545432811453,0.241852897682825752,0.255259770343143622],"hpluv":[353.742009538390391,303.971583410200083,56.2728344602164299],"hsluv":[353.742009538390391,99.9999999999992752,56.2728344602164299]},"#ff2299":{"lch":[56.7893750973531866,129.355771045476672,347.857065824102108],"luv":[56.7893750973531866,126.461550291410035,-27.2101415039127161],"rgb":[1,0.133333333333333331,0.6],"xyz":[0.47560239692052575,0.247075683326454909,0.324026447984261501],"hpluv":[347.857065824102108,289.040064659782502,56.7893750973531866],"hsluv":[347.857065824102108,99.9999999999994316,56.7893750973531866]},"#ff22aa":{"lch":[57.3761062638205743,125.376808270539939,341.281866819384959],"luv":[57.3761062638205743,118.745473604842076,-40.2350164715945766],"rgb":[1,0.133333333333333331,0.66666666666666663],"xyz":[0.49066008988577825,0.253098760512556031,0.403330297601260102],"hpluv":[341.281866819384959,277.284417349873706,57.3761062638205743],"hsluv":[341.281866819384959,99.999999999999531,57.3761062638205743]},"#ff22bb":{"lch":[58.0326640845464112,123.247659375493754,334.254064951888324],"luv":[58.0326640845464112,111.01274832153284,-53.5364852379920606],"rgb":[1,0.133333333333333331,0.733333333333333282],"xyz":[0.507797681993114924,0.25995379735549079,0.493588282699901848],"hpluv":[334.254064951888324,269.491764983662165,58.0326640845464112],"hsluv":[334.254064951888324,99.9999999999997726,58.0326640845464112]},"#ff22cc":{"lch":[58.7581065478829316,123.164795236141373,327.088444575119183],"luv":[58.7581065478829316,103.398114188518221,-66.9208246199849128],"rgb":[1,0.133333333333333331,0.8],"xyz":[0.527090057436836679,0.267670747532979592,0.595194793370172],"hpluv":[327.088444575119183,265.985598747154427,58.7581065478829316],"hsluv":[327.088444575119183,99.9999999999998721,58.7581065478829316]},"#ff22dd":{"lch":[59.550985046801415,125.119413407905796,320.113090366201448],"luv":[59.550985046801415,96.0055877759378,-80.2358693312108358],"rgb":[1,0.133333333333333331,0.866666666666666696],"xyz":[0.548608382987470167,0.276278077753233098,0.708524641270178],"hpluv":[320.113090366201448,266.609166102550091,59.550985046801415],"hsluv":[320.113090366201448,100.000000000000028,59.550985046801415]},"#ff22ee":{"lch":[60.4094179672163705,128.929416765847606,313.598505937960113],"luv":[60.4094179672163705,88.9098108664153273,-93.3693742041783281],"rgb":[1,0.133333333333333331,0.933333333333333348],"xyz":[0.572420563253645,0.285802949859703115,0.833935457338701225],"hpluv":[313.598505937960113,270.823716236275,60.4094179672163705],"hsluv":[313.598505937960113,100.000000000000227,60.4094179672163705]},"#ff22ff":{"lch":[61.3311646171935223,134.305840538380238,307.715012949243601],"luv":[61.3311646171935223,82.1594946996257249,-106.244417422389745],"rgb":[1,0.133333333333333331,1],"xyz":[0.598591611663476297,0.296271369223635839,0.97176964563048307],"hpluv":[307.715012949243601,277.877263991976,61.3311646171935223],"hsluv":[307.715012949243601,100.000000000000398,61.3311646171935223]},"#ff3300":{"lch":[55.7168894472394811,166.476173059961667,14.689559134518138],"luv":[55.7168894472394811,161.034729269155179,42.2153072463082495],"rgb":[1,0.2,0],"xyz":[0.424228545350657182,0.236314498040924637,0.0232767340771599419],"hpluv":[14.689559134518138,379.144314271077917,55.7168894472394811],"hsluv":[14.689559134518138,100.000000000002203,55.7168894472394811]},"#ff3311":{"lch":[55.7578022303213,165.243627812887922,14.2690908575150317],"luv":[55.7578022303213,160.145669888681539,40.7286256663500339],"rgb":[1,0.2,0.0666666666666666657],"xyz":[0.425240210850294287,0.236719164240779489,0.0286048390419155751],"hpluv":[14.2690908575150317,376.06108995847427,55.7578022303213],"hsluv":[14.2690908575150317,99.9999999999988,55.7578022303213]},"#ff3322":{"lch":[55.8335204651182835,163.01701714894287,13.4842232594842422],"luv":[55.8335204651182835,158.523316810386802,38.0119179675594552],"rgb":[1,0.2,0.133333333333333331],"xyz":[0.427115568988771344,0.237469307496170318,0.0384817252378947677],"hpluv":[13.4842232594842422,370.490653647292163,55.8335204651182835],"hsluv":[13.4842232594842422,99.9999999999987494,55.8335204651182835]},"#ff3333":{"lch":[55.9578428172660267,159.511521097175432,12.1770506300617853],"luv":[55.9578428172660267,155.922585303490365,33.6462888742638455],"rgb":[1,0.2,0.2],"xyz":[0.430203319721229049,0.238704407789153417,0.0547438790955059179],"hpluv":[12.1770506300617853,361.718248261175631,55.9578428172660267],"hsluv":[12.1770506300617853,99.9999999999988773,55.9578428172660267]},"#ff3344":{"lch":[56.1365811585215368,154.789240798906889,10.2588910791084782],"luv":[56.1365811585215368,152.31463646984821,27.5673826135157078],"rgb":[1,0.2,0.266666666666666663],"xyz":[0.434661314965447965,0.240487605886841,0.0782226540483925564],"hpluv":[10.2588910791084782,349.892100101075414,56.1365811585215368],"hsluv":[10.2588910791084782,99.9999999999989626,56.1365811585215368]},"#ff3355":{"lch":[56.3742616664660403,149.065442517766684,7.64169944339336649],"luv":[56.3742616664660403,147.741595680550319,19.8223878173745902],"rgb":[1,0.2,0.333333333333333315],"xyz":[0.44062372900480995,0.242872571502585843,0.109624701322366458],"hpluv":[7.64169944339336649,335.533149366899124,56.3742616664660403],"hsluv":[7.64169944339336649,99.9999999999990195,56.3742616664660403]},"#ff3366":{"lch":[56.674385203130754,142.694983818340035,4.24028319431916056],"luv":[56.674385203130754,142.304390380845462,10.550776523662277],"rgb":[1,0.2,0.4],"xyz":[0.448208724778318135,0.245906569811989134,0.14957234572951042],"hpluv":[4.24028319431916056,319.492902958598108,56.674385203130754],"hsluv":[4.24028319431916056,99.9999999999991758,56.674385203130754]},"#ff3377":{"lch":[57.0395646827704468,136.14730874514737,359.983392279567909],"luv":[57.0395646827704468,136.147303025702882,-0.0394635770517579934],"rgb":[1,0.2,0.466666666666666674],"xyz":[0.457522737798520041,0.249632175020069957,0.198626147635908329],"hpluv":[359.983392279567909,302.881107814185,57.0395646827704468],"hsluv":[359.983392279567909,99.9999999999992895,57.0395646827704468]},"#ff3388":{"lch":[57.4716120619286954,129.967879448766553,354.83565117969431],"luv":[57.4716120619286954,129.440287861866665,-11.6987848363070146],"rgb":[1,0.2,0.533333333333333326],"xyz":[0.468663154900463841,0.254088341860847555,0.257299011039480496],"hpluv":[354.83565117969431,286.960407533356261,57.4716120619286954],"hsluv":[354.83565117969431,99.9999999999993889,57.4716120619286954]},"#ff3399":{"lch":[57.9716047421228353,124.724336507791776,348.82951213288959],"luv":[57.9716047421228353,122.361442957788952,-24.1627273832372573],"rgb":[1,0.2,0.6],"xyz":[0.481720119009536596,0.259311127504476713,0.326065688680598431],"hpluv":[348.82951213288959,273.007894976207297,57.9716047421228353],"hsluv":[348.82951213288959,99.9999999999995737,57.9716047421228353]},"#ff33aa":{"lch":[58.5399451724763935,120.937271340322638,342.098036856126953],"luv":[58.5399451724763935,115.081956962752116,-37.174813797329108],"rgb":[1,0.2,0.66666666666666663],"xyz":[0.496777811974789096,0.265334204690577835,0.405369538297597032],"hpluv":[342.098036856126953,262.148381504719794,58.5399451724763935],"hsluv":[342.098036856126953,99.9999999999996732,58.5399451724763935]},"#ff33bb":{"lch":[59.1764201449825862,119.003132790944747,334.888094830460091],"luv":[59.1764201449825862,107.755032536641394,-50.5034511403585498],"rgb":[1,0.2,0.733333333333333282],"xyz":[0.513915404082125771,0.272189241533512594,0.495627523396238778],"hpluv":[334.888094830460091,255.181409444549388,59.1764201449825862],"hsluv":[334.888094830460091,99.9999999999998295,59.1764201449825862]},"#ff33cc":{"lch":[59.8802624584280494,119.13012657470172,327.532171012183937],"luv":[59.8802624584280494,100.509254029343069,-63.9521454852723039],"rgb":[1,0.2,0.8],"xyz":[0.533207779525847525,0.279906191711001395,0.597234034066508879],"hpluv":[327.532171012183937,252.451080902073329,59.8802624584280494],"hsluv":[327.532171012183937,100.000000000000043,59.8802624584280494]},"#ff33dd":{"lch":[60.650215463767978,121.314823858854638,320.378757122173454],"luv":[60.650215463767978,93.4460015542912146,-77.3636302238999747],"rgb":[1,0.2,0.866666666666666696],"xyz":[0.554726105076481,0.288513521931254902,0.710563881966514876],"hpluv":[320.378757122173454,253.817084039055629,60.650215463767978],"hsluv":[320.378757122173454,100.000000000000171,60.650215463767978]},"#ff33ee":{"lch":[61.484599762034378,125.372817174433621,313.71398784253438],"luv":[61.484599762034378,86.6400000332951805,-90.6192787462169775],"rgb":[1,0.2,0.933333333333333348],"xyz":[0.578538285342655723,0.298038394037724919,0.8359746980350381],"hpluv":[313.71398784253438,258.747618308410438,61.484599762034378],"hsluv":[313.71398784253438,100.000000000000242,61.484599762034378]},"#ff33ff":{"lch":[62.3813806681475,131.007738376122177,307.715012949243658],"luv":[62.3813806681475,80.141932350642,-103.635409940481253],"rgb":[1,0.2,1],"xyz":[0.604709333752487144,0.308506813401657642,0.97380888632682],"hpluv":[307.715012949243658,266.490230971107223,62.3813806681475],"hsluv":[307.715012949243658,100.000000000000597,62.3813806681475]},"#ff4400":{"lch":[57.461133143380664,158.273971604467,16.6278363926044079],"luv":[57.461133143380664,151.655533944896689,45.2907177172089845],"rgb":[1,0.266666666666666663,0],"xyz":[0.433061115833623222,0.253979639006856939,0.0262209242381485352],"hpluv":[16.6278363926044079,349.522099776260404,57.461133143380664],"hsluv":[16.6278363926044079,100.000000000002203,57.461133143380664]},"#ff4411":{"lch":[57.500127691013958,157.107055615985729,16.2066010587584444],"luv":[57.500127691013958,150.863862649088418,43.84885256105823],"rgb":[1,0.266666666666666663,0.0666666666666666657],"xyz":[0.434072781333260327,0.254384305206711792,0.031549029202904165],"hpluv":[16.2066010587584444,346.709871357654038,57.500127691013958],"hsluv":[16.2066010587584444,99.9999999999990195,57.500127691013958]},"#ff4422":{"lch":[57.5723039440668174,154.996970095022306,15.4196600073807488],"luv":[57.5723039440668174,149.417734299680745,41.2116660108183908],"rgb":[1,0.266666666666666663,0.133333333333333331],"xyz":[0.435948139471737384,0.255134448462102592,0.0414259153988833645],"hpluv":[15.4196600073807488,341.624434338608523,57.5723039440668174],"hsluv":[15.4196600073807488,99.9999999999990195,57.5723039440668174]},"#ff4433":{"lch":[57.6908335218327437,151.669616752661852,14.1071803519879388],"luv":[57.6908335218327437,147.095485225188412,36.9674298845038223],"rgb":[1,0.266666666666666663,0.2],"xyz":[0.439035890204195089,0.256369548755085719,0.0576880692564945077],"hpluv":[14.1071803519879388,333.603886972203838,57.6908335218327437],"hsluv":[14.1071803519879388,99.9999999999991189,57.6908335218327437]},"#ff4444":{"lch":[57.8612930010941682,147.177084719743902,12.177050630061812],"luv":[57.8612930010941682,143.865668066403089,31.0445457111261],"rgb":[1,0.266666666666666663,0.266666666666666663],"xyz":[0.443493885448414,0.258152746852773285,0.0811668442093811393],"hpluv":[12.177050630061812,322.76868159643891,57.8612930010941682],"hsluv":[12.177050630061812,99.9999999999991616,57.8612930010941682]},"#ff4455":{"lch":[58.088054010202,141.716285969530816,9.53556562214303405],"luv":[58.088054010202,139.758186425649882,23.4766913344092778],"rgb":[1,0.266666666666666663,0.333333333333333315],"xyz":[0.449456299487776,0.260537712468518146,0.112568891483355055],"hpluv":[9.53556562214303405,309.579547415252762,58.088054010202],"hsluv":[9.53556562214303405,99.9999999999992184,58.088054010202]},"#ff4466":{"lch":[58.3745334436288772,135.619673907166316,6.08910281061040859],"luv":[58.3745334436288772,134.854526247228307,14.3858507333331573],"rgb":[1,0.266666666666666663,0.4],"xyz":[0.457041295261284175,0.263571710777921464,0.152516535890499016],"hpluv":[6.08910281061040859,294.807548797669426,58.3745334436288772],"hsluv":[6.08910281061040859,99.9999999999992468,58.3745334436288772]},"#ff4477":{"lch":[58.7233249761193292,129.336052383116169,1.75519751784143763],"luv":[58.7233249761193292,129.275370036155351,3.96145782045869943],"rgb":[1,0.266666666666666663,0.466666666666666674],"xyz":[0.466355308281486081,0.26729731598600226,0.201570337796896926],"hpluv":[1.75519751784143763,279.478426792191101,58.7233249761193292],"hsluv":[1.75519751784143763,99.99999999999946,58.7233249761193292]},"#ff4488":{"lch":[59.1362810655005831,123.398173767481396,356.485857706034096],"luv":[59.1362810655005831,123.16614811103635,-7.56367957014252212],"rgb":[1,0.266666666666666663,0.533333333333333326],"xyz":[0.477495725383429881,0.271753482826779857,0.260243201200469065],"hpluv":[356.485857706034096,264.785408966002421,59.1362810655005831],"hsluv":[356.485857706034096,99.9999999999995595,59.1362810655005831]},"#ff4499":{"lch":[59.6145739069951901,118.37348532064955,350.303370213710309],"luv":[59.6145739069951901,116.682328099077466,-19.9378117238896806],"rgb":[1,0.266666666666666663,0.6],"xyz":[0.490552689492502636,0.276976268470409,0.329009878841587],"hpluv":[350.303370213710309,251.965637795338,59.6145739069951901],"hsluv":[350.303370213710309,99.9999999999997158,59.6145739069951901]},"#ff44aa":{"lch":[60.1587486598557177,114.795436800176844,343.339450530546515],"luv":[60.1587486598557177,109.976338996192666,-32.9119609129858475],"rgb":[1,0.266666666666666663,0.66666666666666663],"xyz":[0.505610382457755136,0.282999345656510137,0.408313728458585601],"hpluv":[343.339450530546515,242.139230170638513,60.1587486598557177],"hsluv":[343.339450530546515,99.9999999999997726,60.1587486598557177]},"#ff44bb":{"lch":[60.768775409955694,113.081121999454581,335.854341209703],"luv":[60.768775409955694,103.187483930843442,-46.2567110015126133],"rgb":[1,0.266666666666666663,0.733333333333333282],"xyz":[0.522747974565091811,0.289854382499444896,0.498571713557227347],"hpluv":[335.854341209703,236.128794952899398,60.768775409955694],"hsluv":[335.854341209703,99.9999999999999716,60.768775409955694]},"#ff44cc":{"lch":[61.4441027606342232,113.457557937670586,328.208302422827],"luv":[61.4441027606342232,96.4354118722023088,-59.7731443895883743],"rgb":[1,0.266666666666666663,0.8],"xyz":[0.542040350008813565,0.297571332676933697,0.600178224227497559],"hpluv":[328.208302422827,234.310931883055929,61.4441027606342232],"hsluv":[328.208302422827,100.000000000000128,61.4441027606342232]},"#ff44dd":{"lch":[62.1837139115479403,115.929787300919912,320.782684481283354],"luv":[62.1837139115479403,89.8170022013310358,-73.2981698216444357],"rgb":[1,0.266666666666666663,0.866666666666666696],"xyz":[0.563558675559447,0.306178662897187204,0.713508072127503556],"hpluv":[320.782684481283354,236.568931830040128,62.1837139115479403],"hsluv":[320.782684481283354,100.000000000000384,62.1837139115479403]},"#ff44ee":{"lch":[62.986184892514558,120.309477517885213,313.888915695758442],"luv":[62.986184892514558,83.4060394378513195,-86.7052649261745643],"rgb":[1,0.266666666666666663,0.933333333333333348],"xyz":[0.587370855825621874,0.315703535003657221,0.83891888819602678],"hpluv":[313.888915695758442,242.378371703623515,62.986184892514558],"hsluv":[313.888915695758442,100.000000000000512,62.986184892514558]},"#ff44ff":{"lch":[63.8497439492436,126.288239910703226,307.715012949243771],"luv":[63.8497439492436,77.2548530724802447,-99.9019880507531468],"rgb":[1,0.266666666666666663,1],"xyz":[0.613541904235453184,0.326171954367589945,0.976753076487808514],"hpluv":[307.715012949243771,250.982289693600563,63.8497439492436],"hsluv":[307.715012949243771,100.000000000000711,63.8497439492436]},"#ff5500":{"lch":[59.6718499915998279,148.630700843778015,19.3008598736449528],"luv":[59.6718499915998279,140.27705963161867,49.1266910591374923],"rgb":[1,0.333333333333333315,0],"xyz":[0.444874372547969188,0.277606152435549203,0.030158676476263746],"hpluv":[19.3008598736449528,316.066414507984518,59.6718499915998279],"hsluv":[19.3008598736449528,100.00000000000226,59.6718499915998279]},"#ff5511":{"lch":[59.7086010657385486,147.530698996531413,18.8803784611224046],"luv":[59.7086010657385486,139.59299153240957,47.7399608445355526],"rgb":[1,0.333333333333333315,0.0666666666666666657],"xyz":[0.445886038047606292,0.278010818635404056,0.0354867814410193758],"hpluv":[18.8803784611224046,313.53413530658878,59.7086010657385486],"hsluv":[18.8803784611224046,99.9999999999992184,59.7086010657385486]},"#ff5522":{"lch":[59.7766335415963255,145.539064184811622,18.0939597274483681],"luv":[59.7766335415963255,138.341936048844929,45.2009727113036],"rgb":[1,0.333333333333333315,0.133333333333333331],"xyz":[0.447761396186083349,0.278760961890794856,0.0453636676369985753],"hpluv":[18.0939597274483681,308.949467849715688,59.7766335415963255],"hsluv":[18.0939597274483681,99.9999999999993,59.7766335415963255]},"#ff5533":{"lch":[59.8883826376776085,142.391759670631302,16.7797766500676033],"luv":[59.8883826376776085,136.328925827546385,41.1076295206398825],"rgb":[1,0.333333333333333315,0.2],"xyz":[0.450849146918541055,0.279996062183778,0.0616258214946097185],"hpluv":[16.7797766500676033,301.704368813615531,59.8883826376776085],"hsluv":[16.7797766500676033,99.9999999999992752,59.8883826376776085]},"#ff5544":{"lch":[60.0491441299879654,138.129067713899872,14.841281480974498],"luv":[60.0491441299879654,133.520956258941027,35.3806951204903228],"rgb":[1,0.333333333333333315,0.266666666666666663],"xyz":[0.45530714216275997,0.281779260281465549,0.0851045964474963501],"hpluv":[14.841281480974498,291.888903616465711,60.0491441299879654],"hsluv":[14.841281480974498,99.9999999999994458,60.0491441299879654]},"#ff5555":{"lch":[60.2631003442631936,132.926854505406169,12.1770506300618191],"luv":[60.2631003442631936,129.936061471805857,28.0386978637829927],"rgb":[1,0.333333333333333315,0.333333333333333315],"xyz":[0.461269556202121955,0.28416422589721041,0.116506643721470265],"hpluv":[12.1770506300618191,279.898508055628838,60.2631003442631936],"hsluv":[12.1770506300618191,99.99999999999946,60.2631003442631936]},"#ff5566":{"lch":[60.5335583680784168,127.091978224389294,8.68145952340772098],"luv":[60.5335583680784168,125.635857711143842,19.1833830742614],"rgb":[1,0.333333333333333315,0.4],"xyz":[0.468854551975630141,0.287198224206613728,0.156454288128614227],"hpluv":[8.68145952340772098,266.416588145649541,60.5335583680784168],"hsluv":[8.68145952340772098,99.9999999999995737,60.5335583680784168]},"#ff5577":{"lch":[60.8630749033481351,121.049870295691591,4.25532383082281918],"luv":[60.8630749033481351,120.716171483201308,8.98203991541407],"rgb":[1,0.333333333333333315,0.466666666666666674],"xyz":[0.478168564995832046,0.290923829414694524,0.205508090035012136],"hpluv":[4.25532383082281918,252.376995060411161,60.8630749033481351],"hsluv":[4.25532383082281918,99.9999999999997158,60.8630749033481351]},"#ff5588":{"lch":[61.2535329118914404,115.319895978664789,358.830706871579594],"luv":[61.2535329118914404,115.295882188952703,-2.35328680810625102],"rgb":[1,0.333333333333333315,0.533333333333333326],"xyz":[0.489308982097775846,0.295379996255472121,0.264180953438584276],"hpluv":[358.830706871579594,238.897951612134108,61.2535329118914404],"hsluv":[358.830706871579594,99.9999999999997868,61.2535329118914404]},"#ff5599":{"lch":[61.7061969251912075,110.472562823261683,352.412124726619879],"luv":[61.7061969251912075,109.505210454219565,-14.5875296097928366],"rgb":[1,0.333333333333333315,0.6],"xyz":[0.502365946206848601,0.300602781899101279,0.332947631079702211],"hpluv":[352.412124726619879,227.177321581811952,61.7061969251912075],"hsluv":[352.412124726619879,99.9999999999998721,61.7061969251912075]},"#ff55aa":{"lch":[62.2217597266614177,107.062368992166355,345.125792918237266],"luv":[62.2217597266614177,103.474894783269619,-27.4826673342684735],"rgb":[1,0.333333333333333315,0.66666666666666663],"xyz":[0.517423639172101102,0.306625859085202401,0.412251480696700812],"hpluv":[345.125792918237266,218.340291577764589,62.2217597266614177],"hsluv":[345.125792918237266,100.000000000000071,62.2217597266614177]},"#ff55bb":{"lch":[62.8003867495987862,105.538663220643826,337.249357740418191],"luv":[62.8003867495987862,97.3274002701012,-40.8140489422941855],"rgb":[1,0.333333333333333315,0.733333333333333282],"xyz":[0.534561231279437776,0.31348089592813716,0.502509465795342614],"hpluv":[337.249357740418191,213.249782655969199,62.8003867495987862],"hsluv":[337.249357740418191,100.000000000000284,62.8003867495987862]},"#ff55cc":{"lch":[63.441761241476712,106.157882562261193,329.184616986090759],"luv":[63.441761241476712,91.1707664760994447,-54.3818661895983837],"rgb":[1,0.333333333333333315,0.8],"xyz":[0.553853606723159531,0.321197846105625961,0.60411597646561277],"hpluv":[329.184616986090759,212.332436268611161,63.441761241476712],"hsluv":[329.184616986090759,100.000000000000441,63.441761241476712]},"#ff55dd":{"lch":[64.1451313698934769,108.938462409011748,321.364198961949114],"luv":[64.1451313698934769,85.0951546537234549,-68.0176686346904518],"rgb":[1,0.333333333333333315,0.866666666666666696],"xyz":[0.575371932273793,0.329805176325879468,0.717445824365618767],"hpluv":[321.364198961949114,215.504760823814451,64.1451313698934769],"hsluv":[321.364198961949114,100.000000000000597,64.1451313698934769]},"#ff55ee":{"lch":[64.9093593252901258,113.686114680552976,314.13939983200612],"luv":[64.9093593252901258,79.1717442713053288,-81.5865649491316418],"rgb":[1,0.333333333333333315,0.933333333333333348],"xyz":[0.599184112539967728,0.339330048432349485,0.842856640434142],"hpluv":[314.13939983200612,222.248801840624651,64.9093593252901258],"hsluv":[314.13939983200612,100.000000000000753,64.9093593252901258]},"#ff55ff":{"lch":[65.7329718140353378,120.074032289562709,307.715012949243885],"luv":[65.7329718140353378,73.4534088756767147,-94.9861566483116633],"rgb":[1,0.333333333333333315,1],"xyz":[0.625355160949799149,0.349798467796282209,0.980690828725923724],"hpluv":[307.715012949243885,231.795582155087629,65.7329718140353378],"hsluv":[307.715012949243885,100.000000000000981,65.7329718140353378]},"#ff6600":{"lch":[62.3097916023938438,138.227046243322206,22.8239093069931798],"luv":[62.3097916023938438,127.404056867086908,53.6183047751569717],"rgb":[1,0.4,0],"xyz":[0.459902430253815608,0.307662267847242543,0.03516802904487909],"hpluv":[22.8239093069931798,281.498480884542573,62.3097916023938438],"hsluv":[22.8239093069931798,100.000000000002359,62.3097916023938438]},"#ff6611":{"lch":[62.344110015411573,137.186959502953613,22.4076195476895244],"luv":[62.344110015411573,126.828705913080029,52.2947532174930245],"rgb":[1,0.4,0.0666666666666666657],"xyz":[0.460914095753452713,0.308066934047097396,0.0404961340096347197],"hpluv":[22.4076195476895244,279.226561167599414,62.344110015411573],"hsluv":[22.4076195476895244,99.9999999999995737,62.344110015411573]},"#ff6622":{"lch":[62.4076477973658257,135.300699513710725,21.6278909170268392],"luv":[62.4076477973658257,125.775148313603225,49.8687412673566115],"rgb":[1,0.4,0.133333333333333331],"xyz":[0.46278945389192977,0.308817077302488197,0.0503730202056139192],"hpluv":[21.6278909170268392,275.106945224361368,62.4076477973658257],"hsluv":[21.6278909170268392,99.9999999999996163,62.4076477973658257]},"#ff6633":{"lch":[62.5120380635233346,132.311574345484274,20.3215228987586443],"luv":[62.5120380635233346,124.076309265494103,45.9502141979128851],"rgb":[1,0.4,0.2],"xyz":[0.465877204624387475,0.310052177595471323,0.0666351740632250555],"hpluv":[20.3215228987586443,268.579898420339646,62.5120380635233346],"hsluv":[20.3215228987586443,99.9999999999995879,62.5120380635233346]},"#ff6644":{"lch":[62.6622654373265675,128.246261163642686,18.3868048135947362],"luv":[62.6622654373265675,121.699120282046835,40.4527826611364603],"rgb":[1,0.4,0.266666666666666663],"xyz":[0.470335199868606391,0.311835375693158889,0.0901139490161117],"hpluv":[18.3868048135947362,259.703586528718,62.6622654373265675],"hsluv":[18.3868048135947362,99.9999999999997726,62.6622654373265675]},"#ff6655":{"lch":[62.8622967709428764,123.257362768531593,15.7125644918265355],"luv":[62.8622967709428764,118.651528823693667,33.3795174388964284],"rgb":[1,0.4,0.333333333333333315],"xyz":[0.476297613907968376,0.31422034130890375,0.121515996290085609],"hpluv":[15.7125644918265355,248.806632458920831,62.8622967709428764],"hsluv":[15.7125644918265355,99.9999999999997158,62.8622967709428764]},"#ff6666":{"lch":[63.1153061541487119,117.623502253606588,12.1770506300618742],"luv":[63.1153061541487119,114.97702760078576,24.8107115273291683],"rgb":[1,0.4,0.4],"xyz":[0.483882609681476561,0.317254339618307069,0.161463640697229571],"hpluv":[12.1770506300618742,236.482353971627703,63.1153061541487119],"hsluv":[12.1770506300618742,99.9999999999999,63.1153061541487119]},"#ff6677":{"lch":[63.4237926928396121,111.744324598031497,7.65713975886231157],"luv":[63.4237926928396121,110.747917341816802,14.8893547314965815],"rgb":[1,0.4,0.466666666666666674],"xyz":[0.493196622701678467,0.320979944826387864,0.21051744260362748],"hpluv":[7.65713975886231157,223.569519019308729,63.4237926928396121],"hsluv":[7.65713975886231157,100.000000000000071,63.4237926928396121]},"#ff6688":{"lch":[63.7896518301749751,106.125321016318935,2.05404070639815961],"luv":[63.7896518301749751,106.057131857198982,3.80375380925921824],"rgb":[1,0.4,0.533333333333333326],"xyz":[0.504337039803622322,0.325436111667165462,0.26919030600719962],"hpluv":[2.05404070639815961,211.109662635719985,63.7896518301749751],"hsluv":[2.05404070639815961,100.000000000000128,63.7896518301749751]},"#ff6699":{"lch":[64.2142253202301276,101.344202045456129,355.341285926877504],"luv":[64.2142253202301276,101.009378125853075,-8.23121004826552394],"rgb":[1,0.4,0.6],"xyz":[0.517394003912695,0.330658897310794619,0.337956983648317555],"hpluv":[355.341285926877504,200.265890662959123,64.2142253202301276],"hsluv":[355.341285926877504,100.000000000000199,64.2142253202301276]},"#ff66aa":{"lch":[64.6983418323177233,97.9876087444390436,347.629516841099075],"luv":[64.6983418323177233,95.7126081968365838,-20.9920961224008664],"rgb":[1,0.4,0.66666666666666663],"xyz":[0.532451696877947578,0.336681974496895742,0.417260833265316156],"hpluv":[347.629516841099075,192.184047560801417,64.6983418323177233],"hsluv":[347.629516841099075,100.000000000000441,64.6983418323177233]},"#ff66bb":{"lch":[65.2423543089962408,96.5541832870936787,339.215698562051898],"luv":[65.2423543089962408,90.270720679111,-34.2623306024503123],"rgb":[1,0.4,0.733333333333333282],"xyz":[0.549589288985284141,0.3435370113398305,0.507518818363957847],"hpluv":[339.215698562051898,187.793604034801348,65.2423543089962408],"hsluv":[339.215698562051898,100.000000000000597,65.2423543089962408]},"#ff66cc":{"lch":[65.8461771980182533,97.3465701370285,330.562118792095362],"luv":[65.8461771980182533,84.7780628468697159,-47.8438583036069218],"rgb":[1,0.4,0.8],"xyz":[0.568881664429005895,0.351253961517319302,0.609125329034228],"hpluv":[330.562118792095362,187.598522894675455,65.8461771980182533],"hsluv":[330.562118792095362,100.000000000000711,65.8461771980182533]},"#ff66dd":{"lch":[66.5093249736543157,100.405273498350255,322.181562409870594],"luv":[66.5093249736543157,79.3159229397089831,-61.5646271368605298],"rgb":[1,0.4,0.866666666666666696],"xyz":[0.590399989979639495,0.359861291737572808,0.722455176934234],"hpluv":[322.181562409870594,191.563741116159406,66.5093249736543157],"hsluv":[322.181562409870594,100.000000000000952,66.5093249736543157]},"#ff66ee":{"lch":[67.2309523334132706,105.527911758853008,314.488878023448478],"luv":[67.2309523334132706,73.9508789773533408,-75.2821868615750702],"rgb":[1,0.4,0.933333333333333348],"xyz":[0.614212170245814204,0.369386163844042825,0.847865993002757223],"hpluv":[314.488878023448478,199.176184031939982,67.2309523334132706],"hsluv":[314.488878023448478,100.000000000001066,67.2309523334132706]},"#ff66ff":{"lch":[68.0098958254125137,112.360313920932768,307.715012949244056],"luv":[68.0098958254125137,68.7346624616611592,-88.8841173702707437],"rgb":[1,0.4,1],"xyz":[0.640383218655645625,0.379854583207975549,0.985700181294539179],"hpluv":[307.715012949244056,209.642901019847784,68.0098958254125137],"hsluv":[307.715012949244056,100.000000000001421,68.0098958254125137]},"#ff7700":{"lch":[65.3236824647912755,127.817378582796977,27.3102887077963814],"luv":[65.3236824647912755,113.570196302134065,58.6437786953806466],"rgb":[1,0.466666666666666674,0],"xyz":[0.478356168307233265,0.344569743954078356,0.0413192750626848],"hpluv":[27.3102887077963814,248.289625700463205,65.3236824647912755],"hsluv":[27.3102887077963814,100.00000000000226,65.3236824647912755]},"#ff7711":{"lch":[65.3555057958206476,126.824695098806032,26.9045059733925385],"luv":[65.3555057958206476,113.097436843789765,57.3887886809793],"rgb":[1,0.466666666666666674,0.0666666666666666657],"xyz":[0.479367833806870369,0.344974410153933209,0.0466473800274404271],"hpluv":[26.9045059733925385,246.24134425049084,65.3555057958206476],"hsluv":[26.9045059733925385,99.9999999999999716,65.3555057958206476]},"#ff7722":{"lch":[65.4144320044565291,125.020679344179442,26.1430666348463],"luv":[65.4144320044565291,112.230643754756542,55.0858681158159058],"rgb":[1,0.466666666666666674,0.133333333333333331],"xyz":[0.481243191945347426,0.345724553409324,0.0565242662234196266],"hpluv":[26.1430666348463,242.520026060215031,65.4144320044565291],"hsluv":[26.1430666348463,100.000000000000156,65.4144320044565291]},"#ff7733":{"lch":[65.511267747206432,122.151716277204869,24.8632302030062533],"luv":[65.511267747206432,110.829965834679456,51.3591322215488688],"rgb":[1,0.466666666666666674,0.2],"xyz":[0.484330942677805132,0.346959653702307136,0.0727864200810307699],"hpluv":[24.8632302030062533,236.604443239770575,65.511267747206432],"hsluv":[24.8632302030062533,100.000000000000128,65.511267747206432]},"#ff7744":{"lch":[65.6506715027637853,118.22870540382597,22.9581907744090898],"luv":[65.6506715027637853,108.863777518532288,46.1162089276663139],"rgb":[1,0.466666666666666674,0.266666666666666663],"xyz":[0.488788937922024047,0.348742851799994702,0.0962651950339174084],"hpluv":[22.9581907744090898,228.519406804146513,65.6506715027637853],"hsluv":[22.9581907744090898,100.000000000000199,65.6506715027637853]},"#ff7755":{"lch":[65.8363783536997857,113.378413750733145,20.3056908730066645],"luv":[65.8363783536997857,106.332452226692425,39.3455754576116092],"rgb":[1,0.466666666666666674,0.333333333333333315],"xyz":[0.494751351961386032,0.351127817415739563,0.12766724230789131],"hpluv":[20.3056908730066645,218.526329281612362,65.8363783536997857],"hsluv":[20.3056908730066645,100.000000000000171,65.8363783536997857]},"#ff7766":{"lch":[66.0714111968285351,107.847817312906827,16.7638759706376135],"luv":[66.0714111968285351,103.264450834403533,31.1063481146080676],"rgb":[1,0.466666666666666674,0.4],"xyz":[0.502336347734894217,0.354161815725142881,0.167614886715035272],"hpluv":[16.7638759706376135,207.127185394700234,66.0714111968285351],"hsluv":[16.7638759706376135,100.000000000000426,66.0714111968285351]},"#ff7777":{"lch":[66.3581913431115851,102.006782949974053,12.1770506300619488],"luv":[66.3581913431115851,99.7116772923406671,21.5166256497442419],"rgb":[1,0.466666666666666674,0.466666666666666674],"xyz":[0.511650360755096067,0.357887420933223677,0.216668688621433181],"hpluv":[12.1770506300619488,195.062523033846361,66.3581913431115851],"hsluv":[12.1770506300619488,100.000000000000355,66.3581913431115851]},"#ff7788":{"lch":[66.6986047917809,96.3441833198397291,6.39999172914420456],"luv":[66.6986047917809,95.7437601312525,10.7393694179903871],"rgb":[1,0.466666666666666674,0.533333333333333326],"xyz":[0.52279077785704,0.362343587774001274,0.275341552025005376],"hpluv":[6.39999172914420456,183.293927388427107,66.6986047917809],"hsluv":[6.39999172914420456,100.000000000000639,66.6986047917809]},"#ff7799":{"lch":[67.0940474565320244,91.4474963932601,359.352586865695173],"luv":[67.0940474565320244,91.4416585161261679,-1.0332881570442134],"rgb":[1,0.466666666666666674,0.6],"xyz":[0.535847741966112623,0.367566373417630432,0.344108229666123255],"hpluv":[359.352586865695173,172.952623850798517,67.0940474565320244],"hsluv":[359.352586865695173,100.000000000000782,67.0940474565320244]},"#ff77aa":{"lch":[67.5454605183692,87.9484746627524,351.107126776790835],"luv":[67.5454605183692,86.8912550098467449,-13.5957345634056814],"rgb":[1,0.466666666666666674,0.66666666666666663],"xyz":[0.550905434931365234,0.373589450603731554,0.423412079283121856],"hpluv":[351.107126776790835,165.223368139110704,67.5454605183692],"hsluv":[351.107126776790835,100.000000000000938,67.5454605183692]},"#ff77bb":{"lch":[68.0533617234635244,86.4195813509952,341.973592157308417],"luv":[68.0533617234635244,82.1775887588569,-26.7429980866295693],"rgb":[1,0.466666666666666674,0.733333333333333282],"xyz":[0.568043027038701798,0.380444487446666313,0.513670064381763658],"hpluv":[341.973592157308417,161.139458954487083,68.0533617234635244],"hsluv":[341.973592157308417,100.000000000001037,68.0533617234635244]},"#ff77cc":{"lch":[68.6178757233526682,87.2373067072756214,332.49967924393593],"luv":[68.6178757233526682,77.3802105983984347,-40.2821385887937],"rgb":[1,0.466666666666666674,0.8],"xyz":[0.587335402482423552,0.388161437624155115,0.615276575052033814],"hpluv":[332.49967924393593,161.325977991170333,68.6178757233526682],"hsluv":[332.49967924393593,100.000000000001265,68.6178757233526682]},"#ff77dd":{"lch":[69.238765020261809,90.480647802514838,323.326201907778],"luv":[69.238765020261809,72.5699004301545756,-54.0403291840472],"rgb":[1,0.466666666666666674,0.866666666666666696],"xyz":[0.608853728033057151,0.396768767844408621,0.728606422952039812],"hpluv":[323.326201907778,165.823361543811586,69.238765020261809],"hsluv":[323.326201907778,100.00000000000145,69.238765020261809]},"#ff77ee":{"lch":[69.9154621504300593,95.9376886025569604,314.973456368277198],"luv":[69.9154621504300593,67.8067552495039791,-67.8696105553513149],"rgb":[1,0.466666666666666674,0.933333333333333348],"xyz":[0.632665908299231861,0.406293639950878638,0.854017239020563],"hpluv":[314.973456368277198,174.122680701596721,69.9154621504300593],"hsluv":[314.973456368277198,100.000000000001535,69.9154621504300593]},"#ff77ff":{"lch":[70.6471031550122,103.213892868752552,307.715012949244283],"luv":[70.6471031550122,63.1394826173239494,-81.6487196221654],"rgb":[1,0.466666666666666674,1],"xyz":[0.658836956709063282,0.416762059314811362,0.99185142731234488],"hpluv":[307.715012949244283,185.388643374650655,70.6471031550122],"hsluv":[307.715012949244283,100.000000000001975,70.6471031550122]},"#ff8800":{"lch":[68.6580440198892603,118.150361410828182,32.8458067740872153],"luv":[68.6580440198892603,99.2620471866307383,64.0823992202883375],"rgb":[1,0.533333333333333326,0],"xyz":[0.500428538032203774,0.388714483404019873,0.0486767316376747472],"hpluv":[32.8458067740872153,218.364961888913399,68.6580440198892603],"hsluv":[32.8458067740872153,100.000000000002245,68.6580440198892603]},"#ff8811":{"lch":[68.6874112197728408,117.19102013872596,32.4606037779481582],"luv":[68.6874112197728408,98.8811760474647485,62.89871401408422],"rgb":[1,0.533333333333333326,0.0666666666666666657],"xyz":[0.501440203531840933,0.389119149603874726,0.0540048366024303769],"hpluv":[32.4606037779481582,216.499308154785638,68.6874112197728408],"hsluv":[32.4606037779481582,100.000000000000739,68.6874112197728408]},"#ff8822":{"lch":[68.7417963707939492,115.443262249268372,31.7362513605757321],"luv":[68.7417963707939492,98.1820090833864754,60.724294076614548],"rgb":[1,0.533333333333333326,0.133333333333333331],"xyz":[0.503315561670317879,0.389869292859265526,0.0638817227984095765],"hpluv":[31.7362513605757321,213.101761826290613,68.7417963707939492],"hsluv":[31.7362513605757321,100.000000000000668,68.7417963707939492]},"#ff8833":{"lch":[68.8311889682804292,112.651741292777714,30.5141745142023382],"luv":[68.8311889682804292,97.0498776480180823,57.1990914683060439],"rgb":[1,0.533333333333333326,0.2],"xyz":[0.506403312402775696,0.391104393152248653,0.0801438766560207128],"hpluv":[30.5141745142023382,207.678703624478942,68.8311889682804292],"hsluv":[30.5141745142023382,100.000000000000824,68.8311889682804292]},"#ff8844":{"lch":[68.9599197258043688,108.808998086617962,28.6842020071901302],"luv":[68.9599197258043688,95.4557990826346554,52.2263198599069725],"rgb":[1,0.533333333333333326,0.266666666666666663],"xyz":[0.510861307646994556,0.392887591249936219,0.103622651608907351],"hpluv":[28.6842020071901302,200.2199693629492,68.9599197258043688],"hsluv":[28.6842020071901302,100.000000000000838,68.9599197258043688]},"#ff8855":{"lch":[69.1314852187197602,104.012526361958052,26.1137258191789492],"luv":[69.1314852187197602,93.395152113439849,45.7815596272609682],"rgb":[1,0.533333333333333326,0.333333333333333315],"xyz":[0.516823721686356485,0.39527255686568108,0.135024698882881267],"hpluv":[26.1137258191789492,190.918970683811096,69.1314852187197602],"hsluv":[26.1137258191789492,100.000000000000867,69.1314852187197602]},"#ff8866":{"lch":[69.3487452092138881,98.4723154092605171,22.6389332988698087],"luv":[69.3487452092138881,90.8849122177262529,37.9042165627661802],"rgb":[1,0.533333333333333326,0.4],"xyz":[0.524408717459864726,0.398306555175084398,0.174972343290025228],"hpluv":[22.6389332988698087,180.183437843423292,69.3487452092138881],"hsluv":[22.6389332988698087,100.000000000001066,69.3487452092138881]},"#ff8877":{"lch":[69.6140261744794344,92.5206854303452246,18.0637242730473773],"luv":[69.6140261744794344,87.9605480867009248,28.6883114314535526],"rgb":[1,0.533333333333333326,0.466666666666666674],"xyz":[0.533722730480066576,0.402032160383165194,0.224026145196423138],"hpluv":[18.0637242730473773,168.648085666048672,69.6140261744794344],"hsluv":[18.0637242730473773,100.000000000001108,69.6140261744794344]},"#ff8888":{"lch":[69.9291829132988596,86.6211090413054,12.1770506300619186],"luv":[69.9291829132988596,84.672173963834382,18.2712749359175248],"rgb":[1,0.533333333333333326,0.533333333333333326],"xyz":[0.544863147582010487,0.406488327223942791,0.282699008599995305],"hpluv":[12.1770506300619186,157.182652238587849,69.9291829132988596],"hsluv":[12.1770506300619186,100.000000000001251,69.9291829132988596]},"#ff8899":{"lch":[70.29563969089034,81.3665448969888274,4.80888772903122597],"luv":[70.29563969089034,81.0801238487794791,6.82115423812421362],"rgb":[1,0.533333333333333326,0.6],"xyz":[0.557920111691083132,0.411711112867571949,0.351465686241113184],"hpluv":[4.80888772903122597,146.878021536398364,70.29563969089034],"hsluv":[4.80888772903122597,100.00000000000135,70.29563969089034]},"#ff88aa":{"lch":[70.7144212664750427,77.4442353273614827,355.944797831634332],"luv":[70.7144212664750427,77.2503443699940533,-5.47666688388778589],"rgb":[1,0.533333333333333326,0.66666666666666663],"xyz":[0.572977804656335743,0.417734190053673071,0.430769535858111841],"hpluv":[355.944797831634332,138.969799542374091,70.7144212664750427],"hsluv":[355.944797831634332,100.000000000001648,70.7144212664750427]},"#ff88bb":{"lch":[71.1861792611668847,75.5334875912487718,345.875835641341098],"luv":[71.1861792611668847,73.2500487000805,-18.431986141845023],"rgb":[1,0.533333333333333326,0.733333333333333282],"xyz":[0.590115396763672306,0.42458922689660783,0.521027520956753532],"hpluv":[345.875835641341098,134.642814203514433,71.1861792611668847],"hsluv":[345.875835641341098,100.000000000001776,71.1861792611668847]},"#ff88cc":{"lch":[71.711216864189268,76.1313589407537563,335.260476444218114],"luv":[71.711216864189268,69.1440007334156377,-31.8604924121286039],"rgb":[1,0.533333333333333326,0.8],"xyz":[0.609407772207394061,0.432306177074096631,0.622634031627023687],"hpluv":[335.260476444218114,134.714956877670915,71.711216864189268],"hsluv":[335.260476444218114,100.000000000001933,71.711216864189268]},"#ff88dd":{"lch":[72.2895135005839649,79.3885839073469413,324.950129439258774],"luv":[72.2895135005839649,64.9916618916399784,-45.5920074067441803],"rgb":[1,0.533333333333333326,0.866666666666666696],"xyz":[0.63092609775802766,0.440913507294350138,0.735963879527029685],"hpluv":[324.950129439258774,139.354847315526115,72.2895135005839649],"hsluv":[324.950129439258774,100.000000000002245,72.2895135005839649]},"#ff88ee":{"lch":[72.9207502525545124,85.0855243828499,315.651995307064169],"luv":[72.9207502525545124,60.845281511842515,-59.4760302748021203],"rgb":[1,0.533333333333333326,0.933333333333333348],"xyz":[0.654738278024202369,0.450438379400820155,0.861374695595552908],"hpluv":[315.651995307064169,148.062090862911901,72.9207502525545124],"hsluv":[315.651995307064169,100.000000000002444,72.9207502525545124]},"#ff88ff":{"lch":[73.6043362991539709,92.7672005781522842,307.715012949244624],"luv":[73.6043362991539709,56.7488822053271349,-73.3847250560567375],"rgb":[1,0.533333333333333326,1],"xyz":[0.68090932643403379,0.460906798764752879,0.999208883887334753],"hpluv":[307.715012949244624,159.930161835956909,73.6043362991539709],"hsluv":[307.715012949244624,100.000000000002771,73.6043362991539709]},"#ff9900":{"lch":[72.2588108283115389,109.907462524380705,39.4434130396340095],"luv":[72.2588108283115389,84.8763034831777077,69.8259509464759418],"rgb":[1,0.6,0],"xyz":[0.526298138484671219,0.440453684308955595,0.057299931788497],"hpluv":[39.4434130396340095,193.008172097547572,72.2588108283115389],"hsluv":[39.4434130396340095,100.000000000002288,72.2588108283115389]},"#ff9911":{"lch":[72.2858317740783889,108.970035258541955,39.0927051304156805],"luv":[72.2858317740783889,84.5745536570817791,68.7139975401902348],"rgb":[1,0.6,0.0666666666666666657],"xyz":[0.527309803984308378,0.440858350508810448,0.0626280367532526389],"hpluv":[39.0927051304156805,191.2904264008464,72.2858317740783889],"hsluv":[39.0927051304156805,100.000000000001506,72.2858317740783889]},"#ff9922":{"lch":[72.3358777005795304,107.257428554778556,38.4317580680427469],"luv":[72.3358777005795304,84.0200042697796,66.6692947517044274],"rgb":[1,0.6,0.133333333333333331],"xyz":[0.529185162122785324,0.441608493764201249,0.0725049229492318315],"hpluv":[38.4317580680427469,188.15378179700545,72.3358777005795304],"hsluv":[38.4317580680427469,100.00000000000145,72.3358777005795304]},"#ff9933":{"lch":[72.418154282067718,104.508625212907305,37.3122251519614778],"luv":[72.418154282067718,83.1203251002183237,63.3487513620113845],"rgb":[1,0.6,0.2],"xyz":[0.532272912855243141,0.442843594057184375,0.0887670768068429816],"hpluv":[37.3122251519614778,183.123470124205028,72.418154282067718],"hsluv":[37.3122251519614778,100.00000000000162,72.418154282067718]},"#ff9944":{"lch":[72.5366731246789556,100.695423976150749,35.6250099256014607],"luv":[72.5366731246789556,81.8499313718691326,58.6528528219818952],"rgb":[1,0.6,0.266666666666666663],"xyz":[0.536730908099462,0.444626792154871942,0.11224585175972962],"hpluv":[35.6250099256014607,176.153561585765658,72.5366731246789556],"hsluv":[35.6250099256014607,100.000000000001748,72.5366731246789556]},"#ff9955":{"lch":[72.6946936633514582,95.8821930466240673,33.2320443565807508],"luv":[72.6946936633514582,80.201421842029859,52.5464259293328269],"rgb":[1,0.6,0.333333333333333315],"xyz":[0.54269332213882393,0.447011757770616802,0.143647899033703508],"hpluv":[33.2320443565807508,167.368827825995851,72.6946936633514582],"hsluv":[33.2320443565807508,100.000000000001705,72.6946936633514582]},"#ff9966":{"lch":[72.8949069034106,90.2347392462793749,29.9516480142673025],"luv":[72.8949069034106,78.1836232693519406,45.0514064077924345],"rgb":[1,0.6,0.4],"xyz":[0.550278317912332171,0.450045756080020121,0.183595543440847497],"hpluv":[29.9516480142673025,157.078197331028889,72.8949069034106],"hsluv":[29.9516480142673025,100.000000000001819,72.8949069034106]},"#ff9977":{"lch":[73.1395321193821,84.0351966301436,25.5464816978182121],"luv":[73.1395321193821,75.8195571045914,36.2396058633438045],"rgb":[1,0.6,0.466666666666666674],"xyz":[0.559592330932534,0.453771361288100916,0.232649345347245406],"hpluv":[25.5464816978182121,145.796926659053128,73.1395321193821],"hsluv":[25.5464816978182121,100.000000000002018,73.1395321193821]},"#ff9988":{"lch":[73.430374185650777,77.702838567593929,19.7240568661095921],"luv":[73.430374185650777,73.1439295084068419,26.2239718107454713],"rgb":[1,0.6,0.533333333333333326],"xyz":[0.570732748034477932,0.458227528128878514,0.291322208750817546],"hpluv":[19.7240568661095921,134.276641294628575,73.430374185650777],"hsluv":[19.7240568661095921,100.000000000002203,73.430374185650777]},"#ff9999":{"lch":[73.76886125649402,71.8160022700114098,12.1770506300620251],"luv":[73.76886125649402,70.2001752793754,15.1483851545719261],"rgb":[1,0.6,0.6],"xyz":[0.583789712143550577,0.463450313772507672,0.360088886391935481],"hpluv":[12.1770506300620251,123.534275619879125,73.76886125649402],"hsluv":[12.1770506300620251,100.000000000002331,73.76886125649402]},"#ff99aa":{"lch":[74.1560723225582592,67.1124973440613,2.7130535693684088],"luv":[74.1560723225582592,67.0372720786985923,3.17670458229478481],"rgb":[1,0.6,0.66666666666666663],"xyz":[0.598847405108803188,0.469473390958608794,0.439392736008934082],"hpluv":[2.7130535693684088,114.840746523486033,74.1560723225582592],"hsluv":[2.7130535693684088,100.00000000000253,74.1560723225582592]},"#ff99bb":{"lch":[74.5927597146433925,64.4136927281220864,351.502648062184],"luv":[74.5927597146433925,63.7066038913843187,-9.51800564715024322],"rgb":[1,0.6,0.733333333333333282],"xyz":[0.615984997216139751,0.476328427801543552,0.529650721107575828],"hpluv":[351.502648062184,109.577363966618833,74.5927597146433925],"hsluv":[351.502648062184,100.000000000002615,74.5927597146433925]},"#ff99cc":{"lch":[75.0793694015197,64.4152606478183145,339.305696269483292],"luv":[75.0793694015197,60.259134450288677,-22.7631834247409977],"rgb":[1,0.6,0.8],"xyz":[0.635277372659861506,0.484045377979032354,0.631257231777846],"hpluv":[339.305696269483292,108.869813431806975,75.0793694015197],"hsluv":[339.305696269483292,100.000000000002871,75.0793694015197]},"#ff99dd":{"lch":[75.6160606971696296,67.4118390527965232,327.324068761847229],"luv":[75.6160606971696296,56.7430830794555,-36.3947601601954887],"rgb":[1,0.6,0.866666666666666696],"xyz":[0.656795698210495105,0.49265270819928586,0.744587079677852],"hpluv":[327.324068761847229,113.125745227459021,75.6160606971696296],"hsluv":[327.324068761847229,100.00000000000324,75.6160606971696296]},"#ff99ee":{"lch":[76.202726253448489,73.1905233351813393,316.627151984536795],"luv":[76.202726253448489,53.2022056350908201,-50.2630880631028845],"rgb":[1,0.6,0.933333333333333348],"xyz":[0.680607878476669814,0.502177580305755877,0.869997895746375205],"hpluv":[316.627151984536795,123.107716827744753,76.202726253448489],"hsluv":[316.627151984536795,100.000000000003524,76.202726253448489]},"#ff99ff":{"lch":[76.8390127436129,81.2030526869262275,307.715012949245],"luv":[76.8390127436129,49.6746958291708154,-64.2367524082209229],"rgb":[1,0.6,1],"xyz":[0.706778926886501235,0.512645999669688601,1.00783208403815694],"hpluv":[307.715012949245,141.150312559224801,76.8390127436129],"hsluv":[307.715012949245,100.000000000003752,76.8390127436129]},"#ee0000":{"lch":[49.7142799595632,167.190689697178925,12.1770506300617765],"luv":[49.7142799595632,163.428976145092918,35.2660811203203934],"rgb":[0.933333333333333348,0,0],"xyz":[0.352591085030832,0.181804778219026603,0.0165277071108199],"hpluv":[12.1770506300617765,426.746789183125202,49.7142799595632],"hsluv":[12.1770506300617765,100.000000000002217,49.7142799595632]},"#ee0011":{"lch":[49.7630000621001756,165.722449822455,11.6881730851639158],"luv":[49.7630000621001756,162.286136628676445,33.5729092170260728],"rgb":[0.933333333333333348,0,0.0666666666666666657],"xyz":[0.353602750530469079,0.182209444418881455,0.0218558120755755342],"hpluv":[11.6881730851639158,422.585038037937124,49.7630000621001756],"hsluv":[11.6881730851639158,99.9999999999963762,49.7630000621001756]},"#ee0022":{"lch":[49.8531236873270558,163.0858535413212,10.7756858750078184],"luv":[49.8531236873270558,160.210108449799208,30.4912573667411486],"rgb":[0.933333333333333348,0,0.133333333333333331],"xyz":[0.355478108668946136,0.182959587674272284,0.0317326982715547268],"hpluv":[10.7756858750078184,415.110044299310516,49.8531236873270558],"hsluv":[10.7756858750078184,99.9999999999964473,49.8531236873270558]},"#ee0033":{"lch":[50.000975779064234,158.977402767524836,9.25647316775448559],"luv":[50.000975779064234,156.907230803998146,25.5721628363475],"rgb":[0.933333333333333348,0,0.2],"xyz":[0.358565859401403841,0.184194687967255383,0.047994852129165877],"hpluv":[9.25647316775448559,403.456061197389261,50.000975779064234],"hsluv":[9.25647316775448559,99.9999999999965183,50.000975779064234]},"#ee0044":{"lch":[50.2132784041556164,153.529579514286212,7.02933300215353],"luv":[50.2132784041556164,152.375594335021788,18.7885613308314312],"rgb":[0.933333333333333348,0,0.266666666666666663],"xyz":[0.363023854645622757,0.185977886064942977,0.0714736270820525155],"hpluv":[7.02933300215353,387.983100931209492,50.2132784041556164],"hsluv":[7.02933300215353,99.9999999999966462,50.2132784041556164]},"#ee0055":{"lch":[50.4951150037793326,147.071833727726926,3.99754465361350508],"luv":[50.4951150037793326,146.714013644902735,10.2529252527975352],"rgb":[0.933333333333333348,0,0.333333333333333315],"xyz":[0.368986268684984742,0.188362851680687809,0.102875674356026417],"hpluv":[3.99754465361350508,369.589367027053072,50.4951150037793326],"hsluv":[3.99754465361350508,99.999999999996831,50.4951150037793326]},"#ee0066":{"lch":[50.8502318550204109,140.098840030056522,0.0757634158231174915],"luv":[50.8502318550204109,140.0987175463531,0.185255592479522613],"rgb":[0.933333333333333348,0,0.4],"xyz":[0.376571264458492927,0.1913968499900911,0.142823318763170393],"hpluv":[0.0757634158231174915,349.60765112382461,50.8502318550204109],"hsluv":[0.0757634158231174915,99.9999999999970584,50.8502318550204109]},"#ee0077":{"lch":[51.2812017254514956,133.219993530026585,355.209470699020642],"luv":[51.2812017254514956,132.754613083251769,-11.1256182415379214],"rgb":[0.933333333333333348,0,0.466666666666666674],"xyz":[0.385885277478694833,0.195122455198171924,0.191877120669568302],"hpluv":[355.209470699020642,329.648072606093592,51.2812017254514956],"hsluv":[355.209470699020642,99.9999999999973284,51.2812017254514956]},"#ee0088":{"lch":[51.7895361854883163,127.090944021268115,349.407446028193533],"luv":[51.7895361854883163,124.925218603260163,-23.3623160055840167],"rgb":[0.933333333333333348,0,0.533333333333333326],"xyz":[0.397025694580638633,0.199578622038949521,0.250549984073140442],"hpluv":[349.407446028193533,311.395197619459395,51.7895361854883163],"hsluv":[349.407446028193533,99.9999999999974705,51.7895361854883163]},"#ee0099":{"lch":[52.3757812732210652,122.329563392952366,342.780178840499048],"luv":[52.3757812732210652,116.846263825073436,-36.2142611415956637],"rgb":[0.933333333333333348,0,0.6],"xyz":[0.410082658689711388,0.204801407682578679,0.319316661714258376],"hpluv":[342.780178840499048,296.374093031221,52.3757812732210652],"hsluv":[342.780178840499048,99.9999999999978,52.3757812732210652]},"#ee00aa":{"lch":[53.0396114453995722,119.424239873739239,335.563712743666827],"luv":[53.0396114453995722,108.726436909364494,-49.403552366347],"rgb":[0.933333333333333348,0,0.66666666666666663],"xyz":[0.425140351654963888,0.210824484868679773,0.398620511331257],"hpluv":[335.563712743666827,285.713971708863653,53.0396114453995722],"hsluv":[335.563712743666827,99.999999999998,53.0396114453995722]},"#ee00bb":{"lch":[53.779927529436435,118.655378520732356,328.101249142938343],"luv":[53.779927529436435,100.736423933687789,-62.6998544252744381],"rgb":[0.933333333333333348,0,0.733333333333333282],"xyz":[0.442277943762300563,0.217679521711614532,0.488878496429898723],"hpluv":[328.101249142938343,279.966806180862307,53.779927529436435],"hsluv":[328.101249142938343,99.9999999999982094,53.779927529436435]},"#ee00cc":{"lch":[54.5949595671901,120.061129768120921,320.773339602207614],"luv":[54.5949595671901,93.0053918954961,-75.9254368414351575],"rgb":[0.933333333333333348,0,0.8],"xyz":[0.461570319206022317,0.225396471889103334,0.590485007100168824],"hpluv":[320.773339602207614,279.054611328209262,54.5949595671901],"hsluv":[320.773339602207614,99.9999999999984,54.5949595671901]},"#ee00dd":{"lch":[55.4823728661035744,123.466264594666441,313.907226483092529],"luv":[55.4823728661035744,85.6229535549924634,-88.9529556421808252],"rgb":[0.933333333333333348,0,0.866666666666666696],"xyz":[0.483088644756655805,0.234003802109356868,0.703814855000174822],"hpluv":[313.907226483092529,282.379138449157608,55.4823728661035744],"hsluv":[313.907226483092529,99.9999999999986215,55.4823728661035744]},"#ee00ee":{"lch":[56.4393743497109597,128.559742977308588,307.715012949243601],"luv":[56.4393743497109597,78.644409501394918,-101.698890694877051],"rgb":[0.933333333333333348,0,0.933333333333333348],"xyz":[0.506900825022830626,0.243528674215826912,0.829225671068698],"hpluv":[307.715012949243601,289.042783730483393,56.4393743497109597],"hsluv":[307.715012949243601,99.9999999999988489,56.4393743497109597]},"#ee00ff":{"lch":[57.4628159598150745,134.982567880189606,302.284502363601803],"luv":[57.4628159598150745,72.0973885084188879,-114.115118199983058],"rgb":[0.933333333333333348,0,1],"xyz":[0.533071873432661936,0.253997093579759636,0.96705985936047989],"hpluv":[302.284502363601803,298.078126285043766,57.4628159598150745],"hsluv":[302.284502363601803,99.9999999999989484,57.4628159598150745]},"#ee1100":{"lch":[50.1937733395544683,164.746074066243921,12.6667024036514828],"luv":[50.1937733395544683,160.736507742479517,36.1253927174799117],"rgb":[0.933333333333333348,0.0666666666666666657,0],"xyz":[0.354595485291760382,0.185813578740883473,0.0171958405311293527],"hpluv":[12.6667024036514828,416.489977947977081,50.1937733395544683],"hsluv":[12.6667024036514828,100.000000000002245,50.1937733395544683]},"#ee1111":{"lch":[50.2417909300708345,163.305921695383518,12.1770506300617907],"luv":[50.2417909300708345,159.631613634988071,34.4466542507197317],"rgb":[0.933333333333333348,0.0666666666666666657,0.0666666666666666657],"xyz":[0.355607150791397486,0.186218244940738326,0.0225239454958849825],"hpluv":[12.1770506300617907,412.454596338970589,50.2417909300708345],"hsluv":[12.1770506300617907,96.6508962208003197,50.2417909300708345]},"#ee1122":{"lch":[50.3306190654122219,160.718934991358793,11.2629010575952293],"luv":[50.3306190654122219,157.623701713525833,31.390201064696047],"rgb":[0.933333333333333348,0.0666666666666666657,0.133333333333333331],"xyz":[0.357482508929874543,0.186968388196129154,0.032400831691864182],"hpluv":[11.2629010575952293,405.204351077732667,50.3306190654122219],"hsluv":[11.2629010575952293,96.6948337079543592,50.3306190654122219]},"#ee1133":{"lch":[50.4763571232054318,156.685700791802191,9.74029685215880647],"luv":[50.4763571232054318,154.427033260746356,26.5084935615454427],"rgb":[0.933333333333333348,0.0666666666666666657,0.2],"xyz":[0.360570259662332249,0.188203488489112253,0.0486629855494753252],"hpluv":[9.74029685215880647,393.895198182016713,50.4763571232054318],"hsluv":[9.74029685215880647,96.7647175585846,50.4763571232054318]},"#ee1144":{"lch":[50.6856484752898382,151.333831494518165,7.50679337730589413],"luv":[50.6856484752898382,150.036806479185287,19.7708183022028514],"rgb":[0.933333333333333348,0.0666666666666666657,0.266666666666666663],"xyz":[0.365028254906551164,0.189986686586799847,0.0721417605023619568],"hpluv":[7.50679337730589413,378.870112575267399,50.6856484752898382],"hsluv":[7.50679337730589413,96.8605546889772455,50.6856484752898382]},"#ee1155":{"lch":[50.9635312364098496,144.984673036864649,4.46374659640210858],"luv":[50.9635312364098496,144.544902405536135,11.283909082431693],"rgb":[0.933333333333333348,0.0666666666666666657,0.333333333333333315],"xyz":[0.370990668945913149,0.19237165220254468,0.103543807776335872],"hpluv":[4.46374659640210858,360.995599227985224,50.9635312364098496],"hsluv":[4.46374659640210858,96.9801964566503,50.9635312364098496]},"#ee1166":{"lch":[51.3137360134299598,138.123816003378664,0.523151936541392],"luv":[51.3137360134299598,138.118058344046318,1.26115288756691357],"rgb":[0.933333333333333348,0.0666666666666666657,0.4],"xyz":[0.378575664719421334,0.19540565051194797,0.143491452183479834],"hpluv":[0.523151936541392,341.565705345826359,51.3137360134299598],"hsluv":[0.523151936541392,97.1198273857598764,51.3137360134299598]},"#ee1177":{"lch":[51.7388469835676119,131.353183798903302,355.627348241097309],"luv":[51.7388469835676119,130.970848560864681,-10.014775152519368],"rgb":[0.933333333333333348,0.0666666666666666657,0.466666666666666674],"xyz":[0.38788967773962324,0.199131255720028794,0.192545254089877743],"hpluv":[355.627348241097309,322.153744971780554,51.7388469835676119],"hsluv":[355.627348241097309,97.2745732157476,51.7388469835676119]},"#ee1188":{"lch":[52.2404115410600411,125.324707533591734,349.782339698165117],"luv":[52.2404115410600411,123.337180279157977,-22.2311106147846438],"rgb":[0.933333333333333348,0.0666666666666666657,0.533333333333333326],"xyz":[0.39903009484156704,0.203587422560806391,0.251218117493449911],"hpluv":[349.782339698165117,304.417375015566734,52.2404115410600411],"hsluv":[349.782339698165117,97.4391430985313605,52.2404115410600411]},"#ee1199":{"lch":[52.819032808459994,120.657103381490217,343.097768544337384],"luv":[52.819032808459994,115.44498939014953,-35.079780802050081],"rgb":[0.933333333333333348,0.0666666666666666657,0.6],"xyz":[0.412087058950639795,0.208810208204435549,0.31998479513456779],"hpluv":[343.097768544337384,289.869003225703352,52.819032808459994],"hsluv":[343.097768544337384,97.6083995478766298,52.819032808459994]},"#ee11aa":{"lch":[53.4744599034404615,117.843047501566133,335.812437212199143],"luv":[53.4744599034404615,107.497497568615216,-48.2832461723726496],"rgb":[0.933333333333333348,0.0666666666666666657,0.66666666666666663],"xyz":[0.427144751915892296,0.214833285390536644,0.399288644751566446],"hpluv":[335.812437212199143,279.638449078323276,53.4744599034404615],"hsluv":[335.812437212199143,97.7777799659692,53.4744599034404615]},"#ee11bb":{"lch":[54.205681814132376,117.167943285093472,328.276238054291071],"luv":[54.205681814132376,99.6622453247977376,-61.6097702517929662],"rgb":[0.933333333333333348,0.0666666666666666657,0.733333333333333282],"xyz":[0.44428234402322897,0.221688322233471402,0.489546629850208137],"hpluv":[328.276238054291071,274.285798241860448,54.205681814132376],"hsluv":[328.276238054291071,97.9435422525978652,54.205681814132376]},"#ee11cc":{"lch":[55.0110259993956703,118.672848043699901,320.878255441103249],"luv":[55.0110259993956703,92.0672263164348266,-74.8790404666182781],"rgb":[0.933333333333333348,0.0666666666666666657,0.8],"xyz":[0.463574719466950724,0.229405272410960204,0.591153140520478293],"hpluv":[320.878255441103249,273.741691636115945,55.0110259993956703],"hsluv":[320.878255441103249,98.102849778989,55.0110259993956703]},"#ee11dd":{"lch":[55.8882602794840864,122.182226882396691,313.952719233652829],"luv":[55.8882602794840864,84.8023500190691522,-87.9605479586430334],"rgb":[0.933333333333333348,0.0666666666666666657,0.866666666666666696],"xyz":[0.485093045017584212,0.238012602631213738,0.704482988420484291],"hpluv":[313.952719233652829,277.412976370396279,55.8882602794840864],"hsluv":[313.952719233652829,98.2537358693348608,55.8882602794840864]},"#ee11ee":{"lch":[56.83469533821048,127.382376320214306,307.715012949243601],"luv":[56.83469533821048,77.9241738866570302,-100.767519176899128],"rgb":[0.933333333333333348,0.0666666666666666657,0.933333333333333348],"xyz":[0.508905225283758922,0.247537474737683783,0.829893804489007514],"hpluv":[307.715012949243601,284.403630900032795,56.83469533821048],"hsluv":[307.715012949243601,98.3949944120453495,56.83469533821048]},"#ee11ff":{"lch":[57.8472847680859275,133.910906422249354,302.2526850652647],"luv":[57.8472847680859275,71.4621107907268254,-113.248830369952643],"rgb":[0.933333333333333348,0.0666666666666666657,1],"xyz":[0.535076273693590343,0.258005894101616451,0.967727992780789359],"hpluv":[302.2526850652647,293.746227206253536,57.8472847680859275],"hsluv":[302.2526850652647,99.99999999999892,57.8472847680859275]},"#ee2200":{"lch":[51.0646940471157222,160.407609402057773,13.5847947923325787],"luv":[51.0646940471157222,155.919944837816502,37.677207378671163],"rgb":[0.933333333333333348,0.133333333333333331,0],"xyz":[0.358311109026528296,0.19324482621041944,0.018434381776051962],"hpluv":[13.5847947923325787,398.605749597291435,51.0646940471157222],"hsluv":[13.5847947923325787,100.000000000002203,51.0646940471157222]},"#ee2211":{"lch":[51.1114738997186322,159.015005648229618,13.0939108674416342],"luv":[51.1114738997186322,154.880623331235768,36.0244991337056817],"rgb":[0.933333333333333348,0.133333333333333331,0.0666666666666666657],"xyz":[0.3593227745261654,0.193649492410274293,0.0237624867408075952],"hpluv":[13.0939108674416342,394.783534202752207,51.1114738997186322],"hsluv":[13.0939108674416342,96.7702863870018462,51.1114738997186322]},"#ee2222":{"lch":[51.1980191888258105,156.511980987808,12.1770506300618031],"luv":[51.1980191888258105,152.990533465747774,33.0135860305098348],"rgb":[0.933333333333333348,0.133333333333333331,0.133333333333333331],"xyz":[0.361198132664642457,0.194399635665665121,0.0336393729367867877],"hpluv":[12.1770506300618031,387.912483642854795,51.1980191888258105],"hsluv":[12.1770506300618031,90.899918517349,51.1980191888258105]},"#ee2233":{"lch":[51.340031013958,152.605977320930094,10.6487510890373542],"luv":[51.340031013958,149.977869701108148,28.1996970549978769],"rgb":[0.933333333333333348,0.133333333333333331,0.2],"xyz":[0.364285883397100163,0.19563473595864822,0.0499015267943979379],"hpluv":[10.6487510890373542,377.185287566809563,51.340031013958],"hsluv":[10.6487510890373542,91.0856949770771,51.340031013958]},"#ee2244":{"lch":[51.5440125284501391,147.416232714385046,8.4042516634418849],"luv":[51.5440125284501391,145.833202035739902,21.5458314229178391],"rgb":[0.933333333333333348,0.133333333333333331,0.266666666666666663],"xyz":[0.368743878641319078,0.197417934056335814,0.0733803017472845764],"hpluv":[8.4042516634418849,362.916246958463432,51.5440125284501391],"hsluv":[8.4042516634418849,91.3409150161676848,51.5440125284501391]},"#ee2255":{"lch":[51.8149196409757,141.25016266814734,5.34127242035781613],"luv":[51.8149196409757,140.636840571385164,13.1486701942394504],"rgb":[0.933333333333333348,0.133333333333333331,0.333333333333333315],"xyz":[0.374706292680681063,0.199802899672080647,0.104782349021258478],"hpluv":[5.34127242035781613,345.918233291596209,51.8149196409757],"hsluv":[5.34127242035781613,91.6602615743055082,51.8149196409757]},"#ee2266":{"lch":[52.1564522427987924,134.577740656965489,1.36671179444129165],"luv":[52.1564522427987924,134.539455426625494,3.20986196595936],"rgb":[0.933333333333333348,0.133333333333333331,0.4],"xyz":[0.382291288454189249,0.202836897981483938,0.144729993428402454],"hpluv":[1.36671179444129165,327.419481975304109,52.1564522427987924],"hsluv":[1.36671179444129165,92.0339967122243365,52.1564522427987924]},"#ee2277":{"lch":[52.5712108639856694,127.988129961564283,356.416786702014292],"luv":[52.5712108639856694,127.737923683219179,-7.99901644943552803],"rgb":[0.933333333333333348,0.133333333333333331,0.466666666666666674],"xyz":[0.391605301474391154,0.206562503189564761,0.193783795334800363],"hpluv":[356.416786702014292,308.930679724572485,52.5712108639856694],"hsluv":[356.416786702014292,92.4494947830095,52.5712108639856694]},"#ee2288":{"lch":[53.0608018273771194,122.127216672078461,350.491948161024197],"luv":[53.0608018273771194,120.449481512132621,-20.1737318195523763],"rgb":[0.933333333333333348,0.133333333333333331,0.533333333333333326],"xyz":[0.402745718576334955,0.211018670030342359,0.25245665873837253],"hpluv":[350.491948161024197,292.063965437042782,53.0608018273771194],"hsluv":[350.491948161024197,92.892885362452958,53.0608018273771194]},"#ee2299":{"lch":[53.6259244704506557,117.615935516390621,343.699890485995525],"luv":[53.6259244704506557,112.888334232708232,-33.0110933105844282],"rgb":[0.933333333333333348,0.133333333333333331,0.6],"xyz":[0.415802682685407654,0.216241455673971517,0.32122333637949041],"hpluv":[343.699890485995525,278.311211390643507,53.6259244704506557],"hsluv":[343.699890485995525,93.3505397228777412,53.6259244704506557]},"#ee22aa":{"lch":[54.266455218013121,114.955451111725907,336.284451026203612],"luv":[54.266455218013121,105.247863162980167,-46.2346519390706305],"rgb":[0.933333333333333348,0.133333333333333331,0.66666666666666663],"xyz":[0.43086037565066021,0.222264532860072611,0.400527185996489],"hpluv":[336.284451026203612,268.805062052359688,54.266455218013121],"hsluv":[336.284451026203612,93.8102001508292,54.266455218013121]},"#ee22bb":{"lch":[54.981534566577821,114.440827463928798,328.608334651454868],"luv":[54.981534566577821,97.6897319326175,-59.6105633722921],"rgb":[0.933333333333333348,0.133333333333333331,0.733333333333333282],"xyz":[0.447997967757996884,0.22911956970300737,0.490785171095130757],"hpluv":[328.608334651454868,264.121319791368,54.981534566577821],"hsluv":[328.608334651454868,94.2616688954678636,54.981534566577821]},"#ee22cc":{"lch":[55.7696584616915629,116.118636638570607,321.077185717181408],"luv":[55.7696584616915629,90.3394913251054419,-72.9541916679335856],"rgb":[0.933333333333333348,0.133333333333333331,0.8],"xyz":[0.467290343201718583,0.236836519880496171,0.592391681765400913],"hpluv":[321.077185717181408,264.206361207665168,55.7696584616915629],"hsluv":[321.077185717181408,94.6970823725699518,55.7696584616915629]},"#ee22dd":{"lch":[56.6287730491083749,119.812596042269817,314.038835862099],"luv":[56.6287730491083749,83.2872216309056,-86.1295354880806201],"rgb":[0.933333333333333348,0.133333333333333331,0.866666666666666696],"xyz":[0.488808668752352182,0.245443850100749705,0.70572152966540691],"hpluv":[314.038835862099,268.475495638829329,56.6287730491083749],"hsluv":[314.038835862099,95.1108639535381,56.6287730491083749]},"#ee22ee":{"lch":[57.5563705104872128,125.203701850491953,307.715012949243658],"luv":[57.5563705104872128,76.5914038981754,-99.0440498261932163],"rgb":[0.933333333333333348,0.133333333333333331,0.933333333333333348],"xyz":[0.512620849018526892,0.254968722207219722,0.831132345733930133],"hpluv":[307.715012949243658,276.03432908057755,57.5563705104872128],"hsluv":[307.715012949243658,95.4994708803944263,57.5563705104872128]},"#ee22ff":{"lch":[58.5495832280214046,131.922896299071255,302.192710378625122],"luv":[58.5495832280214046,70.2843784028787582,-111.641196341030223],"rgb":[0.933333333333333348,0.133333333333333331,1],"xyz":[0.538791897428358313,0.265437141571152446,0.968966534025712],"hpluv":[302.192710378625122,285.914180736870946,58.5495832280214046],"hsluv":[302.192710378625122,99.9999999999989,58.5495832280214046]},"#ee3300":{"lch":[52.4512471844783761,153.77210005382733,15.1254552240259841],"luv":[52.4512471844783761,148.444942331914945,40.1242800687903269],"rgb":[0.933333333333333348,0.2,0],"xyz":[0.364428831115539142,0.205480270388441244,0.0204736224723888437],"hpluv":[15.1254552240259841,372.015515114283232,52.4512471844783761],"hsluv":[15.1254552240259841,100.000000000002174,52.4512471844783761]},"#ee3311":{"lch":[52.4961529429458693,152.446596739109111,14.6331501802662043],"luv":[52.4961529429458693,147.501711829562538,38.5124637576621893],"rgb":[0.933333333333333348,0.2,0.0666666666666666657],"xyz":[0.365440496615176247,0.205884936588296097,0.0258017274371444769],"hpluv":[14.6331501802662043,368.493287978140756,52.4961529429458693],"hsluv":[14.6331501802662043,96.9493433827183395,52.4961529429458693]},"#ee3322":{"lch":[52.5792408568970302,150.061966488521733,13.7129404445972121],"luv":[52.5792408568970302,145.784540850223095,35.5733247742160685],"rgb":[0.933333333333333348,0.2,0.133333333333333331],"xyz":[0.367315854753653304,0.206635079843686925,0.0356786136331236695],"hpluv":[13.7129404445972121,362.155969729293304,52.5792408568970302],"hsluv":[13.7129404445972121,91.3983957113456,52.5792408568970302]},"#ee3333":{"lch":[52.7156069212027916,146.335083442311,12.177050630061796],"luv":[52.7156069212027916,143.042611430097821,30.8669396171076365],"rgb":[0.933333333333333348,0.2,0.2],"xyz":[0.370403605486111,0.207870180136670024,0.0519407674907348127],"hpluv":[12.177050630061796,352.248031751653059,52.7156069212027916],"hsluv":[12.177050630061796,82.5426319963487316,52.7156069212027916]},"#ee3344":{"lch":[52.9115382124740705,141.372894204534333,9.91688783885485314],"luv":[52.9115382124740705,139.260586308771792,24.3471623953096028],"rgb":[0.933333333333333348,0.2,0.266666666666666663],"xyz":[0.374861600730329925,0.209653378234357618,0.0754195424436214512],"hpluv":[9.91688783885485314,339.043238938553714,52.9115382124740705],"hsluv":[9.91688783885485314,83.0163224279527867,52.9115382124740705]},"#ee3355":{"lch":[53.1718605143623222,135.462446214194244,6.82400118051175664],"luv":[53.1718605143623222,134.502806079917804,16.0956357737583851],"rgb":[0.933333333333333348,0.2,0.333333333333333315],"xyz":[0.38082401476969191,0.212038343850102451,0.106821589717595367],"hpluv":[6.82400118051175664,323.278173463789,53.1718605143623222],"hsluv":[6.82400118051175664,83.6110915378108,53.1718605143623222]},"#ee3366":{"lch":[53.5002196972096158,129.050901787066266,2.79642975700151464],"luv":[53.5002196972096158,128.89722530875369,6.29607494868134765],"rgb":[0.933333333333333348,0.2,0.4],"xyz":[0.388409010543200095,0.215072342159505742,0.146769234124739328],"hpluv":[2.79642975700151464,306.086943567777439,53.5002196972096158],"hsluv":[2.79642975700151464,84.310080928774866,53.5002196972096158]},"#ee3377":{"lch":[53.8992319384372252,122.709031404530748,357.759441587930837],"luv":[53.8992319384372252,122.615219389586755,-4.79732866099687261],"rgb":[0.933333333333333348,0.2,0.466666666666666674],"xyz":[0.397723023563402,0.218797947367586565,0.195823036031137238],"hpluv":[357.759441587930837,288.89051161323988,53.8992319384372252],"hsluv":[357.759441587930837,85.0909052409050872,53.8992319384372252]},"#ee3388":{"lch":[54.3705825415329,117.074862235921088,351.703100554939169],"luv":[54.3705825415329,115.849509832295894,-16.8942131860788436],"rgb":[0.933333333333333348,0.2,0.533333333333333326],"xyz":[0.408863440665345801,0.223254114208364163,0.254495899434709405],"hpluv":[351.703100554939169,273.2366774905733,54.3705825415329],"hsluv":[351.703100554939169,85.9285066952877,54.3705825415329]},"#ee3399":{"lch":[54.9151057717267292,112.774715889061866,344.730687431692274],"luv":[54.9151057717267292,108.793611621096844,-29.6999430015709507],"rgb":[0.933333333333333348,0.2,0.6],"xyz":[0.4219204047744185,0.22847689985199332,0.323262577075827284],"hpluv":[344.730687431692274,260.590898768244074,54.9151057717267292],"hsluv":[344.730687431692274,86.7978129198036896,54.9151057717267292]},"#ee33aa":{"lch":[55.5328602544255,110.325325240584178,337.093995035693695],"luv":[55.5328602544255,101.625579555338021,-42.9408776049389047],"rgb":[0.933333333333333348,0.2,0.66666666666666663],"xyz":[0.436978097739671056,0.234499977038094415,0.402566426692825885],"hpluv":[337.093995035693695,252.095155701888757,55.5328602544255],"hsluv":[337.093995035693695,87.6758366884225779,55.5328602544255]},"#ee33bb":{"lch":[56.2232062298057826,110.03895679054483,329.178007243031175],"luv":[56.2232062298057826,94.4974163460242664,-56.3809392922602726],"rgb":[0.933333333333333348,0.2,0.733333333333333282],"xyz":[0.454115689847007731,0.241355013881029173,0.492824411791467631],"hpluv":[329.178007243031175,248.353441541401367,56.2232062298057826],"hsluv":[329.178007243031175,88.5430404155392665,56.2232062298057826]},"#ee33cc":{"lch":[56.9848866198670123,111.971807156825847,321.417898872172259],"luv":[56.9848866198670123,87.5300782585605788,-69.8295854062993726],"rgb":[0.933333333333333348,0.2,0.8],"xyz":[0.47340806529072943,0.249071964058517975,0.594430922461737787],"hpluv":[321.417898872172259,249.337916143678171,56.9848866198670123],"hsluv":[321.417898872172259,89.3839737673679764,56.9848866198670123]},"#ee33dd":{"lch":[57.8161114567543848,115.945977330727956,314.185904182223908],"luv":[57.8161114567543848,80.813036999634221,-83.1427850752753557],"rgb":[0.933333333333333348,0.2,0.866666666666666696],"xyz":[0.494926390841363029,0.257679294278771509,0.707760770361743785],"hpluv":[314.185904182223908,254.475591939392586,57.8161114567543848],"hsluv":[314.185904182223908,90.1873197259471482,57.8161114567543848]},"#ee33ee":{"lch":[58.7146439354817886,121.632779311923699,307.715012949243715],"luv":[58.7146439354817886,74.4069479563921448,-96.2192241652253415],"rgb":[0.933333333333333348,0.2,0.933333333333333348],"xyz":[0.518738571107537738,0.267204166385241526,0.833171586430267],"hpluv":[307.715012949243715,262.87151341613469,58.7146439354817886],"hsluv":[307.715012949243715,90.9455375510239747,58.7146439354817886]},"#ee33ff":{"lch":[59.6778857977730581,128.651158016084139,302.091050100274117],"luv":[59.6778857977730581,68.3480180420837229,-108.993893813362092],"rgb":[0.933333333333333348,0.2,1],"xyz":[0.544909619517369159,0.27767258574917425,0.971005774722048853],"hpluv":[302.091050100274117,273.551812848380507,59.6778857977730581],"hsluv":[302.091050100274117,99.9999999999986784,59.6778857977730581]},"#ee4400":{"lch":[54.3591594970822598,145.188828472067655,17.4116852889838647],"luv":[54.3591594970822598,138.536177662057611,43.4456372018905412],"rgb":[0.933333333333333348,0.266666666666666663,0],"xyz":[0.373261401598505183,0.223145411354373546,0.023417812633377437],"hpluv":[17.4116852889838647,338.922026437804789,54.3591594970822598],"hsluv":[17.4116852889838647,100.000000000002217,54.3591594970822598]},"#ee4411":{"lch":[54.4016650840252112,143.940172045268554,16.9187727396215735],"luv":[54.4016650840252112,137.710194578710485,41.8888462184768713],"rgb":[0.933333333333333348,0.266666666666666663,0.0666666666666666657],"xyz":[0.374273067098142287,0.223550077554228399,0.0287459175981330667],"hpluv":[16.9187727396215735,335.744689025208913,54.4016650840252112],"hsluv":[16.9187727396215735,97.1754310281257574,54.4016650840252112]},"#ee4422":{"lch":[54.4803236312215944,141.690847159829417,15.9963876830432117],"luv":[54.4803236312215944,136.204446081142294,39.0467032744039173],"rgb":[0.933333333333333348,0.266666666666666663,0.133333333333333331],"xyz":[0.376148425236619344,0.224300220809619227,0.0386228037941122662],"hpluv":[15.9963876830432117,330.020900264600868,54.4803236312215944],"hsluv":[15.9963876830432117,92.0288025918740118,54.4803236312215944]},"#ee4433":{"lch":[54.6094526105793534,138.167821982121467,14.4538486850626899],"luv":[54.6094526105793534,133.794673004457735,34.4867004352900608],"rgb":[0.933333333333333348,0.266666666666666663,0.2],"xyz":[0.37923617596907705,0.225535321102602326,0.0548849576517234095],"hpluv":[14.4538486850626899,321.054243711338643,54.6094526105793534],"hsluv":[14.4538486850626899,83.7991355104008591,54.6094526105793534]},"#ee4444":{"lch":[54.7950558424119549,133.462657054844783,12.1770506300618084],"luv":[54.7950558424119549,130.459808710538397,28.151716454753565],"rgb":[0.933333333333333348,0.266666666666666663,0.266666666666666663],"xyz":[0.383694171213295965,0.22731851920028992,0.078363732604610048],"hpluv":[12.1770506300618084,309.070617226475065,54.7950558424119549],"hsluv":[12.1770506300618084,79.6495466444067546,54.7950558424119549]},"#ee4455":{"lch":[55.04178262974213,127.837203216659944,9.0482956458548145],"luv":[55.04178262974213,126.246413461005446,20.1045670057943724],"rgb":[0.933333333333333348,0.266666666666666663,0.333333333333333315],"xyz":[0.38965658525265795,0.229703484816034753,0.109765779878583963],"hpluv":[9.0482956458548145,294.716259365516066,55.04178262974213],"hsluv":[9.0482956458548145,80.0457187830871106,55.04178262974213]},"#ee4466":{"lch":[55.3531965298607105,121.710491561886229,4.95183922571805102],"luv":[55.3531965298607105,121.256220070521849,10.5058483924504795],"rgb":[0.933333333333333348,0.266666666666666663,0.4],"xyz":[0.397241581026166135,0.232737483125438044,0.149713424285727925],"hpluv":[4.95183922571805102,279.013127650855779,55.3531965298607105],"hsluv":[4.95183922571805102,80.511500113091131,55.3531965298607105]},"#ee4477":{"lch":[55.7319177265462855,115.631099927359429,359.795147057523252],"luv":[55.7319177265462855,115.63036086114974,-0.41342173536332294],"rgb":[0.933333333333333348,0.266666666666666663,0.466666666666666674],"xyz":[0.406555594046368041,0.236463088333518867,0.198767226192125834],"hpluv":[359.795147057523252,263.275227085929203,55.7319177265462855],"hsluv":[359.795147057523252,81.0316034214938412,55.7319177265462855]},"#ee4488":{"lch":[56.1797144871475069,110.229334232011354,353.550243523911263],"luv":[56.1797144871475069,109.531664472369371,-12.3822697089333467],"rgb":[0.933333333333333348,0.266666666666666663,0.533333333333333326],"xyz":[0.417696011148311841,0.240919255174296465,0.257440089595698],"hpluv":[353.550243523911263,248.975712077739217,56.1797144871475069],"hsluv":[353.550243523911263,81.5885451367485217,56.1797144871475069]},"#ee4499":{"lch":[56.6975745677487,106.142668326601637,346.310852745323245],"luv":[56.6975745677487,103.127575819694869,-25.1190992084518889],"rgb":[0.933333333333333348,0.266666666666666663,0.6],"xyz":[0.430752975257384541,0.246142040817925623,0.326206767236815909],"hpluv":[346.310852745323245,237.55536706581762,56.6975745677487],"hsluv":[346.310852745323245,82.1643886194057,56.6975745677487]},"#ee44aa":{"lch":[57.2857706939250164,103.913945498461985,338.339047623856459],"luv":[57.2857706939250164,96.5759938315173798,-38.356035828954532],"rgb":[0.933333333333333348,0.266666666666666663,0.66666666666666663],"xyz":[0.445810668222637096,0.252165118004026745,0.405510616853814509],"hpluv":[338.339047623856459,230.179372132151769,57.2857706939250164],"hsluv":[338.339047623856459,82.742186475039972,57.2857706939250164]},"#ee44bb":{"lch":[57.9439265752057224,103.883653730246948,330.054621671216069],"luv":[57.9439265752057224,90.015359877018625,-51.8560362788815183],"rgb":[0.933333333333333348,0.266666666666666663,0.733333333333333282],"xyz":[0.462948260329973771,0.259020154846961503,0.495768601952456256],"hpluv":[330.054621671216069,227.498543532010189,57.9439265752057224],"hsluv":[330.054621671216069,83.3069826860278,57.9439265752057224]},"#ee44cc":{"lch":[58.6710858878032866,106.123661593235155,321.940977409416575],"luv":[58.6710858878032866,83.5592367986741493,-65.4223623509468837],"rgb":[0.933333333333333348,0.266666666666666663,0.8],"xyz":[0.48224063577369547,0.266737105024450305,0.597375112622726356],"hpluv":[321.940977409416575,229.523641905846944,58.6710858878032866],"hsluv":[321.940977409416575,83.8463488142865288,58.6710858878032866]},"#ee44dd":{"lch":[59.4657843936948041,110.45324904546132,314.41066654104867],"luv":[59.4657843936948041,77.2947793232282407,-78.9014405069524116],"rgb":[0.933333333333333348,0.266666666666666663,0.866666666666666696],"xyz":[0.503758961324329069,0.275344435244703811,0.710704960522732354],"hpluv":[314.41066654104867,235.695163072106425,59.4657843936948041],"hsluv":[314.41066654104867,84.3505154479208699,59.4657843936948041]},"#ee44ee":{"lch":[60.3261240941145189,116.527805305600168,307.715012949243771],"luv":[60.3261240941145189,71.28406005268711,-92.180866733529669],"rgb":[0.933333333333333348,0.266666666666666663,0.933333333333333348],"xyz":[0.527571141590503778,0.284869307351173828,0.836115776591255577],"hpluv":[307.715012949243771,245.111377339321677,60.3261240941145189],"hsluv":[307.715012949243771,84.8122051950840898,60.3261240941145189]},"#ee44ff":{"lch":[61.2498476847862321,123.946828366557639,301.937515996566106],"luv":[61.2498476847862321,65.5671420475233617,-105.184438705774298],"rgb":[0.933333333333333348,0.266666666666666663,1],"xyz":[0.553742190000335199,0.295337726715106552,0.973949964883037422],"hpluv":[301.937515996566106,256.785047727470896,61.2498476847862321],"hsluv":[301.937515996566106,99.9999999999986073,61.2498476847862321]},"#ee5500":{"lch":[56.7595334156469136,135.29504726150742,20.5772435658132551],"luv":[56.7595334156469136,126.663115619922038,47.5521288161507414],"rgb":[0.933333333333333348,0.333333333333333315,0],"xyz":[0.385074658312851148,0.24677192478306581,0.0273555648714926478],"hpluv":[20.5772435658132551,302.470071141489655,56.7595334156469136],"hsluv":[20.5772435658132551,100.000000000002331,56.7595334156469136]},"#ee5511":{"lch":[56.7992830001534799,134.121232245619609,20.0864579205919],"luv":[56.7992830001534799,125.963368804879124,46.0622910677426],"rgb":[0.933333333333333348,0.333333333333333315,0.0666666666666666657],"xyz":[0.386086323812488252,0.247176590982920663,0.0326836698362482775],"hpluv":[20.0864579205919,299.636011805134103,56.7992830001534799],"hsluv":[20.0864579205919,97.4301566790671245,56.7992830001534799]},"#ee5522":{"lch":[56.8728535321199331,132.003018379302972,19.1666168944474329],"luv":[56.8728535321199331,124.685803630375247,43.3387498007741385],"rgb":[0.933333333333333348,0.333333333333333315,0.133333333333333331],"xyz":[0.387961681950965309,0.247926734238311491,0.042560556032227477],"hpluv":[19.1666168944474329,294.522290528054612,56.8728535321199331],"hsluv":[19.1666168944474329,92.7404035063857748,56.8728535321199331]},"#ee5533":{"lch":[56.9936637318031813,128.675597773649343,17.6241311186411558],"luv":[56.9936637318031813,122.635981466153211,38.9592801812266671],"rgb":[0.933333333333333348,0.333333333333333315,0.2],"xyz":[0.391049432683423,0.24916183453129459,0.0588227098898386203],"hpluv":[17.6241311186411558,286.489655583397507,56.9936637318031813],"hsluv":[17.6241311186411558,85.2217597168545353,56.9936637318031813]},"#ee5544":{"lch":[57.1673833238913431,124.212647444540593,15.3377586553938237],"luv":[57.1673833238913431,119.788604494467549,32.8553194848226298],"rgb":[0.933333333333333348,0.333333333333333315,0.266666666666666663],"xyz":[0.39550742792764193,0.250945032628982156,0.0823014848427252588],"hpluv":[15.3377586553938237,275.712737821839653,57.1673833238913431],"hsluv":[15.3377586553938237,78.8138286806830308,57.1673833238913431]},"#ee5555":{"lch":[57.3984455800741813,118.847398490007407,12.1770506300618084],"luv":[57.3984455800741813,116.173386735287238,25.068871978930396],"rgb":[0.933333333333333348,0.333333333333333315,0.333333333333333315],"xyz":[0.401469841967003915,0.253329998244727,0.113703532116699174],"hpluv":[12.1770506300618084,262.741620924066638,57.3984455800741813],"hsluv":[12.1770506300618084,79.1862648733910817,57.3984455800741813]},"#ee5566":{"lch":[57.6903015433249777,112.967028718059339,8.00617638558467881],"luv":[57.6903015433249777,111.865945908872092,15.7340307391382019],"rgb":[0.933333333333333348,0.333333333333333315,0.4],"xyz":[0.409054837740512101,0.256363996554130336,0.153651176523843136],"hpluv":[8.00617638558467881,248.478160638648092,57.6903015433249777],"hsluv":[8.00617638558467881,79.626682914648967,57.6903015433249777]},"#ee5577":{"lch":[58.0455538260385,107.095574323644513,2.70497781295448236],"luv":[58.0455538260385,106.976246145051803,5.05418642558356],"rgb":[0.933333333333333348,0.333333333333333315,0.466666666666666674],"xyz":[0.418368850760714,0.260089601762211131,0.202704978430241045],"hpluv":[2.70497781295448236,234.121819944652458,58.0455538260385],"hsluv":[2.70497781295448236,80.121743738144815,58.0455538260385]},"#ee5588":{"lch":[58.4660405277881523,101.857434077675435,356.214905006905212],"luv":[58.4660405277881523,101.63524992227579,-6.72405012805051783],"rgb":[0.933333333333333348,0.333333333333333315,0.533333333333333326],"xyz":[0.429509267862657806,0.264545768602988729,0.261377841833813185],"hpluv":[356.214905006905212,221.069268787819283,58.4660405277881523],"hsluv":[356.214905006905212,80.6557447307456385,58.4660405277881523]},"#ee5599":{"lch":[58.9528982622070714,97.9100075268454475,348.609359498013816],"luv":[58.9528982622070714,95.9815181358717808,-19.3369529719717974],"rgb":[0.933333333333333348,0.333333333333333315,0.6],"xyz":[0.442566231971730506,0.269768554246617887,0.33014451947493112],"hpluv":[348.609359498013816,210.746926462762332,58.9528982622070714],"hsluv":[348.609359498013816,81.2121283261168685,58.9528982622070714]},"#ee55aa":{"lch":[59.5066178042993812,95.8379147411847327,340.160257686713578],"luv":[59.5066178042993812,90.1495111294489817,-32.5264745255299346],"rgb":[0.933333333333333348,0.333333333333333315,0.66666666666666663],"xyz":[0.457623924936983062,0.275791631432719,0.40944836909192972],"hpluv":[340.160257686713578,204.36730380296666,59.5066178042993812],"hsluv":[340.160257686713578,81.7747968800248515,59.5066178042993812]},"#ee55bb":{"lch":[60.1270988419473156,96.02691270708236,331.338718337462637],"luv":[60.1270988419473156,84.2607812264238305,-46.0574501157669],"rgb":[0.933333333333333348,0.333333333333333315,0.733333333333333282],"xyz":[0.474761517044319736,0.282646668275653767,0.499706354190571467],"hpluv":[331.338718337462637,202.657202566236862,60.1270988419473156],"hsluv":[331.338718337462637,82.3290961128101202,60.1270988419473156]},"#ee55cc":{"lch":[60.8137066481247359,98.5745380895967855,322.704854800823],"luv":[60.8137066481247359,78.4184921400445774,-59.728382282288],"rgb":[0.933333333333333348,0.333333333333333315,0.8],"xyz":[0.494053892488041435,0.290363618453142569,0.601312864860841567],"hpluv":[322.704854800823,205.68499115665557,60.8137066481247359],"hsluv":[322.704854800823,82.862416210457269,60.8137066481247359]},"#ee55dd":{"lch":[61.5653314057239669,103.296154527471415,314.73674606959],"luv":[61.5653314057239669,72.7050419742243577,-73.3762387404091925],"rgb":[0.933333333333333348,0.333333333333333315,0.866666666666666696],"xyz":[0.515572218038675,0.298970948673396075,0.714642712760847565],"hpluv":[314.73674606959,212.905685416828703,61.5653314057239669],"hsluv":[314.73674606959,83.3644351442966496,61.5653314057239669]},"#ee55ee":{"lch":[62.3804497031794796,109.822432229930158,307.715012949243942],"luv":[62.3804497031794796,67.1821530808003473,-86.8764923804219364],"rgb":[0.933333333333333348,0.333333333333333315,0.933333333333333348],"xyz":[0.539384398304849744,0.308495820779866092,0.840053528829370788],"hpluv":[307.715012949243942,223.399338603574023,62.3804497031794796],"hsluv":[307.715012949243942,83.8270760150894318,62.3804497031794796]},"#ee55ff":{"lch":[63.2571870514493355,117.722992850638121,301.718618818209791],"luv":[63.2571870514493355,61.8926401270512301,-100.139922827085911],"rgb":[0.933333333333333348,0.333333333333333315,1],"xyz":[0.565555446714681165,0.318964240143798816,0.977887717121152633],"hpluv":[301.718618818209791,236.15152010236153,63.2571870514493355],"hsluv":[301.718618818209791,99.9999999999986358,63.2571870514493355]},"#ee6600":{"lch":[59.6010827175637274,124.896403377083828,24.7633991985742],"luv":[59.6010827175637274,113.411584725929117,52.315619335764687],"rgb":[0.933333333333333348,0.4,0],"xyz":[0.400102716018697624,0.276828040194759151,0.032364917440108],"hpluv":[24.7633991985742,265.910269095548301,59.6010827175637274],"hsluv":[24.7633991985742,100.000000000002458,59.6010827175637274]},"#ee6611":{"lch":[59.6379025762155521,123.785593795891074,24.2806773941880323],"luv":[59.6379025762155521,112.835768380983566,50.9014990474188],"rgb":[0.933333333333333348,0.4,0.0666666666666666657],"xyz":[0.401114381518334728,0.277232706394614,0.0376930224048636284],"hpluv":[24.2806773941880323,263.38259338209491,59.6379025762155521],"hsluv":[24.2806773941880323,97.6946368166697425,59.6379025762155521]},"#ee6622":{"lch":[59.7060621192549235,121.776511986799889,23.3741045361832462],"luv":[59.7060621192549235,111.782804083827386,48.312768320888857],"rgb":[0.933333333333333348,0.4,0.133333333333333331],"xyz":[0.402989739656811785,0.277982849650004804,0.0475699086008428279],"hpluv":[23.3741045361832462,258.812011755725052,59.7060621192549235],"hsluv":[23.3741045361832462,93.4807634058905847,59.7060621192549235]},"#ee6633":{"lch":[59.818019190990654,118.60827278102343,21.848413141726418],"luv":[59.818019190990654,110.088842330137865,44.1403349161252621],"rgb":[0.933333333333333348,0.4,0.2],"xyz":[0.406077490389269491,0.279217949942987931,0.0638320624584539642],"hpluv":[21.848413141726418,251.606745577849637,59.818019190990654],"hsluv":[21.848413141726418,86.7067277856042722,59.818019190990654]},"#ee6644":{"lch":[59.9790782653121,114.334087778781978,19.5741908506499591],"luv":[59.9790782653121,107.726545105393242,38.3050271878496318],"rgb":[0.933333333333333348,0.4,0.266666666666666663],"xyz":[0.410535485633488406,0.281001148040675497,0.0873108374113406],"hpluv":[19.5741908506499591,241.888527179759762,59.9790782653121],"hsluv":[19.5741908506499591,77.7164494297015551,59.9790782653121]},"#ee6655":{"lch":[60.1934276072459227,109.155383321287928,16.4048569251700904],"luv":[60.1934276072459227,104.711671726378157,30.827966398783424],"rgb":[0.933333333333333348,0.4,0.333333333333333315],"xyz":[0.416497899672850391,0.283386113656420358,0.118712884685314518],"hpluv":[16.4048569251700904,230.109957101660228,60.1934276072459227],"hsluv":[16.4048569251700904,78.0627041699660822,60.1934276072459227]},"#ee6666":{"lch":[60.4643778553048179,103.423697151150392,12.1770506300619203],"luv":[60.4643778553048179,101.096711576265875,21.8155000143976636],"rgb":[0.933333333333333348,0.4,0.4],"xyz":[0.424082895446358576,0.286420111965823676,0.15866052909245848],"hpluv":[12.1770506300619203,217.050003231938149,60.4643778553048179],"hsluv":[12.1770506300619203,78.4746058088251601,60.4643778553048179]},"#ee6677":{"lch":[60.7944870758990845,97.6355083856116,6.72933164538236728],"luv":[60.7944870758990845,96.9628770314166388,11.4408468002682859],"rgb":[0.933333333333333348,0.4,0.466666666666666674],"xyz":[0.433396908466560482,0.290145717173904472,0.207714330998856389],"hpluv":[6.72933164538236728,203.79002370037793,60.7944870758990845],"hsluv":[6.72933164538236728,78.9407958828298177,60.7944870758990845]},"#ee6688":{"lch":[61.1856375663111294,92.4106294683140419,359.951978350089689],"luv":[61.1856375663111294,92.4105970103857,-0.0774526573243247418],"rgb":[0.933333333333333348,0.4,0.533333333333333326],"xyz":[0.444537325568504282,0.294601884014682069,0.266387194402428529],"hpluv":[359.951978350089689,191.6512981090967,61.1856375663111294],"hsluv":[359.951978350089689,79.4474583444281706,61.1856375663111294]},"#ee6699":{"lch":[61.6390913266860281,88.437141466109523,351.875732288608958],"luv":[61.6390913266860281,87.5495765855601746,-12.4979850530316181],"rgb":[0.933333333333333348,0.4,0.6],"xyz":[0.457594289677577,0.299824669658311227,0.335153872043546464],"hpluv":[351.875732288608958,182.061365307506776,61.6390913266860281],"hsluv":[351.875732288608958,79.9795786975914353,61.6390913266860281]},"#ee66aa":{"lch":[62.1555369290736337,86.3639450462453624,342.77320214224],"luv":[62.1555369290736337,82.489654306882187,-25.5770978862333536],"rgb":[0.933333333333333348,0.4,0.66666666666666663],"xyz":[0.472651982642829538,0.305847746844412349,0.414457721660545064],"hpluv":[342.77320214224,176.316102232879075,62.1555369290736337],"hsluv":[342.77320214224,80.5221008496243,62.1555369290736337]},"#ee66bb":{"lch":[62.735134131647655,86.6495273870251168,333.187217955259598],"luv":[62.735134131647655,77.3334216921159765,-39.0855790002422907],"rgb":[0.933333333333333348,0.4,0.733333333333333282],"xyz":[0.489789574750166212,0.312702783687347108,0.504715706759186755],"hpluv":[333.187217955259598,175.264796900814019,62.735134131647655],"hsluv":[333.187217955259598,81.0608551813628679,62.735134131647655]},"#ee66cc":{"lch":[63.3775592853136516,89.4351699392481549,323.800511847500275],"luv":[63.3775592853136516,72.1711045195964545,-52.8202735176909144],"rgb":[0.933333333333333348,0.4,0.8],"xyz":[0.509081950193887911,0.320419733864835909,0.606322217429456911],"hpluv":[323.800511847500275,179.065596131410075,63.3775592853136516],"hsluv":[323.800511847500275,81.5831918811758072,63.3775592853136516]},"#ee66dd":{"lch":[64.0820526997291751,94.5324861988586918,315.200217206616742],"luv":[64.0820526997291751,67.0777383779463179,-66.6105694393704795],"rgb":[0.933333333333333348,0.4,0.866666666666666696],"xyz":[0.53060027574452151,0.329027064085089416,0.719652065329462909],"hpluv":[315.200217206616742,187.190580763285084,64.0820526997291751],"hsluv":[315.200217206616742,82.0783141076240241,64.0820526997291751]},"#ee66ee":{"lch":[64.8474680131467,101.534802649490857,307.715012949244169],"luv":[64.8474680131467,62.1123254704966499,-80.32045302236628],"rgb":[0.933333333333333348,0.4,0.933333333333333348],"xyz":[0.55441245601069622,0.338551936191559433,0.845062881397986132],"hpluv":[307.715012949244169,198.683239249207219,64.8474680131467],"hsluv":[307.715012949244169,82.5373501246235,64.8474680131467]},"#ee66ff":{"lch":[65.6723229483953759,109.966867844968618,301.415067453827589],"luv":[65.6723229483953759,57.3184789471434897,-93.8472375449520797],"rgb":[0.933333333333333348,0.4,1],"xyz":[0.580583504420527641,0.349020355555492157,0.982897069689768088],"hpluv":[301.415067453827589,212.480364902930489,65.6723229483953759],"hsluv":[301.415067453827589,99.9999999999984794,65.6723229483953759]},"#ee7700":{"lch":[62.8217158048736763,114.851740825540901,30.0981414692213356],"luv":[62.8217158048736763,99.3660150566978,57.5961580525066097],"rgb":[0.933333333333333348,0.466666666666666674,0],"xyz":[0.418556454072115225,0.313735516301594908,0.0385161634579137],"hpluv":[30.0981414692213356,231.988851559171735,62.8217158048736763],"hsluv":[30.0981414692213356,100.000000000002203,62.8217158048736763]},"#ee7711":{"lch":[62.8555901763931075,113.786950077776382,29.6341042910547],"luv":[62.8555901763931075,98.9037041004629458,56.2630191441096059],"rgb":[0.933333333333333348,0.466666666666666674,0.0666666666666666657],"xyz":[0.419568119571752329,0.314140182501449761,0.0438442684226693288],"hpluv":[29.6341042910547,229.71421718860654,62.8555901763931075],"hsluv":[29.6341042910547,97.9532933827149463,62.8555901763931075]},"#ee7722":{"lch":[62.9183073649527955,111.855609649988921,28.7604537228304977],"luv":[62.9183073649527955,98.0569879769147406,53.8191835600085398],"rgb":[0.933333333333333348,0.466666666666666674,0.133333333333333331],"xyz":[0.421443477710229386,0.314890325756840561,0.0537211546186485284],"hpluv":[28.7604537228304977,225.59011469442973,62.9183073649527955],"hsluv":[28.7604537228304977,94.206312745702121,62.9183073649527955]},"#ee7733":{"lch":[63.0213536795682501,108.794922632811733,27.2836719807386174],"luv":[63.0213536795682501,96.6912591797812411,49.8711899688373208],"rgb":[0.933333333333333348,0.466666666666666674,0.2],"xyz":[0.424531228442687092,0.316125426049823688,0.0699833084762596647],"hpluv":[27.2836719807386174,219.058559128587405,63.0213536795682501],"hsluv":[27.2836719807386174,88.1668112455654,63.0213536795682501]},"#ee7744":{"lch":[63.1696562136619235,104.634411539935968,25.0668522383795889],"luv":[63.1696562136619235,94.7793214210065571,44.3310309972846497],"rgb":[0.933333333333333348,0.466666666666666674,0.266666666666666663],"xyz":[0.428989223686906,0.317908624147511254,0.0934620834291463],"hpluv":[25.0668522383795889,210.186756956079222,63.1696562136619235],"hsluv":[25.0668522383795889,79.7210233436604199,63.1696562136619235]},"#ee7755":{"lch":[63.3671413614491286,99.5393983003294096,21.9455950678528],"luv":[63.3671413614491286,92.3266881357997278,37.2004633286522051],"rgb":[0.933333333333333348,0.466666666666666674,0.333333333333333315],"xyz":[0.434951637726268,0.320293589763256115,0.124864130703120219],"hpluv":[21.9455950678528,199.328877993420377,63.3671413614491286],"hsluv":[21.9455950678528,76.6090179557391,63.3671413614491286]},"#ee7766":{"lch":[63.6169573916324822,93.8195852400781263,17.7221756586824775],"luv":[63.6169573916324822,89.367258373090749,28.5588463614608763],"rgb":[0.933333333333333348,0.466666666666666674,0.4],"xyz":[0.442536633499776177,0.323327588072659433,0.16481177511026418],"hpluv":[17.7221756586824775,187.13711975631665,63.6169573916324822],"hsluv":[17.7221756586824775,76.9903860669667,63.6169573916324822]},"#ee7777":{"lch":[63.9215909451051232,87.936547917610838,12.1770506300618937],"luv":[63.9215909451051232,85.9580160709841863,18.5487447771187846],"rgb":[0.933333333333333348,0.466666666666666674,0.466666666666666674],"xyz":[0.451850646519978083,0.327053193280740229,0.21386557701666209],"hpluv":[12.1770506300618937,174.56660414904394,63.9215909451051232],"hsluv":[12.1770506300618937,77.4248320836617268,63.9215909451051232]},"#ee7788":{"lch":[64.2829374304473,82.5014209284754543,5.11726519711922112],"luv":[64.2829374304473,82.1725895095950847,7.35866757674724514],"rgb":[0.933333333333333348,0.466666666666666674,0.533333333333333326],"xyz":[0.462991063621921883,0.331509360121517827,0.272538440420234229],"hpluv":[5.11726519711922112,162.85647909200884,64.2829374304473],"hsluv":[5.11726519711922112,77.9003779592442669,64.2829374304473]},"#ee7799":{"lch":[64.7023501026032477,78.2413537817778177,356.48599323172067],"luv":[64.7023501026032477,78.0942478632934893,-4.79561177242263259],"rgb":[0.933333333333333348,0.466666666666666674,0.6],"xyz":[0.476048027730994638,0.336732145765147,0.341305118061352164],"hpluv":[356.48599323172067,153.446019679421255,64.7023501026032477],"hsluv":[356.48599323172067,78.4035888028378167,64.7023501026032477]},"#ee77aa":{"lch":[65.1806796634753596,75.8992199041959,346.522692233148291],"luv":[65.1806796634753596,73.8091300431969302,-17.6890899803221124],"rgb":[0.933333333333333348,0.466666666666666674,0.66666666666666663],"xyz":[0.491105720696247139,0.342755222951248106,0.420608967678350765],"hpluv":[346.522692233148291,147.76029654451807,65.1806796634753596],"hsluv":[346.522692233148291,78.9205551316135256,65.1806796634753596]},"#ee77bb":{"lch":[65.7183104585581646,76.0514193956389875,335.85959217762661],"luv":[65.7183104585581646,69.4004166910179094,-31.1030634376174824],"rgb":[0.933333333333333348,0.466666666666666674,0.733333333333333282],"xyz":[0.508243312803583813,0.349610259794182865,0.510866952776992456],"hpluv":[335.85959217762661,146.845370988132231,65.7183104585581646],"hsluv":[335.85959217762661,79.4377328719524627,65.7183104585581646]},"#ee77cc":{"lch":[66.3151963922866,78.9180750862202416,325.378996221060731],"luv":[66.3151963922866,64.9439055461397459,-44.8369457894756067],"rgb":[0.933333333333333348,0.466666666666666674,0.8],"xyz":[0.527535688247305568,0.357327209971671667,0.612473463447262612],"hpluv":[325.378996221060731,151.008971652655617,66.3151963922866],"hsluv":[325.378996221060731,79.9425706591808307,66.3151963922866]},"#ee77dd":{"lch":[66.9708980107196652,84.3115421117289543,315.859798591258766],"luv":[66.9708980107196652,60.5051526262217152,-58.7159487612646842],"rgb":[0.933333333333333348,0.466666666666666674,0.866666666666666696],"xyz":[0.549054013797939056,0.365934540191925173,0.725803311347268609],"hpluv":[315.859798591258766,159.749768323538632,66.9708980107196652],"hsluv":[315.859798591258766,80.4238985377879345,66.9708980107196652]},"#ee77ee":{"lch":[67.6846211881785251,91.7687338274624409,307.715012949244453],"luv":[67.6846211881785251,56.1380858067324056,-72.5948746830766112],"rgb":[0.933333333333333348,0.466666666666666674,0.933333333333333348],"xyz":[0.572866194064113765,0.37545941229839519,0.851214127415791832],"hpluv":[307.715012949244453,172.045795420537047,67.6846211881785251],"hsluv":[307.715012949244453,80.8720902094370757,67.6846211881785251]},"#ee77ff":{"lch":[68.4552572311626761,100.746525491660947,300.997699928034137],"luv":[68.4552572311626761,51.8848298156272918,-86.3587102361150585],"rgb":[0.933333333333333348,0.466666666666666674,1],"xyz":[0.599037242473945186,0.385927831662327914,0.989048315707573789],"hpluv":[300.997699928034137,186.750854251257437,68.4552572311626761],"hsluv":[300.997699928034137,99.9999999999982,68.4552572311626761]},"#ee8800":{"lch":[66.3576417146455,105.981377873447272,36.6492300119340797],"luv":[66.3576417146455,85.0293774107247771,63.2618165491550428],"rgb":[0.933333333333333348,0.533333333333333326,0],"xyz":[0.440628823797085678,0.35788025575153648,0.045873620032903642],"hpluv":[36.6492300119340797,202.664622836431278,66.3576417146455],"hsluv":[36.6492300119340797,100.000000000002288,66.3576417146455]},"#ee8811":{"lch":[66.3886714607036907,104.946342152180421,36.2201184819273792],"luv":[66.3886714607036907,84.6657638625926552,62.0116373004794923],"rgb":[0.933333333333333348,0.533333333333333326,0.0666666666666666657],"xyz":[0.441640489296722782,0.358284921951391333,0.0512017249976592717],"hpluv":[36.2201184819273792,200.591559481147556,66.3886714607036907],"hsluv":[36.2201184819273792,98.1954604930108701,66.3886714607036907]},"#ee8822":{"lch":[66.4461305943750773,103.062674429887437,35.4099902294173745],"luv":[66.4461305943750773,83.9988395226221201,59.7169140151578],"rgb":[0.933333333333333348,0.533333333333333326,0.133333333333333331],"xyz":[0.443515847435199839,0.359035065206782134,0.0610786111936384712],"hpluv":[35.4099902294173745,196.820821024497235,66.4461305943750773],"hsluv":[35.4099902294173745,94.8869488142181581,66.4461305943750773]},"#ee8833":{"lch":[66.5405621290638578,100.059958052790449,34.0337853874148877],"luv":[66.5405621290638578,82.920456825626232,56.0017235927220369],"rgb":[0.933333333333333348,0.533333333333333326,0.2],"xyz":[0.446603598167657545,0.36027016549976526,0.0773407650512496214],"hpluv":[34.0337853874148877,190.815292572549708,66.5405621290638578],"hsluv":[34.0337853874148877,89.5408718212573689,66.5405621290638578]},"#ee8844":{"lch":[66.6765193585480347,95.9403990837829639,31.9512880443390657],"luv":[66.6765193585480347,81.4052672986078107,50.7714745934935223],"rgb":[0.933333333333333348,0.533333333333333326,0.266666666666666663],"xyz":[0.45106159341187646,0.362053363597452826,0.10081954000413626],"hpluv":[31.9512880443390657,182.586190035925256,66.6765193585480347],"hsluv":[31.9512880443390657,82.0371002457568608,66.6765193585480347]},"#ee8855":{"lch":[66.8576614114874559,90.8274017958005,28.983496619036984],"luv":[66.8576614114874559,79.4521157428502391,44.0111147434430805],"rgb":[0.933333333333333348,0.533333333333333326,0.333333333333333315],"xyz":[0.457024007451238445,0.364438329213197687,0.132221587278110175],"hpluv":[28.983496619036984,172.387208051834335,66.8576614114874559],"hsluv":[28.983496619036984,74.7174368883009663,66.8576614114874559]},"#ee8866":{"lch":[67.0869600103699213,84.978663004295683,24.8971939400565283],"luv":[67.0869600103699213,77.081139807049837,35.7752854921339249],"rgb":[0.933333333333333348,0.533333333333333326,0.4],"xyz":[0.464609003224746631,0.367472327522601,0.172169231685254109],"hpluv":[24.8971939400565283,160.735241770302764,67.0869600103699213],"hsluv":[24.8971939400565283,75.0669061044520447,67.0869600103699213]},"#ee8877":{"lch":[67.3668077908477727,78.8051510957513841,19.4009345351312952],"luv":[67.3668077908477727,74.3303771171996743,26.1772205713113095],"rgb":[0.933333333333333348,0.533333333333333326,0.466666666666666674],"xyz":[0.473923016244948536,0.371197932730681801,0.221223033591652019],"hpluv":[19.4009345351312952,148.438980876884,67.3668077908477727],"hsluv":[19.4009345351312952,75.4672397967126329,67.3668077908477727]},"#ee8888":{"lch":[67.6990830402889117,72.8916076032019191,12.177050630062066],"luv":[67.6990830402889117,71.2515799877231757,15.3752661190709663],"rgb":[0.933333333333333348,0.533333333333333326,0.533333333333333326],"xyz":[0.485063433346892336,0.375654099571459399,0.279895896995224214],"hpluv":[12.177050630062066,136.626224949154164,67.6990830402889117],"hsluv":[12.177050630062066,75.9081099773692927,67.6990830402889117]},"#ee8899":{"lch":[68.0851935471165319,67.9986383575237312,2.99916583787236446],"luv":[68.0851935471165319,67.9055003914663615,3.55778513430191889],"rgb":[0.933333333333333348,0.533333333333333326,0.6],"xyz":[0.498120397455965036,0.380876885215088556,0.348662574636342093],"hpluv":[2.99916583787236446,126.732168582193651,68.0851935471165319],"hsluv":[2.99916583787236446,76.3775584855855385,68.0851935471165319]},"#ee88aa":{"lch":[68.5261104708773274,64.9933943358063573,351.976176804910949],"luv":[68.5261104708773274,64.3571165389368,-9.07209226602857832],"rgb":[0.933333333333333348,0.533333333333333326,0.66666666666666663],"xyz":[0.513178090421217648,0.386899962401189679,0.427966424253340694],"hpluv":[351.976176804910949,120.351764916629207,68.5261104708773274],"hsluv":[351.976176804910949,76.8628030471707859,68.5261104708773274]},"#ee88bb":{"lch":[69.0223979406526098,64.6433047463018,339.810246341231903],"luv":[69.0223979406526098,60.6712812589502875,-22.3103670727442456],"rgb":[0.933333333333333348,0.533333333333333326,0.733333333333333282],"xyz":[0.530315682528554211,0.393754999244124437,0.51822440935198244],"hpluv":[339.810246341231903,118.842788638920595,69.0223979406526098],"hsluv":[339.810246341231903,77.3509666785266887,69.0223979406526098]},"#ee88cc":{"lch":[69.5742414545850778,67.3203562589766307,327.709288072293873],"luv":[69.5742414545850778,56.9091584539883399,-35.9635656031820687],"rgb":[0.933333333333333348,0.533333333333333326,0.8],"xyz":[0.549608057972276,0.401471949421613239,0.619830920022252596],"hpluv":[327.709288072293873,122.782720563937247,69.5742414545850778],"hsluv":[327.709288072293873,77.8296635442389686,69.5742414545850778]},"#ee88dd":{"lch":[70.1814766713242,72.856404222049747,316.817937357318669],"luv":[70.1814766713242,53.1256441200966663,-49.8570112721525547],"rgb":[0.933333333333333348,0.533333333333333326,0.866666666666666696],"xyz":[0.571126383522909564,0.410079279641866745,0.733160767922258594],"hpluv":[316.817937357318669,131.729959343498166,70.1814766713242],"hsluv":[316.817937357318669,78.2874043120714163,70.1814766713242]},"#ee88ee":{"lch":[70.8436192863675558,80.7013698438951224,307.715012949244851],"luv":[70.8436192863675558,49.367799206375345,-63.839889537812887],"rgb":[0.933333333333333348,0.533333333333333326,0.933333333333333348],"xyz":[0.594938563789084274,0.419604151748336762,0.858571583990781817],"hpluv":[307.715012949244851,144.550464850223619,70.8436192863675558],"hsluv":[307.715012949244851,78.7138135635212848,70.8436192863675558]},"#ee88ff":{"lch":[71.5598961203093182,90.2054153167292583,300.42003582834775],"luv":[71.5598961203093182,45.674190228859068,-77.7874366424399426],"rgb":[0.933333333333333348,0.533333333333333326,1],"xyz":[0.621109612198915695,0.430072571112269486,0.996405772282563662],"hpluv":[300.42003582834775,159.956626210428567,71.5598961203093182],"hsluv":[300.42003582834775,99.99999999999784,71.5598961203093182]},"#ee9900":{"lch":[70.1492527845175715,98.9919938823364731,44.3502140795235036],"luv":[70.1492527845175715,70.7872313214223112,69.1995862317686772],"rgb":[0.933333333333333348,0.6,0],"xyz":[0.466498424249553179,0.409619456656472147,0.0544968201837259],"hpluv":[44.3502140795235036,179.06732625175573,70.1492527845175715],"hsluv":[44.3502140795235036,100.000000000002217,70.1492527845175715]},"#ee9911":{"lch":[70.1776126165771785,97.9766822185852533,43.9766782844564119],"luv":[70.1776126165771785,70.5062245085518526,68.0316291449155273],"rgb":[0.933333333333333348,0.6,0.0666666666666666657],"xyz":[0.467510089749190283,0.410024122856327,0.0598249251484815267],"hpluv":[43.9766782844564119,177.15910010767405,70.1776126165771785],"hsluv":[43.9766782844564119,98.4152296143538337,70.1776126165771785]},"#ee9922":{"lch":[70.2301348691785,96.1222676294158447,43.2696050504519505],"luv":[70.2301348691785,69.9901292501651824,65.8852953379296622],"rgb":[0.933333333333333348,0.6,0.133333333333333331],"xyz":[0.46938544788766734,0.410774266111717801,0.0697018113444607262],"hpluv":[43.2696050504519505,173.676009463775955,70.2301348691785],"hsluv":[43.2696050504519505,95.5057584668238,70.2301348691785]},"#ee9933":{"lch":[70.3164728806357573,93.1473438817036339,42.0626701373461103],"luv":[70.3164728806357573,69.1537511222041417,62.4034163964169508],"rgb":[0.933333333333333348,0.6,0.2],"xyz":[0.472473198620125046,0.412009366404700927,0.0859639652020718625],"hpluv":[42.0626701373461103,168.094198140054317,70.3164728806357573],"hsluv":[42.0626701373461103,90.7937976503380213,70.3164728806357573]},"#ee9944":{"lch":[70.4408210614760719,89.024296887742608,40.221678197216157],"luv":[70.4408210614760719,67.9746586813449483,57.4871395488729533],"rgb":[0.933333333333333348,0.6,0.266666666666666663],"xyz":[0.476931193864343961,0.413792564502388494,0.109442740154958501],"hpluv":[40.221678197216157,160.370125602871781,70.4408210614760719],"hsluv":[40.221678197216157,84.1577311163605657,70.4408210614760719]},"#ee9955":{"lch":[70.6065752665828654,83.8291063606938138,37.5652459120346904],"luv":[70.6065752665828654,66.4479455240540631,51.1076276974862154],"rgb":[0.933333333333333348,0.6,0.333333333333333315],"xyz":[0.482893607903705946,0.416177530118133354,0.140844787428932416],"hpluv":[37.5652459120346904,150.656896294971034,70.6065752665828654],"hsluv":[37.5652459120346904,75.5772228053980797,70.6065752665828654]},"#ee9966":{"lch":[70.8165243284349373,77.7550236522342,33.8383101580563],"luv":[70.8165243284349373,64.5842808158336652,43.297971946282189],"rgb":[0.933333333333333348,0.6,0.4],"xyz":[0.490478603677214131,0.419211528427536673,0.180792431836076378],"hpluv":[33.8383101580563,139.326323276972687,70.8165243284349373],"hsluv":[33.8383101580563,72.525293376848623,70.8165243284349373]},"#ee9977":{"lch":[71.0729506656700778,71.1378337295946,28.6840524218341386],"luv":[71.0729506656700778,62.4077841236731601,34.1446901949989154],"rgb":[0.933333333333333348,0.6,0.466666666666666674],"xyz":[0.499792616697416037,0.422937133635617468,0.229846233742474287],"hpluv":[28.6840524218341386,127.009327518651787,71.0729506656700778],"hsluv":[28.6840524218341386,72.8885787597460677,71.0729506656700778]},"#ee9988":{"lch":[71.3776900371935312,64.4963091800695878,21.6331741754282376],"luv":[71.3776900371935312,59.9533946760230378,23.7773918811996943],"rgb":[0.933333333333333348,0.6,0.533333333333333326],"xyz":[0.510933033799359837,0.427393300476395066,0.288519097146046455],"hpluv":[21.6331741754282376,114.659937381049531,71.3776900371935312],"hsluv":[21.6331741754282376,73.2902809537896189,71.3776900371935312]},"#ee9999":{"lch":[71.732171153908709,58.5818834203282179,12.1770506300621602],"luv":[71.732171153908709,57.263818011494017,12.3568690136061505],"rgb":[0.933333333333333348,0.6,0.6],"xyz":[0.523989997908432592,0.432616086120024224,0.35728577478716439],"hpluv":[12.1770506300621602,103.630759412975706,71.732171153908709],"hsluv":[12.1770506300621602,73.7196701825771186,71.732171153908709]},"#ee99aa":{"lch":[72.1374451439022408,54.3863410009709725,0.0659165211073427237],"luv":[72.1374451439022408,54.3863050092105,0.0625693137293968082],"rgb":[0.933333333333333348,0.6,0.66666666666666663],"xyz":[0.539047690873685093,0.438639163306125346,0.436589624404162935],"hpluv":[0.0659165211073427237,95.6683780017161,72.1374451439022408],"hsluv":[0.0659165211073427237,74.1649147609968082,72.1374451439022408]},"#ee99bb":{"lch":[72.5942101669252366,52.9692652640659247,345.882936464906891],"luv":[72.5942101669252366,51.3695627363271683,-12.9194073739288822],"rgb":[0.933333333333333348,0.6,0.733333333333333282],"xyz":[0.556185282981021767,0.445494200149060104,0.526847609502804737],"hpluv":[345.882936464906891,92.5894045166522091,72.5942101669252366],"hsluv":[345.882936464906891,74.6136876066909878,72.5942101669252366]},"#ee99cc":{"lch":[73.1028341171650737,55.013164482536844,331.314039518972208],"luv":[73.1028341171650737,48.2610582375421515,-26.4067893575727517],"rgb":[0.933333333333333348,0.6,0.8],"xyz":[0.575477658424743521,0.453211150326548906,0.628454120173074893],"hpluv":[331.314039518972208,95.4930444317639342,73.1028341171650737],"hsluv":[331.314039518972208,75.0536815693659491,73.1028341171650737]},"#ee99dd":{"lch":[73.6633770412179274,60.4388711558699896,318.269971219550712],"luv":[73.6633770412179274,45.1048908137830935,-40.2294167403973049],"rgb":[0.933333333333333348,0.6,0.866666666666666696],"xyz":[0.596995983975377,0.461818480546802412,0.74178396807308089],"hpluv":[318.269971219550712,104.112780668711437,73.6633770412179274],"hsluv":[318.269971219550712,75.472992612571872,73.6633770412179274]},"#ee99ee":{"lch":[74.2756141069900337,68.5596754700476083,307.71501294924542],"luv":[74.2756141069900337,41.9403078139404499,-54.2350410807456953],"rgb":[0.933333333333333348,0.6,0.933333333333333348],"xyz":[0.620808164241551719,0.471343352653272429,0.867194784141604114],"hpluv":[307.71501294924542,117.128296895720368,74.2756141069900337],"hsluv":[307.71501294924542,75.8603506282489235,74.2756141069900337]},"#ee99ff":{"lch":[74.9390594560707,78.5455210447045857,299.603294913962486],"luv":[74.9390594560707,38.8008486558083519,-68.2927010724659],"rgb":[0.933333333333333348,0.6,1],"xyz":[0.64697921265138314,0.481811772017205153,1.00502897243338585],"hpluv":[299.603294913962486,133.000267199001968,74.9390594560707],"hsluv":[299.603294913962486,99.9999999999973284,74.9390594560707]},"#dd0000":{"lch":[46.1435564305616239,155.182233977468201,12.1770506300617765],"luv":[46.1435564305616239,151.69070515099267,32.7330981276182555],"rgb":[0.866666666666666696,0,0],"xyz":[0.298181282529475455,0.153749723804264049,0.0139772476185688679],"hpluv":[12.1770506300617765,426.746789183125316,46.1435564305616239],"hsluv":[12.1770506300617765,100.000000000002217,46.1435564305616239]},"#dd0011":{"lch":[46.1980288678146636,153.577384001942391,11.5987087531524224],"luv":[46.1980288678146636,150.441300178721519,30.8776306962803169],"rgb":[0.866666666666666696,0,0.0666666666666666657],"xyz":[0.29919294802911256,0.154154390004118902,0.0193053525833244977],"hpluv":[11.5987087531524224,421.835520233675084,46.1980288678146636],"hsluv":[11.5987087531524224,99.9999999999964473,46.1980288678146636]},"#dd0022":{"lch":[46.2987546285526292,150.712226421231577,10.5179424282654246],"luv":[46.2987546285526292,148.17992816752087,27.5115263319381462],"rgb":[0.866666666666666696,0,0.133333333333333331],"xyz":[0.301068306167589617,0.15490453325950973,0.0291822387793036972],"hpluv":[10.5179424282654246,413.065099977246746,46.2987546285526292],"hsluv":[10.5179424282654246,99.9999999999964615,46.2987546285526292]},"#dd0033":{"lch":[46.4638920568500637,146.293058552209629,8.71533624525386585],"luv":[46.4638920568500637,144.603865814948932,22.1671146505918131],"rgb":[0.866666666666666696,0,0.2],"xyz":[0.304156056900047322,0.156139633552492829,0.0454443926369148404],"hpluv":[8.71533624525386585,399.528220173505417,46.4638920568500637],"hsluv":[8.71533624525386585,99.9999999999966,46.4638920568500637]},"#dd0044":{"lch":[46.7007828741672242,140.527307525302433,6.06736355557067153],"luv":[46.7007828741672242,139.740117429456177,14.853408400522655],"rgb":[0.866666666666666696,0,0.266666666666666663],"xyz":[0.308614052144266238,0.157922831650180423,0.0689231675898014789],"hpluv":[6.06736355557067153,381.835137536210595,46.7007828741672242],"hsluv":[6.06736355557067153,99.9999999999967315,46.7007828741672242]},"#dd0055":{"lch":[47.0148448700731194,133.854751810486647,2.4577968894866693],"luv":[47.0148448700731194,133.731616129679537,5.74015936982693],"rgb":[0.866666666666666696,0,0.333333333333333315],"xyz":[0.314576466183628223,0.160307797265925256,0.10032521486377538],"hpluv":[2.4577968894866693,361.275168455412427,47.0148448700731194],"hsluv":[2.4577968894866693,99.9999999999969873,47.0148448700731194]},"#dd0066":{"lch":[47.4099042919878073,126.898325188331157,357.792852491951692],"luv":[47.4099042919878073,126.80418183984473,-4.88716722969802841],"rgb":[0.866666666666666696,0,0.4],"xyz":[0.322161461957136408,0.163341795575328547,0.140272859270919342],"hpluv":[357.792852491951692,339.645713706877359,47.4099042919878073],"hsluv":[357.792852491951692,99.9999999999972857,47.4099042919878073]},"#dd0077":{"lch":[47.8883827301537,120.388643903007392,352.036106438093952],"luv":[47.8883827301537,119.227564738695264,-16.6797298325047478],"rgb":[0.866666666666666696,0,0.466666666666666674],"xyz":[0.331475474977338314,0.16706740078340937,0.189326661177317251],"hpluv":[352.036106438093952,319.002934776287759,47.8883827301537],"hsluv":[352.036106438093952,99.9999999999974136,47.8883827301537]},"#dd0088":{"lch":[48.4514347566520058,115.064311489444805,345.260130057314882],"luv":[48.4514347566520058,111.277652945923506,-29.2759241252361342],"rgb":[0.866666666666666696,0,0.533333333333333326],"xyz":[0.342615892079282114,0.171523567624186968,0.247999524580889419],"hpluv":[345.260130057314882,301.351479235409442,48.4514347566520058],"hsluv":[345.260130057314882,99.9999999999976836,48.4514347566520058]},"#dd0099":{"lch":[49.0990738312553816,111.554442433955828,337.69359677942],"luv":[49.0990738312553816,103.206522936464793,-42.3415546492536166],"rgb":[0.866666666666666696,0,0.6],"xyz":[0.355672856188354869,0.176746353267816125,0.316766202222007354],"hpluv":[337.69359677942,288.305479360883112,49.0990738312553816],"hsluv":[337.69359677942,99.9999999999979252,49.0990738312553816]},"#dd00aa":{"lch":[49.8303011832281442,110.265023964610052,329.72204926251294],"luv":[49.8303011832281442,95.2237329190616606,-55.5951094870335041],"rgb":[0.866666666666666696,0,0.66666666666666663],"xyz":[0.370730549153607369,0.18276943045391722,0.396070051839005954],"hpluv":[329.72204926251294,280.791263168904948,49.8303011832281442],"hsluv":[329.72204926251294,99.9999999999981526,49.8303011832281442]},"#dd00bb":{"lch":[50.6432416523731064,111.311454300018838,321.811503537589374],"luv":[50.6432416523731064,87.4886923962170613,-68.8183737179635244],"rgb":[0.866666666666666696,0,0.733333333333333282],"xyz":[0.387868141260944044,0.189624467296851978,0.486328036937647701],"hpluv":[321.811503537589374,278.905890401213071,50.6432416523731064],"hsluv":[321.811503537589374,99.9999999999984,50.6432416523731064]},"#dd00cc":{"lch":[51.5352850119508901,114.534817141075266,314.3830496716472],"luv":[51.5352850119508901,80.1116001600253753,-81.8557014345352201],"rgb":[0.866666666666666696,0,0.8],"xyz":[0.407160516704665798,0.19734141747434078,0.587934547607917857],"hpluv":[314.3830496716472,282.014975724645751,51.5352850119508901],"hsluv":[314.3830496716472,99.9999999999986215,51.5352850119508901]},"#dd00dd":{"lch":[52.5032286812834883,119.593841400887641,307.715012949243601],"luv":[52.5032286812834883,73.1596596193909647,-94.6062952735996419],"rgb":[0.866666666666666696,0,0.866666666666666696],"xyz":[0.428678842255299286,0.205948747694594314,0.701264395507923854],"hpluv":[307.715012949243601,289.042783730483222,52.5032286812834883],"hsluv":[307.715012949243601,99.9999999999987779,52.5032286812834883]},"#dd00ee":{"lch":[53.5434168792756111,126.080010820296707,301.921476351261958],"luv":[53.5434168792756111,66.6656277920787659,-107.01337860068783],"rgb":[0.866666666666666696,0,0.933333333333333348],"xyz":[0.452491022521474051,0.215473619801064359,0.826675211576447078],"hpluv":[301.921476351261958,298.799235277631283,53.5434168792756111],"hsluv":[301.921476351261958,99.999999999998991,53.5434168792756111]},"#dd00ff":{"lch":[54.6518715304170399,133.605457484958208,296.990855958497434],"luv":[54.6518715304170399,60.6366090811706258,-119.053013019000375],"rgb":[0.866666666666666696,0,1],"xyz":[0.478662070931305417,0.225942039164997055,0.964509399868228923],"hpluv":[296.990855958497434,310.211923209940835,54.6518715304170399],"hsluv":[296.990855958497434,99.99999999999919,54.6518715304170399]},"#dd1100":{"lch":[46.6790301132195,152.538998994032681,12.7564763340959253],"luv":[46.6790301132195,148.773935032481603,33.6817824506429915],"rgb":[0.866666666666666696,0.0666666666666666657,0],"xyz":[0.300185682790403863,0.157758524326120919,0.0146453810388783197],"hpluv":[12.7564763340959253,414.665968881342394,46.6790301132195],"hsluv":[12.7564763340959253,100.000000000002373,46.6790301132195]},"#dd1111":{"lch":[46.7325769897078942,150.969760125239,12.1770506300617818],"luv":[46.7325769897078942,147.573010021229663,31.8445471870185592],"rgb":[0.866666666666666696,0.0666666666666666657,0.0666666666666666657],"xyz":[0.301197348290040967,0.158163190525975772,0.0199734860036339529],"hpluv":[12.1770506300617818,409.92986676092562,46.7325769897078942],"hsluv":[12.1770506300617818,96.0592738250283,46.7325769897078942]},"#dd1122":{"lch":[46.8315975390355774,148.166934443607602,11.093898425687982],"luv":[46.8315975390355774,145.398162733087418,28.509905932130728],"rgb":[0.866666666666666696,0.0666666666666666657,0.133333333333333331],"xyz":[0.303072706428518,0.1589133337813666,0.0298503721996131455],"hpluv":[11.093898425687982,401.468660625611221,46.8315975390355774],"hsluv":[11.093898425687982,96.1199649520447821,46.8315975390355774]},"#dd1133":{"lch":[46.9939567691892393,143.840838530693645,9.28627571582045697],"luv":[46.9939567691892393,141.955717705878527,23.2112265902085468],"rgb":[0.866666666666666696,0.0666666666666666657,0.2],"xyz":[0.30616045716097573,0.160148434074349699,0.0461125260572242957],"hpluv":[9.28627571582045697,388.400266865181436,46.9939567691892393],"hsluv":[9.28627571582045697,96.2159198798013477,46.9939567691892393]},"#dd1144":{"lch":[47.2268997120704555,138.191174032002039,6.62861883301083665],"luv":[47.2268997120704555,137.267398010546174,15.951865839373701],"rgb":[0.866666666666666696,0.0666666666666666657,0.266666666666666663],"xyz":[0.310618452405194645,0.161931632172037293,0.0695913010101109342],"hpluv":[6.62861883301083665,371.304486157060069,47.2268997120704555],"hsluv":[6.62861883301083665,96.346372634165391,47.2268997120704555]},"#dd1155":{"lch":[47.5357948285950442,131.646215003298352,3.00154982487266553],"luv":[47.5357948285950442,131.465612026054913,6.89338663571585908],"rgb":[0.866666666666666696,0.0666666666666666657,0.333333333333333315],"xyz":[0.31658086644455663,0.164316597787782126,0.100993348284084836],"hpluv":[3.00154982487266553,351.420379681935685,47.5357948285950442],"hsluv":[3.00154982487266553,96.5074087268808114,47.5357948285950442]},"#dd1166":{"lch":[47.9244613368761776,124.817323026056556,358.307054390798669],"luv":[47.9244613368761776,124.762840903711279,-3.68750010524401839],"rgb":[0.866666666666666696,0.0666666666666666657,0.4],"xyz":[0.324165862218064815,0.167350596097185417,0.140940992691228811],"hpluv":[358.307054390798669,330.488955339688346,47.9244613368761776],"hsluv":[358.307054390798669,96.6928417837132912,47.9244613368761776]},"#dd1177":{"lch":[48.3953520744879313,118.427317384197096,352.504166614065639],"luv":[48.3953520744879313,117.415279069986227,-15.4493282615978131],"rgb":[0.866666666666666696,0.0666666666666666657,0.466666666666666674],"xyz":[0.333479875238266721,0.17107620130526624,0.189994794597626721],"hpluv":[352.504166614065639,310.51856077863863,48.3953520744879313],"hsluv":[352.504166614065639,96.8952584834877229,48.3953520744879313]},"#dd1188":{"lch":[48.949686611979061,113.213254375126112,345.662599129740954],"luv":[48.949686611979061,109.687147393784173,-28.0351683216148473],"rgb":[0.866666666666666696,0.0666666666666666657,0.533333333333333326],"xyz":[0.344620292340210521,0.175532368146043838,0.248667658001198888],"hpluv":[345.662599129740954,293.48552443008623,48.949686611979061],"hsluv":[345.662599129740954,97.1070447043031209,48.949686611979061]},"#dd1199":{"lch":[49.5875717372425,109.808639676001164,338.012756373247385],"luv":[49.5875717372425,101.821953610845213,-41.1123717433662961],"rgb":[0.866666666666666696,0.0666666666666666657,0.6],"xyz":[0.357677256449283276,0.180755153789673,0.317434335642316767],"hpluv":[338.012756373247385,280.997849503034615,49.5875717372425],"hsluv":[338.012756373247385,97.321211179253126,49.5875717372425]},"#dd11aa":{"lch":[50.3081241313593779,108.626384639058173,329.948207544292131],"luv":[50.3081241313593779,94.0240738412992556,-54.3982074892042462],"rgb":[0.866666666666666696,0.0666666666666666657,0.66666666666666663],"xyz":[0.372734949414535777,0.18677823097577409,0.396738185259315368],"hpluv":[329.948207544292131,273.991145484396441,50.3081241313593779],"hsluv":[329.948207544292131,97.5319211216277751,50.3081241313593779]},"#dd11bb":{"lch":[51.1095995740137,109.78676639377484,321.947120969557943],"luv":[51.1095995740137,86.4507346157054855,-67.6712979010019495],"rgb":[0.866666666666666696,0.0666666666666666657,0.733333333333333282],"xyz":[0.389872541521872451,0.193633267818708849,0.486996170357957114],"hpluv":[321.947120969557943,272.57551535007633,51.1095995740137],"hsluv":[321.947120969557943,97.7347175386083791,51.1095995740137]},"#dd11cc":{"lch":[51.9895276454598303,113.13117809908816,314.441471026924035],"luv":[51.9895276454598303,79.2122218564644527,-80.7718228508547469],"rgb":[0.866666666666666696,0.0666666666666666657,0.8],"xyz":[0.409164916965594205,0.20135021799619765,0.588602681028227326],"hpluv":[314.441471026924035,276.12502270002949,51.9895276454598303],"hsluv":[314.441471026924035,97.9265130550616,51.9895276454598303]},"#dd11dd":{"lch":[52.9448482611329325,118.314931067086022,307.715012949243601],"luv":[52.9448482611329325,72.3773062506166553,-93.594596282658145],"rgb":[0.866666666666666696,0.0666666666666666657,0.866666666666666696],"xyz":[0.430683242516227693,0.209957548216451184,0.701932528928233324],"hpluv":[307.715012949243601,283.566663729067216,52.9448482611329325],"hsluv":[307.715012949243601,98.1054292618058525,52.9448482611329325]},"#dd11ee":{"lch":[53.9720454332022257,124.924845967379298,301.881652150577509],"luv":[53.9720454332022257,65.9811112999591103,-106.078791902980541],"rgb":[0.866666666666666696,0.0666666666666666657,0.933333333333333348],"xyz":[0.454495422782402458,0.219482420322921229,0.827343344996756547],"hpluv":[301.881652150577509,293.71036424495378,53.9720454332022257],"hsluv":[301.881652150577509,98.2705657762439841,53.9720454332022257]},"#dd11ff":{"lch":[55.067273793018515,132.56906123155207,296.926443611211937],"luv":[55.067273793018515,60.0334023394080774,-118.197066796810802],"rgb":[0.866666666666666696,0.0666666666666666657,1],"xyz":[0.480666471192233824,0.229950839686853925,0.965177533288538392],"hpluv":[296.926443611211937,305.483621811531123,55.067273793018515],"hsluv":[296.926443611211937,99.9999999999990763,55.067273793018515]},"#dd2200":{"lch":[47.6481385708110494,147.881667770992,13.8451074484812633],"luv":[47.6481385708110494,143.585141583480663,35.3877772568702937],"rgb":[0.866666666666666696,0.133333333333333331,0],"xyz":[0.303901306525171777,0.165189771795656887,0.0158839222838009289],"hpluv":[13.8451074484812633,393.829031299888356,47.6481385708110494],"hsluv":[13.8451074484812633,100.000000000002302,47.6481385708110494]},"#dd2211":{"lch":[47.7000692420668,146.371743885583,13.2640103652051735],"luv":[47.7000692420668,142.467011758872331,33.583298953557744],"rgb":[0.866666666666666696,0.133333333333333331,0.0666666666666666657],"xyz":[0.304912972024808882,0.16559443799551174,0.0212120272485565586],"hpluv":[13.2640103652051735,389.383517616197651,47.7000692420668],"hsluv":[13.2640103652051735,96.2235359913314596,47.7000692420668]},"#dd2222":{"lch":[47.796111526211412,143.672697420673273,12.1770506300617871],"luv":[47.796111526211412,140.440127868319678,30.3053537920670948],"rgb":[0.866666666666666696,0.133333333333333331,0.133333333333333331],"xyz":[0.306788330163285938,0.166344581250902568,0.0310889134445357582],"hpluv":[12.1770506300617871,381.435408792809369,47.796111526211412],"hsluv":[12.1770506300617871,89.3821391188339618,47.796111526211412]},"#dd2233":{"lch":[47.9536166692339805,139.501418135148583,10.3611027729364178],"luv":[47.9536166692339805,137.226679529052944,25.0895214611231978],"rgb":[0.866666666666666696,0.133333333333333331,0.2],"xyz":[0.309876080895743644,0.167579681543885667,0.0473510673021469],"hpluv":[10.3611027729364178,369.144652707036585,47.9536166692339805],"hsluv":[10.3611027729364178,89.634195646670733,47.9536166692339805]},"#dd2244":{"lch":[48.1796580724099073,134.044487106872765,7.68678657448498281],"luv":[48.1796580724099073,132.839973125453383,17.9294747210675],"rgb":[0.866666666666666696,0.133333333333333331,0.266666666666666663],"xyz":[0.314334076139962559,0.169362879641573261,0.0708298422550335399],"hpluv":[7.68678657448498281,353.040533161258963,48.1796580724099073],"hsluv":[7.68678657448498281,89.9776949827144819,48.1796580724099073]},"#dd2255":{"lch":[48.4795139291676236,127.710640494506933,4.02871777991100277],"luv":[48.4795139291676236,127.395062601571667,8.9724979943620351],"rgb":[0.866666666666666696,0.133333333333333331,0.333333333333333315],"xyz":[0.320296490179324544,0.171747845257318094,0.102231889529007441],"hpluv":[4.02871777991100277,334.278275235680212,48.4795139291676236],"hsluv":[4.02871777991100277,90.4030378986951746,48.4795139291676236]},"#dd2266":{"lch":[48.8569858046774499,121.091623353111601,359.280669781128381],"luv":[48.8569858046774499,121.082080247128843,-1.52022673298942879],"rgb":[0.866666666666666696,0.133333333333333331,0.4],"xyz":[0.32788148595283273,0.174781843566721384,0.142179533936151403],"hpluv":[359.280669781128381,314.504423311283745,48.8569858046774499],"hsluv":[359.280669781128381,90.8946273178398627,48.8569858046774499]},"#dd2277":{"lch":[49.3145747506863046,114.897314975199777,353.392641366134796],"luv":[49.3145747506863046,114.134166521370943,-13.2206286152450421],"rgb":[0.866666666666666696,0.133333333333333331,0.466666666666666674],"xyz":[0.337195498973034635,0.178507448774802208,0.191233335842549312],"hpluv":[353.392641366134796,295.64729776044,49.3145747506863046],"hsluv":[353.392641366134796,91.4334620569677128,49.3145747506863046]},"#dd2288":{"lch":[49.8536069462695934,109.863045744465836,346.42832123602642],"luv":[49.8536069462695934,106.795352255968297,-25.780643063628979],"rgb":[0.866666666666666696,0.133333333333333331,0.533333333333333326],"xyz":[0.348335916074978436,0.182963615615579805,0.24990619924612148],"hpluv":[346.42832123602642,279.636833718457694,49.8536069462695934],"hsluv":[346.42832123602642,91.999736258284841,49.8536069462695934]},"#dd2299":{"lch":[50.4743452384724947,106.631383564155598,338.620922954440232],"luv":[50.4743452384724947,99.2939711585852507,-38.8710593162073792],"rgb":[0.866666666666666696,0.133333333333333331,0.6],"xyz":[0.361392880184051135,0.188186401259208963,0.318672876887239387],"hpluv":[338.620922954440232,268.07337181170567,50.4743452384724947],"hsluv":[338.620922954440232,92.5749897333771088,50.4743452384724947]},"#dd22aa":{"lch":[51.176101525576982,105.62881092572934,330.379319008457628],"luv":[51.176101525576982,91.8248770713425699,-52.2076397514415902],"rgb":[0.866666666666666696,0.133333333333333331,0.66666666666666663],"xyz":[0.376450573149303691,0.194209478445310058,0.397976726504238],"hpluv":[330.379319008457628,261.911470041672374,51.176101525576982],"hsluv":[330.379319008457628,93.1435427232804898,51.176101525576982]},"#dd22bb":{"lch":[51.9573548685870321,106.984993341056935,322.205396597718504],"luv":[51.9573548685870321,84.5409044706425306,-65.5638945721781425],"rgb":[0.866666666666666696,0.133333333333333331,0.733333333333333282],"xyz":[0.393588165256640365,0.201064515288244816,0.488234711602879734],"hpluv":[322.205396597718504,261.285408571692301,51.9573548685870321],"hsluv":[322.205396597718504,93.6931794305449301,51.9573548685870321]},"#dd22cc":{"lch":[52.8158750154556174,110.541708291411879,314.55250800555325],"luv":[52.8158750154556174,77.5519304210182838,-78.7728846745956],"rgb":[0.866666666666666696,0.133333333333333331,0.8],"xyz":[0.412880540700362064,0.208781465465733618,0.58984122227315],"hpluv":[314.55250800555325,265.583456637160452,52.8158750154556174],"hsluv":[314.55250800555325,94.2152138812719073,52.8158750154556174]},"#dd22dd":{"lch":[53.7488483860564088,115.947384169062644,307.715012949243658],"luv":[53.7488483860564088,70.9289965118926204,-91.721716891171],"rgb":[0.866666666666666696,0.133333333333333331,0.866666666666666696],"xyz":[0.434398866250995663,0.217388795685987152,0.703171070173155943],"hpluv":[307.715012949243658,273.735496610715643,53.7488483860564088],"hsluv":[307.715012949243658,94.704144859729837,53.7488483860564088]},"#dd22ee":{"lch":[54.7530025006588374,122.779599443276055,301.806367069585178],"luv":[54.7530025006588374,64.7110170709106,-104.342293961267828],"rgb":[0.866666666666666696,0.133333333333333331,0.933333333333333348],"xyz":[0.458211046517170373,0.226913667792457197,0.828581886241679166],"hpluv":[301.806367069585178,284.549350776984397,54.7530025006588374],"hsluv":[301.806367069585178,95.1571011878196629,54.7530025006588374]},"#dd22ff":{"lch":[55.8247247862810525,130.638613434108407,296.804995701950531],"luv":[55.8247247862810525,58.9121835814083425,-116.601037498200881],"rgb":[0.866666666666666696,0.133333333333333331,1],"xyz":[0.484382094927001794,0.237382087156389893,0.966416074533461],"hpluv":[296.804995701950531,296.950662194199822,55.8247247862810525],"hsluv":[296.804995701950531,99.9999999999989768,55.8247247862810525]},"#dd3300":{"lch":[49.1823134049741526,140.84390252957769,15.6779143459349193],"luv":[49.1823134049741526,135.603943521894649,38.06015476941716],"rgb":[0.866666666666666696,0.2,0],"xyz":[0.310019028614182623,0.17742521597367869,0.0179231629801378106],"hpluv":[15.6779143459349193,363.386194305474646,49.1823134049741526],"hsluv":[15.6779143459349193,100.000000000002331,49.1823134049741526]},"#dd3311":{"lch":[49.2318310772226226,139.415415721210906,15.0950854994101622],"luv":[49.2318310772226226,134.60488288385605,36.3067988748864323],"rgb":[0.866666666666666696,0.2,0.0666666666666666657],"xyz":[0.311030694113819728,0.177829882173533543,0.0232512679448934403],"hpluv":[15.0950854994101622,359.338818773581409,49.2318310772226226],"hsluv":[15.0950854994101622,96.4660724045404834,49.2318310772226226]},"#dd3322":{"lch":[49.3234253076193,136.858666305461554,14.0037238091571297],"luv":[49.3234253076193,132.791226888227897,33.117738516222083],"rgb":[0.866666666666666696,0.2,0.133333333333333331],"xyz":[0.312906052252296785,0.178580025428924372,0.0331281541408726399],"hpluv":[14.0037238091571297,352.093818956611813,49.3234253076193],"hsluv":[14.0037238091571297,90.0546185843159321,49.3234253076193]},"#dd3333":{"lch":[49.4736766963079901,132.899088309008249,12.1770506300618315],"luv":[49.4736766963079901,129.908920002044738,28.0328410488111714],"rgb":[0.866666666666666696,0.2,0.2],"xyz":[0.31599380298475449,0.179815125721907471,0.0493903079984837831],"hpluv":[12.1770506300618315,340.868713502871344,49.4736766963079901],"hsluv":[12.1770506300618315,79.876105021286179,49.4736766963079901]},"#dd3344":{"lch":[49.6893958667399289,127.704341644457742,9.47932118493828391],"luv":[49.6893958667399289,125.960552293014786,21.031836364974712],"rgb":[0.866666666666666696,0.2,0.266666666666666663],"xyz":[0.320451798228973406,0.181598323819595064,0.0728690829513704286],"hpluv":[9.47932118493828391,326.122882655454703,49.6893958667399289],"hsluv":[9.47932118493828391,80.502956859434363,49.6893958667399289]},"#dd3355":{"lch":[49.9757165444531495,121.655077778432485,5.77481987360355742],"luv":[49.9757165444531495,121.037681249067731,12.2408197080725127],"rgb":[0.866666666666666696,0.2,0.333333333333333315],"xyz":[0.326414212268335391,0.183983289435339897,0.10427113022534433],"hpluv":[5.77481987360355742,308.89475746512926,49.9757165444531495],"hsluv":[5.77481987360355742,81.2827465905028674,49.9757165444531495]},"#dd3366":{"lch":[50.3364012453720164,115.314978813651479,0.942739432835561],"luv":[50.3364012453720164,115.29936949267524,1.8972963354308543],"rgb":[0.866666666666666696,0.2,0.4],"xyz":[0.333999208041843576,0.187017287744743188,0.144218774632488278],"hpluv":[0.942739432835561,290.698564526315124,50.3364012453720164],"hsluv":[0.942739432835561,82.1889615211792375,50.3364012453720164]},"#dd3377":{"lch":[50.77400791740952,109.376176789803836,354.916348657894],"luv":[50.77400791740952,108.945933542464203,-9.69183231981436],"rgb":[0.866666666666666696,0.2,0.466666666666666674],"xyz":[0.343313221062045482,0.190742892952824,0.193272576538886187],"hpluv":[354.916348657894,273.35096965093777,50.77400791740952],"hsluv":[354.916348657894,83.1884512053650269,50.77400791740952]},"#dd3388":{"lch":[51.2900053848270545,104.574014460431073,347.747121452304157],"luv":[51.2900053848270545,102.191864987712989,-22.1934051173651383],"rgb":[0.866666666666666696,0.2,0.533333333333333326],"xyz":[0.354453638163989282,0.195199059793601609,0.251945439942458382],"hpluv":[347.747121452304157,258.720214242298141,51.2900053848270545],"hsluv":[347.747121452304157,84.245872474104587,51.2900053848270545]},"#dd3399":{"lch":[51.8848727297214509,101.568582070491487,339.671486537323062],"luv":[51.8848727297214509,95.2425012264059347,-35.2851643605103433],"rgb":[0.866666666666666696,0.2,0.6],"xyz":[0.367510602273062,0.200421845437230767,0.320712117583576262],"hpluv":[339.671486537323062,248.403642764366595,51.8848727297214509],"hsluv":[339.671486537323062,85.3275173092541763,51.8848727297214509]},"#dd33aa":{"lch":[52.5581975758694284,100.811065681036794,331.124654782349864],"luv":[52.5581975758694284,88.2774684157494,-48.6822301651504219],"rgb":[0.866666666666666696,0.2,0.66666666666666663],"xyz":[0.382568295238314537,0.206444922623331861,0.400015967200574862],"hpluv":[331.124654782349864,243.392431352391867,52.5581975758694284],"hsluv":[331.124654782349864,86.4040244757801,52.5581975758694284]},"#dd33bb":{"lch":[53.3087788146031301,102.447919096954379,322.651217662355],"luv":[53.3087788146031301,81.4417156804123579,-62.1516136100020091],"rgb":[0.866666666666666696,0.2,0.733333333333333282],"xyz":[0.399705887345651212,0.21329995946626662,0.490273952299216609],"hpluv":[322.651217662355,243.861776984359892,53.3087788146031301],"hsluv":[322.651217662355,87.4518397844355633,53.3087788146031301]},"#dd33cc":{"lch":[54.1347343907921612,106.321268361530926,314.743497623169446],"luv":[54.1347343907921612,74.8431687457043751,-75.5163041872859253],"rgb":[0.866666666666666696,0.2,0.8],"xyz":[0.418998262789372911,0.221016909643755421,0.59188046296948682],"hpluv":[314.743497623169446,249.220329072313831,54.1347343907921612],"hsluv":[314.743497623169446,88.4535853271675734,54.1347343907921612]},"#dd33dd":{"lch":[55.033612168624586,112.066789743934578,307.715012949243715],"luv":[55.033612168624586,68.5551036430149,-88.6519211749340741],"rgb":[0.866666666666666696,0.2,0.866666666666666696],"xyz":[0.44051658834000651,0.229624239864008955,0.705210310869492818],"hpluv":[307.715012949243715,258.397459164480438,55.033612168624586],"hsluv":[307.715012949243715,89.3976510430439077,55.033612168624586]},"#dd33ee":{"lch":[56.0025007026426351,119.245240694744666,301.678101579798295],"luv":[56.0025007026426351,62.6212128139869506,-101.479116738632214],"rgb":[0.866666666666666696,0.2,0.933333333333333348],"xyz":[0.464328768606181219,0.239149111970479,0.830621126938016],"hpluv":[301.678101579798295,270.192295422478139,56.0025007026426351],"hsluv":[301.678101579798295,90.277343199481848,56.0025007026426351]},"#dd33ff":{"lch":[57.0381364623091116,127.442655532056975,296.59904001960814],"luv":[57.0381364623091116,57.0616979163907772,-113.954346472440875],"rgb":[0.866666666666666696,0.2,1],"xyz":[0.49049981701601264,0.249617531334411696,0.968455315229797886],"hpluv":[296.59904001960814,283.523336448078851,57.0381364623091116],"hsluv":[296.59904001960814,99.9999999999989626,57.0381364623091116]},"#dd4400":{"lch":[51.2775121999195278,131.902040393952689,18.409420821930695],"luv":[51.2775121999195278,125.151834557466444,41.6553305951168156],"rgb":[0.866666666666666696,0.266666666666666663,0],"xyz":[0.318851599097148664,0.19509035693961102,0.0208673531411264039],"hpluv":[18.409420821930695,326.410329295551833,51.2775121999195278],"hsluv":[18.409420821930695,100.000000000002245,51.2775121999195278]},"#dd4411":{"lch":[51.3239968707682124,130.563017922041524,17.8265447991253865],"luv":[51.3239968707682124,124.294382399750674,39.9700907276414128],"rgb":[0.866666666666666696,0.266666666666666663,0.0666666666666666657],"xyz":[0.319863264596785768,0.195495023139465873,0.0261954581058820371],"hpluv":[17.8265447991253865,322.804096021626094,51.3239968707682124],"hsluv":[17.8265447991253865,96.7659447415066154,51.3239968707682124]},"#dd4422":{"lch":[51.4099976690743148,128.162025810787327,16.7333496749677373],"luv":[51.4099976690743148,122.735013936090269,36.9001519513490237],"rgb":[0.866666666666666696,0.266666666666666663,0.133333333333333331],"xyz":[0.321738622735262825,0.196245166394856702,0.0360723443018612297],"hpluv":[16.7333496749677373,316.337811591652041,51.4099976690743148],"hsluv":[16.7333496749677373,90.8878404873512551,51.4099976690743148]},"#dd4433":{"lch":[51.551120550377874,124.432504768689228,14.8985084842763058],"luv":[51.551120550377874,120.249428964759446,31.9925472049216744],"rgb":[0.866666666666666696,0.266666666666666663,0.2],"xyz":[0.324826373467720531,0.197480266687839801,0.0523344981594723729],"hpluv":[14.8985084842763058,306.291581325991444,51.551120550377874],"hsluv":[14.8985084842763058,81.5276169642245634,51.551120550377874]},"#dd4444":{"lch":[51.7538349343952575,119.518854000271219,12.1770506300618191],"luv":[51.7538349343952575,116.829734805674121,25.2105042943215345],"rgb":[0.866666666666666696,0.266666666666666663,0.266666666666666663],"xyz":[0.329284368711939446,0.199263464785527394,0.0758132731123590115],"hpluv":[12.1770506300618191,293.044254198223086,51.7538349343952575],"hsluv":[12.1770506300618191,68.6693518559736,51.7538349343952575]},"#dd4455":{"lch":[52.0230766847265045,113.767549619287195,8.41751308754220773],"luv":[52.0230766847265045,112.542004033713866,16.6539086839248256],"rgb":[0.866666666666666696,0.266666666666666663,0.333333333333333315],"xyz":[0.335246782751301431,0.201648430401272227,0.107215320386332927],"hpluv":[8.41751308754220773,277.499175779034886,52.0230766847265045],"hsluv":[8.41751308754220773,69.8262296658756867,52.0230766847265045]},"#dd4466":{"lch":[52.3625377834239316,107.708396397149357,3.47572472865958737],"luv":[52.3625377834239316,107.51027478189765,6.52989056311981209],"rgb":[0.866666666666666696,0.266666666666666663,0.4],"xyz":[0.342831778524809616,0.204682428710675518,0.147162964793476875],"hpluv":[3.47572472865958737,261.016642983210886,52.3625377834239316],"hsluv":[3.47572472865958737,71.1800009153795088,52.3625377834239316]},"#dd4477":{"lch":[52.7748219535637304,102.013560717275851,357.256373562230806],"luv":[52.7748219535637304,101.896624345108023,-4.88308481282748108],"rgb":[0.866666666666666696,0.266666666666666663,0.466666666666666674],"xyz":[0.352145791545011522,0.208408033918756341,0.196216766699874784],"hpluv":[357.256373562230806,245.284698321799027,52.7748219535637304],"hsluv":[357.256373562230806,72.6848757644217898,52.7748219535637304]},"#dd4488":{"lch":[53.2615487789460502,97.4233940898595137,349.787328406912707],"luv":[53.2615487789460502,95.8798587184095368,-17.273401753155067],"rgb":[0.866666666666666696,0.266666666666666663,0.533333333333333326],"xyz":[0.363286208646955322,0.212864200759533939,0.254889630103446951],"hpluv":[349.787328406912707,232.107295472344475,53.2615487789460502],"hsluv":[349.787328406912707,74.290572198007979,53.2615487789460502]},"#dd4499":{"lch":[53.8234397136373133,94.6288173232078123,341.30539151945959],"luv":[53.8234397136373133,89.63624285692255,-30.330793502376995],"rgb":[0.866666666666666696,0.266666666666666663,0.6],"xyz":[0.376343172756028,0.218086986403163097,0.323656307744564886],"hpluv":[341.30539151945959,223.095746339835301,53.8234397136373133],"hsluv":[341.30539151945959,75.9477058190526577,53.8234397136373133]},"#dd44aa":{"lch":[54.4604007326765327,94.1226543521493539,332.285935566136516],"luv":[54.4604007326765327,83.3248558176969425,-43.7726223255380802],"rgb":[0.866666666666666696,0.266666666666666663,0.66666666666666663],"xyz":[0.391400865721280578,0.224110063589264191,0.402960157361563487],"hpluv":[332.285935566136516,219.307083848265933,54.4604007326765327],"hsluv":[332.285935566136516,77.6118806813578175,54.4604007326765327]},"#dd44bb":{"lch":[55.1716077278512387,96.0796222427451596,323.344264550451],"luv":[55.1716077278512387,77.0786382371216,-57.3600674495728526],"rgb":[0.866666666666666696,0.266666666666666663,0.733333333333333282],"xyz":[0.408538457828617252,0.23096510043219895,0.493218142460205233],"hpluv":[323.344264550451,220.981019921853772,55.1716077278512387],"hsluv":[323.344264550451,79.2461809113807334,55.1716077278512387]},"#dd44cc":{"lch":[55.9555962107488511,100.342448880687911,315.038748994660807],"luv":[55.9555962107488511,71.0007950362134,-70.9048246002984],"rgb":[0.866666666666666696,0.266666666666666663,0.8],"xyz":[0.427830833272338951,0.238682050609687751,0.594824653130475389],"hpluv":[315.038748994660807,227.551915064947707,55.9555962107488511],"hsluv":[315.038748994660807,80.8221578956601547,55.9555962107488511]},"#dd44dd":{"lch":[56.8103543983327484,106.525561993860563,307.715012949243828],"luv":[56.8103543983327484,65.1653443433699664,-84.2684594300729515],"rgb":[0.866666666666666696,0.266666666666666663,0.866666666666666696],"xyz":[0.44934915882297255,0.247289380829941285,0.708154501030481387],"hpluv":[307.715012949243828,237.939016458104504,56.8103543983327484],"hsluv":[307.715012949243828,82.3196529548951474,56.8103543983327484]},"#dd44ee":{"lch":[57.7334174818232384,114.162073161526394,301.482814132357476],"luv":[57.7334174818232384,59.6203198077272134,-97.3570563162323452],"rgb":[0.866666666666666696,0.266666666666666663,0.933333333333333348],"xyz":[0.473161339089147259,0.256814252936411302,0.83356531709900461],"hpluv":[301.482814132357476,250.91920763959763,57.7334174818232384],"hsluv":[301.482814132357476,85.8927976857303577,57.7334174818232384]},"#dd44ff":{"lch":[58.721960397178492,122.814959128704743,296.287773174859751],"luv":[58.721960397178492,54.3922733794591196,-110.113554035820684],"rgb":[0.866666666666666696,0.266666666666666663,1],"xyz":[0.49933238749897868,0.267282672300344,0.971399505390786455],"hpluv":[296.287773174859751,265.393357493052918,58.721960397178492],"hsluv":[296.287773174859751,99.9999999999987779,58.721960397178492]},"#dd5500":{"lch":[53.8905970004369834,121.845910621274882,22.2085433527856502],"luv":[53.8905970004369834,112.806678507237621,46.055175814369008],"rgb":[0.866666666666666696,0.333333333333333315,0],"xyz":[0.330664855811494629,0.218716870368303284,0.0248051053792416147],"hpluv":[22.2085433527856502,286.904453583707834,53.8905970004369834],"hsluv":[22.2085433527856502,100.000000000002217,53.8905970004369834]},"#dd5511":{"lch":[53.9336739056601573,120.58904296901602,21.6306448037720749],"luv":[53.9336739056601573,112.097097503939963,44.4517492948856656],"rgb":[0.866666666666666696,0.333333333333333315,0.0666666666666666657],"xyz":[0.331676521311131733,0.219121536568158137,0.0301332103439972479],"hpluv":[21.6306448037720749,283.71818310283129,53.9336739056601573],"hsluv":[21.6306448037720749,97.0955711707227493,53.9336739056601573]},"#dd5522":{"lch":[54.0133869328819856,118.329807147086328,20.5443811064534074],"luv":[54.0133869328819856,110.804107011743554,41.5258128011568957],"rgb":[0.866666666666666696,0.333333333333333315,0.133333333333333331],"xyz":[0.33355187944960879,0.219871679823548966,0.0400100965399764405],"hpluv":[20.5443811064534074,277.99185559962018,54.0133869328819856],"hsluv":[20.5443811064534074,91.805999212684128,54.0133869328819856]},"#dd5533":{"lch":[54.1442392255445526,114.805940194650788,18.7140712474621722],"luv":[54.1442392255445526,108.736323489647134,36.8349814433582736],"rgb":[0.866666666666666696,0.333333333333333315,0.2],"xyz":[0.336639630182066496,0.221106780116532065,0.0562722503975875837],"hpluv":[18.7140712474621722,269.061420184977408,54.1442392255445526],"hsluv":[18.7140712474621722,83.3546452149230674,54.1442392255445526]},"#dd5544":{"lch":[54.3323026853354207,110.135081135525823,15.9827981501284579],"luv":[54.3323026853354207,105.877744255237971,30.3255563535325479],"rgb":[0.866666666666666696,0.333333333333333315,0.266666666666666663],"xyz":[0.341097625426285411,0.222889978214219658,0.0797510253504742223],"hpluv":[15.9827981501284579,257.221277658214035,54.3323026853354207],"hsluv":[15.9827981501284579,71.6878656400709104,54.3323026853354207]},"#dd5555":{"lch":[54.5822696158357132,104.625049281135261,12.1770506300618937],"luv":[54.5822696158357132,102.271033836367579,22.0689051636128752],"rgb":[0.866666666666666696,0.333333333333333315,0.333333333333333315],"xyz":[0.347060039465647396,0.225274943829964491,0.111153072624448138],"hpluv":[12.1770506300618937,243.233512665758,54.5822696158357132],"hsluv":[12.1770506300618937,61.8784513389384,54.5822696158357132]},"#dd5566":{"lch":[54.8977244977922254,98.7674373059184205,7.11744080010036573],"luv":[54.8977244977922254,98.0063618739055897,12.2376347477602359],"rgb":[0.866666666666666696,0.333333333333333315,0.4],"xyz":[0.354645035239155582,0.228308942139367782,0.151100717031592086],"hpluv":[7.11744080010036573,228.296245111676484,54.8977244977922254],"hsluv":[7.11744080010036573,62.7979151590930655,54.8977244977922254]},"#dd5577":{"lch":[55.2812881935381597,93.2135187108595886,0.661514811515945267],"luv":[55.2812881935381597,93.2073060454778783,1.07618316489082022],"rgb":[0.866666666666666696,0.333333333333333315,0.466666666666666674],"xyz":[0.363959048259357487,0.232034547347448605,0.20015451893799],"hpluv":[0.661514811515945267,213.963687644495565,55.2812881935381597],"hsluv":[0.661514811515945267,63.8225359413096456,55.2812881935381597]},"#dd5588":{"lch":[55.7347110848163538,88.7163187329837,352.791835078768599],"luv":[55.7347110848163538,88.0151786426913532,-11.1316457915027787],"rgb":[0.866666666666666696,0.333333333333333315,0.533333333333333326],"xyz":[0.375099465361301287,0.236490714188226203,0.258827382341562162],"hpluv":[352.791835078768599,201.984054112510194,55.7347110848163538],"hsluv":[352.791835078768599,64.9173177009572,55.7347110848163538]},"#dd5599":{"lch":[56.2589463845586408,86.0173277442407169,343.733753082454825],"luv":[56.2589463845586408,82.5740942724548717,-24.0935598727929836],"rgb":[0.866666666666666696,0.333333333333333315,0.6],"xyz":[0.388156429470374,0.241713499831855361,0.327594059982680097],"hpluv":[343.733753082454825,194.014271994181229,56.2589463845586408],"hsluv":[343.733753082454825,66.0466553819121,56.2589463845586408]},"#dd55aa":{"lch":[56.8542178605490278,85.677853149792881,334.018383993549605],"luv":[56.8542178605490278,77.0187914763158545,-37.5339883290498477],"rgb":[0.866666666666666696,0.333333333333333315,0.66666666666666663],"xyz":[0.403214122435626543,0.247736577017956455,0.406897909599678698],"hpluv":[334.018383993549605,191.225239227061849,56.8542178605490278],"hsluv":[334.018383993549605,67.3075554564469485,56.8542178605490278]},"#dd55bb":{"lch":[57.5200884026389332,87.9206422548043633,324.375348896731964],"luv":[57.5200884026389332,71.4663144117056817,-51.2113780219251638],"rgb":[0.866666666666666696,0.333333333333333315,0.733333333333333282],"xyz":[0.420351714542963217,0.254591613860891242,0.497155894698320444],"hpluv":[324.375348896731964,193.959311397505388,57.5200884026389332],"hsluv":[324.375348896731964,69.5366313504716,57.5200884026389332]},"#dd55cc":{"lch":[58.2555317670128829,92.5910381182408315,315.474469199465034],"luv":[58.2555317670128829,66.0116746837007895,-64.9273374262858596],"rgb":[0.866666666666666696,0.333333333333333315,0.8],"xyz":[0.439644089986684916,0.262308564038380043,0.5987624053685906],"hpluv":[315.474469199465034,201.683843426221756,58.2555317670128829],"hsluv":[315.474469199465034,71.7082017587958802,58.2555317670128829]},"#dd55dd":{"lch":[59.0590075291469532,99.2700295618383848,307.715012949244056],"luv":[59.0590075291469532,60.7268860008133231,-78.5288742174016363],"rgb":[0.866666666666666696,0.333333333333333315,0.866666666666666696],"xyz":[0.461162415537318515,0.270915894258633549,0.712092253268596598],"hpluv":[307.715012949244056,213.290412049590259,59.0590075291469532],"hsluv":[307.715012949244056,73.7919865345850923,59.0590075291469532]},"#dd55ee":{"lch":[59.9285380001613674,107.447476486145689,301.201070052482692],"luv":[59.9285380001613674,55.6624113436061592,-91.905691698915],"rgb":[0.866666666666666696,0.333333333333333315,0.933333333333333348],"xyz":[0.484974595803493225,0.280440766365103566,0.837503069337119821],"hpluv":[301.201070052482692,227.510719406260364,59.9285380001613674],"hsluv":[301.201070052482692,84.9240358585231405,59.9285380001613674]},"#dd55ff":{"lch":[60.8617852443614,116.651127585902827,295.843561463814751],"luv":[60.8617852443614,50.8500320114402413,-104.984569397117028],"rgb":[0.866666666666666696,0.333333333333333315,1],"xyz":[0.511145644213324646,0.29090918572903629,0.975337257628901666],"hpluv":[295.843561463814751,243.211205533984923,60.8617852443614],"hsluv":[295.843561463814751,99.9999999999987,60.8617852443614]},"#dd6600":{"lch":[56.9556719941368783,111.624872970007345,27.247071009398578],"luv":[56.9556719941368783,99.2390381331236568,51.1050445257873349],"rgb":[0.866666666666666696,0.4,0],"xyz":[0.345692913517341105,0.248772985779996625,0.0298144579478569621],"hpluv":[27.247071009398578,248.69286407076,56.9556719941368783],"hsluv":[27.247071009398578,100.000000000002402,56.9556719941368783]},"#dd6611":{"lch":[56.9952083090352204,110.431802069127656,26.6846840374429064],"luv":[56.9952083090352204,98.6698726856829325,49.5927326573774181],"rgb":[0.866666666666666696,0.4,0.0666666666666666657],"xyz":[0.346704579016978209,0.249177651979851478,0.0351425629126125919],"hpluv":[26.6846840374429064,245.864111809588593,56.9952083090352204],"hsluv":[26.6846840374429064,97.4289366186781,56.9952083090352204]},"#dd6622":{"lch":[57.0683850250612181,108.280332786330632,25.6245441521289443],"luv":[57.0683850250612181,97.630674939023308,46.8282156319165637],"rgb":[0.866666666666666696,0.4,0.133333333333333331],"xyz":[0.348579937155455266,0.249927795235242306,0.0450194491085917914],"hpluv":[25.6245441521289443,240.764984433182946,57.0683850250612181],"hsluv":[25.6245441521289443,92.7369917538900239,57.0683850250612181]},"#dd6633":{"lch":[57.1885511035567617,104.905985735707603,23.8291565941278485],"luv":[57.1885511035567617,95.9631904105633566,42.3831561992078036],"rgb":[0.866666666666666696,0.4,0.2],"xyz":[0.351667687887912972,0.251162895528225405,0.0612816029662029346],"hpluv":[23.8291565941278485,232.771873337598265,57.1885511035567617],"hsluv":[23.8291565941278485,85.2149281001260306,57.1885511035567617]},"#dd6644":{"lch":[57.3613500282636153,100.395707721520722,21.1283100845564071],"luv":[57.3613500282636153,93.6466609873464222,36.1884099516133162],"rgb":[0.866666666666666696,0.4,0.266666666666666663],"xyz":[0.356125683132131887,0.252946093625912971,0.0847603779190895801],"hpluv":[21.1283100845564071,222.093121414046323,57.3613500282636153],"hsluv":[21.1283100845564071,74.7790089775498785,57.3613500282636153]},"#dd6655":{"lch":[57.5911977652478555,95.0134939889914136,17.3206113628181804],"luv":[57.5911977652478555,90.7049894048208927,28.2872575034667619],"rgb":[0.866666666666666696,0.4,0.333333333333333315],"xyz":[0.362088097171493872,0.255331059241657832,0.116162425193063482],"hpluv":[17.3206113628181804,209.347849744778358,57.5911977652478555],"hsluv":[17.3206113628181804,61.5516693045169205,57.5911977652478555]},"#dd6666":{"lch":[57.8815358558834703,89.2064417623026742,12.1770506300619559],"luv":[57.8815358558834703,87.1993378887650579,18.8166076552624659],"rgb":[0.866666666666666696,0.4,0.4],"xyz":[0.369673092945002058,0.25836505755106115,0.156110069600207457],"hpluv":[12.1770506300619559,195.566965385494854,57.8815358558834703],"hsluv":[12.1770506300619559,60.6635523422702,57.8815358558834703]},"#dd6677":{"lch":[58.2349645673757834,83.6008411979688901,5.48003957367995387],"luv":[58.2349645673757834,83.2187459143753188,7.98379467713524704],"rgb":[0.866666666666666696,0.4,0.466666666666666674],"xyz":[0.378987105965203963,0.262090662759141946,0.205163871506605366],"hpluv":[5.48003957367995387,182.165511808695555,58.2349645673757834],"hsluv":[5.48003957367995387,61.6238417996400329,58.2349645673757834]},"#dd6688":{"lch":[58.6533262634944208,78.9686504698842,357.125632416080862],"luv":[58.6533262634944208,78.8692993006444,-3.95997283577995],"rgb":[0.866666666666666696,0.4,0.533333333333333326],"xyz":[0.390127523067147763,0.266546829599919544,0.263836734910177506],"hpluv":[357.125632416080862,170.8446551494321,58.6533262634944208],"hsluv":[357.125632416080862,62.6596910240402778,58.6533262634944208]},"#dd6699":{"lch":[59.1377678367746853,76.1279623836736192,347.292482429378936],"luv":[59.1377678367746853,74.2632604984211184,-16.746187531306056],"rgb":[0.866666666666666696,0.4,0.6],"xyz":[0.403184487176220463,0.271769615243548701,0.332603412551295441],"hpluv":[347.292482429378936,163.349798950832565,59.1377678367746853],"hsluv":[347.292482429378936,63.7390009960191435,59.1377678367746853]},"#dd66aa":{"lch":[59.6887956605557406,75.751758533498986,336.577260120739709],"luv":[59.6887956605557406,69.5095811529117,-30.1122408476074845],"rgb":[0.866666666666666696,0.4,0.66666666666666663],"xyz":[0.418242180141473,0.277792692429649823,0.411907262168294042],"hpluv":[336.577260120739709,161.042027442088397,59.6887956605557406],"hsluv":[336.577260120739709,64.8305690383666473,59.6887956605557406]},"#dd66bb":{"lch":[60.3063295400458372,78.1477005551706,325.894443158435308],"luv":[60.3063295400458372,64.706761589723726,-43.8189240697585518],"rgb":[0.866666666666666696,0.4,0.733333333333333282],"xyz":[0.435379772248809693,0.284647729272584582,0.502165247266935788],"hpluv":[325.894443158435308,164.434383230317081,60.3063295400458372],"hsluv":[325.894443158435308,65.9059953936301213,60.3063295400458372]},"#dd66cc":{"lch":[60.9897585015337427,83.1712006992562891,316.109248272524042],"luv":[60.9897585015337427,59.9384091909213694,-57.6613885491638314],"rgb":[0.866666666666666696,0.4,0.8],"xyz":[0.454672147692531392,0.292364679450073384,0.603771757937205944],"hpluv":[316.109248272524042,173.043537218511,60.9897585015337427],"hsluv":[316.109248272524042,66.9408479310096709,60.9897585015337427]},"#dd66dd":{"lch":[61.7379991889007158,90.3518241723814555,307.715012949244283],"luv":[61.7379991889007158,55.2713135142553753,-71.4740094977595675],"rgb":[0.866666666666666696,0.4,0.866666666666666696],"xyz":[0.476190473243165,0.30097200967032689,0.717101605837211942],"hpluv":[307.715012949244283,185.705044478150711,61.7379991889007158],"hsluv":[307.715012949244283,67.9151328937623759,61.7379991889007158]},"#dd66ee":{"lch":[62.5495564285741779,99.1126076890086125,300.803780654240427],"luv":[62.5495564285741779,50.7555210146825431,-85.1304063742412183],"rgb":[0.866666666666666696,0.4,0.933333333333333348],"xyz":[0.500002653509339701,0.310496881776796907,0.842512421905735165],"hpluv":[300.803780654240427,201.068480083703747,62.5495564285741779],"hsluv":[300.803780654240427,83.670703518064812,62.5495564285741779]},"#dd66ff":{"lch":[63.4225848554444696,108.928953372808309,295.226788235463459],"luv":[63.4225848554444696,46.4257694276883512,-98.5401685402585628],"rgb":[0.866666666666666696,0.4,1],"xyz":[0.526173701919171122,0.320965301140729631,0.980346610197517],"hpluv":[295.226788235463459,217.940889521273107,63.4225848554444696],"hsluv":[295.226788235463459,99.9999999999986073,63.4225848554444696]},"#dd7700":{"lch":[60.3985006876916088,102.209421710697811,33.6568691403047779],"luv":[60.3985006876916088,85.0762157619203,56.6463008330327753],"rgb":[0.866666666666666696,0.466666666666666674,0],"xyz":[0.364146651570758706,0.285680461886832382,0.0359657039656626626],"hpluv":[33.6568691403047779,214.735624532269611,60.3985006876916088],"hsluv":[33.6568691403047779,100.000000000002245,60.3985006876916088]},"#dd7711":{"lch":[60.4345564785723894,101.058408313912437,33.1281817520222],"luv":[60.4345564785723894,84.6313647704988,55.2298287886556736],"rgb":[0.866666666666666696,0.466666666666666674,0.0666666666666666657],"xyz":[0.36515831707039581,0.286085128086687235,0.0412938089304182923],"hpluv":[33.1281817520222,212.190746676882327,60.4345564785723894],"hsluv":[33.1281817520222,97.7465438968969238,60.4345564785723894]},"#dd7722":{"lch":[60.5013044729937803,98.9745052833742136,32.1281810047412648],"luv":[60.5013044729937803,83.8175940663154364,52.6361436754539582],"rgb":[0.866666666666666696,0.466666666666666674,0.133333333333333331],"xyz":[0.367033675208872867,0.286835271342078035,0.0511706951263974918],"hpluv":[32.1281810047412648,207.585936448863947,60.5013044729937803],"hsluv":[32.1281810047412648,93.6262478826975126,60.5013044729937803]},"#dd7733":{"lch":[60.6109510167574115,95.6833141687104813,30.4242910043150516],"luv":[60.6109510167574115,82.5076313520097813,48.4539717565960331],"rgb":[0.866666666666666696,0.466666666666666674,0.2],"xyz":[0.370121425941330573,0.288070371635061162,0.067432848984008642],"hpluv":[30.4242910043150516,200.320058173129354,60.6109510167574115],"hsluv":[30.4242910043150516,86.9991150080846722,60.6109510167574115]},"#dd7744":{"lch":[60.7687036553482756,91.2360291121886888,27.8356422373186483],"luv":[60.7687036553482756,80.6791699404734857,42.6014617809804932],"rgb":[0.866666666666666696,0.466666666666666674,0.266666666666666663],"xyz":[0.374579421185549488,0.289853569732748728,0.0909116239368952805],"hpluv":[27.8356422373186483,190.513488615549676,60.7687036553482756],"hsluv":[27.8356422373186483,77.760618312285672,60.7687036553482756]},"#dd7755":{"lch":[60.9786842032445122,85.8448802225428125,24.131655223886618],"luv":[60.9786842032445122,78.3427622472179479,35.096368243717265],"rgb":[0.866666666666666696,0.466666666666666674,0.333333333333333315],"xyz":[0.380541835224911473,0.292238535348493589,0.122313671210869182],"hpluv":[24.131655223886618,178.63875223296418,60.9786842032445122],"hsluv":[24.131655223886618,65.9765814384596894,60.9786842032445122]},"#dd7766":{"lch":[61.2441632046235895,79.8999585154359693,19.0216316495787474],"luv":[61.2441632046235895,75.5370685872685073,26.0414024201977448],"rgb":[0.866666666666666696,0.466666666666666674,0.4],"xyz":[0.388126830998419659,0.295272533657896907,0.162261315618013158],"hpluv":[19.0216316495787474,165.546946717194828,61.2441632046235895],"hsluv":[19.0216316495787474,57.9572057581871576,61.2441632046235895]},"#dd7777":{"lch":[61.5676827516498122,73.9875996712566,12.1770506300619097],"luv":[61.5676827516498122,72.3229127387857318,15.6064473244910626],"rgb":[0.866666666666666696,0.466666666666666674,0.466666666666666674],"xyz":[0.397440844018621564,0.298998138865977703,0.211315117524411067],"hpluv":[12.1770506300619097,152.491436777287873,61.5676827516498122],"hsluv":[12.1770506300619097,58.8480912007490744,61.5676827516498122]},"#dd7788":{"lch":[61.9511315612573,68.8928540500868252,3.33484257213660307],"luv":[61.9511315612573,68.7761927043778769,4.00757485979294081],"rgb":[0.866666666666666696,0.466666666666666674,0.533333333333333326],"xyz":[0.408581261120565364,0.303454305706755301,0.269987980927983207],"hpluv":[3.33484257213660307,141.112101622994089,61.9511315612573],"hsluv":[3.33484257213660307,59.8177792812577849,61.9511315612573]},"#dd7799":{"lch":[62.395798681375723,65.5359342889949659,352.534540584191575],"luv":[62.395798681375723,64.9804103256140309,-8.5149842657693231],"rgb":[0.866666666666666696,0.466666666666666674,0.6],"xyz":[0.421638225229638119,0.308677091350384458,0.338754658569101141],"hpluv":[352.534540584191575,133.27953643418,62.395798681375723],"hsluv":[352.534540584191575,60.8378233331756135,62.395798681375723]},"#dd77aa":{"lch":[62.9024183325334576,64.7691926058513587,340.409048511657261],"luv":[62.9024183325334576,61.0197310981447743,-21.7172909803219412],"rgb":[0.866666666666666696,0.466666666666666674,0.66666666666666663],"xyz":[0.43669591819489062,0.314700168536485581,0.418058508186099742],"hpluv":[340.409048511657261,130.659342151792146,62.9024183325334576],"hsluv":[340.409048511657261,61.8795186032410598,62.9024183325334576]},"#dd77bb":{"lch":[63.4712121738611472,67.0588140204747,328.168414880738283],"luv":[63.4712121738611472,56.973307333119962,-35.3684434115847779],"rgb":[0.866666666666666696,0.466666666666666674,0.733333333333333282],"xyz":[0.453833510302227294,0.321555205379420339,0.508316493284741489],"hpluv":[328.168414880738283,134.065922948238125,63.4712121738611472],"hsluv":[328.168414880738283,62.9156692244191049,63.4712121738611472]},"#dd77cc":{"lch":[64.1019320742502856,72.2937871392105649,317.045265551381931],"luv":[64.1019320742502856,52.9112642996390861,-49.2624580095555586],"rgb":[0.866666666666666696,0.466666666666666674,0.8],"xyz":[0.473125885745949049,0.329272155556909141,0.609923003955011644],"hpluv":[317.045265551381931,143.109736775843601,64.1019320742502856],"hsluv":[317.045265551381931,63.9218174738772262,64.1019320742502856]},"#dd77dd":{"lch":[64.7939046430230547,79.9242419089019904,307.715012949244624],"luv":[64.7939046430230547,48.8924033620837761,-63.225132172198613],"rgb":[0.866666666666666696,0.466666666666666674,0.866666666666666696],"xyz":[0.494644211296582537,0.337879485777162647,0.723252851855017642],"hpluv":[307.715012949244624,156.524995415635317,64.7939046430230547],"hsluv":[307.715012949244624,64.8769154463944,64.7939046430230547]},"#dd77ee":{"lch":[65.5460776792256,89.2673698488479772,300.244676230176196],"luv":[65.5460776792256,44.9634126652007424,-77.116501743983946],"rgb":[0.866666666666666696,0.466666666666666674,0.933333333333333348],"xyz":[0.518456391562757357,0.347404357883632664,0.848663667923540865],"hpluv":[300.244676230176196,172.816560464305326,65.5460776792256],"hsluv":[300.244676230176196,82.07388698168063,65.5460776792256]},"#dd77ff":{"lch":[66.3570680439545,99.7204006423648366,294.377473048092611],"luv":[66.3570680439545,41.1592308753033436,-90.8299290874281837],"rgb":[0.866666666666666696,0.466666666666666674,1],"xyz":[0.544627439972588667,0.357872777247565388,0.98649785621532271],"hpluv":[294.377473048092611,190.693615319177383,66.3570680439545],"hsluv":[294.377473048092611,99.9999999999983373,66.3570680439545]},"#dd8800":{"lch":[64.1467534130096766,94.4821411478558701,41.4445641191571781],"luv":[64.1467534130096766,70.8234804869986192,62.5372657508392],"rgb":[0.866666666666666696,0.533333333333333326,0],"xyz":[0.386219021295729159,0.329825201336773954,0.0433231605406526124],"hpluv":[41.4445641191571781,186.902182331454583,64.1467534130096766],"hsluv":[41.4445641191571781,100.000000000002416,64.1467534130096766]},"#dd8811":{"lch":[64.1795176641247593,93.3565504581455,40.9755438084832377],"luv":[64.1795176641247593,70.4832194968749235,61.2173282886440333],"rgb":[0.866666666666666696,0.533333333333333326,0.0666666666666666657],"xyz":[0.387230686795366263,0.330229867536628807,0.0486512655054082421],"hpluv":[40.9755438084832377,184.581288668542754,64.1795176641247593],"hsluv":[40.9755438084832377,98.0366401848460072,64.1795176641247593]},"#dd8822":{"lch":[64.2401831232140665,91.3094921720035444,40.0852847486271529],"luv":[64.2401831232140665,69.8596876954725303,58.7966614341343359],"rgb":[0.866666666666666696,0.533333333333333326,0.133333333333333331],"xyz":[0.38910604493384332,0.330980010792019608,0.0585281517013874417],"hpluv":[40.0852847486271529,180.363429125237786,64.2401831232140665],"hsluv":[40.0852847486271529,94.440421143342,64.2401831232140665]},"#dd8833":{"lch":[64.3398685532121704,88.0506151089842319,38.5586382769189342],"luv":[64.3398685532121704,68.8529964065635,54.8832916916272],"rgb":[0.866666666666666696,0.533333333333333326,0.2],"xyz":[0.392193795666301,0.332215111085002734,0.0747903055589985849],"hpluv":[38.5586382769189342,173.656703033806934,64.3398685532121704],"hsluv":[38.5586382769189342,88.6389494712849171,64.3398685532121704]},"#dd8844":{"lch":[64.4833562447751376,83.590391105324656,36.2144134416389392],"luv":[64.4833562447751376,67.4417066096926305,49.3859260793323571],"rgb":[0.866666666666666696,0.533333333333333326,0.266666666666666663],"xyz":[0.396651790910519941,0.333998309182690301,0.0982690805118852234],"hpluv":[36.2144134416389392,164.493238171948974,64.4833562447751376],"hsluv":[36.2144134416389392,80.515719620269337,64.4833562447751376]},"#dd8855":{"lch":[64.6744699451661234,78.0792033713498768,32.8038905377638059],"luv":[64.6744699451661234,65.6278986079903746,42.3006019272060527],"rgb":[0.866666666666666696,0.533333333333333326,0.333333333333333315],"xyz":[0.402614204949881926,0.336383274798435161,0.129671127785859125],"hpluv":[32.8038905377638059,153.194023310958244,64.6744699451661234],"hsluv":[32.8038905377638059,70.0933757373770874,64.6744699451661234]},"#dd8866":{"lch":[64.9162913059566762,71.8298791231791114,27.9793586637294176],"luv":[64.9162913059566762,63.4341634455056251,33.69923504798588],"rgb":[0.866666666666666696,0.533333333333333326,0.4],"xyz":[0.410199200723390112,0.33941727310783848,0.169618772193003087],"hpluv":[27.9793586637294176,140.40764710249897,64.9162913059566762],"hsluv":[27.9793586637294176,57.516131894534638,64.9162913059566762]},"#dd8877":{"lch":[65.211273186305,65.3549274640793243,21.2774014292581],"luv":[65.211273186305,60.8999714810578325,23.7162395299384023],"rgb":[0.866666666666666696,0.533333333333333326,0.466666666666666674],"xyz":[0.419513213743592,0.343142878315919275,0.218672574099401],"hpluv":[21.2774014292581,127.173019810527066,65.211273186305],"hsluv":[21.2774014292581,55.3192807564291797,65.211273186305]},"#dd8888":{"lch":[65.5613077882642585,59.4140252364257222,12.17705063006205],"luv":[65.5613077882642585,58.0772370198051675,12.5323954190731097],"rgb":[0.866666666666666696,0.533333333333333326,0.533333333333333326],"xyz":[0.430653630845535818,0.347599045156696873,0.277345437502973191],"hpluv":[12.17705063006205,114.995459986814794,65.5613077882642585],"hsluv":[12.17705063006205,56.217054427929,65.5613077882642585]},"#dd8899":{"lch":[65.9677735951440809,55.0265961591163304,0.371909902430330563],"luv":[65.9677735951440809,55.0254369244830599,0.357178006339119947],"rgb":[0.866666666666666696,0.533333333333333326,0.6],"xyz":[0.443710594954608517,0.352821830800326031,0.34611211514409107],"hpluv":[0.371909902430330563,105.847388780281833,65.9677735951440809],"hsluv":[0.371909902430330563,57.1692646853200088,65.9677735951440809]},"#dd88aa":{"lch":[66.4315725960282,53.3143351650078756,346.342357286170909],"luv":[66.4315725960282,51.8068159744011751,-12.5885723051236678],"rgb":[0.866666666666666696,0.533333333333333326,0.66666666666666663],"xyz":[0.458768287919861073,0.358844907986427153,0.425415964761089671],"hpluv":[346.342357286170909,101.837748961685463,66.4315725960282],"hsluv":[346.342357286170909,58.1497775423036174,66.4315725960282]},"#dd88bb":{"lch":[66.9531637379342754,55.0554122119122695,331.715662007953938],"luv":[66.9531637379342754,48.482176665295448,-26.0878699709014299],"rgb":[0.866666666666666696,0.533333333333333326,0.733333333333333282],"xyz":[0.475905880027197747,0.365699944829361911,0.515673949859731473],"hpluv":[331.715662007953938,104.344182679937973,66.9531637379342754],"hsluv":[331.715662007953938,59.1328526037280824,66.9531637379342754]},"#dd88cc":{"lch":[67.5325957217288391,60.2482932018326949,318.477460357427788],"luv":[67.5325957217288391,45.1075955230381,-39.9394749572899741],"rgb":[0.866666666666666696,0.533333333333333326,0.8],"xyz":[0.495198255470919446,0.373416895006850713,0.617280460530001629],"hpluv":[318.477460357427788,113.206309259525241,67.5325957217288391],"hsluv":[318.477460357427788,60.0943355072680134,67.5325957217288391]},"#dd88dd":{"lch":[68.1695406599531566,68.219499196860184,307.715012949245079],"luv":[68.1695406599531566,41.7322103060295,-53.965940125636024],"rgb":[0.866666666666666696,0.533333333333333326,0.866666666666666696],"xyz":[0.516716581021553,0.382024225227104219,0.730610308430007627],"hpluv":[307.715012949245079,126.986480244117786,68.1695406599531566],"hsluv":[307.715012949245079,61.0124281772922785,68.1695406599531566]},"#dd88ee":{"lch":[68.8633291469121,78.1074456653267504,299.445313850889818],"luv":[68.8633291469121,38.3970440138518896,-68.0179393936650456],"rgb":[0.866666666666666696,0.533333333333333326,0.933333333333333348],"xyz":[0.540528761287727755,0.391549097333574236,0.85602112449853085],"hpluv":[299.445313850889818,143.92748858218269,68.8633291469121],"hsluv":[299.445313850889818,80.0342386911036385,68.8633291469121]},"#dd88ff":{"lch":[69.6129866887261244,89.1875622693819281,293.199992160066699],"luv":[69.6129866887261244,35.1347073752451706,-81.975445111391565],"rgb":[0.866666666666666696,0.533333333333333326,1],"xyz":[0.566699809697559176,0.40201751669750696,0.993855312790312695],"hpluv":[293.199992160066699,162.574846632166981,69.6129866887261244],"hsluv":[293.199992160066699,99.9999999999981242,69.6129866887261244]},"#dd9900":{"lch":[68.1357569139589287,89.1370219700488775,50.3810095729648921],"luv":[68.1357569139589287,56.8408371488252229,68.6624199829113735],"rgb":[0.866666666666666696,0.6,0],"xyz":[0.41208862174819666,0.381564402241709621,0.0519463606914748674],"hpluv":[50.3810095729648921,166.005456049637957,68.1357569139589287],"hsluv":[50.3810095729648921,100.000000000002245,68.1357569139589287]},"#dd9911":{"lch":[68.1654896561650077,88.0318570495471278,50.0002977758109424],"luv":[68.1654896561650077,56.5854364905009248,67.4366089951992507],"rgb":[0.866666666666666696,0.6,0.0666666666666666657],"xyz":[0.413100287247833764,0.381969068441564474,0.0572744656562305],"hpluv":[50.0002977758109424,163.875726960716179,68.1654896561650077],"hsluv":[50.0002977758109424,98.2940371374324826,68.1654896561650077]},"#dd9922":{"lch":[68.2205507365204,86.012937831153792,49.27558445879027],"luv":[68.2205507365204,56.1166821435168472,65.1854543556261774],"rgb":[0.866666666666666696,0.6,0.133333333333333331],"xyz":[0.414975645386310821,0.382719211696955275,0.0671513518522096897],"hpluv":[49.27558445879027,159.988175949224541,68.2205507365204],"hsluv":[49.27558445879027,95.1643810214000325,68.2205507365204]},"#dd9933":{"lch":[68.3110514885433133,82.7730333151944677,48.0261582829398179],"luv":[68.3110514885433133,55.3578808500206918,61.5376313485756867],"rgb":[0.866666666666666696,0.6,0.2],"xyz":[0.418063396118768527,0.383954311989938402,0.0834135057098208399],"hpluv":[48.0261582829398179,153.757824966526499,68.3110514885433133],"hsluv":[48.0261582829398179,90.1021642959546512,68.3110514885433133]},"#dd9944":{"lch":[68.4413718194248,78.2806718730308688,46.0898611008159875],"luv":[68.4413718194248,54.2899414547091936,56.3956190296495805],"rgb":[0.866666666666666696,0.6,0.266666666666666663],"xyz":[0.422521391362987442,0.385737510087625968,0.106892280662707478],"hpluv":[46.0898611008159875,145.136005207448051,68.4413718194248],"hsluv":[46.0898611008159875,82.9860784920926449,68.4413718194248]},"#dd9955":{"lch":[68.615044439797245,72.617894762441864,43.2298844404699452],"luv":[68.615044439797245,52.9102318436571935,49.7379734808277689],"rgb":[0.866666666666666696,0.6,0.333333333333333315],"xyz":[0.428483805402349427,0.388122475703370828,0.138294327936681394],"hpluv":[43.2298844404699452,134.296171447129637,68.615044439797245],"hsluv":[43.2298844404699452,73.8078183466747362,68.615044439797245]},"#dd9966":{"lch":[68.8349542760461333,65.9999398631214262,39.0839575312566296],"luv":[68.8349542760461333,51.2306688139135815,41.6102227200810404],"rgb":[0.866666666666666696,0.6,0.4],"xyz":[0.436068801175857612,0.391156474012774147,0.178241972343825356],"hpluv":[39.0839575312566296,121.667290932950721,68.8349542760461333],"hsluv":[39.0839575312566296,62.6592399312796076,68.8349542760461333]},"#dd9977":{"lch":[69.1034430542988929,58.8170492635600723,33.0939178586399834],"luv":[69.1034430542988929,49.2755524050587468,32.1148753578207291],"rgb":[0.866666666666666696,0.6,0.466666666666666674],"xyz":[0.445382814196059518,0.394882079220854942,0.227295774250223265],"hpluv":[33.0939178586399834,108.004754244465147,69.1034430542988929],"hsluv":[33.0939178586399834,50.7393036295826789,69.1034430542988929]},"#dd9988":{"lch":[69.4223715869125328,51.7141196395305656,24.4437159362198635],"luv":[69.4223715869125328,47.0788901370553745,21.3992587150758773],"rgb":[0.866666666666666696,0.6,0.533333333333333326],"xyz":[0.456523231298003318,0.39933824606163254,0.285968637653795432],"hpluv":[24.4437159362198635,94.5255072345235305,69.4223715869125328],"hsluv":[24.4437159362198635,51.5589665528693786,69.4223715869125328]},"#dd9999":{"lch":[69.7931614924381591,45.7097919546320597,12.1770506300622632],"luv":[69.7931614924381591,44.6813426781189875,9.64171649740066705],"rgb":[0.866666666666666696,0.6,0.6],"xyz":[0.469580195407076073,0.404561031705261698,0.354735315294913311],"hpluv":[12.1770506300622632,83.1066353202273689,69.7931614924381591],"hsluv":[12.1770506300622632,52.4335711570844438,69.7931614924381591]},"#dd99aa":{"lch":[70.2168268189972196,42.2311183685245624,355.977290330288042],"luv":[70.2168268189972196,42.1270745474506256,-2.96259155636920823],"rgb":[0.866666666666666696,0.6,0.66666666666666663],"xyz":[0.484637888372328574,0.41058410889136282,0.434039164911911912],"hpluv":[355.977290330288042,76.3186553239153369,70.2168268189972196],"hsluv":[355.977290330288042,53.3392978779897788,70.2168268189972196]},"#dd99bb":{"lch":[70.694001085559151,42.6623948649138427,337.661645838825223],"luv":[70.694001085559151,39.4608168046039651,-16.2149274658665163],"rgb":[0.866666666666666696,0.6,0.733333333333333282],"xyz":[0.501775480479665248,0.417439145734297579,0.524297150010553659],"hpluv":[337.661645838825223,76.5776430619999502,70.694001085559151],"hsluv":[337.661645838825223,54.2517942883204398,70.694001085559151]},"#dd99cc":{"lch":[71.2249627580945912,47.3730793907595,320.82657583403028],"luv":[71.2249627580945912,36.7253906259007294,-29.9241430008982121],"rgb":[0.866666666666666696,0.6,0.8],"xyz":[0.521067855923387,0.42515609591178638,0.625903660680823815],"hpluv":[320.82657583403028,84.3992741769230719,71.2249627580945912],"hsluv":[320.82657583403028,55.1472527266246075,71.2249627580945912]},"#dd99dd":{"lch":[71.8096607795551876,55.5140341348433424,307.715012949246],"luv":[71.8096607795551876,33.9598410238411077,-43.9151133843462844],"rgb":[0.866666666666666696,0.6,0.866666666666666696],"xyz":[0.54258618147402049,0.433763426132039887,0.739233508580829812],"hpluv":[307.715012949246,98.0977936102115677,71.8096607795551876],"hsluv":[307.715012949246,56.0031828352742878,71.8096607795551876]},"#dd99ee":{"lch":[72.447740927007942,65.8885644567307907,298.26171852853804],"luv":[72.447740927007942,31.1982236173053273,-58.0342465212858656],"rgb":[0.866666666666666696,0.6,0.933333333333333348],"xyz":[0.566398361740195311,0.443288298238509904,0.864644324649353],"hpluv":[298.26171852853804,115.404973126410823,72.447740927007942],"hsluv":[298.26171852853804,77.3800261839098908,72.447740927007942]},"#dd99ff":{"lch":[73.1385732331520302,77.5656763031263,291.532620718417377],"luv":[73.1385732331520302,28.4689992262389602,-72.1522710898123592],"rgb":[0.866666666666666696,0.6,1],"xyz":[0.592569410150026621,0.453756717602442627,1.00247851294113488],"hpluv":[291.532620718417377,134.574391894016571,73.1385732331520302],"hsluv":[291.532620718417377,99.9999999999977689,73.1385732331520302]},"#cc0000":{"lch":[42.5207510295766156,142.998625281495549,12.1770506300617818],"luv":[42.5207510295766156,139.781222041964895,30.163169542547891],"rgb":[0.8,0,0],"xyz":[0.249012838889184379,0.128397245052238429,0.0116724768229302719],"hpluv":[12.1770506300617818,426.746789183124861,42.5207510295766156],"hsluv":[12.1770506300617818,100.000000000002174,42.5207510295766156]},"#cc0011":{"lch":[42.5821659889152784,141.236718626044905,11.4841194603559],"luv":[42.5821659889152784,138.409148973409117,28.119711390930437],"rgb":[0.8,0,0.0666666666666666657],"xyz":[0.250024504388821511,0.128801911252093282,0.0170005817876859033],"hpluv":[11.4841194603559,420.880880123779207,42.5821659889152784],"hsluv":[11.4841194603559,99.9999999999964331,42.5821659889152784]},"#cc0022":{"lch":[42.6956735686566518,138.114600243667155,10.1872609469282853],"luv":[42.6956735686566518,135.937217546775798,24.4277646564013864],"rgb":[0.8,0,0.133333333333333331],"xyz":[0.251899862527298513,0.12955205450748411,0.0268774679836651],"hpluv":[10.1872609469282853,410.482879191578036,42.6956735686566518],"hsluv":[10.1872609469282853,99.9999999999964615,42.6956735686566518]},"#cc0033":{"lch":[42.881611378965772,133.362165770655935,8.01952044887972626],"luv":[42.881611378965772,132.057963211529,18.6054188736068511],"rgb":[0.8,0,0.2],"xyz":[0.254987613259756274,0.130787154800467209,0.0431396218412762461],"hpluv":[8.01952044887972626,394.639788400466045,42.881611378965772],"hsluv":[8.01952044887972626,99.9999999999966604,42.881611378965772]},"#cc0044":{"lch":[43.1480085091585153,127.29097956278504,4.82801781999359658],"luv":[43.1480085091585153,126.839328429887985,10.7134607624411853],"rgb":[0.8,0,0.266666666666666663],"xyz":[0.259445608503975134,0.132570352898154803,0.0666183967941628846],"hpluv":[4.82801781999359658,374.34858804079829,43.1480085091585153],"hsluv":[4.82801781999359658,99.9999999999967741,43.1480085091585153]},"#cc0055":{"lch":[43.5005971125795,120.485699890795146,0.473888563816867114],"luv":[43.5005971125795,120.481578818580687,0.996515708296922487],"rgb":[0.8,0,0.333333333333333315],"xyz":[0.265408022543337119,0.134955318513899636,0.0980204440681367861],"hpluv":[0.473888563816867114,351.463000970195878,43.5005971125795],"hsluv":[0.473888563816867114,99.999999999997,43.5005971125795]},"#cc0066":{"lch":[43.9431844272177372,113.726547538665841,354.863826263116096],"luv":[43.9431844272177372,113.269906269789104,-10.1811565500985228],"rgb":[0.8,0,0.4],"xyz":[0.272993018316845304,0.137989316823302927,0.137968088475280748],"hpluv":[354.863826263116096,328.404920869645196,43.9431844272177372],"hsluv":[354.863826263116096,99.9999999999972857,43.9431844272177372]},"#cc0077":{"lch":[44.4778741065655,107.874648109024193,348.012259047653401],"luv":[44.4778741065655,105.522124609829902,-22.4058234053856609],"rgb":[0.8,0,0.466666666666666674],"xyz":[0.28230703133704721,0.14171492203138375,0.187021890381678657],"hpluv":[348.012259047653401,307.761788629886667,44.4778741065655],"hsluv":[348.012259047653401,99.9999999999975273,44.4778741065655]},"#cc0088":{"lch":[45.1052440924579,103.725434836726933,340.1176986346278],"luv":[45.1052440924579,97.5426962017022703,-35.2758876538989838],"rgb":[0.8,0,0.533333333333333326],"xyz":[0.293447448438991065,0.146171088872161348,0.245694753785250825],"hpluv":[340.1176986346278,291.808241377507443,45.1052440924579],"hsluv":[340.1176986346278,99.9999999999978,45.1052440924579]},"#cc0099":{"lch":[45.8245205562958589,101.850048541314862,331.598662995615],"luv":[45.8245205562958589,89.5911194129305102,-48.4444394147173441],"rgb":[0.8,0,0.6],"xyz":[0.306504412548063765,0.151393874515790505,0.314461431426368732],"hpluv":[331.598662995615,282.034759885138044,45.8245205562958589],"hsluv":[331.598662995615,99.9999999999981,45.8245205562958589]},"#cc00aa":{"lch":[46.633760692471931,102.477609530343315,323.022725489580409],"luv":[46.633760692471931,81.8667129915779,-61.640098629123905],"rgb":[0.8,0,0.66666666666666663],"xyz":[0.321562105513316321,0.1574169517018916,0.393765281043367332],"hpluv":[323.022725489580409,278.848217687739293,46.633760692471931],"hsluv":[323.022725489580409,99.9999999999983658,46.633760692471931]},"#cc00bb":{"lch":[47.5300446684938933,105.484027274260768,314.937463984289479],"luv":[47.5300446684938933,74.5070162947061903,-74.6698368342758414],"rgb":[0.8,0,0.733333333333333282],"xyz":[0.33869969762065294,0.164271988544826358,0.484023266142009079],"hpluv":[314.937463984289479,281.616311803476265,47.5300446684938933],"hsluv":[314.937463984289479,99.9999999999986,47.5300446684938933]},"#cc00cc":{"lch":[48.5096711653281147,110.497164945278598,307.715012949243601],"luv":[48.5096711653281147,67.5949102529980621,-87.4102486487325],"rgb":[0.8,0,0.8],"xyz":[0.357992073064374694,0.17198893872231516,0.585629776812279235],"hpluv":[307.715012949243601,289.042783730483393,48.5096711653281147],"hsluv":[307.715012949243601,99.9999999999988,48.5096711653281147]},"#cc00dd":{"lch":[49.5683488162236614,117.049051317219835,301.506761454082039],"luv":[49.5683488162236614,61.1697383356450075,-99.7935044289451],"rgb":[0.8,0,0.866666666666666696],"xyz":[0.379510398615008238,0.180596268942568694,0.698959624712285232],"hpluv":[301.506761454082039,299.64205877637869,49.5683488162236614],"hsluv":[301.506761454082039,99.9999999999990337,49.5683488162236614]},"#cc00ee":{"lch":[50.7013760136427862,124.695255359169607,296.294949026353493],"luv":[50.7013760136427862,55.2390203059142522,-111.792474454818787],"rgb":[0.8,0,0.933333333333333348],"xyz":[0.403322578881182947,0.190121141049038739,0.824370440780808456],"hpluv":[296.294949026353493,312.082566880879938,50.7013760136427862],"hsluv":[296.294949026353493,99.99999999999919,50.7013760136427862]},"#cc00ff":{"lch":[51.9038030272213,133.072735088441448,291.971633700566258],"luv":[51.9038030272213,49.7888328026579075,-123.407556300526],"rgb":[0.8,0,1],"xyz":[0.429493627291014368,0.200589560412971435,0.962204629072590301],"hpluv":[291.971633700566258,325.333832743425603,51.9038030272213],"hsluv":[291.971633700566258,99.9999999999993321,51.9038030272213]},"#cc1100":{"lch":[43.1235624482234172,140.134259476931788,12.8715382160273855],"luv":[43.1235624482234172,136.61296213687416,31.2171307992428524],"rgb":[0.8,0.0666666666666666657,0],"xyz":[0.251017239150112814,0.132406045574095299,0.0123406102432397219],"hpluv":[12.8715382160273855,412.352867097941,43.1235624482234172],"hsluv":[12.8715382160273855,100.000000000002245,43.1235624482234172]},"#cc1111":{"lch":[43.1837333530957892,138.41807101963343,12.1770506300617676],"luv":[43.1837333530957892,135.303728142340162,29.196978192614182],"rgb":[0.8,0.0666666666666666657,0.0666666666666666657],"xyz":[0.252028904649749919,0.132810711773950152,0.0176687152079953516],"hpluv":[12.1770506300617676,406.735363437937394,43.1837333530957892],"hsluv":[12.1770506300617676,95.3107026807431197,43.1837333530957892]},"#cc1122":{"lch":[43.294951674171287,135.375047793376126,10.8766574447476163],"luv":[43.294951674171287,132.943125696930394,25.5446451333550044],"rgb":[0.8,0.0666666666666666657,0.133333333333333331],"xyz":[0.253904262788227,0.13356085502934098,0.0275456014039745511],"hpluv":[10.8766574447476163,396.771701832449367,43.294951674171287],"hsluv":[10.8766574447476163,95.396390587568618,43.294951674171287]},"#cc1133":{"lch":[43.4771672841157724,130.73841758888139,8.7012157385065958],"luv":[43.4771672841157724,129.233706917218683,19.7783424502448213],"rgb":[0.8,0.0666666666666666657,0.2],"xyz":[0.256992013520684681,0.134795955322324079,0.0438077552615856944],"hpluv":[8.7012157385065958,381.576227833431062,43.4771672841157724],"hsluv":[8.7012157385065958,95.5308510527687389,43.4771672841157724]},"#cc1144":{"lch":[43.7382910834512586,124.807582872189826,5.49437317543092796],"luv":[43.7382910834512586,124.234167693991893,11.9500761411646046],"rgb":[0.8,0.0666666666666666657,0.266666666666666663],"xyz":[0.261450008764903596,0.136579153420011673,0.0672865302144723398],"hpluv":[5.49437317543092796,362.091632024479338,43.7382910834512586],"hsluv":[5.49437317543092796,95.7116850897169229,43.7382910834512586]},"#cc1155":{"lch":[44.0840061747103107,118.151091154502552,1.11194247693657511],"luv":[44.0840061747103107,118.128842001262925,2.29282106589917234],"rgb":[0.8,0.0666666666666666657,0.333333333333333315],"xyz":[0.267412422804265582,0.138964119035756506,0.0986885774884462413],"hpluv":[1.11194247693657511,340.091681007194666,44.0840061747103107],"hsluv":[1.11194247693657511,95.9318436200579754,44.0840061747103107]},"#cc1166":{"lch":[44.5181325219627837,111.53522478210337,355.453854482233226],"luv":[44.5181325219627837,111.184314904818763,-8.84050260677650712],"rgb":[0.8,0.0666666666666666657,0.4],"xyz":[0.274997418577773767,0.141998117345159797,0.138636221895590217],"hpluv":[355.453854482233226,317.917500588946211,44.5181325219627837],"hsluv":[355.453854482233226,96.1812476973727115,44.5181325219627837]},"#cc1177":{"lch":[45.0428415016287857,105.814757555455103,348.528515458334311],"luv":[45.0428415016287857,103.700981473984271,-21.0444614531261323],"rgb":[0.8,0.0666666666666666657,0.466666666666666674],"xyz":[0.284311431597975672,0.14572372255324062,0.187690023801988126],"hpluv":[348.528515458334311,298.098498005115459,45.0428415016287857],"hsluv":[348.528515458334311,96.4486017572014589,45.0428415016287857]},"#cc1188":{"lch":[45.6588256994622341,101.788242110562607,340.533613155211185],"luv":[45.6588256994622341,95.9697371205835594,-33.9213176183443323],"rgb":[0.8,0.0666666666666666657,0.533333333333333326],"xyz":[0.295451848699919473,0.150179889394018218,0.246362887205560266],"hpluv":[340.533613155211185,282.886487347344485,45.6588256994622341],"hsluv":[340.533613155211185,96.7230145871901215,45.6588256994622341]},"#cc1199":{"lch":[46.3654632546324876,100.035938879036408,331.896400713626349],"luv":[46.3654632546324876,88.2414291467186,-47.1236591273953138],"rgb":[0.8,0.0666666666666666657,0.6],"xyz":[0.308508812808992228,0.155402675037647375,0.315129564846678201],"hpluv":[331.896400713626349,273.779405248492822,46.3654632546324876],"hsluv":[331.896400713626349,96.9951405388504355,46.3654632546324876]},"#cc11aa":{"lch":[47.1609900317596882,100.794975336059878,323.201580807901109],"luv":[47.1609900317596882,80.7113646178594735,-60.3763420100941488],"rgb":[0.8,0.0666666666666666657,0.66666666666666663],"xyz":[0.323566505774244728,0.16142575222374847,0.394433414463676801],"hpluv":[323.201580807901109,271.203503720358924,47.1609900317596882],"hsluv":[323.201580807901109,97.2577546113476075,47.1609900317596882]},"#cc11bb":{"lch":[48.0426807208370548,103.942897448445919,315.013990059648165],"luv":[48.0426807208370548,73.5166718264647727,-73.4807790754699681],"rgb":[0.8,0.0666666666666666657,0.733333333333333282],"xyz":[0.340704097881581403,0.168280789066683228,0.484691399562318548],"hpluv":[315.013990059648165,274.540811344802705,48.0426807208370548],"hsluv":[315.013990059648165,97.5058443216483,48.0426807208370548]},"#cc11cc":{"lch":[49.0070341259591515,109.103198367120783,307.715012949243601],"luv":[49.0070341259591515,66.7421730285370387,-86.3075328888743769],"rgb":[0.8,0.0666666666666666657,0.8],"xyz":[0.359996473325303157,0.17599773924417203,0.586297910232588704],"hpluv":[307.715012949243601,282.499958642668389,49.0070341259591515],"hsluv":[307.715012949243601,97.7363817897909541,49.0070341259591515]},"#cc11dd":{"lch":[50.0499556366759037,115.801352096543823,301.456118533327128],"luv":[50.0499556366759037,60.4304023076134555,-98.7831950502093292],"rgb":[0.8,0.0666666666666666657,0.866666666666666696],"xyz":[0.381514798875936645,0.184605069464425564,0.699627758132594701],"hpluv":[301.456118533327128,293.595408819402792,50.0499556366759037],"hsluv":[301.456118533327128,97.9479403979501342,50.0499556366759037]},"#cc11ee":{"lch":[51.1669298024285837,123.587345912593733,296.214453457233276],"luv":[51.1669298024285837,54.5925079172689109,-110.876012505059137],"rgb":[0.8,0.0666666666666666657,0.933333333333333348],"xyz":[0.40532697914211141,0.194129941570895609,0.825038574201117925],"hpluv":[296.214453457233276,306.495409047480564,51.1669298024285837],"hsluv":[296.214453457233276,98.1402788193950215,51.1669298024285837]},"#cc11ff":{"lch":[52.3531771468210678,132.094610043027387,291.87590029388349],"luv":[52.3531771468210678,49.2181193296501576,-122.582881072651375],"rgb":[0.8,0.0666666666666666657,1],"xyz":[0.431498027551942775,0.204598360934828305,0.96287276249289977],"hpluv":[291.87590029388349,320.170549145207644,52.3531771468210678],"hsluv":[291.87590029388349,99.9999999999991189,52.3531771468210678]},"#cc2200":{"lch":[44.2095884480383674,135.132222138307952,14.1797238149512133],"luv":[44.2095884480383674,131.015027118873576,33.102569825888537],"rgb":[0.8,0.133333333333333331,0],"xyz":[0.254732862884880729,0.139837293043631267,0.0135791514881623328],"hpluv":[14.1797238149512133,387.866054960954045,44.2095884480383674],"hsluv":[14.1797238149512133,100.00000000000226,44.2095884480383674]},"#cc2211":{"lch":[44.2676114068871129,133.490625771231663,13.482935392010976],"luv":[44.2676114068871129,129.81154471696064,31.1241068464871375],"rgb":[0.8,0.133333333333333331,0.0666666666666666657],"xyz":[0.255744528384517833,0.14024195924348612,0.0189072564529179643],"hpluv":[13.482935392010976,382.652016671578622,44.2676114068871129],"hsluv":[13.482935392010976,95.5414705532830197,44.2676114068871129]},"#cc2222":{"lch":[44.3748759613401162,130.576558981694717,12.1770506300617747],"luv":[44.3748759613401162,127.638646515421286,27.5429423121666019],"rgb":[0.8,0.133333333333333331,0.133333333333333331],"xyz":[0.25761988652299489,0.140992102498876948,0.0287841426488971604],"hpluv":[12.1770506300617747,373.394050741154899,44.3748759613401162],"hsluv":[12.1770506300617747,87.4977996802062847,44.3748759613401162]},"#cc2233":{"lch":[44.5506596541482907,126.128431434884163,9.98899557195718657],"luv":[44.5506596541482907,124.216461430809,21.8781152257824267],"rgb":[0.8,0.133333333333333331,0.2],"xyz":[0.260707637255452596,0.142227202791860047,0.0450462965065083071],"hpluv":[9.98899557195718657,359.251162664680805,44.5506596541482907],"hsluv":[9.98899557195718657,87.8457930667704829,44.5506596541482907]},"#cc2244":{"lch":[44.8026641682027602,120.425301369152351,6.75586226508684629],"luv":[44.8026641682027602,119.589119356054482,14.1667124448306829],"rgb":[0.8,0.133333333333333331,0.266666666666666663],"xyz":[0.265165632499671511,0.144010400889547641,0.0685250714593949456],"hpluv":[6.75586226508684629,341.077623618219945,44.8026641682027602],"hsluv":[6.75586226508684629,88.3153597242729,44.8026641682027602]},"#cc2255":{"lch":[45.136480402373536,114.008772215671115,2.323188749975583],"luv":[45.136480402373536,113.915065115628011,4.62148047999889577],"rgb":[0.8,0.133333333333333331,0.333333333333333315],"xyz":[0.271128046539033496,0.146395366505292474,0.0999271187333688471],"hpluv":[2.323188749975583,320.51614012782295,45.136480402373536],"hsluv":[2.323188749975583,88.8894607126765663,45.136480402373536]},"#cc2266":{"lch":[45.5559407124691731,107.622008592458101,356.577515499379103],"luv":[45.5559407124691731,107.430062323442542,-6.42483016556681452],"rgb":[0.8,0.133333333333333331,0.4],"xyz":[0.278713042312541681,0.149429364814695764,0.139874763140512809],"hpluv":[356.577515499379103,299.774992396016216,45.5559407124691731],"hsluv":[356.577515499379103,89.543058875786258,45.5559407124691731]},"#cc2277":{"lch":[46.0633224094211542,102.110102175352239,349.514816334356908],"luv":[46.0633224094211542,100.405067655344695,-18.5821246198201955],"rgb":[0.8,0.133333333333333331,0.466666666666666674],"xyz":[0.288027055332743587,0.153154970022776588,0.188928565046910718],"hpluv":[349.514816334356908,281.289018816444,46.0633224094211542],"hsluv":[349.514816334356908,90.2475430222303174,46.0633224094211542]},"#cc2288":{"lch":[46.6595045299101443,98.2790088680822294,341.330158110485115],"luv":[46.6595045299101443,93.107459692013677,-31.4605234189234864],"rgb":[0.8,0.133333333333333331,0.533333333333333326],"xyz":[0.299167472434687387,0.157611136863554185,0.247601428450482886],"hpluv":[341.330158110485115,267.276005324070297,46.6595045299101443],"hsluv":[341.330158110485115,90.9748001704168,46.6595045299101443]},"#cc2299":{"lch":[47.3441166442187154,96.727251962869147,332.467163788405],"luv":[47.3441166442187154,85.772509513995189,-44.7128380217581167],"rgb":[0.8,0.133333333333333331,0.6],"xyz":[0.312224436543760087,0.162833922507183343,0.31636810609160082],"hpluv":[332.467163788405,259.252025571181889,47.3441166442187154],"hsluv":[332.467163788405,91.7002075152857259,47.3441166442187154]},"#cc22aa":{"lch":[48.1156936783416285,97.7076198445846131,323.544141865814368],"luv":[48.1156936783416285,78.5876931080813534,-58.0581903579838254],"rgb":[0.8,0.133333333333333331,0.66666666666666663],"xyz":[0.327282129509012643,0.168856999693284437,0.395671955708599421],"hpluv":[323.544141865814368,257.680176436907345,48.1156936783416285],"hsluv":[323.544141865814368,92.4042695013683328,48.1156936783416285]},"#cc22bb":{"lch":[48.9718390817589295,101.100583268181566,315.160199675634601],"luv":[48.9718390817589295,71.6885121422158846,-71.2887450022924867],"rgb":[0.8,0.133333333333333331,0.733333333333333282],"xyz":[0.344419721616349317,0.175712036536219196,0.485929940807241167],"hpluv":[315.160199675634601,261.96699229126267,48.9718390817589295],"hsluv":[315.160199675634601,93.0730408422972602,48.9718390817589295]},"#cc22cc":{"lch":[49.9093929354593513,106.520702596514482,307.715012949243658],"luv":[49.9093929354593513,65.1623716831421405,-84.2646153393173876],"rgb":[0.8,0.133333333333333331,0.8],"xyz":[0.363712097060071,0.183428986713708,0.587536451477511323],"hpluv":[307.715012949243658,270.826440261226253,49.9093929354593513],"hsluv":[307.715012949243658,93.6976999618693327,49.9093929354593513]},"#cc22dd":{"lch":[50.9245991417877377,113.480326695625976,301.360030221234524],"luv":[50.9245991417877377,59.0567580516805819,-96.9024451465042347],"rgb":[0.8,0.133333333333333331,0.866666666666666696],"xyz":[0.385230422610704615,0.192036316933961532,0.700866299377517321],"hpluv":[301.360030221234524,282.769318292038,50.9245991417877377],"hsluv":[301.360030221234524,94.2736696463096848,50.9245991417877377]},"#cc22ee":{"lch":[52.0132654143591964,121.518329969744158,296.062236941936249],"luv":[52.0132654143591964,53.3887372455597244,-109.162022947361166],"rgb":[0.8,0.133333333333333331,0.933333333333333348],"xyz":[0.409042602876879324,0.201561189040431576,0.826277115446040544],"hpluv":[296.062236941936249,296.460610812118318,52.0132654143591964],"hsluv":[296.062236941936249,94.7995997265514,52.0132654143591964]},"#cc22ff":{"lch":[53.170910599170611,130.261070707018604,291.695402941657903],"luv":[53.170910599170611,48.1538976563848422,-121.033667556747687],"rgb":[0.8,0.133333333333333331,1],"xyz":[0.435213651286710745,0.212029608404364273,0.964111303737822389],"hpluv":[291.695402941657903,310.870757963074425,53.170910599170611],"hsluv":[291.695402941657903,99.9999999999990621,53.170910599170611]},"#cc3300":{"lch":[45.9167915379707807,127.686226573765651,16.3911473443809399],"luv":[45.9167915379707807,122.496750231663356,36.0321889333482446],"rgb":[0.8,0.2,0],"xyz":[0.260850584973891519,0.15207273722165307,0.0156183921844992128],"hpluv":[16.3911473443809399,352.867650162608584,45.9167915379707807],"hsluv":[16.3911473443809399,100.000000000002288,45.9167915379707807]},"#cc3311":{"lch":[45.9716631772740811,126.14350976506573,15.6923563051461095],"luv":[45.9716631772740811,121.44186843726601,34.118289029712578],"rgb":[0.8,0.2,0.0666666666666666657],"xyz":[0.261862250473528624,0.152477403421507923,0.020946497149254846],"hpluv":[15.6923563051461095,348.188177538365835,45.9716631772740811],"hsluv":[15.6923563051461095,95.8756509753329595,45.9716631772740811]},"#cc3322":{"lch":[46.0731243265426613,123.399991281457972,14.3806932854006604],"luv":[46.0731243265426613,119.533487768482047,30.6480529588105668],"rgb":[0.8,0.2,0.133333333333333331],"xyz":[0.263737608612005681,0.153227546676898752,0.0308233833452340386],"hpluv":[14.3806932854006604,339.865273437066321,46.0731243265426613],"hsluv":[14.3806932854006604,88.4197842587317524,46.0731243265426613]},"#cc3333":{"lch":[46.2394596481243951,119.199958247304309,12.1770506300617924],"luv":[46.2394596481243951,116.518014060345578,25.1432385661076303],"rgb":[0.8,0.2,0.2],"xyz":[0.266825359344463386,0.154462646969881851,0.0470855372028451818],"hpluv":[12.1770506300617924,327.11667224844831,46.2394596481243951],"hsluv":[12.1770506300617924,76.6535755019082,46.2394596481243951]},"#cc3344":{"lch":[46.4780522046582405,113.793717346871745,8.90746564227168669],"luv":[46.4780522046582405,112.421330819758609,17.6197186224449389],"rgb":[0.8,0.2,0.266666666666666663],"xyz":[0.271283354588682302,0.156245845067569444,0.0705643121557318204],"hpluv":[8.90746564227168669,310.677421508065,46.4780522046582405],"hsluv":[8.90746564227168669,77.4930753906613887,46.4780522046582405]},"#cc3355":{"lch":[46.7943405275181661,107.68493286266704,4.39945159143432907],"luv":[46.7943405275181661,107.367637754253522,8.26045572038872855],"rgb":[0.8,0.2,0.333333333333333315],"xyz":[0.277245768628044287,0.158630810683314277,0.101966359429705736],"hpluv":[4.39945159143432907,292.012160158640199,46.7943405275181661],"hsluv":[4.39945159143432907,78.5258346284665265,46.7943405275181661]},"#cc3366":{"lch":[47.192153202602185,101.584765682520938,358.514989280316684],"luv":[47.192153202602185,101.55064731932022,-2.63261235272558647],"rgb":[0.8,0.2,0.4],"xyz":[0.284830764401552472,0.161664808992717568,0.141914003836849684],"hpluv":[358.514989280316684,273.148057687163259,47.192153202602185],"hsluv":[358.514989280316684,79.7102211537212781,47.192153202602185]},"#cc3377":{"lch":[47.6738975277608859,96.3272258277819589,351.225603296168742],"luv":[47.6738975277608859,95.1998742335289876,-14.6941614798792699],"rgb":[0.8,0.2,0.466666666666666674],"xyz":[0.294144777421754378,0.165390414200798391,0.190967805743247593],"hpluv":[351.225603296168742,256.39391915093114,47.6738975277608859],"hsluv":[351.225603296168742,80.9972134637005894,47.6738975277608859]},"#cc3388":{"lch":[48.2406991607903279,92.7347249941698095,342.718318936463845],"luv":[48.2406991607903279,88.5482927213948301,-27.5486674064369161],"rgb":[0.8,0.2,0.533333333333333326],"xyz":[0.305285194523698178,0.169846581041576,0.24964066914681976],"hpluv":[342.718318936463845,243.93163202064531,48.2406991607903279],"hsluv":[342.718318936463845,82.3372641433758758,48.2406991607903279]},"#cc3399":{"lch":[48.8925304323200436,91.4400639314067405,333.463846826874658],"luv":[48.8925304323200436,81.8070942553503926,-40.8519843003490877],"rgb":[0.8,0.2,0.6],"xyz":[0.318342158632770933,0.175069366685205147,0.318407346787937695],"hpluv":[333.463846826874658,237.319449797121564,48.8925304323200436],"hsluv":[333.463846826874658,83.6856508008112,48.8925304323200436]},"#cc33aa":{"lch":[49.6283419748853873,92.7248127600779242,324.141487451800515],"luv":[49.6283419748853873,75.1503095778714254,-54.3168654447363792],"rgb":[0.8,0.2,0.66666666666666663],"xyz":[0.333399851598023433,0.181092443871306241,0.397711196404936296],"hpluv":[324.141487451800515,237.085790295602294,49.6283419748853873],"hsluv":[324.141487451800515,85.0057245198840263,49.6283419748853873]},"#cc33bb":{"lch":[50.4462014889725054,96.4744776262418355,315.414049480091705],"luv":[50.4462014889725054,68.7089492450233905,-67.7230029377097],"rgb":[0.8,0.2,0.733333333333333282],"xyz":[0.350537443705360108,0.187947480714241,0.487969181503578042],"hpluv":[315.414049480091705,242.674024226837219,50.4462014889725054],"hsluv":[315.414049480091705,86.2701296035756258,50.4462014889725054]},"#cc33cc":{"lch":[51.3434379695087273,102.286811532428814,307.715012949243771],"luv":[51.3434379695087273,62.5723551280607779,-80.915339628518268],"rgb":[0.8,0.2,0.8],"xyz":[0.369829819149081862,0.195664430891729801,0.589575692173848198],"hpluv":[307.715012949243771,252.798225898109365,51.3434379695087273],"hsluv":[307.715012949243771,87.4604868647498,51.3434379695087273]},"#cc33dd":{"lch":[52.3167871114961827,109.649949983538605,301.195256028086874],"luv":[52.3167871114961827,56.7938698017029751,-93.7953510806358],"rgb":[0.8,0.2,0.866666666666666696],"xyz":[0.39134814469971535,0.204271761111983335,0.702905540073854196],"hpluv":[301.195256028086874,265.954105752122757,52.3167871114961827],"hsluv":[301.195256028086874,88.5661577004671,52.3167871114961827]},"#cc33ee":{"lch":[53.3625327970638494,118.082474280319559,295.802769884900215],"luv":[53.3625327970638494,51.3983045372134626,-106.309383512755787],"rgb":[0.8,0.2,0.933333333333333348],"xyz":[0.415160324965890115,0.21379663321845338,0.828316356142377419],"hpluv":[295.802769884900215,280.794331636146467,53.3625327970638494],"hsluv":[295.802769884900215,89.5826266077864375,53.3625327970638494]},"#cc33ff":{"lch":[54.4766398815527566,127.197777570935344,291.389330811727291],"luv":[54.4766398815527566,46.3894624378335,-118.436870921660102],"rgb":[0.8,0.2,1],"xyz":[0.441331373375721481,0.224265052582386076,0.966150544434159264],"hpluv":[291.389330811727291,296.284230666095709,54.4766398815527566],"hsluv":[291.389330811727291,99.9999999999990195,54.4766398815527566]},"#cc4400":{"lch":[48.2269914221542848,118.435883841274119,19.7039935064818295],"luv":[48.2269914221542848,111.501113106022,39.9319465764175447],"rgb":[0.8,0.266666666666666663,0],"xyz":[0.26968315545685756,0.1697378781875854,0.0185625823454878096],"hpluv":[19.7039935064818295,311.625122342549162,48.2269914221542848],"hsluv":[19.7039935064818295,100.000000000002174,48.2269914221542848]},"#cc4411":{"lch":[48.2779913635395,116.996103035931512,19.0066631306561966],"luv":[48.2779913635395,110.617558299276112,38.1030697123021],"rgb":[0.8,0.266666666666666663,0.0666666666666666657],"xyz":[0.270694820956494664,0.170142544387440253,0.0238906873102434428],"hpluv":[19.0066631306561966,307.511619232155283,48.2779913635395],"hsluv":[19.0066631306561966,96.278384876640132,48.2779913635395]},"#cc4422":{"lch":[48.3723181772035389,114.428966114904512,17.6946931608209894],"luv":[48.3723181772035389,109.015290220227484,34.7800917814421453],"rgb":[0.8,0.266666666666666663,0.133333333333333331],"xyz":[0.272570179094971721,0.170892687642831081,0.0337675735062226354],"hpluv":[17.6946931608209894,300.177682052924467,48.3723181772035389],"hsluv":[17.6946931608209894,89.5341066932624869,48.3723181772035389]},"#cc4433":{"lch":[48.5270263662828114,110.48209503335984,15.4815426750504042],"luv":[48.5270263662828114,106.473417017787412,29.4907577304601034],"rgb":[0.8,0.266666666666666663,0.2],"xyz":[0.275657929827429427,0.17212778793581418,0.0500297273638337786],"hpluv":[15.4815426750504042,288.900004133964501,48.5270263662828114],"hsluv":[15.4815426750504042,78.8475327486048,48.5270263662828114]},"#cc4444":{"lch":[48.7490888960709725,105.371058014361893,12.1770506300618457],"luv":[48.7490888960709725,103.000257716521162,22.2262632351064191],"rgb":[0.8,0.266666666666666663,0.266666666666666663],"xyz":[0.280115925071648342,0.173910986033501774,0.0735085023167204171],"hpluv":[12.1770506300618457,274.28001464324592,48.7490888960709725],"hsluv":[12.1770506300618457,64.2723089184284788,48.7490888960709725]},"#cc4455":{"lch":[49.0437296069087,99.5540950311582691,7.58056168126664254],"luv":[49.0437296069087,98.6840273694228074,13.1331861946711772],"rgb":[0.8,0.266666666666666663,0.333333333333333315],"xyz":[0.286078339111010327,0.176295951649246607,0.104910549590694333],"hpluv":[7.58056168126664254,257.581676799067395,49.0437296069087],"hsluv":[7.58056168126664254,65.7689369270132858,49.0437296069087]},"#cc4466":{"lch":[49.4147368002801244,93.7049448509207679,1.51289058041819868],"luv":[49.4147368002801244,93.6722802728102835,2.47398423725391092],"rgb":[0.8,0.266666666666666663,0.4],"xyz":[0.293663334884518512,0.179329949958649898,0.14485819399783828],"hpluv":[1.51289058041819868,240.627550105868352,49.4147368002801244],"hsluv":[1.51289058041819868,67.500804726855,49.4147368002801244]},"#cc4477":{"lch":[49.8646356184384132,88.6490107187132566,353.900159994018],"luv":[49.8646356184384132,88.1471013723349586,-9.41995865499641383],"rgb":[0.8,0.266666666666666663,0.466666666666666674],"xyz":[0.302977347904720418,0.183055555166730721,0.19391199590423619],"hpluv":[353.900159994018,225.590377060975072,49.8646356184384132],"hsluv":[353.900159994018,69.4017616341687784,49.8646356184384132]},"#cc4488":{"lch":[50.3948096201307436,85.2405150759366279,344.907000147604322],"luv":[50.3948096201307436,82.3000967091543743,-22.1954835963269055],"rgb":[0.8,0.266666666666666663,0.533333333333333326],"xyz":[0.314117765006664218,0.187511722007508319,0.252584859307808385],"hpluv":[344.907000147604322,214.634525667930632,50.3948096201307436],"hsluv":[344.907000147604322,71.4025087995354824,50.3948096201307436]},"#cc4499":{"lch":[51.0056074652318046,84.1718897613591679,335.041688295241613],"luv":[51.0056074652318046,76.3115014820887581,-35.5170630478867793],"rgb":[0.8,0.266666666666666663,0.6],"xyz":[0.327174729115737,0.192734507651137477,0.321351536948926264],"hpluv":[335.041688295241613,209.40569084337892,51.0056074652318046],"hsluv":[335.041688295241613,73.4381222823911344,51.0056074652318046]},"#cc44aa":{"lch":[51.6964496814969152,85.7749410926589348,325.085448007895536],"luv":[51.6964496814969152,70.3360122964612913,-49.093644127128691],"rgb":[0.8,0.266666666666666663,0.66666666666666663],"xyz":[0.342232422080989473,0.198757584837238571,0.400655386565924865],"hpluv":[325.085448007895536,210.542141790665795,51.6964496814969152],"hsluv":[325.085448007895536,75.4531429469973602,51.6964496814969152]},"#cc44bb":{"lch":[52.465940673938249,89.9444778306290829,315.812454406659811],"luv":[52.465940673938249,64.4957791941851326,-62.692133145710109],"rgb":[0.8,0.266666666666666663,0.733333333333333282],"xyz":[0.359370014188326148,0.20561262168017333,0.490913371664566611],"hpluv":[315.812454406659811,217.538619181736436,52.465940673938249],"hsluv":[315.812454406659811,77.4040753157756143,52.465940673938249]},"#cc44cc":{"lch":[53.3119860408958175,96.2498903650287758,307.715012949243885],"luv":[53.3119860408958175,58.8793631430003828,-76.1397530279337502],"rgb":[0.8,0.266666666666666663,0.8],"xyz":[0.378662389632047902,0.213329571857662131,0.592519882334836767],"hpluv":[307.715012949243885,229.094523932317799,53.3119860408958175],"hsluv":[307.715012949243885,79.2597279113993,53.3119860408958175]},"#cc44dd":{"lch":[54.2319126329379486,104.138844540210442,300.941773361922515],"luv":[54.2319126329379486,53.5447276840333259,-89.31887303035586],"rgb":[0.8,0.266666666666666663,0.866666666666666696],"xyz":[0.40018071518268139,0.221936902077915665,0.705849730234842765],"hpluv":[300.941773361922515,243.66724889744043,54.2319126329379486],"hsluv":[300.941773361922515,81.0000946003390538,54.2319126329379486]},"#cc44ee":{"lch":[55.2225876682288401,113.096616320403683,295.407423092027],"luv":[55.2225876682288401,48.5243479249087528,-102.157879194837463],"rgb":[0.8,0.266666666666666663,0.933333333333333348],"xyz":[0.423992895448856155,0.23146177418438571,0.831260546303366],"hpluv":[295.407423092027,259.879597148300718,55.2225876682288401],"hsluv":[295.407423092027,86.8652077390175634,55.2225876682288401]},"#cc44ff":{"lch":[56.2805330741479537,122.715491745326418,290.92682559337851],"luv":[56.2805330741479537,43.8309487146615382,-114.62085259266739],"rgb":[0.8,0.266666666666666663,1],"xyz":[0.450163943858687521,0.241930193548318406,0.969094734595147833],"hpluv":[290.92682559337851,276.681751484143376,56.2805330741479537],"hsluv":[290.92682559337851,99.9999999999989768,56.2805330741479537]},"#cc5500":{"lch":[51.07852272981998,108.355754132896138,24.3337665629108457],"luv":[51.07852272981998,98.7294936728878838,44.6481414260866],"rgb":[0.8,0.333333333333333315,0],"xyz":[0.281496412171203525,0.193364391616277664,0.0225003345836030169],"hpluv":[24.3337665629108457,269.186315008697875,51.07852272981998],"hsluv":[24.3337665629108457,100.000000000002217,51.07852272981998]},"#cc5511":{"lch":[51.1252833166066,107.003417336388864,23.6474066829241423],"luv":[51.1252833166066,98.0184651549503201,42.91983003616388],"rgb":[0.8,0.333333333333333315,0.0666666666666666657],"xyz":[0.282508077670840629,0.193769057816132517,0.0278284395483586466],"hpluv":[23.6474066829241423,265.583595811902,51.1252833166066],"hsluv":[23.6474066829241423,96.7082849697218307,51.1252833166066]},"#cc5522":{"lch":[51.2117930688627467,104.583581473170284,22.351909846807331],"luv":[51.2117930688627467,96.7257518395109486,39.7725337995530808],"rgb":[0.8,0.333333333333333315,0.133333333333333331],"xyz":[0.284383435809317686,0.194519201071523345,0.0377053257443378462],"hpluv":[22.351909846807331,259.139045481141636,51.2117930688627467],"hsluv":[22.351909846807331,90.7274756498525079,51.2117930688627467]},"#cc5533":{"lch":[51.3537468781662625,100.840694749975015,20.1540565840537802],"luv":[51.3537468781662625,94.6661789932146718,34.7442120716858369],"rgb":[0.8,0.333333333333333315,0.2],"xyz":[0.287471186541775392,0.195754301364506444,0.0539674796019489894],"hpluv":[20.1540565840537802,249.174169543579183,51.3537468781662625],"hsluv":[20.1540565840537802,81.2092815218714321,51.3537468781662625]},"#cc5544":{"lch":[51.5576456995760424,95.9504499860225764,16.842752904303623],"luv":[51.5576456995760424,91.8345174188591074,27.8012636936791502],"rgb":[0.8,0.333333333333333315,0.266666666666666663],"xyz":[0.291929181785994307,0.197537499462194038,0.0774462545548356279],"hpluv":[16.842752904303623,236.152889903020736,51.5576456995760424],"hsluv":[16.842752904303623,68.1451659970290109,51.5576456995760424]},"#cc5555":{"lch":[51.8284441386287114,90.3192908744292851,12.1770506300618919],"luv":[51.8284441386287114,88.2871484081680364,19.0513445723360242],"rgb":[0.8,0.333333333333333315,0.333333333333333315],"xyz":[0.297891595825356292,0.199922465077938871,0.108848301828809529],"hpluv":[12.1770506300618919,221.132040760117775,51.8284441386287114],"hsluv":[12.1770506300618919,51.8180912815801,51.8284441386287114]},"#cc5566":{"lch":[52.1698415772242612,84.57836719340618,5.91246023067467696],"luv":[52.1698415772242612,84.1284474176031836,8.71232071300305577],"rgb":[0.8,0.333333333333333315,0.4],"xyz":[0.305476591598864478,0.202956463387342162,0.148795946235953491],"hpluv":[5.91246023067467696,205.721226704565879,52.1698415772242612],"hsluv":[5.91246023067467696,54.0130370973951415,52.1698415772242612]},"#cc5577":{"lch":[52.5844387621358607,79.5477054283049654,357.892334615122479],"luv":[52.5844387621358607,79.493890006545314,-2.92555815796844554],"rgb":[0.8,0.333333333333333315,0.466666666666666674],"xyz":[0.314790604619066383,0.206682068595422985,0.1978497481423514],"hpluv":[357.892334615122479,191.959557587962337,52.5844387621358607],"hsluv":[357.892334615122479,56.4492590331968884,52.5844387621358607]},"#cc5588":{"lch":[53.0738428910491962,76.1348505840982,348.222799824086337],"luv":[53.0738428910491962,74.5321119975331072,-15.5396188708133902],"rgb":[0.8,0.333333333333333315,0.533333333333333326],"xyz":[0.325931021721010183,0.211138235436200583,0.256522611545923596],"hpluv":[348.222799824086337,182.029716109510787,53.0738428910491962],"hsluv":[348.222799824086337,59.0443947768825339,53.0738428910491962]},"#cc5599":{"lch":[53.6387547547300443,75.1322702050955655,337.451566852479516],"luv":[53.6387547547300443,69.3888374020903314,-28.8105409556599774],"rgb":[0.8,0.333333333333333315,0.6],"xyz":[0.338987985830082938,0.216361021079829741,0.325289289187041475],"hpluv":[337.451566852479516,177.740808472615271,53.6387547547300443],"hsluv":[337.451566852479516,61.7180151219793274,53.6387547547300443]},"#cc55aa":{"lch":[54.2790527162633651,76.9604755372169507,326.525055670409472],"luv":[54.2790527162633651,64.1948187783047359,-42.449264268479169],"rgb":[0.8,0.333333333333333315,0.66666666666666663],"xyz":[0.354045678795335439,0.222384098265930835,0.404593138804040076],"hpluv":[326.525055670409472,179.918080614224607,54.2790527162633651],"hsluv":[326.525055670409472,64.3982563598392517,54.2790527162633651]},"#cc55bb":{"lch":[54.9938795911038767,81.534325182187132,316.414019967357433],"luv":[54.9938795911038767,59.0586208757266817,-56.2132144888709888],"rgb":[0.8,0.333333333333333315,0.733333333333333282],"xyz":[0.371183270902672113,0.229239135108865594,0.494851123902681822],"hpluv":[316.414019967357433,188.133202867989326,54.9938795911038767],"hsluv":[316.414019967357433,67.0257727218245378,54.9938795911038767]},"#cc55cc":{"lch":[55.7817339145568667,88.3780574248019,307.715012949244169],"luv":[55.7817339145568667,54.0638926159085145,-69.9126351198200382],"rgb":[0.8,0.333333333333333315,0.8],"xyz":[0.390475646346393868,0.236956085286354395,0.596457634572952],"hpluv":[307.715012949244169,201.044301715196383,55.7817339145568667],"hsluv":[307.715012949244169,69.5552053299685156,55.7817339145568667]},"#cc55dd":{"lch":[56.6405645837994882,96.8744721490496232,300.570417552325068],"luv":[56.6405645837994882,49.2700598324241312,-83.4093793183137],"rgb":[0.8,0.333333333333333315,0.866666666666666696],"xyz":[0.411993971897027356,0.245563415506607929,0.709787482472958],"hpluv":[300.570417552325068,217.030665421015726,56.6405645837994882],"hsluv":[300.570417552325068,72.1703256475756234,56.6405645837994882]},"#cc55ee":{"lch":[57.5678665910353118,106.457154357221242,294.836459829444038],"luv":[57.5678665910353118,44.7151619549172707,-96.6109724885468],"rgb":[0.8,0.333333333333333315,0.933333333333333348],"xyz":[0.435806152163202121,0.255088287613077946,0.835198298541481199],"hpluv":[294.836459829444038,234.657286550118499,57.5678665910353118],"hsluv":[294.836459829444038,85.8995510844284809,57.5678665910353118]},"#cc55ff":{"lch":[58.560775097021633,116.686665261471418,290.266986003053091],"luv":[58.560775097021633,40.4196983751927874,-109.462440284789551],"rgb":[0.8,0.333333333333333315,1],"xyz":[0.461977200573033486,0.26555670697701067,0.973032486833263],"hpluv":[290.266986003053091,252.844632524376181,58.560775097021633],"hsluv":[290.266986003053091,99.9999999999988,58.560775097021633]},"#cc6600":{"lch":[54.388060759003551,98.5584029412379579,30.482787603130209],"luv":[54.388060759003551,84.9358174587045482,49.9966569177284157],"rgb":[0.8,0.4,0],"xyz":[0.29652446987705,0.223420507027971,0.0275096871522183678],"hpluv":[30.482787603130209,229.947880001204965,54.388060759003551],"hsluv":[30.482787603130209,100.000000000002359,54.388060759003551]},"#cc6611":{"lch":[54.430531479182676,97.2669366851907711,29.8266301777559697],"luv":[54.430531479182676,84.3824110244092367,48.3783596438383583],"rgb":[0.8,0.4,0.0666666666666666657],"xyz":[0.297536135376687105,0.223825173227825858,0.032837792116974],"hpluv":[29.8266301777559697,226.757672191171366,54.430531479182676],"hsluv":[29.8266301777559697,97.1300271864182463,54.430531479182676]},"#cc6622":{"lch":[54.5091256699603548,94.945229062596681,28.5830621108902889],"luv":[54.5091256699603548,83.3737269438019695,45.4248629854764],"rgb":[0.8,0.4,0.133333333333333331],"xyz":[0.299411493515164162,0.224575316483216686,0.0427146783129532],"hpluv":[28.5830621108902889,221.025945543219876,54.5091256699603548],"hsluv":[28.5830621108902889,91.902111940908739,54.5091256699603548]},"#cc6633":{"lch":[54.6381494647888388,91.324965774397,26.4577509745500876],"luv":[54.6381494647888388,81.7598754062496624,40.688722605278663],"rgb":[0.8,0.4,0.2],"xyz":[0.302499244247621868,0.225810416776199785,0.0589768321705643403],"hpluv":[26.4577509745500876,212.096187894217309,54.6381494647888388],"hsluv":[26.4577509745500876,83.5463344335908289,54.6381494647888388]},"#cc6644":{"lch":[54.8236025158742137,86.5353782352002,23.2174871910251],"luv":[54.8236025158742137,79.5273159773273903,34.1141861950638798],"rgb":[0.8,0.4,0.266666666666666663],"xyz":[0.306957239491840783,0.227593614873887379,0.0824556071234509858],"hpluv":[23.2174871910251,200.292852977212362,54.8236025158742137],"hsluv":[23.2174871910251,72.0055590941951635,54.8236025158742137]},"#cc6655":{"lch":[55.0701314820163077,80.921365039871,18.5706632184066578],"luv":[55.0701314820163077,76.7079190692017505,25.7713498286149552],"rgb":[0.8,0.4,0.333333333333333315],"xyz":[0.312919653531202768,0.229978580489632212,0.113857654397424887],"hpluv":[18.5706632184066578,186.460314881725708,55.0701314820163077],"hsluv":[18.5706632184066578,57.463707489477386,55.0701314820163077]},"#cc6666":{"lch":[55.3812986167643686,75.0592421503045841,12.1770506300619576],"luv":[55.3812986167643686,73.3704437553848834,15.8324923911544637],"rgb":[0.8,0.4,0.4],"xyz":[0.320504649304710953,0.233012578799035502,0.153805298804568835],"hpluv":[12.1770506300619576,171.980959079196282,55.3812986167643686],"hsluv":[12.1770506300619576,45.9214429163451925,55.3812986167643686]},"#cc6677":{"lch":[55.7597240294908403,69.7578535305897702,3.7339069954147126],"luv":[55.7597240294908403,69.6097753289024,4.54283037928401079],"rgb":[0.8,0.4,0.466666666666666674],"xyz":[0.329818662324912859,0.236738184007116326,0.202859100710966744],"hpluv":[3.7339069954147126,158.749300244695775,55.7597240294908403],"hsluv":[3.7339069954147126,47.4001946683844935,55.7597240294908403]},"#cc6688":{"lch":[56.2071770412836855,65.9988703650454198,353.20230012342131],"luv":[56.2071770412836855,65.534915505775615,-7.81189727997758432],"rgb":[0.8,0.4,0.533333333333333326],"xyz":[0.340959079426856659,0.241194350847893924,0.26153196411453894],"hpluv":[353.20230012342131,148.999240608904586,56.2071770412836855],"hsluv":[353.20230012342131,48.9818497710332537,56.2071770412836855]},"#cc6699":{"lch":[56.7246474757154573,64.7364860461136544,341.13073016495332],"luv":[56.7246474757154573,61.2574795353059756,-20.9364234428957907],"rgb":[0.8,0.4,0.6],"xyz":[0.354016043535929414,0.246417136491523081,0.330298641755656819],"hpluv":[341.13073016495332,144.81603174775961,56.7246474757154573],"hsluv":[341.13073016495332,50.615240188358726,56.7246474757154573]},"#cc66aa":{"lch":[57.3124110050500661,66.5536753014576874,328.724652687595039],"luv":[57.3124110050500661,56.882247269492467,-34.5514347271451925],"rgb":[0.8,0.4,0.66666666666666663],"xyz":[0.369073736501181915,0.252440213677624203,0.40960249137265542],"hpluv":[328.724652687595039,147.354258527000582,57.3124110050500661],"hsluv":[328.724652687595039,52.5782983823555057,57.3124110050500661]},"#cc66bb":{"lch":[57.9700950113726634,71.4140361316817831,317.320615294889421],"luv":[57.9700950113726634,52.5006394421278628,-48.4112323204526405],"rgb":[0.8,0.4,0.733333333333333282],"xyz":[0.386211328608518589,0.259295250520558962,0.499860476471297166],"hpluv":[317.320615294889421,156.321564636453559,57.9700950113726634],"hsluv":[317.320615294889421,55.7867325729046044,57.9700950113726634]},"#cc66cc":{"lch":[58.6967474031167882,78.7715159072838844,307.71501294924451],"luv":[58.6967474031167882,48.1872412824568599,-62.3132529717215391],"rgb":[0.8,0.4,0.8],"xyz":[0.405503704052240344,0.267012200698047764,0.601466987141567322],"hpluv":[307.71501294924451,170.292097080892688,58.6967474031167882],"hsluv":[307.71501294924451,58.9158791245518429,58.6967474031167882]},"#cc66dd":{"lch":[59.4909085631812928,87.9045601549668589,300.035118747227784],"luv":[59.4909085631812928,43.9989332886277964,-76.1006278916348151],"rgb":[0.8,0.4,0.866666666666666696],"xyz":[0.427022029602873832,0.27561953091830127,0.71479683504157332],"hpluv":[300.035118747227784,187.499506963343748,59.4909085631812928],"hsluv":[300.035118747227784,69.8010448945604907,59.4909085631812928]},"#cc66ee":{"lch":[60.3506853352839272,98.1678970647401314,294.030303780460372],"luv":[60.3506853352839272,39.9759075841908498,-89.6597057040320919],"rgb":[0.8,0.4,0.933333333333333348],"xyz":[0.450834209869048597,0.285144403024771287,0.840207651110096543],"hpluv":[294.030303780460372,206.408039079415715,60.3506853352839272],"hsluv":[294.030303780460372,84.6650997716967169,60.3506853352839272]},"#cc66ff":{"lch":[61.2738253236974799,109.076950193692937,289.351384827957531],"luv":[61.2738253236974799,36.143813792667018,-102.914555763887847],"rgb":[0.8,0.4,1],"xyz":[0.477005258278879962,0.295612822388704,0.978041839401878388],"hpluv":[289.351384827957531,225.890163025573315,61.2738253236974799],"hsluv":[289.351384827957531,99.9999999999987,61.2738253236974799]},"#cc7700":{"lch":[58.0681687130694684,90.1274111260576,38.2527636780657616],"luv":[58.0681687130694684,70.775890411238,55.8007488550273862],"rgb":[0.8,0.466666666666666674,0],"xyz":[0.314978207930467602,0.260327983134806762,0.0336609331700240683],"hpluv":[38.2527636780657616,196.95095583694345,58.0681687130694684],"hsluv":[38.2527636780657616,100.00000000000226,58.0681687130694684]},"#cc7711":{"lch":[58.1065272060428,88.8714225311590837,37.658223554494576],"luv":[58.1065272060428,70.356768805075,54.2959927252558288],"rgb":[0.8,0.466666666666666674,0.0666666666666666657],"xyz":[0.315989873430104706,0.260732649334661615,0.0389890381347797],"hpluv":[37.658223554494576,194.078102813960953,58.1065272060428],"hsluv":[37.658223554494576,97.5201736027742925,58.1065272060428]},"#cc7722":{"lch":[58.1775287784180364,86.6008188207648573,36.5262538454337786],"luv":[58.1775287784180364,69.5910513475594286,51.5440335321973748],"rgb":[0.8,0.466666666666666674,0.133333333333333331],"xyz":[0.317865231568581763,0.261482792590052415,0.0488659243307589],"hpluv":[36.5262538454337786,188.888733728089306,58.1775287784180364],"hsluv":[36.5262538454337786,92.9922153048462832,58.1775287784180364]},"#cc7733":{"lch":[58.2941365993826111,83.0249283524691606,34.5753600294232513],"luv":[58.2941365993826111,68.3611064237300781,47.1157920070976459],"rgb":[0.8,0.466666666666666674,0.2],"xyz":[0.320952982301039469,0.262717892883035542,0.0651280781883700477],"hpluv":[34.5753600294232513,180.726967614303447,58.2941365993826111],"hsluv":[34.5753600294232513,85.7262720770138458,58.2941365993826111]},"#cc7744":{"lch":[58.4618482438389577,78.2181767747613321,31.5590767862408974],"luv":[58.4618482438389577,66.6497843857434447,40.9376284034837923],"rgb":[0.8,0.466666666666666674,0.266666666666666663],"xyz":[0.325410977545258384,0.264501090980723108,0.0886068531412566862],"hpluv":[31.5590767862408974,169.775287201810244,58.4618482438389577],"hsluv":[31.5590767862408974,75.6318325574838,58.4618482438389577]},"#cc7755":{"lch":[58.6849825995062133,72.4480337937475,27.1381330463907204],"luv":[58.6849825995062133,64.4721877935720187,33.0462494345479811],"rgb":[0.8,0.466666666666666674,0.333333333333333315],"xyz":[0.331373391584620369,0.266886056596467969,0.120008900415230588],"hpluv":[27.1381330463907204,156.653084219512607,58.6849825995062133],"hsluv":[27.1381330463907204,62.8141161752895059,58.6849825995062133]},"#cc7766":{"lch":[58.9669266929607829,66.2083874258113667,20.8554290651987451],"luv":[58.9669266929607829,61.8705265372573407,23.5709251309504673],"rgb":[0.8,0.466666666666666674,0.4],"xyz":[0.338958387358128554,0.269920054905871287,0.159956544822374536],"hpluv":[20.8554290651987451,142.476698671576116,58.9669266929607829],"hsluv":[20.8554290651987451,47.542957476979069,58.9669266929607829]},"#cc7777":{"lch":[59.3102652975897229,60.2635194006596251,12.177050630062082],"luv":[59.3102652975897229,58.907617956407762,12.7115820123061383],"rgb":[0.8,0.466666666666666674,0.466666666666666674],"xyz":[0.34827240037833046,0.273645660113952083,0.209010346728772445],"hpluv":[12.177050630062082,128.932959302114057,59.3102652975897229],"hsluv":[12.177050630062082,43.5373021749198443,59.3102652975897229]},"#cc7788":{"lch":[59.7168613687891963,55.6638868177661834,0.734433949810619269],"luv":[59.7168613687891963,55.6593138534775917,0.713496335773026069],"rgb":[0.8,0.466666666666666674,0.533333333333333326],"xyz":[0.35941281748027426,0.278101826954729681,0.26768321013234464],"hpluv":[0.734433949810619269,118.281243349182901,59.7168613687891963],"hsluv":[0.734433949810619269,45.0130000154657779,59.7168613687891963]},"#cc7799":{"lch":[60.187915321807921,53.6038783156568073,346.890122071781263],"luv":[60.187915321807921,52.2067938730354371,-12.1583898596044406],"rgb":[0.8,0.466666666666666674,0.6],"xyz":[0.37246978158934696,0.283324612598358838,0.336449887773462519],"hpluv":[346.890122071781263,113.012436406344946,60.187915321807921],"hsluv":[346.890122071781263,46.5549497102544,60.187915321807921]},"#cc77aa":{"lch":[60.7240163061688349,54.9761438743297148,332.197464335395125],"luv":[60.7240163061688349,48.6297161920954863,-25.6422912074417866],"rgb":[0.8,0.466666666666666674,0.66666666666666663],"xyz":[0.387527474554599516,0.28934768978445996,0.41575373739046112],"hpluv":[332.197464335395125,114.882297594683308,60.7240163061688349],"hsluv":[332.197464335395125,48.1189262345266471,60.7240163061688349]},"#cc77bb":{"lch":[61.3251919150652043,59.875823087291181,318.726648244723037],"luv":[61.3251919150652043,45.0009333565193046,-39.4972174643062743],"rgb":[0.8,0.466666666666666674,0.733333333333333282],"xyz":[0.40466506666193619,0.296202726627394719,0.506011722489102866],"hpluv":[318.726648244723037,123.894465684476771,61.3251919150652043],"hsluv":[318.726648244723037,49.6642191709372156,61.3251919150652043]},"#cc77cc":{"lch":[61.9909592768387228,67.6487625915650881,307.715012949244965],"luv":[61.9909592768387228,41.3830711255614219,-53.514451360232222],"rgb":[0.8,0.466666666666666674,0.8],"xyz":[0.423957442105657889,0.303919676804883521,0.607618233159373],"hpluv":[307.715012949244965,138.474825543749517,61.9909592768387228],"hsluv":[307.715012949244965,51.1553628289834066,61.9909592768387228]},"#cc77dd":{"lch":[62.7203784873954362,77.3966796673740305,299.257833182927357],"luv":[62.7203784873954362,37.8268934727942252,-67.5231231041040161],"rgb":[0.8,0.466666666666666674,0.866666666666666696],"xyz":[0.445475767656291488,0.312527007025137,0.720948081059379],"hpluv":[299.257833182927357,156.586020071329443,62.7203784873954362],"hsluv":[299.257833182927357,66.8390608629672158,62.7203784873954362]},"#cc77ee":{"lch":[63.5121081687847351,88.3507940057556453,292.894169444170245],"luv":[63.5121081687847351,34.371127600373157,-81.3909601179783],"rgb":[0.8,0.466666666666666674,0.933333333333333348],"xyz":[0.469287947922466198,0.322051879131607044,0.846358897127902243],"hpluv":[292.894169444170245,176.519730115921618,63.5121081687847351],"hsluv":[292.894169444170245,83.1130682001540322,63.5121081687847351]},"#cc77ff":{"lch":[64.3644622692190467,99.9639900757921112,288.092077643344339],"luv":[64.3644622692190467,31.0433170684360782,-95.0216384686225553],"rgb":[0.8,0.466666666666666674,1],"xyz":[0.495458996332297619,0.332520298495539768,0.984193085419684088],"hpluv":[288.092077643344339,197.077372703744913,64.3644622692190467],"hsluv":[288.092077643344339,99.9999999999984794,64.3644622692190467]},"#cc8800":{"lch":[62.03823759594124,83.9779445354575813,47.4964941193052752],"luv":[62.03823759594124,56.738465406715342,61.9115636346826221],"rgb":[0.8,0.533333333333333326,0],"xyz":[0.337050577655438111,0.304472722584748334,0.0410183897450140181],"hpluv":[47.4964941193052752,171.769129739761638,62.03823759594124],"hsluv":[47.4964941193052752,100.000000000002245,62.03823759594124]},"#cc8811":{"lch":[62.0727951053461879,82.7448035916202542,47.0033697453910904],"luv":[62.0727951053461879,56.4282611354359744,60.519037225048919],"rgb":[0.8,0.533333333333333326,0.0666666666666666657],"xyz":[0.338062243155075215,0.304877388784603187,0.0463464947097696478],"hpluv":[47.0033697453910904,169.152629782786704,62.0727951053461879],"hsluv":[47.0033697453910904,97.8669953021426,62.0727951053461879]},"#cc8822":{"lch":[62.1367747194074127,80.5023095814055836,46.0605806208152728],"luv":[62.1367747194074127,55.8603434591127268,57.9676105818622389],"rgb":[0.8,0.533333333333333326,0.133333333333333331],"xyz":[0.339937601293552272,0.305627532039994,0.0562233809057488473],"hpluv":[46.0605806208152728,164.398919884807611,62.1367747194074127],"hsluv":[46.0605806208152728,93.9640765124603,62.1367747194074127]},"#cc8833":{"lch":[62.2418885518498541,76.9329948636363241,44.4230175211057343],"luv":[62.2418885518498541,54.9448944756850963,53.8492736231801246],"rgb":[0.8,0.533333333333333326,0.2],"xyz":[0.34302535202601,0.306862632332977114,0.0724855347633599906],"hpluv":[44.4230175211057343,156.844467463147254,62.2418885518498541],"hsluv":[44.4230175211057343,87.678806867525978,62.2418885518498541]},"#cc8844":{"lch":[62.3931521103864668,72.0506908450526424,41.8566920827827929],"luv":[62.3931521103864668,53.6645163812677168,48.0772475586321661],"rgb":[0.8,0.533333333333333326,0.266666666666666663],"xyz":[0.347483347270228893,0.30864583043066468,0.0959643097162466291],"hpluv":[41.8566920827827929,146.534723453778,62.3931521103864668],"hsluv":[41.8566920827827929,78.900857077449,62.3931521103864668]},"#cc8855":{"lch":[62.5945538889838673,66.028576146577123,38.0101307109045408],"luv":[62.5945538889838673,52.0240395147187513,40.6604498316892062],"rgb":[0.8,0.533333333333333326,0.333333333333333315],"xyz":[0.353445761309590878,0.311030796046409541,0.127366356990220531],"hpluv":[38.0101307109045408,133.855034432196135,62.5945538889838673],"hsluv":[38.0101307109045408,67.6770944211119314,62.5945538889838673]},"#cc8866":{"lch":[62.8492816845599265,59.2369010326618337,32.3420191431213624],"luv":[62.8492816845599265,50.047464385327217,31.6900891849924626],"rgb":[0.8,0.533333333333333326,0.4],"xyz":[0.361030757083099063,0.31406479435581286,0.167314001397364492],"hpluv":[32.3420191431213624,119.60004374597824,62.8492816845599265],"hsluv":[32.3420191431213624,54.1901780257147436,62.8492816845599265]},"#cc8877":{"lch":[63.1598410661450771,52.3169991415742,24.053169540805424],"luv":[63.1598410661450771,47.7741895619322392,21.3235834436907119],"rgb":[0.8,0.533333333333333326,0.466666666666666674],"xyz":[0.370344770103300969,0.317790399563893655,0.216367803303762402],"hpluv":[24.053169540805424,105.109295035123296,63.1598410661450771],"hsluv":[24.053169540805424,38.7316682482548558,63.1598410661450771]},"#cc8888":{"lch":[63.5281271999152182,46.2961098245983322,12.1770506300622312],"luv":[63.5281271999152182,45.2544686659219906,9.76539045078869528],"rgb":[0.8,0.533333333333333326,0.533333333333333326],"xyz":[0.381485187205244769,0.322246566404671253,0.275040666707334569],"hpluv":[12.1770506300622312,92.4736018048895403,63.5281271999152182],"hsluv":[12.1770506300622312,40.0703189706204199,63.5281271999152182]},"#cc8899":{"lch":[63.9554753143552119,42.6335463086933615,356.296984030050055],"luv":[63.9554753143552119,42.5445368433351,-2.7534806412255004],"rgb":[0.8,0.533333333333333326,0.6],"xyz":[0.394542151314317469,0.327469352048300411,0.343807344348452504],"hpluv":[356.296984030050055,84.588837176407921,63.9554753143552119],"hsluv":[356.296984030050055,41.5088242950414781,63.9554753143552119]},"#cc88aa":{"lch":[64.442701858069384,42.8028595258545153,338.056731442080661],"luv":[64.442701858069384,39.701977128446444,-15.9949303118941444],"rgb":[0.8,0.533333333333333326,0.66666666666666663],"xyz":[0.40959984427957,0.333492429234401533,0.423111193965451104],"hpluv":[338.056731442080661,84.28268641071584,64.442701858069384],"hsluv":[338.056731442080661,42.9831867606486924,64.442701858069384]},"#cc88bb":{"lch":[64.9901424985427099,47.2946673003310707,321.051918945199532],"luv":[64.9901424985427099,36.7818149859187784,-29.7301806484697622],"rgb":[0.8,0.533333333333333326,0.733333333333333282],"xyz":[0.426737436386906699,0.340347466077336291,0.513369179064092851],"hpluv":[321.051918945199532,92.3430068912496296,64.9901424985427099],"hsluv":[321.051918945199532,44.4548878388224864,64.9901424985427099]},"#cc88cc":{"lch":[65.5976900795525637,55.3077284551996158,307.715012949245761],"luv":[65.5976900795525637,33.8336367550969399,-43.751912538747959],"rgb":[0.8,0.533333333333333326,0.8],"xyz":[0.446029811830628398,0.348064416254825093,0.614975689734363],"hpluv":[307.715012949245761,106.988377595373095,65.5976900795525637],"hsluv":[307.715012949245761,45.8886814173124122,65.5976900795525637]},"#cc88dd":{"lch":[66.2648339334855905,65.6132669537387727,298.095232643272539],"luv":[66.2648339334855905,30.8998122908772608,-57.8817967994354774],"rgb":[0.8,0.533333333333333326,0.866666666666666696],"xyz":[0.467548137381262,0.356671746475078599,0.728305537634369],"hpluv":[298.095232643272539,125.645770778198369,66.2648339334855905],"hsluv":[298.095232643272539,63.1276078601331037,66.2648339334855905]},"#cc88ee":{"lch":[66.9907009061042,77.2337728548956193,291.267726386147558],"luv":[66.9907009061042,28.0147259973813227,-71.9738202174461463],"rgb":[0.8,0.533333333333333326,0.933333333333333348],"xyz":[0.491360317647436706,0.366196618581548616,0.853716353702892228],"hpluv":[291.267726386147558,146.295866424915545,66.9907009061042],"hsluv":[291.267726386147558,81.1585487563552874,66.9907009061042]},"#cc88ff":{"lch":[67.7740978167257,89.535143384050329,286.350196506734335],"luv":[67.7740978167257,25.2048126805589376,-85.914255618845857],"rgb":[0.8,0.533333333333333326,1],"xyz":[0.517531366057268127,0.37666503794548134,0.991550541994674073],"hpluv":[286.350196506734335,167.63670457649863,67.7740978167257],"hsluv":[286.350196506734335,99.9999999999982379,67.7740978167257]},"#cc9900":{"lch":[66.2294666531998217,80.7116888085701163,57.6888018595631422],"luv":[66.2294666531998217,43.1418134232290527,68.2140795209226383],"rgb":[0.8,0.6,0],"xyz":[0.362920178107905556,0.356211923489684,0.0496415898958362731],"hpluv":[57.6888018595631422,154.64094800189136,66.2294666531998217],"hsluv":[57.6888018595631422,100.000000000002331,66.2294666531998217]},"#cc9911":{"lch":[66.2605931548954459,79.5070460268624,57.3307205104302042],"luv":[66.2605931548954459,42.9170325725223805,66.9290570909725915],"rgb":[0.8,0.6,0.0666666666666666657],"xyz":[0.36393184360754266,0.356616589689538854,0.0549696948605919],"hpluv":[57.3307205104302042,152.261332222626407,66.2605931548954459],"hsluv":[57.3307205104302042,98.1673920986410877,66.2605931548954459]},"#cc9922":{"lch":[66.318231165714252,77.3048675578901339,56.6444543825244],"luv":[66.318231165714252,42.5047546114663533,64.5708013235236535],"rgb":[0.8,0.6,0.133333333333333331],"xyz":[0.365807201746019717,0.357366732944929655,0.0648465810565711],"hpluv":[56.6444543825244,147.915345655385721,66.318231165714252],"hsluv":[56.6444543825244,94.8079930897652901,66.318231165714252]},"#cc9933":{"lch":[66.4129558628457772,73.7662990604099207,55.446788144651876],"luv":[66.4129558628457772,41.8381333944198062,60.7539091017242114],"rgb":[0.8,0.6,0.2],"xyz":[0.368894952478477423,0.358601833237912782,0.0811087349141822456],"hpluv":[55.446788144651876,140.943324602767206,66.4129558628457772],"hsluv":[55.446788144651876,89.3812598244831804,66.4129558628457772]},"#cc9944":{"lch":[66.5493334014023361,68.8491039809152596,53.5533094328142383],"luv":[66.5493334014023361,40.9015039610359423,55.3829043360877122],"rgb":[0.8,0.6,0.266666666666666663],"xyz":[0.373352947722696338,0.360385031335600348,0.104587509867068884],"hpluv":[53.5533094328142383,131.278591794008349,66.5493334014023361],"hsluv":[53.5533094328142383,81.7675495661837459,66.5493334014023361]},"#cc9955":{"lch":[66.7310322275847341,62.6300376921671571,50.6698876242401539],"luv":[66.7310322275847341,39.6941340540006422,48.4447865412296466],"rgb":[0.8,0.6,0.333333333333333315],"xyz":[0.379315361762058323,0.362769996951345208,0.135989557141042799],"hpluv":[50.6698876242401539,119.095172229338388,66.7310322275847341],"hsluv":[50.6698876242401539,71.9728873324543912,66.7310322275847341]},"#cc9966":{"lch":[66.9610303820851,55.3290996264574488,46.2964172073191236],"luv":[66.9610303820851,38.2284030091626121,39.9987308404091877],"rgb":[0.8,0.6,0.4],"xyz":[0.386900357535566508,0.365803995260748527,0.175937201548186761],"hpluv":[46.2964172073191236,104.850571413887963,66.9610303820851],"hsluv":[46.2964172073191236,60.1139469393688586,66.9610303820851]},"#cc9977":{"lch":[67.2417240975963608,47.3725698769106316,39.5497292985384448],"luv":[67.2417240975963608,36.5276723895038842,30.1643751227811094],"rgb":[0.8,0.6,0.466666666666666674],"xyz":[0.396214370555768414,0.369529600468829322,0.22499100345458467],"hpluv":[39.5497292985384448,89.3979234879296598,67.2417240975963608],"hsluv":[39.5497292985384448,46.4000360859745484,67.2417240975963608]},"#cc9988":{"lch":[67.5749927230407508,39.5461637624335367,28.8927829606528306],"luv":[67.5749927230407508,34.6236706423047593,19.1076031876950658],"rgb":[0.8,0.6,0.533333333333333326],"xyz":[0.407354787657712214,0.37398576730960692,0.28366386685815681],"hpluv":[28.8927829606528306,74.2604675709266076,67.5749927230407508],"hsluv":[28.8927829606528306,33.7758353105824227,67.5749927230407508]},"#cc9999":{"lch":[67.962242737641,33.3028609095241,12.177050630062606],"luv":[67.962242737641,32.5535618700051401,7.02468179598591647],"rgb":[0.8,0.6,0.6],"xyz":[0.420411751766784914,0.379208552953236078,0.352430544499274745],"hpluv":[12.177050630062606,62.1803508213615217,67.962242737641],"hsluv":[12.177050630062606,35.0991912912463349,67.962242737641]},"#cc99aa":{"lch":[68.4044417972397838,30.9200145018949506,349.049331623372325],"luv":[68.4044417972397838,30.3569952347367966,-5.87368173427548168],"rgb":[0.8,0.6,0.66666666666666663],"xyz":[0.43546944473203747,0.3852316301393372,0.431734394116273346],"hpluv":[349.049331623372325,57.3580941092039609,68.4044417972397838],"hsluv":[349.049331623372325,36.4663034143199312,68.4044417972397838]},"#cc99bb":{"lch":[68.9021485343020856,34.1112448474386483,325.385883063702067],"luv":[68.9021485343020856,28.0734328763681233,-19.3767745401024669],"rgb":[0.8,0.6,0.733333333333333282],"xyz":[0.452607036839374144,0.392086666982271959,0.521992379214915],"hpluv":[325.385883063702067,62.8208966420876678,68.9021485343020856],"hsluv":[325.385883063702067,37.8410036888738404,68.9021485343020856]},"#cc99cc":{"lch":[69.4555411877739601,42.0770553751994854,307.715012949247],"luv":[69.4555411877739601,25.7399796927440505,-33.285613025220492],"rgb":[0.8,0.6,0.8],"xyz":[0.471899412283095843,0.39980361715976076,0.623598889885185192],"hpluv":[307.715012949247,76.8736967911951581,69.4555411877739601],"hsluv":[307.715012949247,39.1886552488513473,69.4555411877739601]},"#cc99dd":{"lch":[70.0644466506374215,52.8759829560521695,296.254085335195782],"luv":[70.0644466506374215,23.3898305690433475,-47.4213601610093534],"rgb":[0.8,0.6,0.866666666666666696],"xyz":[0.493417737833729442,0.408410947380014266,0.73692873778519119],"hpluv":[296.254085335195782,95.7635162234915498,70.0644466506374215],"hsluv":[296.254085335195782,58.3905887561973813,70.0644466506374215]},"#cc99ee":{"lch":[70.7283706212672,65.1265075826905218,288.858843135035954],"luv":[70.7283706212672,21.0513451251656711,-61.6303728557552191],"rgb":[0.8,0.6,0.933333333333333348],"xyz":[0.517229918099904151,0.417935819486484283,0.862339553853714413],"hpluv":[288.858843135035954,116.843205481858362,70.7283706212672],"hsluv":[288.858843135035954,78.6530020758075494,70.7283706212672]},"#cc99ff":{"lch":[71.4465289765693115,78.0706881495843561,283.894640570210413],"luv":[71.4465289765693115,18.7476796475605703,-75.7862576987549517],"rgb":[0.8,0.6,1],"xyz":[0.543400966509735572,0.428404238850417,1.00017374214549637],"hpluv":[283.894640570210413,138.658404713871533,71.4465289765693115],"hsluv":[283.894640570210413,99.9999999999978,71.4465289765693115]},"#990000":{"lch":[31.2857235930303546,105.214874065330946,12.1770506300617765],"luv":[31.2857235930303546,102.847587834444283,22.1933188419334826],"rgb":[0.6,0,0],"xyz":[0.131365760434599882,0.067735470224092,0.00615777002037173893],"hpluv":[12.1770506300617765,426.746789183125316,31.2857235930303546],"hsluv":[12.1770506300617765,100.000000000002217,31.2857235930303546]},"#990011":{"lch":[31.379701704172021,102.819321078199806,10.8595456684147944],"luv":[31.379701704172021,100.978030711674904,19.3713732237542438],"rgb":[0.6,0,0.0666666666666666657],"xyz":[0.132377425934237014,0.0681401364239468538,0.0114858749851273704],"hpluv":[10.8595456684147944,415.781582167217948,31.379701704172021],"hsluv":[10.8595456684147944,99.9999999999964473,31.379701704172021]},"#990022":{"lch":[31.5529326060038784,98.7447775317108807,8.37468971343924729],"luv":[31.5529326060038784,97.6918390895904309,14.3817824027706251],"rgb":[0.6,0,0.133333333333333331],"xyz":[0.134252784072714015,0.0688902796793376682,0.0213627611811065682],"hpluv":[8.37468971343924729,397.112659756655944,31.5529326060038784],"hsluv":[8.37468971343924729,99.999999999996632,31.5529326060038784]},"#990033":{"lch":[31.8354354483696653,92.9837515463916162,4.18138532137367758],"luv":[31.8354354483696653,92.7362491408617586,6.7798338419980837],"rgb":[0.6,0,0.2],"xyz":[0.137340534805171777,0.070125379972320781,0.0376249150387177114],"hpluv":[4.18138532137367758,370.62575576901952,31.8354354483696653],"hsluv":[4.18138532137367758,99.9999999999969,31.8354354483696653]},"#990044":{"lch":[32.2375108843075537,86.4821897260425771,357.977822115898675],"luv":[32.2375108843075537,86.4283323676992552,-3.05163955108307716],"rgb":[0.6,0,0.266666666666666663],"xyz":[0.141798530049390636,0.071908578070008361,0.0611036899916043499],"hpluv":[357.977822115898675,340.411718586576399,32.2375108843075537],"hsluv":[357.977822115898675,99.9999999999971294,32.2375108843075537]},"#990055":{"lch":[32.7650133258702,80.5606445545256804,349.629319937368109],"luv":[32.7650133258702,79.244583226626645,-14.502188809930411],"rgb":[0.6,0,0.333333333333333315],"xyz":[0.147760944088752622,0.0742935436857532,0.0925057372655782584],"hpluv":[349.629319937368109,311.998071704954214,32.7650133258702],"hsluv":[349.629319937368109,99.9999999999974847,32.7650133258702]},"#990066":{"lch":[33.4199981031921354,76.5714397631706589,339.419101050621862],"luv":[33.4199981031921354,71.6844038684648268,-26.9171252073414813],"rgb":[0.6,0,0.4],"xyz":[0.155345939862260807,0.0773275419951565124,0.13245338167272222],"hpluv":[339.419101050621862,290.7366076723265,33.4199981031921354],"hsluv":[339.419101050621862,99.9999999999978257,33.4199981031921354]},"#990077":{"lch":[34.2012599030024091,75.4745938555541187,328.234093427391315],"luv":[34.2012599030024091,64.1689603650959413,-39.7335984190155429],"rgb":[0.6,0,0.466666666666666674],"xyz":[0.164659952882462712,0.0810531472032373218,0.181507183579120129],"hpluv":[328.234093427391315,280.025774017920355,34.2012599030024091],"hsluv":[328.234093427391315,99.9999999999982094,34.2012599030024091]},"#990088":{"lch":[35.1048906557013396,77.5195253213057214,317.327493504651898],"luv":[35.1048906557013396,56.9954501323273419,-52.5432723595889613],"rgb":[0.6,0,0.533333333333333326],"xyz":[0.175800369984406568,0.0855093140440149196,0.240180046982692297],"hpluv":[317.327493504651898,280.209468657326,35.1048906557013396],"hsluv":[317.327493504651898,99.9999999999985505,35.1048906557013396]},"#990099":{"lch":[36.1248689761228263,82.286593786153162,307.715012949243601],"luv":[36.1248689761228263,50.3375351282041592,-65.0939019735657922],"rgb":[0.6,0,0.6],"xyz":[0.188857334093479268,0.0907320996876440772,0.308946724623810232],"hpluv":[307.715012949243601,289.042783730483336,36.1248689761228263],"hsluv":[307.715012949243601,99.9999999999988205,36.1248689761228263]},"#9900aa":{"lch":[37.2536516336468,89.0432435337247,299.813571633796073],"luv":[37.2536516336468,44.2704748017611038,-77.2581664281054685],"rgb":[0.6,0,0.66666666666666663],"xyz":[0.203915027058731824,0.0967551768737451856,0.388250574240808777],"hpluv":[299.813571633796073,303.299328566743952,37.2536516336468],"hsluv":[299.813571633796073,99.9999999999990905,37.2536516336468]},"#9900bb":{"lch":[38.4827280957899163,97.0854614833978786,293.557760104203282],"luv":[38.4827280957899163,38.802472411223853,-88.9941288300556579],"rgb":[0.6,0,0.733333333333333282],"xyz":[0.221052619166068443,0.103610213716679944,0.478508559339450579],"hpluv":[293.557760104203282,320.130957524774431,38.4827280957899163],"hsluv":[293.557760104203282,99.9999999999993179,38.4827280957899163]},"#9900cc":{"lch":[39.8031058181596933,105.884836559305498,288.673688741635],"luv":[39.8031058181596933,33.9019931565070394,-100.310784431221492],"rgb":[0.6,0,0.8],"xyz":[0.240344994609790197,0.111327163894168746,0.580115070009720735],"hpluv":[288.673688741635,337.564008898092311,39.8031058181596933],"hsluv":[288.673688741635,99.9999999999995879,39.8031058181596933]},"#9900dd":{"lch":[41.2057071388761145,115.092674624289529,284.860629917023232],"luv":[41.2057071388761145,29.5176685469448401,-111.243116621772529],"rgb":[0.6,0,0.866666666666666696],"xyz":[0.26186332016042374,0.11993449411442228,0.693444917909726732],"hpluv":[284.860629917023232,354.429316861661562,41.2057071388761145],"hsluv":[284.860629917023232,99.9999999999996732,41.2057071388761145]},"#9900ee":{"lch":[42.6816722484951754,124.494824438150232,281.862271937449748],"luv":[42.6816722484951754,25.5911328567321625,-121.836181945245357],"rgb":[0.6,0,0.933333333333333348],"xyz":[0.285675500426598505,0.129459366220892297,0.81885573397825],"hpluv":[281.862271937449748,370.125661914021862,42.6816722484951754],"hsluv":[281.862271937449748,99.9999999999998437,42.6816722484951754]},"#9900ff":{"lch":[44.2225734052255817,133.965544030308308,279.479958267333473],"luv":[44.2225734052255817,22.0644732467518,-132.136013288126151],"rgb":[0.6,0,1],"xyz":[0.311846548836429871,0.139927785584825,0.956689922270031801],"hpluv":[279.479958267333473,384.404468177447882,44.2225734052255817],"hsluv":[279.479958267333473,99.9999999999999574,44.2225734052255817]},"#bb0000":{"lch":[38.8409426943877918,130.623313921981463,12.1770506300617818],"luv":[38.8409426943877918,127.684349491075153,27.5528044852332741],"rgb":[0.733333333333333282,0,0],"xyz":[0.20493059501477473,0.105667338054495463,0.00960612164131736251],"hpluv":[12.1770506300617818,426.746789183125145,38.8409426943877918],"hsluv":[12.1770506300617818,100.000000000002217,38.8409426943877918]},"#bb0011":{"lch":[38.9108602521517142,128.680110500437479,11.3344428162225856],"luv":[38.9108602521517142,126.170422440132384,25.2902222149853806],"rgb":[0.733333333333333282,0,0.0666666666666666657],"xyz":[0.205942260514411862,0.106072004254350316,0.014934226606072994],"hpluv":[11.3344428162225856,419.642938315359174,38.9108602521517142],"hsluv":[11.3344428162225856,99.9999999999964189,38.9108602521517142]},"#bb0022":{"lch":[39.0399998564474373,125.270257566289573,9.75441483214293292],"luv":[39.0399998564474373,123.459226352671962,21.2239689767074431],"rgb":[0.733333333333333282,0,0.133333333333333331],"xyz":[0.207817618652888864,0.10682214750974113,0.0248111128020521918],"hpluv":[9.75441483214293292,407.171610230013243,39.0399998564474373],"hsluv":[9.75441483214293292,99.9999999999965326,39.0399998564474373]},"#bb0033":{"lch":[39.2513155564018916,120.169209623826248,7.10634666793171554],"luv":[39.2513155564018916,119.246098647877318,14.866300779810846],"rgb":[0.733333333333333282,0,0.2],"xyz":[0.210905369385346597,0.108057247802724243,0.041073266659663335],"hpluv":[7.10634666793171554,388.488631169232178,39.2513155564018916],"hsluv":[7.10634666793171554,99.9999999999967173,39.2513155564018916]},"#bb0044":{"lch":[39.5535843326651886,113.833969399977519,3.19865110237705785],"luv":[39.5535843326651886,113.656624965458903,6.3517077086437],"rgb":[0.733333333333333282,0,0.266666666666666663],"xyz":[0.215363364629565485,0.109840445900411823,0.0645520416125499735],"hpluv":[3.19865110237705785,365.195452768261646,39.5535843326651886],"hsluv":[3.19865110237705785,99.9999999999968878,39.5535843326651886]},"#bb0055":{"lch":[39.9527871554326666,107.03859947839959,357.869864695501747],"luv":[39.9527871554326666,106.964633924407806,-3.97855095665153691],"rgb":[0.733333333333333282,0,0.333333333333333315],"xyz":[0.221325778668927498,0.112225411516156656,0.095954088886523875],"hpluv":[357.869864695501747,339.963790558847222,39.9527871554326666],"hsluv":[357.869864695501747,99.9999999999971436,39.9527871554326666]},"#bb0066":{"lch":[40.452535568346093,100.749762000256624,351.053086521713055],"luv":[40.452535568346093,99.5239253968718884,-15.6685295004423661],"rgb":[0.733333333333333282,0,0.4],"xyz":[0.228910774442435655,0.115259409825559975,0.135901733293667837],"hpluv":[351.053086521713055,316.036764522848955,40.452535568346093],"hsluv":[351.053086521713055,99.999999999997442,40.452535568346093]},"#bb0077":{"lch":[41.0543478797665813,95.9494038996296581,342.883287985183927],"luv":[41.0543478797665813,91.699536963203,-28.2397420212797314],"rgb":[0.733333333333333282,0,0.466666666666666674],"xyz":[0.238224787462637588,0.118985015033640784,0.184955535200065746],"hpluv":[342.883287985183927,296.56674422547627,41.0543478797665813],"hsluv":[342.883287985183927,99.9999999999977,41.0543478797665813]},"#bb0088":{"lch":[41.7578935904565398,93.4210879643116243,333.788939203308246],"luv":[41.7578935904565398,83.8148890966975699,-41.2621381189091565],"rgb":[0.733333333333333282,0,0.533333333333333326],"xyz":[0.249365204564581389,0.123441181874418382,0.243628398603637913],"hpluv":[333.788939203308246,283.887103643995431,41.7578935904565398],"hsluv":[333.788939203308246,99.9999999999980531,41.7578935904565398]},"#bb0099":{"lch":[42.5612451572515,93.5592166386053918,324.452137443226093],"luv":[42.5612451572515,76.1225984195714318,-54.3937223205229472],"rgb":[0.733333333333333282,0,0.6],"xyz":[0.262422168673654088,0.12866396751804754,0.31239507624475582],"hpluv":[324.452137443226093,278.940502109978524,42.5612451572515],"hsluv":[324.452137443226093,99.9999999999983089,42.5612451572515]},"#bb00aa":{"lch":[43.461144448190268,96.3048592888224562,315.591494301740738],"luv":[43.461144448190268,68.7971872487792,-67.3911934105362747],"rgb":[0.733333333333333282,0,0.66666666666666663],"xyz":[0.277479861638906644,0.134687044704148634,0.391698925861754421],"hpluv":[315.591494301740738,281.181257774391042,43.461144448190268],"hsluv":[315.591494301740738,99.9999999999985647,43.461144448190268]},"#bb00bb":{"lch":[44.4532771259814652,101.257357078489918,307.715012949243601],"luv":[44.4532771259814652,61.9426024872754866,-80.100976021670192],"rgb":[0.733333333333333282,0,0.733333333333333282],"xyz":[0.294617453746243319,0.141542081547083393,0.481956910960396168],"hpluv":[307.715012949243601,289.042783730483507,44.4532771259814652],"hsluv":[307.715012949243601,99.9999999999988205,44.4532771259814652]},"#bb00cc":{"lch":[45.5325428123826796,107.876917991024385,301.028560594476971],"luv":[45.5325428123826796,55.6068066637028551,-92.44085940701639],"rgb":[0.733333333333333282,0,0.8],"xyz":[0.313909829189965,0.149259031724572194,0.583563421630666324],"hpluv":[301.028560594476971,300.639438898355309,45.5325428123826796],"hsluv":[301.028560594476971,99.999999999999,45.5325428123826796]},"#bb00dd":{"lch":[46.6933085129957348,115.650155059812704,295.504945579136574],"luv":[46.6933085129957348,49.7976850024997,-104.379830109799173],"rgb":[0.733333333333333282,0,0.866666666666666696],"xyz":[0.335428154740598616,0.157866361944825728,0.696893269530672321],"hpluv":[295.504945579136574,314.290242754568055,46.6933085129957348],"hsluv":[295.504945579136574,99.9999999999992468,46.6933085129957348]},"#bb00ee":{"lch":[47.929635203682146,124.167261181765113,290.999747870951808],"luv":[47.929635203682146,44.4970566855085821,-115.920320460682433],"rgb":[0.733333333333333282,0,0.933333333333333348],"xyz":[0.359240335006773326,0.167391234051295773,0.822304085599195544],"hpluv":[290.999747870951808,328.732244305823656,47.929635203682146],"hsluv":[290.999747870951808,99.9999999999993889,47.929635203682146]},"#bb00ff":{"lch":[49.2354711183318727,133.13261796854033,287.33664116340708],"luv":[49.2354711183318727,39.6715752597668896,-127.084460433075606],"rgb":[0.733333333333333282,0,1],"xyz":[0.385411383416604747,0.177859653415228469,0.96013827389097739],"hpluv":[287.33664116340708,343.119737385630629,49.2354711183318727],"hsluv":[287.33664116340708,99.9999999999995595,49.2354711183318727]},"#991100":{"lch":[32.2007428060931531,101.551746681272988,13.5001929330929755],"luv":[32.2007428060931531,98.7457840078795,23.707116962774041],"rgb":[0.6,0.0666666666666666657,0],"xyz":[0.133370160695528289,0.071744270745948871,0.00682590344068119],"hpluv":[13.5001929330929755,400.185025755779861,32.2007428060931531],"hsluv":[13.5001929330929755,100.000000000002359,32.2007428060931531]},"#991111":{"lch":[32.2911967351305,99.2607003603350506,12.1770506300617907],"luv":[32.2911967351305,97.0273802968116854,20.9373854328113431],"rgb":[0.6,0.0666666666666666657,0.0666666666666666657],"xyz":[0.134381826195165421,0.0721489369458037239,0.0121540084054368204],"hpluv":[12.1770506300617907,390.060992150638072,32.2911967351305],"hsluv":[12.1770506300617907,91.4033806551417,32.2911967351305]},"#991122":{"lch":[32.4579836187547883,95.3555453821432337,9.67722696349737355],"luv":[32.4579836187547883,93.9986702773161085,16.0290368151797],"rgb":[0.6,0.0666666666666666657,0.133333333333333331],"xyz":[0.136257184333642423,0.0728990802011945382,0.0220308946014160165],"hpluv":[9.67722696349737355,372.789562407290305,32.4579836187547883],"hsluv":[9.67722696349737355,91.6870397393079,32.4579836187547883]},"#991133":{"lch":[32.7301206059751877,89.8170234432985382,5.44607482402752385],"luv":[32.7301206059751877,89.4115862394302,8.52443231910342547],"rgb":[0.6,0.0666666666666666657,0.2],"xyz":[0.139344935066100184,0.0741341804941776511,0.0382930484590271597],"hpluv":[5.44607482402752385,348.217328437078379,32.7301206059751877],"hsluv":[5.44607482402752385,92.1153976677825312,32.7301206059751877]},"#991144":{"lch":[33.1177416447746893,83.547386161100178,359.159050762907725],"luv":[33.1177416447746893,83.5383872622118275,-1.22620878349376072],"rgb":[0.6,0.0666666666666666657,0.266666666666666663],"xyz":[0.143802930310319044,0.0759173785918652311,0.0617718234119138],"hpluv":[359.159050762907725,320.119020896680809,33.1177416447746893],"hsluv":[359.159050762907725,92.6613616101701609,33.1177416447746893]},"#991155":{"lch":[33.6267967661613341,77.8365467514172451,350.652860745276428],"luv":[33.6267967661613341,76.8030661853154,-12.6418762341523276],"rgb":[0.6,0.0666666666666666657,0.333333333333333315],"xyz":[0.149765344349681029,0.078302344207610064,0.0931738706858877136],"hpluv":[350.652860745276428,293.722615948770908,33.6267967661613341],"hsluv":[350.652860745276428,93.2833986807069664,33.6267967661613341]},"#991166":{"lch":[34.2596587707945375,74.039902428482776,340.197584074025258],"luv":[34.2596587707945375,69.661662743272629,-25.0830599301957804],"rgb":[0.6,0.0666666666666666657,0.4],"xyz":[0.157350340123189214,0.0813363425170133825,0.133121515093031662],"hpluv":[340.197584074025258,274.234525914752396,34.2596587707945375],"hsluv":[340.197584074025258,93.9371476037906774,34.2596587707945375]},"#991177":{"lch":[35.0156115165229096,73.1458980715855773,328.71391057162549],"luv":[35.0156115165229096,62.509382661628635,-37.9855167657472848],"rgb":[0.6,0.0666666666666666657,0.466666666666666674],"xyz":[0.16666435314339112,0.0850619477250941919,0.182175316999429571],"hpluv":[328.71391057162549,265.074278305330154,35.0156115165229096],"hsluv":[328.71391057162549,94.5844210689808165,35.0156115165229096]},"#991188":{"lch":[35.8913494409224185,75.4242755669397269,317.528981112118743],"luv":[35.8913494409224185,55.6343762077295239,-50.9277677576239398],"rgb":[0.6,0.0666666666666666657,0.533333333333333326],"xyz":[0.177804770245334975,0.0895181145658717897,0.240848180403001738],"hpluv":[317.528981112118743,266.661726649655066,35.8913494409224185],"hsluv":[317.528981112118743,95.1976582537924116,35.8913494409224185]},"#991199":{"lch":[36.8815072257793,80.448343562419069,307.715012949243601],"luv":[36.8815072257793,49.2130143411107568,-63.6397297401445599],"rgb":[0.6,0.0666666666666666657,0.6],"xyz":[0.190861734354407675,0.0947409002095009473,0.309614858044119645],"hpluv":[307.715012949243601,276.788327826692239,36.8815072257793],"hsluv":[307.715012949243601,95.7603314825458511,36.8815072257793]},"#9911aa":{"lch":[37.9791974354050694,87.4639739592788,299.695850237394552],"luv":[37.9791974354050694,43.3292813921454609,-75.9771025690614152],"rgb":[0.6,0.0666666666666666657,0.66666666666666663],"xyz":[0.205919427319660231,0.100763977395602056,0.388918707661118246],"hpluv":[299.695850237394552,292.228621346341356,37.9791974354050694],"hsluv":[299.695850237394552,96.26500390067784,37.9791974354050694]},"#9911bb":{"lch":[39.176522525078866,95.7489617369993624,293.383950362709356],"luv":[39.176522525078866,38.0018814997404846,-87.8847010360338459],"rgb":[0.6,0.0666666666666666657,0.733333333333333282],"xyz":[0.22305701942699685,0.107619014238536814,0.47917669275976],"hpluv":[293.383950362709356,310.132668732371314,39.176522525078866],"hsluv":[293.383950362709356,96.7106400677762537,39.176522525078866]},"#9911cc":{"lch":[40.465031277763515,104.765415075180798,288.480743990765689],"luv":[40.465031277763515,33.2091620218187842,-99.3626879350770622],"rgb":[0.6,0.0666666666666666657,0.8],"xyz":[0.242349394870718604,0.115335964416025616,0.580783203430030204],"hpluv":[288.480743990765689,328.531778006508034,40.465031277763515],"hsluv":[288.480743990765689,97.1001366995766,40.465031277763515]},"#9911dd":{"lch":[41.8361001822542917,114.161763941518927,284.668123617886636],"luv":[41.8361001822542917,28.9080153835727351,-110.441092863219225],"rgb":[0.6,0.0666666666666666657,0.866666666666666696],"xyz":[0.263867720421352148,0.12394329463627915,0.694113051330036201],"hpluv":[284.668123617886636,346.265164959266087,41.8361001822542917],"hsluv":[284.668123617886636,97.4384492036098,41.8361001822542917]},"#9911ee":{"lch":[43.2812320372341617,123.724619665436521,281.679545129349094],"luv":[43.2812320372341617,25.0465268392882301,-121.162919264293635],"rgb":[0.6,0.0666666666666666657,0.933333333333333348],"xyz":[0.287679900687526913,0.133468166742749167,0.819523867398559425],"hpluv":[281.679545129349094,362.740326129136179,43.2812320372341617],"hsluv":[281.679545129349094,97.7313369542794561,43.2812320372341617]},"#9911ff":{"lch":[44.7922739406791948,133.33068560825987,279.310828677429186],"luv":[44.7922739406791948,21.5716156333953251,-131.574074664174219],"rgb":[0.6,0.0666666666666666657,1],"xyz":[0.313850949097358278,0.143936586106681863,0.95735805569034127],"hpluv":[279.310828677429186,377.716823123197173,44.7922739406791948],"hsluv":[279.310828677429186,99.9999999999993179,44.7922739406791948]},"#bb1100":{"lch":[39.5258701457598747,127.514079962112703,13.0219609303782402],"luv":[39.5258701457598747,124.2348987579322,28.7320469022032583],"rgb":[0.733333333333333282,0.0666666666666666657,0],"xyz":[0.206934995275703137,0.109676138576352333,0.0102742550616268143],"hpluv":[13.0219609303782402,409.370014873310311,39.5258701457598747],"hsluv":[13.0219609303782402,100.000000000002203,39.5258701457598747]},"#bb1111":{"lch":[39.5940766091873897,125.63034182067031,12.177050630061796],"luv":[39.5940766091873897,122.803716963532779,26.4996204863200759],"rgb":[0.733333333333333282,0.0666666666666666657,0.0666666666666666657],"xyz":[0.20794666077534027,0.110080804776207186,0.0156023600263824457],"hpluv":[12.177050630061796,402.627698793753552,39.5940766091873897],"hsluv":[12.177050630061796,94.3481495348726753,39.5940766091873897]},"#bb1122":{"lch":[39.7200723855077413,122.321798686612851,10.5915831721034426],"luv":[39.7200723855077413,120.23772406897838,22.4835972353282152],"rgb":[0.733333333333333282,0.0666666666666666657,0.133333333333333331],"xyz":[0.209822018913817271,0.110830948031598,0.0254792462223616401],"hpluv":[10.5915831721034426,390.780742551338619,39.7200723855077413],"hsluv":[10.5915831721034426,94.4721603032542561,39.7200723855077413]},"#bb1133":{"lch":[39.9262897734852,117.365304386249704,7.93115519261489421],"luv":[39.9262897734852,116.242655940639409,16.194431559742192],"rgb":[0.733333333333333282,0.0666666666666666657,0.2],"xyz":[0.212909769646275,0.112066048324581113,0.0417414000799727902],"hpluv":[7.93115519261489421,373.009679290071517,39.9262897734852],"hsluv":[7.93115519261489421,94.6648992051481173,39.9262897734852]},"#bb1144":{"lch":[40.2213637516280755,111.198866264944101,3.99799547396429888],"luv":[40.2213637516280755,110.928262725239179,7.75295991020434627],"rgb":[0.733333333333333282,0.0666666666666666657,0.266666666666666663],"xyz":[0.217367764890493892,0.113849246422268693,0.0652201750328594287],"hpluv":[3.99799547396429888,350.818828640487084,40.2213637516280755],"hsluv":[3.99799547396429888,94.920595316052,40.2213637516280755]},"#bb1155":{"lch":[40.6112374139617245,104.574630781207446,358.621384873601698],"luv":[40.6112374139617245,104.544360517453882,-2.51596641918957786],"rgb":[0.733333333333333282,0.0666666666666666657,0.333333333333333315],"xyz":[0.223330178929855905,0.116234212038013526,0.0966222223068333302],"hpluv":[358.621384873601698,326.752894857139097,40.6112374139617245],"hsluv":[358.621384873601698,95.2265760165129791,40.6112374139617245]},"#bb1166":{"lch":[41.0995768863194755,98.4443929415329251,351.723860164231496],"luv":[41.0995768863194755,97.4191751888273672,-14.1704907168206535],"rgb":[0.733333333333333282,0.0666666666666666657,0.4],"xyz":[0.230915174703364062,0.119268210347416845,0.136569866713977306],"hpluv":[351.723860164231496,303.943570446579713,41.0995768863194755],"hsluv":[351.723860164231496,95.5663396203906643,41.0995768863194755]},"#bb1177":{"lch":[41.688035181331955,93.7889310063258,343.43446060875408],"luv":[41.688035181331955,89.8961490854954093,-26.7403432832812094],"rgb":[0.733333333333333282,0.0666666666666666657,0.466666666666666674],"xyz":[0.240229187723566,0.122993815555497654,0.185623668620375215],"hpluv":[343.43446060875408,285.48249634694713,41.688035181331955],"hsluv":[343.43446060875408,95.9227087501184883,41.688035181331955]},"#bb1188":{"lch":[42.3764815581906475,91.4027083669889606,334.189166164708297],"luv":[42.3764815581906475,82.2840505377722309,-39.7968607294366805],"rgb":[0.733333333333333282,0.0666666666666666657,0.533333333333333326],"xyz":[0.251369604825509796,0.127449982396275252,0.244296532023947383],"hpluv":[334.189166164708297,273.699179760613617,42.3764815581906475],"hsluv":[334.189166164708297,96.2803174994205,42.3764815581906475]},"#bb1199":{"lch":[43.1632358766101092,91.692942572352564,324.693570122963422],"luv":[43.1632358766101092,74.8281105443768269,-52.9938637007650755],"rgb":[0.733333333333333282,0.0666666666666666657,0.6],"xyz":[0.264426568934582495,0.13267276803990441,0.31306320966506529],"hpluv":[324.693570122963422,269.563595898888195,43.1632358766101092],"hsluv":[324.693570122963422,96.6270445785018239,43.1632358766101092]},"#bb11aa":{"lch":[44.0453166933651,94.6050581990027553,315.694091730478135],"luv":[44.0453166933651,67.7013389352867847,-66.0806003544619784],"rgb":[0.733333333333333282,0.0666666666666666657,0.66666666666666663],"xyz":[0.279484261899835051,0.138695845226005504,0.39236705928206389],"hpluv":[315.694091730478135,272.554870225691275,44.0453166933651],"hsluv":[315.694091730478135,96.9544350138240105,44.0453166933651]},"#bb11bb":{"lch":[45.0186979872658242,99.7328976909900717,307.715012949243601],"luv":[45.0186979872658242,61.0100383302365472,-78.8950321933172205],"rgb":[0.733333333333333282,0.0666666666666666657,0.733333333333333282],"xyz":[0.296621854007171726,0.145550882068940263,0.482625044380705637],"hpluv":[307.715012949243601,281.115526817766181,45.0186979872658242],"hsluv":[307.715012949243601,97.2574105430315115,45.0186979872658242]},"#bb11cc":{"lch":[46.0785638011469771,106.527215460047387,300.962972083371881],"luv":[46.0785638011469771,54.8065495444917161,-91.3470840295328372],"rgb":[0.733333333333333282,0.0666666666666666657,0.8],"xyz":[0.315914229450893425,0.153267832246429064,0.584231555050975793],"hpluv":[300.962972083371881,293.360047474541318,46.0785638011469771],"hsluv":[300.962972083371881,97.5336183018287528,46.0785638011469771]},"#bb11dd":{"lch":[47.2195492447565,114.4666153484132,295.402801066287566],"luv":[47.2195492447565,49.1038079522977853,-103.3993330438134],"rgb":[0.733333333333333282,0.0666666666666666657,0.866666666666666696],"xyz":[0.337432555001527,0.161875162466682598,0.69756140295098179],"hpluv":[295.402801066287566,307.607082675331128,47.2195492447565],"hsluv":[295.402801066287566,97.7826899351839813,47.2195492447565]},"#bb11ee":{"lch":[48.4359581768354701,123.136484869400022,290.880608651701721],"luv":[48.4359581768354701,43.8885280811888,-115.049515465553711],"rgb":[0.733333333333333282,0.0666666666666666657,0.933333333333333348],"xyz":[0.361244735267701733,0.171400034573152643,0.822972219019505],"hpluv":[290.880608651701721,322.595409245987128,48.4359581768354701],"hsluv":[290.880608651701721,98.0055710342431325,48.4359581768354701]},"#bb11ff":{"lch":[49.7219510368964,132.239138283310353,287.21247838519713],"luv":[49.7219510368964,39.1316890181496575,-126.316667975763593],"rgb":[0.733333333333333282,0.0666666666666666657,1],"xyz":[0.387415783677533154,0.181868453937085339,0.960806407311286859],"hpluv":[287.21247838519713,337.482436204013879,49.7219510368964],"hsluv":[287.21247838519713,99.9999999999991758,49.7219510368964]},"#992200":{"lch":[33.8105832897308716,95.4307991554818358,16.0266852535062476],"luv":[33.8105832897308716,91.7217107848809263,26.3470149760569932],"rgb":[0.6,0.133333333333333331,0],"xyz":[0.137085784430296231,0.0791755182154848525,0.0080644446856038],"hpluv":[16.0266852535062476,358.158468302090569,33.8105832897308716],"hsluv":[16.0266852535062476,100.000000000002331,33.8105832897308716]},"#992211":{"lch":[33.8952997814050718,93.2922690289088195,14.6972380002076104],"luv":[33.8952997814050718,90.239744522062125,23.669304365681274],"rgb":[0.6,0.133333333333333331,0.0666666666666666657],"xyz":[0.138097449929933364,0.0795801844153397,0.0133925496503594314],"hpluv":[14.6972380002076104,349.257308780581,33.8952997814050718],"hsluv":[14.6972380002076104,92.1483909924374274,33.8952997814050718]},"#992222":{"lch":[34.0515850466810335,89.6330213591727,12.1770506300618084],"luv":[34.0515850466810335,87.6163196410811338,18.9065874902323579],"rgb":[0.6,0.133333333333333331,0.133333333333333331],"xyz":[0.139972808068410365,0.0803303276707305197,0.0232694358463386292],"hpluv":[12.1770506300618084,334.018122077437397,34.0515850466810335],"hsluv":[12.1770506300618084,78.2707991117683,34.0515850466810335]},"#992233":{"lch":[34.3068003204445446,84.4135643942939282,7.88651435003668233],"luv":[34.3068003204445446,83.6151628365757773,11.58250394183076],"rgb":[0.6,0.133333333333333331,0.2],"xyz":[0.143060558800868098,0.0815654279637136326,0.0395315897039497724],"hpluv":[7.88651435003668233,312.227643050581207,34.3068003204445446],"hsluv":[7.88651435003668233,79.3008398259009226,34.3068003204445446]},"#992244":{"lch":[34.6707661525426,78.4682482149262199,1.45557545410962708],"luv":[34.6707661525426,78.4429281517087134,1.99323879782018309],"rgb":[0.6,0.133333333333333331,0.266666666666666663],"xyz":[0.147518554045086986,0.0833486260614012126,0.0630103646568364],"hpluv":[1.45557545410962708,287.190351340663,34.6707661525426],"hsluv":[1.45557545410962708,80.6267396657693212,34.6707661525426]},"#992255":{"lch":[35.149531709850983,73.0418005898087443,352.659616011821072],"luv":[35.149531709850983,72.4431965063170082,-9.33209051330535821],"rgb":[0.6,0.133333333333333331,0.333333333333333315],"xyz":[0.153480968084449,0.0857335916771460455,0.0944124119308103193],"hpluv":[352.659616011821072,263.688538908073838,35.149531709850983],"hsluv":[352.659616011821072,82.1555178352066804,35.149531709850983]},"#992266":{"lch":[35.7459223236079495,69.5043059181480203,341.734006615383123],"luv":[35.7459223236079495,66.0021002604389793,-21.7846574995905513],"rgb":[0.6,0.133333333333333331,0.4],"xyz":[0.161065963857957156,0.0887675899865493639,0.134360056337954281],"hpluv":[341.734006615383123,246.731460763727796,35.7459223236079495],"hsluv":[341.734006615383123,83.7834402291280753,35.7459223236079495]},"#992277":{"lch":[36.4599553630224946,68.9051746310403104,329.662355423262511],"luv":[36.4599553630224946,59.4695672743266783,-34.8036443370302],"rgb":[0.6,0.133333333333333331,0.466666666666666674],"xyz":[0.17037997687815909,0.0924931951946301734,0.18341385824435219],"hpluv":[329.662355423262511,239.814275331209444,36.4599553630224946],"hsluv":[329.662355423262511,85.4170781092293225,36.4599553630224946]},"#992288":{"lch":[37.2892540647929,71.5563678213307242,317.925484235555643],"luv":[37.2892540647929,53.1144286836587369,-47.9496740488411],"rgb":[0.6,0.133333333333333331,0.533333333333333326],"xyz":[0.18152039398010289,0.0969493620354077712,0.242086721647924358],"hpluv":[317.925484235555643,243.502777039008038,37.2892540647929],"hsluv":[317.925484235555643,86.9852623869732,37.2892540647929]},"#992299":{"lch":[38.2294870734457888,77.015786119064046,307.715012949243771],"luv":[38.2294870734457888,47.1132010795059841,-60.9243596238766827],"rgb":[0.6,0.133333333333333331,0.6],"xyz":[0.194577358089175617,0.102172147679036929,0.310853399289042265],"hpluv":[307.715012949243771,255.635172818446421,38.2294870734457888],"hsluv":[307.715012949243771,88.441984096309227,38.2294870734457888]},"#9922aa":{"lch":[39.2748221448681178,84.484081905089468,299.468150353755561],"luv":[39.2748221448681178,41.5610713460956234,-73.5543162833468],"rgb":[0.6,0.133333333333333331,0.66666666666666663],"xyz":[0.209635051054428145,0.108195224865138023,0.390157248906040865],"hpluv":[299.468150353755561,272.960615272696657,39.2748221448681178],"hsluv":[299.468150353755561,89.7633288768494708,39.2748221448681178]},"#9922bb":{"lch":[40.4183688993281436,93.2013493596814726,293.05045530637],"luv":[40.4183688993281436,36.4922039393154094,-85.7601922462677919],"rgb":[0.6,0.133333333333333331,0.733333333333333282],"xyz":[0.22677264316176482,0.115050261708072782,0.480415234004682612],"hpluv":[293.05045530637,292.605673863240838,40.4183688993281436],"hsluv":[293.05045530637,90.9419133161227222,40.4183688993281436]},"#9922cc":{"lch":[41.6525852773545182,102.609691310931794,288.11294916137831],"luv":[41.6525852773545182,31.900454524651952,-97.5249186210648702],"rgb":[0.6,0.133333333333333331,0.8],"xyz":[0.246065018605486546,0.122767211885561583,0.582021744674952712],"hpluv":[288.11294916137831,312.597676326075884,41.6525852773545182],"hsluv":[288.11294916137831,91.9812251551093851,41.6525852773545182]},"#9922dd":{"lch":[42.969628845807982,112.350489371469905,284.303043907998301],"luv":[42.969628845807982,27.7562437333976213,-108.867917201630149],"rgb":[0.6,0.133333333333333331,0.866666666666666696],"xyz":[0.267583344156120062,0.131374542105815117,0.69535159257495871],"hpluv":[284.303043907998301,331.781902020401162,42.969628845807982],"hsluv":[284.303043907998301,92.8910125551507235,42.969628845807982]},"#9922ee":{"lch":[44.361642902098545,122.210344632057584,281.334390799049743],"luv":[44.361642902098545,24.018574136526297,-119.826860225637532],"rgb":[0.6,0.133333333333333331,0.933333333333333348],"xyz":[0.291395524422294827,0.140899414212285162,0.820762408643481933],"hpluv":[281.334390799049743,349.574442537581717,44.361642902098545],"hsluv":[281.334390799049743,93.6839973987951566,44.361642902098545]},"#9922ff":{"lch":[45.8209755847726612,132.069283427413211,278.992348895848238],"luv":[45.8209755847726612,20.6427685166220094,-130.446049127597433],"rgb":[0.6,0.133333333333333331,1],"xyz":[0.317566572832126193,0.151367833576217858,0.958596596935263889],"hpluv":[278.992348895848238,365.74366826955071,45.8209755847726612],"hsluv":[278.992348895848238,99.9999999999993179,45.8209755847726612]},"#bb2200":{"lch":[40.7526421249889452,122.145166616692975,14.6188079362681389],"luv":[40.7526421249889452,118.190884669319914,30.8278528104570881],"rgb":[0.733333333333333282,0.133333333333333331,0],"xyz":[0.21065061901047108,0.117107386045888315,0.0115127963065494235],"hpluv":[14.6188079362681389,380.329350781024857,40.7526421249889452],"hsluv":[14.6188079362681389,100.000000000002217,40.7526421249889452]},"#bb2211":{"lch":[40.8179368215716849,120.355879944515436,13.7706881972771793],"luv":[40.8179368215716849,116.896392622501153,28.6491052053056343],"rgb":[0.733333333333333282,0.133333333333333331,0.0666666666666666657],"xyz":[0.211662284510108212,0.117512052245743168,0.0168409012713050532],"hpluv":[13.7706881972771793,374.158477594779924,40.8179368215716849],"hsluv":[13.7706881972771793,94.6800257514418,40.8179368215716849]},"#bb2222":{"lch":[40.9385803904414161,117.208042434762348,12.1770506300618102],"luv":[40.9385803904414161,114.570915436608942,24.7230772236478238],"rgb":[0.733333333333333282,0.133333333333333331,0.133333333333333331],"xyz":[0.213537642648585213,0.118262195501133982,0.0267177874672842527],"hpluv":[12.1770506300618102,363.298797482753,40.9385803904414161],"hsluv":[12.1770506300618102,85.1321689328196101,40.9385803904414161]},"#bb2233":{"lch":[41.136111673530813,112.480172956632245,9.49666640172232235],"luv":[41.136111673530813,110.938654987290519,18.5581286223806821],"rgb":[0.733333333333333282,0.133333333333333331,0.2],"xyz":[0.216625393381042974,0.119497295794117095,0.042979941324895396],"hpluv":[9.49666640172232235,346.970109935861444,41.136111673530813],"hsluv":[9.49666640172232235,85.6217357677037398,41.136111673530813]},"#bb2244":{"lch":[41.4189140922405201,106.57909239531196,5.51995404221549],"luv":[41.4189140922405201,106.084859394728952,10.2520994439692306],"rgb":[0.733333333333333282,0.133333333333333331,0.266666666666666663],"xyz":[0.221083388625261834,0.121280493891804675,0.0664587162777820345],"hpluv":[5.51995404221549,326.522141050690152,41.4189140922405201],"hsluv":[5.51995404221549,86.2742612371986297,41.4189140922405201]},"#bb2255":{"lch":[41.7928521194743823,100.22104851316422,0.0579838467833058424],"luv":[41.7928521194743823,100.220997191859041,0.101424589714973798],"rgb":[0.733333333333333282,0.133333333333333331,0.333333333333333315],"xyz":[0.227045802664623819,0.123665459507549508,0.097860763551755936],"hpluv":[0.0579838467833058424,304.296010337655673,41.7928521194743823],"hsluv":[0.0579838467833058424,87.0597094656736772,41.7928521194743823]},"#bb2266":{"lch":[42.2616671880265216,94.3342448936905,353.011685321171171],"luv":[42.2616671880265216,93.6334344607092106,-11.4773564358193614],"rgb":[0.733333333333333282,0.133333333333333331,0.4],"xyz":[0.234630798438132,0.126699457816952826,0.137808407958899898],"hpluv":[353.011685321171171,283.244886623536,42.2616671880265216],"hsluv":[353.011685321171171,87.937804292381287,42.2616671880265216]},"#bb2277":{"lch":[42.8272221099346666,89.9002723684957,344.496654306277264],"luv":[42.8272221099346666,86.6292371691086771,-24.0298614109202155],"rgb":[0.733333333333333282,0.133333333333333331,0.466666666666666674],"xyz":[0.24394481145833391,0.13042506302503365,0.186862209865297807],"hpluv":[344.496654306277264,266.367005402095344,42.8272221099346666],"hsluv":[344.496654306277264,88.8655868844719805,42.8272221099346666]},"#bb2288":{"lch":[43.4897067779173554,87.7363054907772693,334.961981200390596],"luv":[43.4897067779173554,79.4914755013727898,-37.1317199141871441],"rgb":[0.733333333333333282,0.133333333333333331,0.533333333333333326],"xyz":[0.255085228560277766,0.13488122986581122,0.245535073268869974],"hpluv":[334.961981200390596,255.995416581420926,43.4897067779173554],"hsluv":[334.961981200390596,89.8036443318747786,43.4897067779173554]},"#bb2299":{"lch":[44.2478449340908639,88.2751432264235092,325.159464012784042],"luv":[44.2478449340908639,72.4514028672968635,-50.4310929309115],"rgb":[0.733333333333333282,0.133333333333333331,0.6],"xyz":[0.268142192669350465,0.140104015509440405,0.314301750909987909],"hpluv":[325.159464012784042,253.154489640486645,44.2478449340908639],"hsluv":[325.159464012784042,90.7199745934293844,44.2478449340908639]},"#bb22aa":{"lch":[45.0991127685299062,91.4705260319517919,315.891475419905078],"luv":[45.0991127685299062,65.6779186933914758,-63.6652819727222195],"rgb":[0.733333333333333282,0.133333333333333331,0.66666666666666663],"xyz":[0.283199885634603,0.146127092695541499,0.39360560052698651],"hpluv":[315.891475419905078,257.366789521381691,45.0991127685299062],"hsluv":[315.891475419905078,91.5914304646717,45.0991127685299062]},"#bb22bb":{"lch":[46.0399667792549678,96.9048462314552,307.715012949243658],"luv":[46.0399667792549678,59.2800221375787615,-76.6578645574617497],"rgb":[0.733333333333333282,0.133333333333333331,0.733333333333333282],"xyz":[0.30033747774193964,0.152982129538476258,0.483863585625628256],"hpluv":[307.715012949243658,267.0851991180906,46.0399667792549678],"hsluv":[307.715012949243658,92.4033444706684,46.0399667792549678]},"#bb22cc":{"lch":[47.066072507765945,104.009692587178989,300.837938637053412],"luv":[47.066072507765945,53.3165662395356,-89.3048706202785496],"rgb":[0.733333333333333282,0.133333333333333331,0.8],"xyz":[0.319629853185661394,0.16069907971596506,0.585470096295898412],"hpluv":[300.837938637053412,280.417543020287,47.066072507765945],"hsluv":[300.837938637053412,93.1481326309998,47.066072507765945]},"#bb22dd":{"lch":[48.1725242595717589,112.247547842848149,295.20893392435471],"luv":[48.1725242595717589,47.808517424121824,-101.557164486017044],"rgb":[0.733333333333333282,0.133333333333333331,0.866666666666666696],"xyz":[0.341148178736294938,0.169306409936218594,0.69879994419590441],"hpluv":[295.20893392435471,295.676483579310798,48.1725242595717589],"hsluv":[295.20893392435471,93.8235497257627316,48.1725242595717589]},"#bb22ee":{"lch":[49.3540469689012724,121.194036197623419,290.655339197387],"luv":[49.3540469689012724,42.7506603945962169,-113.403595382583688],"rgb":[0.733333333333333282,0.133333333333333331,0.933333333333333348],"xyz":[0.364960359002469703,0.178831282042688611,0.824210760264427633],"hpluv":[290.655339197387,311.600255956968681,49.3540469689012724],"hsluv":[290.655339197387,94.4310255689598,49.3540469689012724]},"#bb22ff":{"lch":[50.6051737457033397,130.547024148317973,286.97844412333734],"luv":[50.6051737457033397,38.1212848334983647,-124.85709093449519],"rgb":[0.733333333333333282,0.133333333333333331,1],"xyz":[0.391131407412301069,0.189299701406621335,0.962044948556209478],"hpluv":[286.97844412333734,327.349274436557835,50.6051737457033397],"hsluv":[286.97844412333734,99.9999999999991616,50.6051737457033397]},"#993300":{"lch":[36.2545465004255476,86.9834057059747749,20.3835344027483316],"luv":[36.2545465004255476,81.5366895093473,30.2965531383769893],"rgb":[0.6,0.2,0],"xyz":[0.14320350651930705,0.0914109623935066423,0.0101036853819406816],"hpluv":[20.3835344027483316,304.448092478673459,36.2545465004255476],"hsluv":[20.3835344027483316,100.00000000000226,36.2545465004255476]},"#993311":{"lch":[36.3315413581227133,85.0112276295678839,19.0571063974297203],"luv":[36.3315413581227133,80.3520694714869279,27.7570487396543],"rgb":[0.6,0.2,0.0666666666666666657],"xyz":[0.144215172018944182,0.0918156285933615,0.0154317903466963131],"hpluv":[19.0571063974297203,296.914762557758195,36.3315413581227133],"hsluv":[19.0571063974297203,93.1288353931581,36.3315413581227133]},"#993322":{"lch":[36.4736730302835852,81.6150828115545863,16.5278497598068661],"luv":[36.4736730302835852,78.2428757472059573,23.217970134019108],"rgb":[0.6,0.2,0.133333333333333331],"xyz":[0.146090530157421183,0.0925657718487523096,0.0253086765426755109],"hpluv":[16.5278497598068661,283.942401799749632,36.4736730302835852],"hsluv":[16.5278497598068661,80.9121244795507124,36.4736730302835852]},"#993333":{"lch":[36.7060271438600836,76.7221326388105638,12.1770506300618369],"luv":[36.7060271438600836,74.9959199734098121,16.1832513417159589],"rgb":[0.6,0.2,0.2],"xyz":[0.149178280889878945,0.0938008721417354224,0.0415708304002866541],"hpluv":[12.1770506300618369,265.229979343802,36.7060271438600836],"hsluv":[12.1770506300618369,62.1516051360361459,36.7060271438600836]},"#993344":{"lch":[37.0379214664673668,71.077614272095758,5.55118145677439934],"luv":[37.0379214664673668,70.7442733159460744,6.87568495580995354],"rgb":[0.6,0.2,0.266666666666666663],"xyz":[0.153636276134097804,0.095584070239423,0.0650496053531732926],"hpluv":[5.55118145677439934,243.514912685509444,37.0379214664673668],"hsluv":[5.55118145677439934,64.3097526797848644,37.0379214664673668]},"#993355":{"lch":[37.4754277574064858,65.8722356173568073,356.298722520573506],"luv":[37.4754277574064858,65.7348379379961614,-4.25235305377523254],"rgb":[0.6,0.2,0.333333333333333315],"xyz":[0.15959869017345979,0.0979690358551678353,0.0964516526271472],"hpluv":[356.298722520573506,223.046355214908289,37.4754277574064858],"hsluv":[356.298722520573506,66.8387430740197885,37.4754277574064858]},"#993366":{"lch":[38.0218512407041942,62.5198646461221941,344.559385799457459],"luv":[38.0218512407041942,60.2633303059628602,-16.6452544529622166],"rgb":[0.6,0.2,0.4],"xyz":[0.167183685946967975,0.101003034164571154,0.136399297034291156],"hpluv":[344.559385799457459,208.652742449272864,38.0218512407041942],"hsluv":[344.559385799457459,69.5808124884664778,38.0218512407041942]},"#993377":{"lch":[38.6780657603296234,62.1964572713534949,331.414072321130675],"luv":[38.6780657603296234,54.6147414507713478,-29.7595247504508862],"rgb":[0.6,0.2,0.466666666666666674],"xyz":[0.17649769896716988,0.104728639372651963,0.185453098940689065],"hpluv":[331.414072321130675,204.051704505442274,38.6780657603296234],"hsluv":[331.414072321130675,72.3848063102254571,38.6780657603296234]},"#993388":{"lch":[39.4428302118465908,65.3028355433768155,318.6521895607018],"luv":[39.4428302118465908,49.0236963230770257,-43.1409031990296086],"rgb":[0.6,0.2,0.533333333333333326],"xyz":[0.187638116069113736,0.109184806213429561,0.244125962344261233],"hpluv":[318.6521895607018,210.08899125401652,39.4428302118465908],"hsluv":[318.6521895607018,75.1271370389489306,39.4428302118465908]},"#993399":{"lch":[40.3131218316236897,71.3679900272828149,307.715012949243942],"luv":[40.3131218316236897,43.6582502656979656,-56.4565955781255226],"rgb":[0.6,0.2,0.6],"xyz":[0.200695080178186436,0.114407591857058719,0.31289263998537914],"hpluv":[307.715012949243942,224.64479534599792,40.3131218316236897],"hsluv":[307.715012949243942,77.7202573427554313,40.3131218316236897]},"#9933aa":{"lch":[41.2844862133256925,79.5040030135899372,299.063916375798101],"luv":[41.2844862133256925,38.6218522191785354,-69.4927264276258825],"rgb":[0.6,0.2,0.66666666666666663],"xyz":[0.215752773143439,0.120430669043159827,0.39219648960237774],"hpluv":[299.063916375798101,244.366370382710016,41.2844862133256925],"hsluv":[299.063916375798101,80.1114582016200814,41.2844862133256925]},"#9933bb":{"lch":[42.3513893410192637,88.8787943355742,292.467029257400327],"luv":[42.3513893410192637,33.9651845170614,-82.1328577566084],"rgb":[0.6,0.2,0.733333333333333282],"xyz":[0.232890365250775611,0.127285705886094586,0.482454474701019487],"hpluv":[292.467029257400327,266.299173904300574,42.3513893410192637],"hsluv":[292.467029257400327,82.2764131802073848,42.3513893410192637]},"#9933cc":{"lch":[43.5075532005759911,98.8962106119506785,287.477062230467],"luv":[43.5075532005759911,29.700902070050418,-94.3308904316533],"rgb":[0.6,0.2,0.8],"xyz":[0.252182740694497365,0.135002656063583387,0.584060985371289698],"hpluv":[287.477062230467,288.439223502221068,43.5075532005759911],"hsluv":[287.477062230467,84.2111914011780129,43.5075532005759911]},"#9933dd":{"lch":[44.7462588110156716,109.182503226938962,283.677602435208257],"luv":[44.7462588110156716,25.8171133061496079,-106.086265234656878],"rgb":[0.6,0.2,0.866666666666666696],"xyz":[0.273701066245130908,0.143609986283836921,0.697390833271295696],"hpluv":[283.677602435208257,309.624731809924413,44.7462588110156716],"hsluv":[283.677602435208257,85.9249592908513478,44.7462588110156716]},"#9933ee":{"lch":[46.0606056636097208,119.52114969179982,280.747238708189116],"luv":[46.0606056636097208,22.2879081330132465,-117.42467532296601],"rgb":[0.6,0.2,0.933333333333333348],"xyz":[0.297513246511305618,0.153134858390306938,0.822801649339818919],"hpluv":[280.747238708189116,329.271729063034456,46.0606056636097208],"hsluv":[280.747238708189116,90.0471632149093324,46.0606056636097208]},"#9933ff":{"lch":[47.4437223771408512,129.794782591236896,278.453521985212944],"luv":[47.4437223771408512,19.0807517890999456,-128.38461940228359],"rgb":[0.6,0.2,1],"xyz":[0.323684294921137039,0.163603277754239662,0.960635837631600764],"hpluv":[278.453521985212944,347.150508646733101,47.4437223771408512],"hsluv":[278.453521985212944,99.999999999999261,47.4437223771408512]},"#bb3300":{"lch":[42.6640590509798585,114.303280915030754,17.3320761189885637],"luv":[42.6640590509798585,109.113245500432,34.0520143942012652],"rgb":[0.733333333333333282,0.2,0],"xyz":[0.216768341099481898,0.129342830223910105,0.0135520370028863052],"hpluv":[17.3320761189885637,339.966286272656077,42.6640590509798585],"hsluv":[17.3320761189885637,100.000000000002302,42.6640590509798585]},"#bb3311":{"lch":[42.7251747888925806,112.6335820513806,16.4819551739351198],"luv":[42.7251747888925806,108.005370801027979,31.9556518296457135],"rgb":[0.733333333333333282,0.2,0.0666666666666666657],"xyz":[0.21778000659911903,0.129747496423764958,0.0188801419676419349],"hpluv":[16.4819551739351198,334.52099084556113,42.7251747888925806],"hsluv":[16.4819551739351198,95.1490253673008368,42.7251747888925806]},"#bb3322":{"lch":[42.8381318005571785,109.688338781622747,14.8808580240480524],"luv":[42.8381318005571785,106.009603708482885,28.1690536980292627],"rgb":[0.733333333333333282,0.2,0.133333333333333331],"xyz":[0.219655364737596032,0.130497639679155786,0.0287570281636211345],"hpluv":[14.8808580240480524,324.914627119009424,42.8381318005571785],"hsluv":[14.8808580240480524,86.4181297836030211,42.8381318005571785]},"#bb3333":{"lch":[43.023174549414108,105.246046554892928,12.1770506300618351],"luv":[43.023174549414108,102.878058957341324,22.1998941575065203],"rgb":[0.733333333333333282,0.2,0.2],"xyz":[0.222743115470053765,0.131732739972138885,0.0450191820212322777],"hpluv":[12.1770506300618351,310.414975564112126,43.023174549414108],"hsluv":[12.1770506300618351,72.7398502888125762,43.023174549414108]},"#bb3344":{"lch":[43.2883038991094082,99.6704509181560496,8.14070356751482116],"luv":[43.2883038991094082,98.6661026897846085,14.1137863891102171],"rgb":[0.733333333333333282,0.2,0.266666666666666663],"xyz":[0.227201110714272653,0.133515938069826479,0.0684979569741189231],"hpluv":[8.14070356751482116,292.169703441320848,43.2883038991094082],"hsluv":[8.14070356751482116,73.8775464962187556,43.2883038991094082]},"#bb3355":{"lch":[43.6392404977582515,93.6285749325397632,2.54995992142812078],"luv":[43.6392404977582515,93.5358645919991289,4.16558266337591299],"rgb":[0.733333333333333282,0.2,0.333333333333333315],"xyz":[0.233163524753634666,0.135900903685571312,0.0999000042480928246],"hpluv":[2.54995992142812078,272.251672456619758,43.6392404977582515],"hsluv":[2.54995992142812078,75.2585830443305781,43.6392404977582515]},"#bb3366":{"lch":[44.0797950159491521,88.0182600678664784,355.263953050872033],"luv":[44.0797950159491521,87.7177339493983794,-7.26727295188107547],"rgb":[0.733333333333333282,0.2,0.4],"xyz":[0.240748520527142823,0.138934901994974602,0.1398476486552368],"hpluv":[355.263953050872033,253.380121177946961,44.0797950159491521],"hsluv":[355.263953050872033,76.8177075569623753,44.0797950159491521]},"#bb3377":{"lch":[44.6120878205181057,83.829516929164356,346.367941021132197],"luv":[44.6120878205181057,81.4679789337245239,-19.757437005625782],"rgb":[0.733333333333333282,0.2,0.466666666666666674],"xyz":[0.250062533547344756,0.142660507203055426,0.188901450561634709],"hpluv":[346.367941021132197,238.442541154787421,44.6120878205181057],"hsluv":[346.367941021132197,78.4827471040858597,44.6120878205181057]},"#bb3388":{"lch":[45.2367248685103078,81.924239827592,336.329010851829594],"luv":[45.2367248685103078,75.03162551729379,-32.8912791414593499],"rgb":[0.733333333333333282,0.2,0.533333333333333326],"xyz":[0.261202950649288557,0.147116674043833023,0.247574313965206849],"hpluv":[336.329010851829594,229.805591899252,45.2367248685103078],"hsluv":[336.329010851829594,80.18501002925629,45.2367248685103078]},"#bb3399":{"lch":[45.9529692994627226,82.7837935230449347,325.982908927834501],"luv":[45.9529692994627226,68.6170634488305495,-46.3125800806357404],"rgb":[0.733333333333333282,0.2,0.6],"xyz":[0.274259914758361312,0.152339459687462181,0.316340991606324784],"hpluv":[325.982908927834501,228.597286714525296,45.9529692994627226],"hsluv":[325.982908927834501,81.8663863744617402,45.9529692994627226]},"#bb33aa":{"lch":[46.7589216358443664,86.3774619636168524,316.238480868355282],"luv":[46.7589216358443664,62.3839556422166126,-59.7436859735489136],"rgb":[0.733333333333333282,0.2,0.66666666666666663],"xyz":[0.289317607723613812,0.158362536873563275,0.395644841223323385],"hpluv":[316.238480868355282,234.409537876970433,46.7589216358443664],"hsluv":[316.238480868355282,83.4827024616804181,46.7589216358443664]},"#bb33bb":{"lch":[47.6517090930198108,92.2657594707273461,307.715012949243828],"luv":[47.6517090930198108,56.4421334605023191,-72.9880534138084585],"rgb":[0.733333333333333282,0.2,0.733333333333333282],"xyz":[0.306455199830950487,0.165217573716498034,0.485902826321965131],"hpluv":[307.715012949243828,245.697877980233102,47.6517090930198108],"hsluv":[307.715012949243828,85.0039827354176,47.6517090930198108]},"#bb33cc":{"lch":[48.6276786348411179,99.8443429984049402,300.621719827817344],"luv":[48.6276786348411179,50.8574804969275078,-85.9209491700817551],"rgb":[0.733333333333333282,0.2,0.8],"xyz":[0.325747575274672241,0.172934523893986836,0.587509336992235287],"hpluv":[300.621719827817344,260.542905615006589,48.6276786348411179],"hsluv":[300.621719827817344,86.4127454729900535,48.6276786348411179]},"#bb33dd":{"lch":[49.6825862492002273,108.545865187730342,294.87630802524211],"luv":[49.6825862492002273,45.6609809337446322,-98.4747666639588459],"rgb":[0.733333333333333282,0.2,0.866666666666666696],"xyz":[0.347265900825305729,0.18154185411424037,0.700839184892241285],"hpluv":[294.87630802524211,277.235228758227834,49.6825862492002273],"hsluv":[294.87630802524211,87.70141038259,49.6825862492002273]},"#bb33ee":{"lch":[50.8117750205940695,117.927813495206621,290.271422146528892],"luv":[50.8117750205940695,40.8581913283156268,-110.623584271795281],"rgb":[0.733333333333333282,0.2,0.933333333333333348],"xyz":[0.371078081091480494,0.191066726220710414,0.826250000960764508],"hpluv":[290.271422146528892,294.504005794210514,50.8117750205940695],"hsluv":[290.271422146528892,88.8695912604113687,50.8117750205940695]},"#bb33ff":{"lch":[52.0103359867018611,127.679308171663493,286.581788346289272],"luv":[52.0103359867018611,36.4375993761859931,-122.36955130625914],"rgb":[0.733333333333333282,0.2,1],"xyz":[0.39724912950131186,0.201535145584643111,0.964084189252546353],"hpluv":[286.581788346289272,311.508705442628695,52.0103359867018611],"hsluv":[286.581788346289272,99.9999999999991616,52.0103359867018611]},"#994400":{"lch":[39.4244247356725168,77.6708634712958315,27.0445710144404678],"luv":[39.4244247356725168,69.1777945884316097,35.3156589667733627],"rgb":[0.6,0.266666666666666663,0],"xyz":[0.152036077002273062,0.109076103359438958,0.0130478755429292749],"hpluv":[27.0445710144404678,249.995444431237956,39.4244247356725168],"hsluv":[27.0445710144404678,100.000000000002302,39.4244247356725168]},"#994411":{"lch":[39.4928806474909351,75.8240556098730849,25.7566327743493559],"luv":[39.4928806474909351,68.2907795083206395,32.9493071744317447],"rgb":[0.6,0.266666666666666663,0.0666666666666666657],"xyz":[0.153047742501910194,0.109480769559293811,0.0183759805076849081],"hpluv":[25.7566327743493559,243.628181561178451,39.4928806474909351],"hsluv":[25.7566327743493559,94.1783894720599,39.4928806474909351]},"#994422":{"lch":[39.6193348047394807,72.6128884539244268,23.2788782073808527],"luv":[39.6193348047394807,66.7016282141236161,28.6971141964989123],"rgb":[0.6,0.266666666666666663,0.133333333333333331],"xyz":[0.154923100640387196,0.110230912814684626,0.0282528667036641],"hpluv":[23.2788782073808527,232.565805292122405,39.6193348047394807],"hsluv":[23.2788782073808527,83.7619004180350402,39.6193348047394807]},"#994433":{"lch":[39.8262957210095,67.9099451463512764,18.9473520481579776],"luv":[39.8262957210095,64.2304033034813671,22.0503047882012062],"rgb":[0.6,0.266666666666666663,0.2],"xyz":[0.158010851372844929,0.111466013107667739,0.0445150205612752509],"hpluv":[18.9473520481579776,216.372863201479333,39.8262957210095],"hsluv":[18.9473520481579776,67.5996848307310358,39.8262957210095]},"#994444":{"lch":[40.1224193460439267,62.3513134554678956,12.1770506300619097],"luv":[40.1224193460439267,60.9484376060972082,13.1519672672071142],"rgb":[0.6,0.266666666666666663,0.266666666666666663],"xyz":[0.162468846617063817,0.113249211205355318,0.0679937955141618894],"hpluv":[12.1770506300619097,197.195872414250289,40.1224193460439267],"hsluv":[12.1770506300619097,46.2091051210312429,40.1224193460439267]},"#994455":{"lch":[40.5136546800823041,57.0624194645929776,2.37288379618767387],"luv":[40.5136546800823041,57.0134905267935324,2.36254377830001205],"rgb":[0.6,0.266666666666666663,0.333333333333333315],"xyz":[0.16843126065642583,0.115634176821100151,0.0993958427881357909],"hpluv":[2.37288379618767387,178.726144329621945,40.5136546800823041],"hsluv":[2.37288379618767387,49.5312591923758063,40.5136546800823041]},"#994466":{"lch":[41.0036603670202382,53.5416261730848646,349.413399835018254],"luv":[41.0036603670202382,52.6302589877717111,-9.83674601372026558],"rgb":[0.6,0.266666666666666663,0.4],"xyz":[0.176016256429934,0.11866817513050347,0.139343487195279753],"hpluv":[349.413399835018254,165.694562401887765,41.0036603670202382],"hsluv":[349.413399835018254,53.2076295784804643,41.0036603670202382]},"#994477":{"lch":[41.594070304433572,53.2098960104776424,334.460192523955527],"luv":[41.594070304433572,48.0105420863306946,-22.9408125841809181],"rgb":[0.6,0.266666666666666663,0.466666666666666674],"xyz":[0.18533026945013592,0.122393780338584279,0.188397289101677662],"hpluv":[334.460192523955527,162.330570569563577,41.594070304433572],"hsluv":[334.460192523955527,57.0495308436177666,41.594070304433572]},"#994488":{"lch":[42.2847251453823887,56.6612659292255287,319.901700116735],"luv":[42.2847251453823887,43.3424978513170416,-36.4955742071691631],"rgb":[0.6,0.266666666666666663,0.533333333333333326],"xyz":[0.196470686552079721,0.126849947179361877,0.247070152505249829],"hpluv":[319.901700116735,170.036472949794188,42.2847251453823887],"hsluv":[319.901700116735,60.8903164523640683,42.2847251453823887]},"#994499":{"lch":[43.0739091348830314,63.3829857303906,307.715012949244226],"luv":[43.0739091348830314,38.7735489334465555,-50.1399519665159232],"rgb":[0.6,0.266666666666666663,0.6],"xyz":[0.209527650661152448,0.132072732822991035,0.315836830146367764],"hpluv":[307.715012949244226,186.722963823125951,43.0739091348830314],"hsluv":[307.715012949244226,64.600458594127474,43.0739091348830314]},"#9944aa":{"lch":[43.9586008361636686,72.3252063731545,298.405725418599673],"luv":[43.9586008361636686,34.4059763632637896,-63.6173267861038099],"rgb":[0.6,0.266666666666666663,0.66666666666666663],"xyz":[0.224585343626404976,0.138095810009092129,0.395140679763366365],"hpluv":[298.405725418599673,208.77819920337123,43.9586008361636686],"hsluv":[298.405725418599673,68.0913106207235,43.9586008361636686]},"#9944bb":{"lch":[44.9347323991438827,82.5300732915554676,291.540124858279853],"luv":[44.9347323991438827,30.3011407548278626,-76.7662286846607316],"rgb":[0.6,0.266666666666666663,0.733333333333333282],"xyz":[0.241722935733741651,0.144950846852026888,0.485398664862008111],"hpluv":[291.540124858279853,233.060888419388505,44.9347323991438827],"hsluv":[291.540124858279853,71.3111773355981882,44.9347323991438827]},"#9944cc":{"lch":[45.9974464532923903,93.3382836250318206,286.486143775676851],"luv":[45.9974464532923903,26.4878609436744341,-89.5009967134190561],"rgb":[0.6,0.266666666666666663,0.8],"xyz":[0.261015311177463349,0.152667797029515689,0.587005175532278267],"hpluv":[286.486143775676851,257.492992496327645,45.9974464532923903],"hsluv":[286.486143775676851,74.2376853125076792,45.9974464532923903]},"#9944dd":{"lch":[47.1413389271288139,104.350309752399141,282.717215233582351],"luv":[47.1413389271288139,22.9716047676972792,-101.790434323753402],"rgb":[0.6,0.266666666666666663,0.866666666666666696],"xyz":[0.282533636728096949,0.161275127249769223,0.700335023432284265],"hpluv":[282.717215233582351,280.886686990529654,47.1413389271288139],"hsluv":[282.717215233582351,78.691216526215527,47.1413389271288139]},"#9944ee":{"lch":[48.3606780479664593,115.341161543855208,279.855683836472622],"luv":[48.3606780479664593,19.7426125181249787,-113.638958096441911],"rgb":[0.6,0.266666666666666663,0.933333333333333348],"xyz":[0.306345816994271658,0.170799999356239268,0.825745839500807488],"hpluv":[279.855683836472622,302.643440789384783,48.3606780479664593],"hsluv":[279.855683836472622,89.2619995530309325,48.3606780479664593]},"#9944ff":{"lch":[49.6495929972458185,126.19285787586071,277.642335930208503],"luv":[49.6495929972458185,16.7822322716138856,-125.071955525044785],"rgb":[0.6,0.266666666666666663,1],"xyz":[0.332516865404103079,0.181268418720171964,0.963580027792589333],"hpluv":[277.642335930208503,322.521305960549284,49.6495929972458185],"hsluv":[277.642335930208503,99.9999999999991616,49.6495929972458185]},"#bb4400":{"lch":[45.2216387767487547,104.837609625168909,21.4216552556228201],"luv":[45.2216387767487547,97.5952013308911,38.2896992558330354],"rgb":[0.733333333333333282,0.266666666666666663,0],"xyz":[0.225600911582447911,0.147007971189842435,0.0164962271638749],"hpluv":[21.4216552556228201,294.177965476355098,45.2216387767487547],"hsluv":[21.4216552556228201,100.000000000002373,45.2216387767487547]},"#bb4411":{"lch":[45.2777618800582076,103.283777149094803,20.576768268141489],"luv":[45.2777618800582076,96.6944911384892123,36.3003306548646947],"rgb":[0.733333333333333282,0.266666666666666663,0.0666666666666666657],"xyz":[0.226612577082085043,0.147412637389697287,0.0218243321286305317],"hpluv":[20.576768268141489,289.458620037032802,45.2777618800582076],"hsluv":[20.576768268141489,95.6967439910137614,45.2777618800582076]},"#bb4422":{"lch":[45.3815280810129238,100.53232916519147,18.9799525675269258],"luv":[45.3815280810129238,95.0666309197234,32.6968636561903381],"rgb":[0.733333333333333282,0.266666666666666663,0.133333333333333331],"xyz":[0.228487935220562044,0.148162780645088116,0.0317012183246097243],"hpluv":[18.9799525675269258,281.103307599105051,45.3815280810129238],"hsluv":[18.9799525675269258,87.925891065222288,45.3815280810129238]},"#bb4433":{"lch":[45.5516172521931111,96.3559005693685862,16.2666991179303722],"luv":[45.5516172521931111,92.4986058403436147,26.9901369416087924],"rgb":[0.733333333333333282,0.266666666666666663,0.2],"xyz":[0.231575685953019805,0.149397880938071215,0.0479633721822208675],"hpluv":[16.2666991179303722,268.419362556396,45.5516172521931111],"hsluv":[16.2666991179303722,75.6846484949249572,45.5516172521931111]},"#bb4444":{"lch":[45.7955406359936816,91.066890863790789,12.177050630061844],"luv":[45.7955406359936816,89.0179277419259734,19.2090382927107299],"rgb":[0.733333333333333282,0.266666666666666663,0.266666666666666663],"xyz":[0.236033681197238665,0.151181079035758809,0.0714421471351075],"hpluv":[12.177050630061844,252.334507458167678,45.7955406359936816],"hsluv":[12.177050630061844,59.1297963696904461,45.7955406359936816]},"#bb4455":{"lch":[46.1187996938414813,85.2741675307746,6.43569277192082279],"luv":[46.1187996938414813,84.7367941199702273,9.55820957796975],"rgb":[0.733333333333333282,0.266666666666666663,0.333333333333333315],"xyz":[0.24199609523660065,0.153566044651503641,0.102844194409081421],"hpluv":[6.43569277192082279,234.627449284537505,46.1187996938414813],"hsluv":[6.43569277192082279,61.0765315010866274,46.1187996938414813]},"#bb4466":{"lch":[46.5252276318027427,79.8426568240615637,358.82639812637143],"luv":[46.5252276318027427,79.8259079304732779,-1.63532009113408461],"rgb":[0.733333333333333282,0.266666666666666663,0.4],"xyz":[0.249581091010108835,0.156600042960906932,0.142791838816225369],"hpluv":[358.82639812637143,217.763856882437722,46.5252276318027427],"hsluv":[358.82639812637143,63.3003300169989842,46.5252276318027427]},"#bb4477":{"lch":[47.0171837667790697,75.785442181693,349.367581794189107],"luv":[47.0171837667790697,74.484290362097866,-13.9829802234512588],"rgb":[0.733333333333333282,0.266666666666666663,0.466666666666666674],"xyz":[0.258895104030310741,0.160325648168987756,0.191845640722623278],"hpluv":[349.367581794189107,204.535408840651428,47.0171837667790697],"hsluv":[349.367581794189107,65.7062458495858266,47.0171837667790697]},"#bb4488":{"lch":[47.5956997014540235,74.0450948660102,338.538246495536782],"luv":[47.5956997014540235,68.9109568360576219,-27.0916241974425098],"rgb":[0.733333333333333282,0.266666666666666663,0.533333333333333326],"xyz":[0.270035521132254597,0.164781815009765353,0.250518504126195474],"hpluv":[338.538246495536782,197.409434601059019,47.5956997014540235],"hsluv":[338.538246495536782,68.1997676790361,47.5956997014540235]},"#bb4499":{"lch":[48.2606154557730633,75.1911240047971,327.313188255720945],"luv":[48.2606154557730633,63.2834900243205496,-40.6067115074158309],"rgb":[0.733333333333333282,0.266666666666666663,0.6],"xyz":[0.283092485241327296,0.170004600653394511,0.319285181767313353],"hpluv":[327.313188255720945,197.702903480158483,48.2606154557730633],"hsluv":[327.313188255720945,70.6969578310621074,48.2606154557730633]},"#bb44aa":{"lch":[49.0107199856960278,79.2228796099941093,316.794363507436401],"luv":[49.0107199856960278,57.7456584584256944,-54.2374739723603838],"rgb":[0.733333333333333282,0.266666666666666663,0.66666666666666663],"xyz":[0.298150178206579852,0.176027677839495605,0.398589031384311954],"hpluv":[316.794363507436401,205.115683333718124,49.0107199856960278],"hsluv":[316.794363507436401,73.1302855273877128,49.0107199856960278]},"#bb44bb":{"lch":[49.8438993628519427,85.6636869410227746,307.715012949243942],"luv":[49.8438993628519427,52.4034189799077268,-67.7653963284049752],"rgb":[0.733333333333333282,0.266666666666666663,0.733333333333333282],"xyz":[0.315287770313916471,0.182882714682430364,0.4888470164829537],"hpluv":[307.715012949243942,218.084137693810391,49.8438993628519427],"hsluv":[307.715012949243942,75.450469608388417,49.8438993628519427]},"#bb44cc":{"lch":[50.757290285110841,93.8478600934752905,300.284565440631638],"luv":[50.757290285110841,47.3270085455435918,-81.0405769121528152],"rgb":[0.733333333333333282,0.266666666666666663,0.8],"xyz":[0.334580145757638225,0.190599664859919166,0.590453527153223856],"hpluv":[300.284565440631638,234.620130462749955,50.757290285110841],"hsluv":[300.284565440631638,77.6254237907312898,50.757290285110841]},"#bb44dd":{"lch":[51.7474340276366291,103.158361374368454,294.364201848969515],"luv":[51.7474340276366291,42.5564715489483518,-93.971241615445],"rgb":[0.733333333333333282,0.266666666666666663,0.866666666666666696],"xyz":[0.356098471308271769,0.1992069950801727,0.703783375053229854],"hpluv":[294.364201848969515,252.961799427415912,51.7474340276366291],"hsluv":[294.364201848969515,79.6375689955678467,51.7474340276366291]},"#bb44ee":{"lch":[52.8104252671910217,113.122924260907325,289.686672533024307],"luv":[52.8104252671910217,38.1084271425454304,-106.510768347901248],"rgb":[0.733333333333333282,0.266666666666666663,0.933333333333333348],"xyz":[0.379910651574446478,0.208731867186642744,0.829194191121753077],"hpluv":[289.686672533024307,271.813038246621943,52.8104252671910217],"hsluv":[289.686672533024307,87.7449679178180872,52.8104252671910217]},"#bb44ff":{"lch":[53.942050711908152,123.415863319803691,285.982908620336502],"luv":[53.942050711908152,33.9826318144238115,-118.645084406973112],"rgb":[0.733333333333333282,0.266666666666666663,1],"xyz":[0.4060816999842779,0.219200286550575441,0.967028379413534922],"hpluv":[285.982908620336502,290.323946696930363,53.942050711908152],"hsluv":[285.982908620336502,99.9999999999990621,53.942050711908152]},"#995500":{"lch":[43.167672396478018,69.2675138179999,36.3951762413548678],"luv":[43.167672396478018,55.7564526526882105,41.099956911356287],"rgb":[0.6,0.333333333333333315,0],"xyz":[0.163849333716619028,0.132702616788131222,0.0169856277810444857],"hpluv":[36.3951762413548678,203.615246511519132,43.167672396478018],"hsluv":[36.3951762413548678,100.000000000002288,43.167672396478018]},"#995511":{"lch":[43.2277537555276865,67.4837391190291385,35.2266717066771307],"luv":[43.2277537555276865,55.1258789529511333,38.9254738590266101],"rgb":[0.6,0.333333333333333315,0.0666666666666666657],"xyz":[0.16486099921625616,0.133107282987986075,0.0223137327458001189],"hpluv":[35.2266717066771307,198.096040704981476,43.2277537555276865],"hsluv":[35.2266717066771307,95.1659583326808303,43.2277537555276865]},"#995522":{"lch":[43.3388072781739,64.3407602415628475,32.9528815923873708],"luv":[43.3388072781739,53.9895016234129059,34.998101990218963],"rgb":[0.6,0.333333333333333315,0.133333333333333331],"xyz":[0.166736357354733161,0.133857426243376904,0.0321906189417793115],"hpluv":[32.9528815923873708,188.385971738918272,43.3388072781739],"hsluv":[32.9528815923873708,86.4646465379692302,43.3388072781739]},"#995533":{"lch":[43.5207548807750584,59.6262244551406582,28.8908620435756234],"luv":[43.5207548807750584,52.2052395636471,28.8079781462883915],"rgb":[0.6,0.333333333333333315,0.2],"xyz":[0.169824108087190895,0.13509252653636,0.0484527727993904617],"hpluv":[28.8908620435756234,173.852210644027934,43.5207548807750584],"hsluv":[28.8908620435756234,72.8304069554253601,43.5207548807750584]},"#995544":{"lch":[43.7814988718974831,53.8284560366537335,22.2989672577237812],"luv":[43.7814988718974831,49.8029788080235036,20.4246415179685634],"rgb":[0.6,0.333333333333333315,0.266666666666666663],"xyz":[0.174282103331409782,0.136875724634047596,0.0719315477522771],"hpluv":[22.2989672577237812,156.01294104827457,43.7814988718974831],"hsluv":[22.2989672577237812,54.5318604429391058,43.7814988718974831]},"#995555":{"lch":[44.1267187000120629,47.9518139182857226,12.1770506300620411],"luv":[44.1267187000120629,46.8729201797035,10.1146335514957979],"rgb":[0.6,0.333333333333333315,0.333333333333333315],"xyz":[0.180244517370771795,0.139260690249792429,0.103333595026251],"hpluv":[12.1770506300620411,137.893162706519348,44.1267187000120629],"hsluv":[12.1770506300620411,32.3126421104369754,44.1267187000120629]},"#995566":{"lch":[44.5602350881765048,43.578232165907,357.727809148728397],"luv":[44.5602350881765048,43.5439690351937116,-1.72773822316436432],"rgb":[0.6,0.333333333333333315,0.4],"xyz":[0.187829513144279953,0.14229468855919572,0.143281239433394963],"hpluv":[357.727809148728397,124.097051059849122,44.5602350881765048],"hsluv":[357.727809148728397,36.5660257696708157,44.5602350881765048]},"#995577":{"lch":[45.0842241078155226,42.5628566452735342,339.858530865537546],"luv":[45.0842241078155226,39.9599368331855729,-14.6560640723873874],"rgb":[0.6,0.333333333333333315,0.466666666666666674],"xyz":[0.197143526164481886,0.146020293767276543,0.192335041339792873],"hpluv":[339.858530865537546,119.796876557388956,45.0842241078155226],"hsluv":[339.858530865537546,41.1101378179314167,45.0842241078155226]},"#995588":{"lch":[45.699386409692309,45.957423726275,322.088602167082399],"luv":[45.699386409692309,36.2586549471185506,-28.2381787122006145],"rgb":[0.6,0.333333333333333315,0.533333333333333326],"xyz":[0.208283943266425686,0.150476460608054141,0.25100790474336504],"hpluv":[322.088602167082399,127.609977655436467,45.699386409692309],"hsluv":[322.088602167082399,45.7577454208568852,45.699386409692309]},"#995599":{"lch":[46.4051108942887964,53.2218555896971921,307.715012949244795],"luv":[46.4051108942887964,32.5576366947089113,-42.1018551285561102],"rgb":[0.6,0.333333333333333315,0.6],"xyz":[0.221340907375498414,0.155699246251683299,0.319774582384483],"hpluv":[307.715012949244795,145.533684272522947,46.4051108942887964],"hsluv":[307.715012949244795,50.3502223422482516,46.4051108942887964]},"#9955aa":{"lch":[47.1996461355186625,63.0010233462712037,297.353030705211779],"luv":[47.1996461355186625,28.9471952899390068,-55.9570266143899246],"rgb":[0.6,0.333333333333333315,0.66666666666666663],"xyz":[0.236398600340750942,0.161722323437784393,0.399078432001481576],"hpluv":[297.353030705211779,169.374563019623821,47.1996461355186625],"hsluv":[297.353030705211779,54.7667714505238337,47.1996461355186625]},"#9955bb":{"lch":[48.0802807126223541,74.1194144420538,290.114722102094788],"luv":[48.0802807126223541,25.4897394646759068,-69.5985688017783701],"rgb":[0.6,0.333333333333333315,0.733333333333333282],"xyz":[0.253536192448087616,0.168577360280719152,0.489336417100123322],"hpluv":[290.114722102094788,195.615971831826613,48.0802807126223541],"hsluv":[290.114722102094788,58.9252289891592866,48.0802807126223541]},"#9955cc":{"lch":[49.0435277691913,85.8237639836856658,285.007043429489613],"luv":[49.0435277691913,22.2230153813451068,-82.8966588692685491],"rgb":[0.6,0.333333333333333315,0.8],"xyz":[0.272828567891809315,0.176294310458207953,0.590942927770393478],"hpluv":[285.007043429489613,222.057364979540267,49.0435277691913],"hsluv":[285.007043429489613,65.256702758776143,49.0435277691913]},"#9955dd":{"lch":[50.0853068419578875,97.6800340866365104,281.315028513382344],"luv":[50.0853068419578875,19.1651498984824649,-95.7814496055220843],"rgb":[0.6,0.333333333333333315,0.866666666666666696],"xyz":[0.294346893442442914,0.184901640678461487,0.704272775670399476],"hpluv":[281.315028513382344,247.476970093373268,50.0853068419578875],"hsluv":[281.315028513382344,76.6956878028438638,50.0853068419578875]},"#9955ee":{"lch":[51.2011159126469266,109.450459224116145,278.575243894560685],"luv":[51.2011159126469266,16.3199513369978568,-108.226901520499666],"rgb":[0.6,0.333333333333333315,0.933333333333333348],"xyz":[0.318159073708617623,0.194426512784931532,0.829683591738922699],"hpluv":[278.575243894560685,271.254835109068836,51.2011159126469266],"hsluv":[278.575243894560685,88.2491190723243335,51.2011159126469266]},"#9955ff":{"lch":[52.3861878346365444,121.012399839465246,276.491711029928183],"luv":[52.3861878346365444,13.6815981187824764,-120.2364952409323],"rgb":[0.6,0.333333333333333315,1],"xyz":[0.344330122118449045,0.204894932148864228,0.967517780030704544],"hpluv":[276.491711029928183,293.124692446110771,52.3861878346365444],"hsluv":[276.491711029928183,99.9999999999991,52.3861878346365444]},"#bb5500":{"lch":[48.3398816318057811,94.9450628471467724,27.1627331553413143],"luv":[48.3398816318057811,84.4739036935134,43.344256295703957],"rgb":[0.733333333333333282,0.333333333333333315,0],"xyz":[0.237414168296793876,0.170634484618534699,0.0204339794019901093],"hpluv":[27.1627331553413143,249.233335779464397,48.3398816318057811],"hsluv":[27.1627331553413143,100.000000000002217,48.3398816318057811]},"#bb5511":{"lch":[48.3907029738951735,93.4795954244126364,26.3417432533787057],"luv":[48.3907029738951735,83.7729911103365907,41.4791600823755289],"rgb":[0.733333333333333282,0.333333333333333315,0.0666666666666666657],"xyz":[0.238425833796431,0.171039150818389551,0.0257620843667457425],"hpluv":[26.3417432533787057,245.128732426237889,48.3907029738951735],"hsluv":[26.3417432533787057,96.2613278044251786,48.3907029738951735]},"#bb5522":{"lch":[48.4847005727335869,90.8707197847641623,24.7826102649670759],"luv":[48.4847005727335869,82.5019575685759321,38.090874386840035],"rgb":[0.733333333333333282,0.333333333333333315,0.133333333333333331],"xyz":[0.240301191934908,0.17178929407378038,0.0356389705627249351],"hpluv":[24.7826102649670759,237.825586669453713,48.4847005727335869],"hsluv":[24.7826102649670759,89.48684037186257,48.4847005727335869]},"#bb5533":{"lch":[48.6388719159228629,86.8743588299812473,22.1104535643633149],"luv":[48.6388719159228629,80.4856161939384407,32.6989267102511363],"rgb":[0.733333333333333282,0.333333333333333315,0.2],"xyz":[0.243388942667365771,0.173024394366763479,0.0519011244203360783],"hpluv":[22.1104535643633149,226.64567974804504,48.6388719159228629],"hsluv":[22.1104535643633149,78.7542493880857393,48.6388719159228629]},"#bb5544":{"lch":[48.8601705631915,81.7431600256382751,18.0266646696809296],"luv":[48.8601705631915,77.730600917119915,25.2962031151029265],"rgb":[0.733333333333333282,0.333333333333333315,0.266666666666666663],"xyz":[0.24784693791158463,0.174807592464451073,0.0753798993732227168],"hpluv":[18.0266646696809296,212.293047020031764,48.8601705631915],"hsluv":[18.0266646696809296,64.1199207289341,48.8601705631915]},"#bb5555":{"lch":[49.1538097277392154,76.0172073873862075,12.1770506300619399],"luv":[49.1538097277392154,74.3068552156307,16.0345591439297159],"rgb":[0.733333333333333282,0.333333333333333315,0.333333333333333315],"xyz":[0.253809351950946616,0.177192558080195905,0.106781946647196632],"hpluv":[12.1770506300619399,196.242945408672853,49.1538097277392154],"hsluv":[12.1770506300619399,45.9858047870319879,49.1538097277392154]},"#bb5566":{"lch":[49.523574907380123,70.5220596563995,4.21567942747197],"luv":[49.523574907380123,70.3312550088346882,5.18415538569556134],"rgb":[0.733333333333333282,0.333333333333333315,0.4],"xyz":[0.261394347724454801,0.180226556389599196,0.14672959105434058],"hpluv":[4.21567942747197,180.697576197923894,49.523574907380123],"hsluv":[4.21567942747197,48.7291682320237527,49.523574907380123]},"#bb5577":{"lch":[49.971995559373525,66.3094111666939341,354.014227306533371],"luv":[49.971995559373525,65.9478803557508257,-6.91484532417379327],"rgb":[0.733333333333333282,0.333333333333333315,0.466666666666666674],"xyz":[0.270708360744656706,0.18395216159768002,0.195783392960738489],"hpluv":[354.014227306533371,168.378953180241098,49.971995559373525],"hsluv":[354.014227306533371,51.7390719561838495,49.971995559373525]},"#bb5588":{"lch":[50.5004659153875508,64.4571905510646275,342.016521446261379],"luv":[50.5004659153875508,61.308172080607541,-19.9006896832966476],"rgb":[0.733333333333333282,0.333333333333333315,0.533333333333333326],"xyz":[0.281848777846600562,0.188408328438457617,0.254456256364310685],"hpluv":[342.016521446261379,161.962814057843559,50.5004659153875508],"hsluv":[342.016521446261379,54.9055054808170055,50.5004659153875508]},"#bb5599":{"lch":[51.1093507584050286,65.6961991151429459,329.411862939203161],"luv":[51.1093507584050286,56.5544024759803,-33.4303774845774342],"rgb":[0.733333333333333282,0.333333333333333315,0.6],"xyz":[0.294905741955673262,0.193631114082086775,0.323222934005428564],"hpluv":[329.411862939203161,163.109481188372769,51.1093507584050286],"hsluv":[329.411862939203161,58.1255686218068561,51.1093507584050286]},"#bb55aa":{"lch":[51.7980911374347386,70.0901192661774246,317.660759061539352],"luv":[51.7980911374347386,51.8085124997667563,-47.2070212077450151],"rgb":[0.733333333333333282,0.333333333333333315,0.66666666666666663],"xyz":[0.309963434920925818,0.199654191268187869,0.402526783622427164],"hpluv":[317.660759061539352,171.704773930815691,51.7980911374347386],"hsluv":[317.660759061539352,61.3115173935257403,51.7980911374347386]},"#bb55bb":{"lch":[52.5653152299933737,77.1031380177621344,307.715012949244226],"luv":[52.5653152299933737,47.1666372355911179,-60.9934605025180332],"rgb":[0.733333333333333282,0.333333333333333315,0.733333333333333282],"xyz":[0.327101027028262437,0.206509228111122628,0.492784768721068911],"hpluv":[307.715012949244226,186.128169856082764,52.5653152299933737],"hsluv":[307.715012949244226,64.3946779967479,52.5653152299933737]},"#bb55cc":{"lch":[53.4089544864585,85.9678373228364308,299.780474196008072],"luv":[53.4089544864585,42.6983512805399883,-74.6144748148057175],"rgb":[0.733333333333333282,0.333333333333333315,0.8],"xyz":[0.346393402471984191,0.21422617828861143,0.594391279391339067],"hpluv":[299.780474196008072,204.249617293250537,53.4089544864585],"hsluv":[299.780474196008072,67.3259326792693855,53.4089544864585]},"#bb55dd":{"lch":[54.3263625650166944,95.9883710948233926,293.613183872979789],"luv":[54.3263625650166944,38.4490902963257213,-87.9513208588848698],"rgb":[0.733333333333333282,0.333333333333333315,0.866666666666666696],"xyz":[0.367911728022617734,0.222833508508864964,0.707721127291345065],"hpluv":[293.613183872979789,224.206046477737118,54.3263625650166944],"hsluv":[293.613183872979789,73.8407928406032283,54.3263625650166944]},"#bb55ee":{"lch":[55.314433433552054,106.647677925948784,288.842761327535072],"luv":[55.314433433552054,34.444226028074695,-100.932266893812525],"rgb":[0.733333333333333282,0.333333333333333315,0.933333333333333348],"xyz":[0.391723908288792444,0.232358380615335,0.833131943359868288],"hpluv":[288.842761327535072,244.653966901481454,55.314433433552054],"hsluv":[288.842761327535072,86.7715876359309135,55.314433433552054]},"#bb55ff":{"lch":[56.3697148536960526,117.598184211748716,285.129655441003138],"luv":[56.3697148536960526,30.6936185759692179,-113.521956944959783],"rgb":[0.733333333333333282,0.333333333333333315,1],"xyz":[0.417894956698623865,0.242826799979267705,0.970966131651650133],"hpluv":[285.129655441003138,264.724480425834031,56.3697148536960526],"hsluv":[285.129655441003138,99.9999999999989,56.3697148536960526]},"#996600":{"lch":[47.3343652017352454,63.4240894393546952,48.3260196362919672],"luv":[47.3343652017352454,42.1701199842588,47.3740023823666476],"rgb":[0.6,0.4,0],"xyz":[0.178877391422465504,0.162758732199824563,0.0219949803496598331],"hpluv":[48.3260196362919672,170.026654750900292,47.3343652017352454],"hsluv":[48.3260196362919672,100.000000000002288,47.3343652017352454]},"#996611":{"lch":[47.3868110627231189,61.667674323653,47.4017350737566616],"luv":[47.3868110627231189,41.7399921999205,45.3946594616449133],"rgb":[0.6,0.4,0.0666666666666666657],"xyz":[0.179889056922102636,0.163163398399679416,0.0273230853144154628],"hpluv":[47.4017350737566616,165.135107398016657,47.3868110627231189],"hsluv":[47.4017350737566616,96.0239926064661,47.3868110627231189]},"#996622":{"lch":[47.4838028017404099,58.5263777304533406,45.5834379771503322],"luv":[47.4838028017404099,40.9608465044279413,41.8036594557031336],"rgb":[0.6,0.4,0.133333333333333331],"xyz":[0.181764415060579637,0.163913541655070244,0.0371999715103946624],"hpluv":[45.5834379771503322,156.40314428015364,47.4838028017404099],"hsluv":[45.5834379771503322,88.8298219708016177,47.4838028017404099]},"#996633":{"lch":[47.642855645786625,53.6803525088045674,42.2629253198225712],"luv":[47.642855645786625,39.7270268335614887,36.1018501525199724],"rgb":[0.6,0.4,0.2],"xyz":[0.184852165793037371,0.165148641948053343,0.0534621253680058056],"hpluv":[42.2629253198225712,142.973945144987511,47.642855645786625],"hsluv":[42.2629253198225712,77.4596172761956865,47.642855645786625]},"#996644":{"lch":[47.8710980897590872,47.4159845831850149,36.6424092143452071],"luv":[47.8710980897590872,38.045445264132745,28.298757722676072],"rgb":[0.6,0.4,0.266666666666666663],"xyz":[0.189310161037256258,0.166931840045740937,0.0769409003208924441],"hpluv":[36.6424092143452071,125.687101185572914,47.8710980897590872],"hsluv":[36.6424092143452071,62.0095295256686185,47.8710980897590872]},"#996655":{"lch":[48.173837669734425,40.4765536471140521,27.3183313201514686],"luv":[48.173837669734425,35.9622216701857838,18.5760600691352664],"rgb":[0.6,0.4,0.333333333333333315],"xyz":[0.195272575076618271,0.16931680566148577,0.108342947594866346],"hpluv":[27.3183313201514686,106.618264590322553,48.173837669734425],"hsluv":[27.3183313201514686,42.9499413016611484,48.173837669734425]},"#996666":{"lch":[48.5548823199147819,34.3240193245421,12.1770506300621335],"luv":[48.5548823199147819,33.551744690774747,7.24007809326721219],"rgb":[0.6,0.4,0.4],"xyz":[0.202857570850126429,0.17235080397088906,0.148290592002010307],"hpluv":[12.1770506300621335,89.702502372613651,48.5548823199147819],"hsluv":[12.1770506300621335,21.0200766933302461,48.5548823199147819]},"#996677":{"lch":[49.0167186013709,31.3606600839303482,350.2076113500313],"luv":[49.0167186013709,30.9037509766054157,-5.33377694282222681],"rgb":[0.6,0.4,0.466666666666666674],"xyz":[0.212171583870328362,0.176076409178969884,0.197344393908408217],"hpluv":[350.2076113500313,81.185839798992177,49.0167186013709],"hsluv":[350.2076113500313,25.8881256225468483,49.0167186013709]},"#996688":{"lch":[49.5606396668562752,33.7929953796712823,326.289263208678278],"luv":[49.5606396668562752,28.1107077320421368,-18.7551232343109682],"rgb":[0.6,0.4,0.533333333333333326],"xyz":[0.223312000972272162,0.180532576019747482,0.256017257311980384],"hpluv":[326.289263208678278,86.5225105267045365,49.5606396668562752],"hsluv":[326.289263208678278,30.9767265160446463,49.5606396668562752]},"#996699":{"lch":[50.1868595811773304,41.2886932006772,307.715012949245818],"luv":[50.1868595811773304,25.2577114783499113,-32.6619686653465351],"rgb":[0.6,0.4,0.6],"xyz":[0.236368965081344889,0.185755361663376639,0.324783934953098319],"hpluv":[307.715012949245818,104.395179003902854,50.1868595811773304],"hsluv":[307.715012949245818,36.1175524455388413,50.1868595811773304]},"#9966aa":{"lch":[50.8946289106688141,51.8448774557822,295.617938374847199],"luv":[50.8946289106688141,22.4160699516755599,-46.7483810021979451],"rgb":[0.6,0.4,0.66666666666666663],"xyz":[0.251426658046597418,0.191778438849477734,0.40408778457009692],"hpluv":[295.617938374847199,129.262701065701,50.8946289106688141],"hsluv":[295.617938374847199,41.1705422178494445,50.8946289106688141]},"#9966bb":{"lch":[51.6823563026294,63.8712345518136,287.908782454232437],"luv":[51.6823563026294,19.6405628457828776,-60.776499523036378],"rgb":[0.6,0.4,0.733333333333333282],"xyz":[0.268564250153934092,0.198633475692412492,0.494345769668738666],"hpluv":[287.908782454232437,156.820318415219759,51.6823563026294],"hsluv":[287.908782454232437,49.349420166275209,51.6823563026294]},"#9966cc":{"lch":[52.5477355185796569,76.4825896496335389,282.819195018988751],"luv":[52.5477355185796569,16.9695880464031816,-74.5762670093482285],"rgb":[0.6,0.4,0.8],"xyz":[0.287856625597655791,0.206350425869901294,0.595952280339008822],"hpluv":[282.819195018988751,184.691924030055,52.5477355185796569],"hsluv":[282.819195018988751,61.7185051859638136,52.5477355185796569]},"#9966dd":{"lch":[53.4878747475352725,89.2117449852098758,279.306611445978092],"luv":[53.4878747475352725,14.4271177471338046,-88.0374563286358],"rgb":[0.6,0.4,0.866666666666666696],"xyz":[0.30937495114828939,0.214957756090154828,0.70928212823901482],"hpluv":[279.306611445978092,211.644028054176175,53.4878747475352725],"hsluv":[279.306611445978092,74.2596178074049362,53.4878747475352725]},"#9966ee":{"lch":[54.4994239962059339,101.810849438236403,276.783380903602506],"luv":[54.4994239962059339,12.0254847729914225,-101.098154183495325],"rgb":[0.6,0.4,0.933333333333333348],"xyz":[0.333187131414464099,0.224482628196624873,0.834692944307538],"hpluv":[276.783380903602506,237.050827216632513,54.4994239962059339],"hsluv":[276.783380903602506,86.9990828065156734,54.4994239962059339]},"#9966ff":{"lch":[55.5786963614876,114.151421142661491,274.908981870437117],"luv":[55.5786963614876,9.76829238934238475,-113.732701597586171],"rgb":[0.6,0.4,1],"xyz":[0.359358179824295521,0.234951047560557569,0.972527132599319888],"hpluv":[274.908981870437117,260.622732185953453,55.5786963614876],"hsluv":[274.908981870437117,99.999999999998991,55.5786963614876]},"#bb6600":{"lch":[51.9152024616159622,85.9194467179265899,34.7713476038742],"luv":[51.9152024616159622,70.5771984524152884,49.0001059480794936],"rgb":[0.733333333333333282,0.4,0],"xyz":[0.252442226002640324,0.200690600030228039,0.0254433319706054567],"hpluv":[34.7713476038742,210.008196913669821,51.9152024616159622],"hsluv":[34.7713476038742,100.000000000002217,51.9152024616159622]},"#bb6611":{"lch":[51.960819173128,84.5067938711160735,34.0102696578751846],"luv":[51.960819173128,70.0508360673827184,47.2681560528436],"rgb":[0.733333333333333282,0.4,0.0666666666666666657],"xyz":[0.253453891502277429,0.201095266230082892,0.0307714369353610864],"hpluv":[34.0102696578751846,206.373990798532162,51.960819173128],"hsluv":[34.0102696578751846,96.7960731817087492,51.960819173128]},"#bb6622":{"lch":[52.0452187907305586,81.9745670334704215,32.5563816919222901],"luv":[52.0452187907305586,69.0932729256005587,44.1129150788451909],"rgb":[0.733333333333333282,0.4,0.133333333333333331],"xyz":[0.255329249640754485,0.20184540948547372,0.040648323131340286],"hpluv":[32.5563816919222901,199.865401092535734,52.0452187907305586],"hsluv":[32.5563816919222901,90.9716633106406221,52.0452187907305586]},"#bb6633":{"lch":[52.1837271506259412,78.04817012610809,30.0375791414029081],"luv":[52.1837271506259412,67.5660884046363,39.0684086920722109],"rgb":[0.733333333333333282,0.4,0.2],"xyz":[0.258417000373212191,0.203080509778456819,0.0569104769889514292],"hpluv":[30.0375791414029081,189.787216830323956,52.1837271506259412],"hsluv":[30.0375791414029081,81.6941023093515639,52.1837271506259412]},"#bb6644":{"lch":[52.3827138306128859,72.9081368603095257,26.1184165145312406],"luv":[52.3827138306128859,65.4632041398932,32.0961886238895318],"rgb":[0.733333333333333282,0.4,0.266666666666666663],"xyz":[0.262874995617431106,0.204863707876144413,0.0803892519418380747],"hpluv":[26.1184165145312406,176.614896915735159,52.3827138306128859],"hsluv":[26.1184165145312406,68.9437006343278824,52.3827138306128859]},"#bb6655":{"lch":[52.6470547760809637,67.004522830646,20.3474245095699864],"luv":[52.6470547760809637,62.823537757634746,23.2982656731697979],"rgb":[0.733333333333333282,0.4,0.333333333333333315],"xyz":[0.268837409656793092,0.207248673491889246,0.111791299215811976],"hpluv":[20.3474245095699864,161.498824171429789,52.6470547760809637],"hsluv":[20.3474245095699864,52.9816895309479534,52.6470547760809637]},"#bb6666":{"lch":[52.9804174131186727,61.0960132663801261,12.1770506300620109],"luv":[52.9804174131186727,59.7213810933874498,12.8871826767560087],"rgb":[0.733333333333333282,0.4,0.4],"xyz":[0.276422405430301277,0.210282671801292537,0.151738943622955924],"hpluv":[12.1770506300620109,146.331162504643544,52.9804174131186727],"hsluv":[12.1770506300620109,34.2899270044314335,52.9804174131186727]},"#bb6677":{"lch":[53.3854132757716826,56.2661599102721226,1.17050216666979279],"luv":[53.3854132757716826,56.2544190111897535,1.14938799445880213],"rgb":[0.733333333333333282,0.4,0.466666666666666674],"xyz":[0.285736418450503182,0.21400827700937336,0.200792745529353833],"hpluv":[1.17050216666979279,133.74082367080041,53.3854132757716826],"hsluv":[1.17050216666979279,37.694842795415525,53.3854132757716826]},"#bb6688":{"lch":[53.8636991644475387,53.7950791600554297,347.554026547444039],"luv":[53.8636991644475387,52.5308766640911458,-11.5938578022448873],"rgb":[0.733333333333333282,0.4,0.533333333333333326],"xyz":[0.296876835552447,0.218464443850150958,0.259465608932926028],"hpluv":[347.554026547444039,126.731828674836166,53.8636991644475387],"hsluv":[347.554026547444039,41.3310399817098855,53.8636991644475387]},"#bb6699":{"lch":[54.4160596975863484,54.7145736516266723,332.78581188167891],"luv":[54.4160596975863484,48.6578429809048814,-25.0219680745716886],"rgb":[0.733333333333333282,0.4,0.6],"xyz":[0.309933799661519682,0.223687229493780115,0.328232286574043908],"hpluv":[332.78581188167891,127.589593839900076,54.4160596975863484],"hsluv":[332.78581188167891,45.0871489409768813,54.4160596975863484]},"#bb66aa":{"lch":[55.0424859024436,59.2427277394444332,319.03138367428437],"luv":[55.0424859024436,44.7323366642012274,-38.8422301956323963],"rgb":[0.733333333333333282,0.4,0.66666666666666663],"xyz":[0.324991492626772238,0.22971030667988121,0.407536136191042508],"hpluv":[319.03138367428437,136.57661144398341,55.0424859024436],"hsluv":[319.03138367428437,48.8627280546895548,55.0424859024436]},"#bb66bb":{"lch":[55.7422560614222,66.7541112543564168,307.715012949244738],"luv":[55.7422560614222,40.8357821803987235,-52.8067255477370452],"rgb":[0.733333333333333282,0.4,0.733333333333333282],"xyz":[0.342129084734108913,0.236565343522815968,0.497794121289684255],"hpluv":[307.715012949244738,151.961230908585406,55.7422560614222],"hsluv":[307.715012949244738,52.5739577191036176,55.7422560614222]},"#bb66cc":{"lch":[56.5140206008290704,76.3075420390205466,299.031845144425],"luv":[56.5140206008290704,37.0317190732607671,-66.7195080506142801],"rgb":[0.733333333333333282,0.4,0.8],"xyz":[0.361421460177830611,0.24428229370030477,0.599400631959954411],"hpluv":[299.031845144425,171.336773989457299,56.5140206008290704],"hsluv":[299.031845144425,57.7422914315118732,56.5140206008290704]},"#bb66dd":{"lch":[57.3558903641351208,87.0819801731049523,292.529347086481266],"luv":[57.3558903641351208,33.3660351201831276,-80.4361794917420809],"rgb":[0.733333333333333282,0.4,0.866666666666666696],"xyz":[0.38293978572846421,0.252889623920558304,0.712730479859960409],"hpluv":[292.529347086481266,192.659130793538424,57.3558903641351208],"hsluv":[292.529347086481266,71.4699790991907,57.3558903641351208]},"#bb66ee":{"lch":[58.2655263288606164,98.4965661150924916,287.652756970849339],"luv":[58.2655263288606164,29.8688319231142287,-93.8585447149780805],"rgb":[0.733333333333333282,0.4,0.933333333333333348],"xyz":[0.40675196599463892,0.262414496027028321,0.838141295928483632],"hpluv":[287.652756970849339,214.510592558062115,58.2655263288606164],"hsluv":[287.652756970849339,85.5420625539119186,58.2655263288606164]},"#bb66ff":{"lch":[59.2402283004695533,110.175409569553764,283.948158265715847],"luv":[59.2402283004695533,26.5571064878979755,-106.926801919861816],"rgb":[0.733333333333333282,0.4,1],"xyz":[0.432923014404470341,0.272882915390961045,0.975975484220265477],"hpluv":[283.948158265715847,235.997431668916079,59.2402283004695533],"hsluv":[283.948158265715847,99.9999999999988205,59.2402283004695533]},"#997700":{"lch":[51.799451349173637,61.2288227532233265,61.7368019650066202],"luv":[51.799451349173637,28.9932293289078338,53.9292257391759406],"rgb":[0.6,0.466666666666666674,0],"xyz":[0.197331129475883132,0.19966620830666032,0.028146226367465537],"hpluv":[61.7368019650066202,149.992683828924328,51.799451349173637],"hsluv":[61.7368019650066202,100.000000000002373,51.799451349173637]},"#997711":{"lch":[51.8452237949875752,59.5195003520895298,61.1595916745536812],"luv":[51.8452237949875752,28.7105152364728049,52.1371003894409952],"rgb":[0.6,0.466666666666666674,0.0666666666666666657],"xyz":[0.198342794975520265,0.200070874506515173,0.0334743313322211702],"hpluv":[61.1595916745536812,145.676617799321178,51.8452237949875752],"hsluv":[61.1595916745536812,96.7355174862457687,51.8452237949875752]},"#997722":{"lch":[51.9299107218419778,56.4237897442973448,60.0184197539949],"luv":[51.9299107218419778,28.1961842142201746,48.8735024820856836],"rgb":[0.6,0.466666666666666674,0.133333333333333331],"xyz":[0.200218153113997266,0.200821017761906,0.0433512175282003628],"hpluv":[60.0184197539949,137.874516690543771,51.9299107218419778],"hsluv":[60.0184197539949,90.8032063934702762,51.9299107218419778]},"#997733":{"lch":[52.0688882655341843,51.532107019520943,57.9108306747127841],"luv":[52.0688882655341843,27.375836028403171,43.6591531710973797],"rgb":[0.6,0.466666666666666674,0.2],"xyz":[0.203305903846455027,0.2020561180548891,0.0596133713858115061],"hpluv":[57.9108306747127841,125.585333003110208,52.0688882655341843],"hsluv":[57.9108306747127841,81.359583819486275,52.0688882655341843]},"#997744":{"lch":[52.2685439893789265,44.9234500117750244,54.2507061045172563],"luv":[52.2685439893789265,26.2460613351246792,36.4590266649196622],"rgb":[0.6,0.466666666666666674,0.266666666666666663],"xyz":[0.207763899090673887,0.203839316152576694,0.0830921463386981446],"hpluv":[54.2507061045172563,109.061640425204757,52.2685439893789265],"hsluv":[54.2507061045172563,68.3925961892813632,52.2685439893789265]},"#997755":{"lch":[52.5337646967731615,36.9638675487782962,47.8040559904272229],"luv":[52.5337646967731615,24.8274523779219614,27.3847605902560787],"rgb":[0.6,0.466666666666666674,0.333333333333333315],"xyz":[0.213726313130035872,0.206224281768321527,0.11449419361267206],"hpluv":[47.8040559904272229,89.2849392346346,52.5337646967731615],"hsluv":[47.8040559904272229,52.1784042692219217,52.5337646967731615]},"#997766":{"lch":[52.8682223623880958,28.5307109293219519,35.7342712802299047],"luv":[52.8682223623880958,23.1593577603421643,16.6627012894371447],"rgb":[0.6,0.466666666666666674,0.4],"xyz":[0.221311308903544057,0.209258280077724818,0.154441838019816],"hpluv":[35.7342712802299047,68.4789688439394695,52.8682223623880958],"hsluv":[35.7342712802299047,33.2180784313787072,52.8682223623880958]},"#997777":{"lch":[53.2745272921510349,21.7835186536615062,12.1770506300626185],"luv":[53.2745272921510349,21.2933995119794766,4.59486911213486],"rgb":[0.6,0.466666666666666674,0.466666666666666674],"xyz":[0.230625321923745963,0.212983885285805641,0.203495639926213917],"hpluv":[12.1770506300626185,51.8857087556556777,53.2745272921510349],"hsluv":[12.1770506300626185,12.1864056638809046,53.2745272921510349]},"#997788":{"lch":[53.7543298043441524,21.0694932264164443,336.259644884191403],"luv":[53.7543298043441524,19.28657717102978,-8.48242216845644492],"rgb":[0.6,0.466666666666666674,0.533333333333333326],"xyz":[0.241765739025689819,0.217440052126583239,0.262168503329786085],"hpluv":[336.259644884191403,49.7370433553737143,53.7543298043441524],"hsluv":[336.259644884191403,17.3594920402921318,53.7543298043441524]},"#997799":{"lch":[54.308403390094881,28.1087123643927,307.715012949247921],"luv":[54.308403390094881,17.1950646022419384,-22.235769923906151],"rgb":[0.6,0.466666666666666674,0.6],"xyz":[0.254822703134762518,0.222662837770212396,0.330935180970904],"hpluv":[307.715012949247921,65.67699031054849,54.308403390094881],"hsluv":[307.715012949247921,22.7222383700086681,54.308403390094881]},"#9977aa":{"lch":[54.9367240193748785,39.361724048309469,292.510155009375],"luv":[54.9367240193748785,15.0695247856183894,-36.3628208860492137],"rgb":[0.6,0.466666666666666674,0.66666666666666663],"xyz":[0.269880396100015074,0.228685914956313491,0.41023903058790262],"hpluv":[292.510155009375,90.9181689788077847,54.9367240193748785],"hsluv":[292.510155009375,30.8964586946041671,54.9367240193748785]},"#9977bb":{"lch":[55.6385517902762388,52.2405182414828104,284.355371582691191],"luv":[55.6385517902762388,12.9522722169503091,-50.6093903397058824],"rgb":[0.6,0.466666666666666674,0.733333333333333282],"xyz":[0.287017988207351693,0.235540951799248249,0.500497015686544366],"hpluv":[284.355371582691191,119.143673365147691,55.6385517902762388],"hsluv":[284.355371582691191,44.025050152294007,55.6385517902762388]},"#9977cc":{"lch":[56.4125166695819615,65.6830300518217172,279.531250686135081],"luv":[56.4125166695819615,10.8761592408186605,-64.7763042860340192],"rgb":[0.6,0.466666666666666674,0.8],"xyz":[0.306310363651073447,0.243257901976737051,0.602103526356814522],"hpluv":[279.531250686135081,147.746441920881637,56.4125166695819615],"hsluv":[279.531250686135081,57.5215558896316352,56.4125166695819615]},"#9977dd":{"lch":[57.256707620000924,79.2159287347205,276.425234899334782],"luv":[57.256707620000924,8.86478593594131858,-78.718351962006011],"rgb":[0.6,0.466666666666666674,0.866666666666666696],"xyz":[0.327828689201707,0.251865232196990585,0.71543337425682052],"hpluv":[276.425234899334782,175.559960004438778,57.256707620000924],"hsluv":[276.425234899334782,71.3413917340773764,57.256707620000924]},"#9977ee":{"lch":[58.1687631275758434,92.5981917117116211,274.294200356840065],"luv":[58.1687631275758434,6.93354781471817905,-92.3382424728774822],"rgb":[0.6,0.466666666666666674,0.933333333333333348],"xyz":[0.351640869467881756,0.261390104303460602,0.840844190325343743],"hpluv":[274.294200356840065,202.000294664132923,58.1687631275758434],"hsluv":[274.294200356840065,85.4864748016987903,58.1687631275758434]},"#9977ff":{"lch":[59.1459606243173,105.700835267318482,272.760722153075335],"luv":[59.1459606243173,5.0910859147335179,-105.578157875659116],"rgb":[0.6,0.466666666666666674,1],"xyz":[0.377811917877713122,0.271858523667393326,0.978678378617125588],"hpluv":[272.760722153075335,226.773684284234889,59.1459606243173],"hsluv":[272.760722153075335,99.9999999999988,59.1459606243173]},"#bb7700":{"lch":[55.8465021194210323,78.9426527823167703,44.2288975260652037],"luv":[55.8465021194210323,56.5670601566064,55.0645996403160751],"rgb":[0.733333333333333282,0.466666666666666674,0],"xyz":[0.270895964056058,0.237598076137063796,0.0315945779884111572],"hpluv":[44.2288975260652037,179.372171604304526,55.8465021194210323],"hsluv":[44.2288975260652037,100.000000000002402,55.8465021194210323]},"#bb7711":{"lch":[55.8872675460691113,77.5581898683241775,43.5811171927028127],"luv":[55.8872675460691113,56.1830827877517081,53.4671303149482782],"rgb":[0.733333333333333282,0.466666666666666674,0.0666666666666666657],"xyz":[0.271907629555695085,0.238002742336918649,0.0369226829531667869],"hpluv":[43.5811171927028127,176.097874689063588,55.8872675460691113],"hsluv":[43.5811171927028127,97.2747266570755613,55.8872675460691113]},"#bb7722":{"lch":[55.9627137258116534,75.0570685818031365,42.3362918908129799],"luv":[55.9627137258116534,55.4825342436315907,50.549499878809371],"rgb":[0.733333333333333282,0.466666666666666674,0.133333333333333331],"xyz":[0.273782987694172142,0.238752885592309477,0.0467995691491459864],"hpluv":[42.3362918908129799,170.189263625481374,55.9627137258116534],"hsluv":[42.3362918908129799,92.3060252972229875,55.9627137258116534]},"#bb7733":{"lch":[56.086591241629975,71.12386069085467,40.1553843778465094],"luv":[56.086591241629975,54.3598535070873652,45.8651271257379562],"rgb":[0.733333333333333282,0.466666666666666674,0.2],"xyz":[0.276870738426629848,0.239987985885292576,0.0630617230067571366],"hpluv":[40.1553843778465094,160.914656808849855,56.086591241629975],"hsluv":[40.1553843778465094,84.3528141134219425,56.086591241629975]},"#bb7744":{"lch":[56.2646940492590346,65.8532423012147632,36.6949041745596887],"luv":[56.2646940492590346,52.8030258036740747,39.3508575199960617],"rgb":[0.733333333333333282,0.466666666666666674,0.266666666666666663],"xyz":[0.281328733670848763,0.24177118398298017,0.0865404979596437751],"hpluv":[36.6949041745596887,148.518490760970963,56.2646940492590346],"hsluv":[36.6949041745596887,73.3442464951488517,56.2646940492590346]},"#bb7755":{"lch":[56.5015366957073866,59.5720019456390375,31.4313823601585],"luv":[56.5015366957073866,50.8307220514796256,31.0654327434279267],"rgb":[0.733333333333333282,0.466666666666666674,0.333333333333333315],"xyz":[0.287291147710210748,0.244156149598725,0.117942545233617677],"hpluv":[31.4313823601585,133.789263155984059,56.5015366957073866],"hsluv":[31.4313823601585,59.433527841274838,56.5015366957073866]},"#bb7766":{"lch":[56.8006139195957758,52.9060784141758376,23.584548946691168],"luv":[56.8006139195957758,48.4868685528452588,21.1678225404983067],"rgb":[0.733333333333333282,0.466666666666666674,0.4],"xyz":[0.294876143483718933,0.247190147908128294,0.157890189640761625],"hpluv":[23.584548946691168,118.193030459121616,56.8006139195957758],"hsluv":[23.584548946691168,42.9582981176577476,56.8006139195957758]},"#bb7777":{"lch":[57.1645375630264851,46.8887603377642677,12.1770506300621175],"luv":[57.1645375630264851,45.8337848153679062,9.89040016939892652],"rgb":[0.733333333333333282,0.466666666666666674,0.466666666666666674],"xyz":[0.304190156503920839,0.250915753116209117,0.206943991547159534],"hpluv":[12.1770506300621175,104.083378979503351,57.1645375630264851],"hsluv":[12.1770506300621175,30.9338815185941769,57.1645375630264851]},"#bb7788":{"lch":[57.5951231639082408,43.0166042307866761,356.679907444569722],"luv":[57.5951231639082408,42.9444038116514264,-2.49126891562360298],"rgb":[0.733333333333333282,0.466666666666666674,0.533333333333333326],"xyz":[0.315330573605864639,0.255371919956986715,0.265616854950731729],"hpluv":[356.679907444569722,94.7741152880685149,57.5951231639082408],"hsluv":[356.679907444569722,32.9204937798227419,57.5951231639082408]},"#bb7799":{"lch":[58.0934559183715322,42.8683503206465062,338.533521874652],"luv":[58.0934559183715322,39.8946515879682408,-15.6879646190414519],"rgb":[0.733333333333333282,0.466666666666666674,0.6],"xyz":[0.328387537714937339,0.260594705600615872,0.334383532591849608],"hpluv":[338.533521874652,93.6373004736019823,58.0934559183715322],"hsluv":[338.533521874652,34.9811369830312131,58.0934559183715322]},"#bb77aa":{"lch":[58.6599497668646706,47.0820583870944276,321.324781752589786],"luv":[58.6599497668646706,36.7569990603765,-29.4218157502430451],"rgb":[0.733333333333333282,0.466666666666666674,0.66666666666666663],"xyz":[0.343445230680189895,0.266617782786717,0.413687382208848209],"hpluv":[321.324781752589786,101.848135129910219,58.6599497668646706],"hsluv":[321.324781752589786,37.0556810629478051,58.6599497668646706]},"#bb77bb":{"lch":[59.2944060970233693,54.9189596898792303,307.71501294924542],"luv":[59.2944060970233693,33.5958135510894706,-43.4443718479046765],"rgb":[0.733333333333333282,0.466666666666666674,0.733333333333333282],"xyz":[0.360582822787526569,0.273472819629651753,0.50394536730749],"hpluv":[307.71501294924542,117.529775077760561,59.2944060970233693],"hsluv":[307.71501294924542,40.6617226560308467,59.2944060970233693]},"#bb77cc":{"lch":[59.9960747587738155,65.1135012197087519,297.896140559284788],"luv":[59.9960747587738155,30.4646722292654815,-57.5471266620014177],"rgb":[0.733333333333333282,0.466666666666666674,0.8],"xyz":[0.379875198231248268,0.281189769807140555,0.605551877977760111],"hpluv":[297.896140559284788,137.716994859863917,59.9960747587738155],"hsluv":[297.896140559284788,53.5682479917909,59.9960747587738155]},"#bb77dd":{"lch":[60.7637179337253599,76.6332290650186394,290.953982706702106],"luv":[60.7637179337253599,27.4054240934965065,-71.5653165100750357],"rgb":[0.733333333333333282,0.466666666666666674,0.866666666666666696],"xyz":[0.401393523781881867,0.289797100027394061,0.718881725877766109],"hpluv":[290.953982706702106,160.033945707839,60.7637179337253599],"hsluv":[290.953982706702106,68.5485010485900119,60.7637179337253599]},"#bb77ee":{"lch":[61.5956761624293563,88.8082274030350902,285.979672103614405],"luv":[61.5956761624293563,24.4485758512518743,-85.3766267389077456],"rgb":[0.733333333333333282,0.466666666666666674,0.933333333333333348],"xyz":[0.425205704048056576,0.299321972133864078,0.844292541946289332],"hpluv":[285.979672103614405,182.954165183101395,61.5956761624293563],"hsluv":[285.979672103614405,84.0163684558434909,61.5956761624293563]},"#bb77ff":{"lch":[62.4899351736807773,101.23109143545085,282.328516880108566],"luv":[62.4899351736807773,21.6145233767131266,-98.8966442929694693],"rgb":[0.733333333333333282,0.466666666666666674,1],"xyz":[0.451376752457888,0.309790391497796802,0.982126730238071177],"hpluv":[282.328516880108566,205.562159598045383,62.4899351736807773],"hsluv":[282.328516880108566,99.9999999999986784,62.4899351736807773]},"#998800":{"lch":[56.4673516485332527,62.834492950420568,74.7562721675545561],"luv":[56.4673516485332527,16.5207966112614884,60.6237311922136897],"rgb":[0.6,0.533333333333333326,0],"xyz":[0.219403499200853586,0.243810947756601892,0.0355036829424554834],"hpluv":[74.7562721675545561,141.201731332299261,56.4673516485332527],"hsluv":[74.7562721675545561,100.000000000002331,56.4673516485332527]},"#998811":{"lch":[56.5074221469723881,61.2259080808398366,74.51872844438833],"luv":[56.5074221469723881,16.3426261455871646,59.0044946676862878],"rgb":[0.6,0.533333333333333326,0.0666666666666666657],"xyz":[0.220415164700490718,0.244215613956456745,0.0408317879072111131],"hpluv":[74.51872844438833,137.489352382480689,56.5074221469723881],"hsluv":[74.51872844438833,97.3110722480099781,56.5074221469723881]},"#998822":{"lch":[56.5815852437789744,58.2905156727598666,74.0508275651119],"luv":[56.5815852437789744,16.0173304476746452,56.0466711119068961],"rgb":[0.6,0.533333333333333326,0.133333333333333331],"xyz":[0.222290522838967719,0.244965757211847573,0.0507086741031903127],"hpluv":[74.0508275651119,130.726042229432494,56.5815852437789744],"hsluv":[74.0508275651119,92.4075523300517574,56.5815852437789744]},"#998833":{"lch":[56.7033645714083,53.5858970619529273,73.1917859227149],"luv":[56.7033645714083,15.4953822971072128,51.2966031175623911],"rgb":[0.6,0.533333333333333326,0.2],"xyz":[0.22537827357142548,0.246200857504830672,0.066970827960801449],"hpluv":[73.1917859227149,119.917068416956084,56.7033645714083],"hsluv":[73.1917859227149,84.5557602276611533,56.7033645714083]},"#998844":{"lch":[56.8784692361674189,47.0662938677721456,71.7105236832421156],"luv":[56.8784692361674189,14.7702533586865563,44.6886521856241927],"rgb":[0.6,0.533333333333333326,0.266666666666666663],"xyz":[0.22983626881564434,0.247984055602518266,0.0904496029136880875],"hpluv":[71.7105236832421156,105.00293267331034,56.8784692361674189],"hsluv":[71.7105236832421156,73.6816499137771075,56.8784692361674189]},"#998855":{"lch":[57.1113583918905761,38.8337969655052433,69.1066660847648393],"luv":[57.1113583918905761,13.8492700909341142,36.2803184206870242],"rgb":[0.6,0.533333333333333326,0.333333333333333315],"xyz":[0.235798682855006325,0.250369021218263099,0.121851650187662],"hpluv":[69.1066660847648393,86.2832891510872599,57.1113583918905761],"hsluv":[69.1066660847648393,59.9309888570698774,57.1113583918905761]},"#998866":{"lch":[57.4054971647218224,29.1657433305745144,64.0747883902216],"luv":[57.4054971647218224,12.7511922431808031,26.2306629806110223],"rgb":[0.6,0.533333333333333326,0.4],"xyz":[0.24338367862851451,0.253403019527666418,0.161799294594805965],"hpluv":[64.0747883902216,64.4701815948561574,57.4054971647218224],"hsluv":[64.0747883902216,43.6310875702010321,57.4054971647218224]},"#998877":{"lch":[57.7634914296009612,18.7238256654584347,52.0945218145914097],"luv":[57.7634914296009612,11.5031815844705712,14.773573060880608],"rgb":[0.6,0.533333333333333326,0.466666666666666674],"xyz":[0.252697691648716416,0.257128624735747213,0.210853096501203874],"hpluv":[52.0945218145914097,41.1320618043462858,57.7634914296009612],"hsluv":[52.0945218145914097,25.2418236256697028,57.7634914296009612]},"#998888":{"lch":[58.1871725604667489,10.3706980586515272,12.1770506300640946],"luv":[58.1871725604667489,10.1373621264743505,2.18752539195365081],"rgb":[0.6,0.533333333333333326,0.533333333333333326],"xyz":[0.263838108750660272,0.261584791576524811,0.269525959904776],"hpluv":[12.1770506300640946,22.6162221883482317,58.1871725604667489],"hsluv":[12.1770506300640946,7.14421708061451799,58.1871725604667489]},"#998899":{"lch":[58.6776613659523605,14.2013195506443459,307.715012949254117],"luv":[58.6776613659523605,8.6874348403017283,-11.2341422847952668],"rgb":[0.6,0.533333333333333326,0.6],"xyz":[0.276895072859732971,0.266807577220153969,0.338292637545893948],"hpluv":[307.715012949254117,30.7110899398720818,58.6776613659523605],"hsluv":[307.715012949254117,10.6251017733449729,58.6776613659523605]},"#9988aa":{"lch":[59.2354248002074399,26.2127450059066938,285.910383521223935],"luv":[59.2354248002074399,7.18579172527609789,-25.2085778659891844],"rgb":[0.6,0.533333333333333326,0.66666666666666663],"xyz":[0.291952765824985527,0.272830654406255091,0.417596487162892549],"hpluv":[285.910383521223935,56.1526584479988173,59.2354248002074399],"hsluv":[285.910383521223935,23.5088603674401817,59.2354248002074399]},"#9988bb":{"lch":[59.8603319378123189,39.8857557696632696,278.160160819701673],"luv":[59.8603319378123189,5.66141142610705117,-39.4819190767314581],"rgb":[0.6,0.533333333333333326,0.733333333333333282],"xyz":[0.309090357932322146,0.279685691249189849,0.507854472261534351],"hpluv":[278.160160819701673,84.5508603994872,59.8603319378123189],"hsluv":[278.160160819701673,37.7262541103550291,59.8603319378123189]},"#9988cc":{"lch":[60.55171199345871,53.9990869041691823,274.395593429514747],"luv":[60.55171199345871,4.13861667015410095,-53.8402566723222264],"rgb":[0.6,0.533333333333333326,0.8],"xyz":[0.3283827333760439,0.287402641426678651,0.609460982931804507],"hpluv":[274.395593429514747,113.161661700826286,60.55171199345871],"hsluv":[274.395593429514747,52.5240219153236723,60.55171199345871]},"#9988dd":{"lch":[61.3084150605589855,68.1648195931338563,272.216747448240312],"luv":[61.3084150605589855,2.63660773112319324,-68.1138086575451],"rgb":[0.6,0.533333333333333326,0.866666666666666696],"xyz":[0.349901058926677444,0.296009971646932157,0.722790830831810505],"hpluv":[272.216747448240312,141.084572716849891,61.3084150605589855],"hsluv":[272.216747448240312,67.8395486149695,61.3084150605589855]},"#9988ee":{"lch":[62.128875020953032,82.18421866163294,270.815422264053723],"luv":[62.128875020953032,1.1695901512833331,-82.1758958326656597],"rgb":[0.6,0.533333333333333326,0.933333333333333348],"xyz":[0.373713239192852154,0.305534843753402174,0.848201646900333728],"hpluv":[270.815422264053723,167.854994169255662,62.128875020953032],"hsluv":[270.815422264053723,83.6558877567472905,62.128875020953032]},"#9988ff":{"lch":[63.0111734122257303,95.9388777898474387,269.8490772999765],"luv":[63.0111734122257303,-0.252712116882344406,-95.9385449554102],"rgb":[0.6,0.533333333333333326,1],"xyz":[0.399884287602683575,0.316003263117334898,0.986035835192115462],"hpluv":[269.8490772999765,193.204124490752207,63.0111734122257303],"hsluv":[269.8490772999765,99.9999999999985363,63.0111734122257303]},"#bb8800":{"lch":[60.0458653136574,74.8864062555341832,55.056379834278971],"luv":[60.0458653136574,42.8926945435799,61.3855894869476728],"rgb":[0.733333333333333282,0.533333333333333326,0],"xyz":[0.292968333781028434,0.281742815587005313,0.038952034563401107],"hpluv":[55.056379834278971,158.255644288368103,60.0458653136574],"hsluv":[55.056379834278971,100.000000000002288,60.0458653136574]},"#bb8811":{"lch":[60.0822560315187957,73.5298298886522161,54.5759299869630823],"luv":[60.0822560315187957,42.619621560372849,59.9183089005750773],"rgb":[0.733333333333333282,0.533333333333333326,0.0666666666666666657],"xyz":[0.293979999280665538,0.282147481786860166,0.0442801395281567367],"hpluv":[54.5759299869630823,155.294707870281485,60.0822560315187957],"hsluv":[54.5759299869630823,97.6878818876268866,60.0822560315187957]},"#bb8822":{"lch":[60.1496227929862499,71.0610449842002367,53.6488709316330343],"luv":[60.1496227929862499,42.1201645307819774,57.2325419158225586],"rgb":[0.733333333333333282,0.533333333333333326,0.133333333333333331],"xyz":[0.295855357419142595,0.282897625042250966,0.0541570257241359362],"hpluv":[53.6488709316330343,149.912555699661567,60.1496227929862499],"hsluv":[53.6488709316330343,93.46183514856709,60.1496227929862499]},"#bb8833":{"lch":[60.2602822329103844,67.1261991777524,52.0115270519145412],"luv":[60.2602822329103844,41.3163720666953154,52.9044801061090197],"rgb":[0.733333333333333282,0.533333333333333326,0.2],"xyz":[0.298943108151600301,0.284132725335234093,0.0704191795817470795],"hpluv":[52.0115270519145412,141.351435183858257,60.2602822329103844],"hsluv":[52.0115270519145412,86.668700859176,60.2602822329103844]},"#bb8844":{"lch":[60.4194844691316746,61.7320119628667285,49.374045706205429],"luv":[60.4194844691316746,40.1948297943626258,46.8531424643613406],"rgb":[0.733333333333333282,0.533333333333333326,0.266666666666666663],"xyz":[0.303401103395819216,0.285915923432921659,0.093897954534633718],"hpluv":[49.374045706205429,129.650066203053939,60.4194844691316746],"hsluv":[49.374045706205429,77.207197386412,60.4194844691316746]},"#bb8855":{"lch":[60.6313805732006585,55.0590005000961682,45.2500033552910708],"luv":[60.6313805732006585,38.7623447760430935,39.1020992215604082],"rgb":[0.733333333333333282,0.533333333333333326,0.333333333333333315],"xyz":[0.309363517435181201,0.28830088904866652,0.125300001808607619],"hpluv":[45.2500033552910708,115.231228654446355,60.6313805732006585],"hsluv":[45.2500033552910708,65.1528926573884775,60.6313805732006585]},"#bb8866":{"lch":[60.8992588402534949,47.519038379270981,38.7816256818529581],"luv":[60.8992588402534949,37.0429375720225096,29.7637327048519147],"rgb":[0.733333333333333282,0.533333333333333326,0.4],"xyz":[0.316948513208689386,0.291334887358069838,0.165247646215751581],"hpluv":[38.7816256818529581,99.0136254476035305,60.8992588402534949],"hsluv":[38.7816256818529581,50.7321114426118,60.8992588402534949]},"#bb8877":{"lch":[61.2256685857267087,39.8992767652027354,28.4701407483744688],"luv":[61.2256685857267087,35.0740840991728362,19.0200134329710231],"rgb":[0.733333333333333282,0.533333333333333326,0.466666666666666674],"xyz":[0.326262526228891292,0.295060492566150634,0.21430144812214949],"hpluv":[28.4701407483744688,82.6933933486175761,61.2256685857267087],"hsluv":[28.4701407483744688,34.2887258466009897,61.2256685857267087]},"#bb8888":{"lch":[61.6124959728340684,33.6595928281588499,12.1770506300623627],"luv":[61.6124959728340684,32.9022674846918903,7.09992843085263114],"rgb":[0.733333333333333282,0.533333333333333326,0.533333333333333326],"xyz":[0.337402943330835092,0.299516659406928232,0.272974311525721658],"hpluv":[12.1770506300623627,69.3233245158679,61.6124959728340684],"hsluv":[12.1770506300623627,26.8235367690150284,61.6124959728340684]},"#bb8899":{"lch":[62.0610184830546388,31.1131530731089718,349.361203223606594],"luv":[62.0610184830546388,30.5783355372127765,-5.74401339869088723],"rgb":[0.733333333333333282,0.533333333333333326,0.6],"xyz":[0.350459907439907847,0.304739445050557389,0.341740989166839593],"hpluv":[349.361203223606594,63.6157209963685091,62.0610184830546388],"hsluv":[349.361203223606594,28.7433747177793393,62.0610184830546388]},"#bb88aa":{"lch":[62.5719506337331097,34.1093853871598185,325.627133749050586],"luv":[62.5719506337331097,28.1532372220531357,-19.2573467904743723],"rgb":[0.733333333333333282,0.533333333333333326,0.66666666666666663],"xyz":[0.365517600405160348,0.310762522236658512,0.421044838783838193],"hpluv":[325.627133749050586,69.1725086761469328,62.5719506337331097],"hsluv":[325.627133749050586,30.7007491098828176,62.5719506337331097]},"#bb88bb":{"lch":[63.1454872588298,41.9701566603395477,307.715012949246614],"luv":[63.1454872588298,25.674586077978244,-33.2010493782640808],"rgb":[0.733333333333333282,0.533333333333333326,0.733333333333333282],"xyz":[0.382655192512497,0.31761755907959327,0.51130282388247994],"hpluv":[307.715012949246614,84.3407770596407,63.1454872588298],"hsluv":[307.715012949246614,32.6446535119142354,63.1454872588298]},"#bb88cc":{"lch":[63.7813474201422,52.7335158558763055,296.081540752202443],"luv":[63.7813474201422,23.1842810338905281,-47.3636232510092228],"rgb":[0.733333333333333282,0.533333333333333326,0.8],"xyz":[0.401947567956218776,0.325334509257082072,0.612909334552750096],"hpluv":[296.081540752202443,104.913738848088499,63.7813474201422],"hsluv":[296.081540752202443,48.441096457031712,63.7813474201422]},"#bb88dd":{"lch":[64.4788201663492089,64.9599578897110916,288.597779393076337],"luv":[64.4788201663492089,20.7171971389296665,-61.56779898404492],"rgb":[0.733333333333333282,0.533333333333333326,0.866666666666666696],"xyz":[0.423465893506852264,0.333941839477335578,0.726239182452756094],"hpluv":[288.597779393076337,127.840358269428478,64.4788201663492089],"hsluv":[288.597779393076337,64.9415793589177,64.4788201663492089]},"#bb88ee":{"lch":[65.2368122498474463,77.8541115668441392,283.595470556329246],"luv":[65.2368122498474463,18.300798164755431,-75.6726071600252084],"rgb":[0.733333333333333282,0.533333333333333326,0.933333333333333348],"xyz":[0.44727807377302703,0.343466711583805595,0.851649998521279317],"hpluv":[283.595470556329246,151.435657753316406,65.2368122498474463],"hsluv":[283.595470556329246,82.1213401763518789,65.2368122498474463]},"#bb88ff":{"lch":[66.0538972531437452,90.9819525935223652,280.100148709787334],"luv":[66.0538972531437452,15.9554396417090967,-89.5719802369565201],"rgb":[0.733333333333333282,0.533333333333333326,1],"xyz":[0.473449122182858395,0.353935130947738319,0.989484186813061162],"hpluv":[280.100148709787334,174.781769995450787,66.0538972531437452],"hsluv":[280.100148709787334,99.99999999999838,66.0538972531437452]},"#999900":{"lch":[61.2683639221826866,67.5422828804358772,85.8743202181747449],"luv":[61.2683639221826866,4.85929488236129092,67.3672563635114869],"rgb":[0.6,0.6,0],"xyz":[0.245273099653321058,0.295550148661537559,0.0441268830932777384],"hpluv":[85.8743202181747449,139.887458074797593,61.2683639221826866],"hsluv":[85.8743202181747449,100.000000000002359,61.2683639221826866]},"#999911":{"lch":[61.3036130280217861,66.0751339072958785,85.8743202181746881],"luv":[61.3036130280217861,4.75374160235953358,65.9039093047224185],"rgb":[0.6,0.6,0.0666666666666666657],"xyz":[0.24628476515295819,0.295954814861392412,0.0494549880580333681],"hpluv":[85.8743202181746881,136.770144995815713,61.3036130280217861],"hsluv":[85.8743202181746881,97.7715564197957718,61.3036130280217861]},"#999922":{"lch":[61.3688705786650104,63.38848415762304,85.8743202181745744],"luv":[61.3688705786650104,4.56045196477970372,63.2242216375825663],"rgb":[0.6,0.6,0.133333333333333331],"xyz":[0.248160123291435192,0.296704958116783213,0.0593318742540125676],"hpluv":[85.8743202181745744,131.069475710796667,61.3688705786650104],"hsluv":[85.8743202181745744,93.6963738669960691,61.3688705786650104]},"#999933":{"lch":[61.4760769955270945,59.0559618954583243,85.8743202181743754],"luv":[61.4760769955270945,4.24875087387181871,58.9029265097210484],"rgb":[0.6,0.6,0.2],"xyz":[0.251247874023892925,0.29794005840976634,0.0755940281116237178],"hpluv":[85.8743202181743754,121.898097720990123,61.4760769955270945],"hsluv":[85.8743202181743754,87.1401192062652683,61.4760769955270945]},"#999944":{"lch":[61.6303367515695,52.9921690524208,85.8743202181739775],"luv":[61.6303367515695,3.81249440942850049,52.8548471500809569],"rgb":[0.6,0.6,0.266666666666666663],"xyz":[0.255705869268111841,0.299723256507453906,0.0990728030645103563],"hpluv":[85.8743202181739775,109.10797160418339,61.6303367515695],"hsluv":[85.8743202181739775,77.9969649215058,61.6303367515695]},"#999955":{"lch":[61.8357003743425935,45.2147461889200173,85.8743202181734517],"luv":[61.8357003743425935,3.25295171251598125,45.0975784059909],"rgb":[0.6,0.6,0.333333333333333315],"xyz":[0.261668283307473826,0.302108222123198766,0.130474850338484272],"hpluv":[85.8743202181734517,92.7855058259100218,61.8357003743425935],"hsluv":[85.8743202181734517,66.3286810003367577,61.8357003743425935]},"#999966":{"lch":[62.0953945325949377,35.8293841981041083,85.874320218172457],"luv":[62.0953945325949377,2.57772666020637553,35.7365372872164784],"rgb":[0.6,0.6,0.4],"xyz":[0.269253279080982,0.305142220432602085,0.170422494745628206],"hpluv":[85.874320218172457,73.2182390722606,62.0953945325949377],"hsluv":[85.874320218172457,52.3408174542086542,62.0953945325949377]},"#999977":{"lch":[62.4119425079225749,25.0116267171883422,85.8743202181703],"luv":[62.4119425079225749,1.79944864939855109,24.9468125338318],"rgb":[0.6,0.6,0.466666666666666674],"xyz":[0.278567292101183916,0.30886782564068288,0.219476296652026115],"hpluv":[85.8743202181703,50.8526471570801775,62.4119425079225749],"hsluv":[85.8743202181703,36.3525421484824918,62.4119425079225749]},"#999988":{"lch":[62.7872374999600567,12.9853368609797517,85.8743202181639589],"luv":[62.7872374999600567,0.934223397011331502,12.9516871502363],"rgb":[0.6,0.6,0.533333333333333326],"xyz":[0.289707709203127717,0.313323992481460478,0.27814916005559831],"hpluv":[85.8743202181639589,26.2434647477884546,62.7872374999600567],"hsluv":[85.8743202181639589,18.7604129126121961,62.7872374999600567]},"#999999":{"lch":[63.2225945523589843,3.33307052034688283e-12,0],"luv":[63.2225945523589843,3.14807442966336163e-12,1.09498241031769098e-12],"rgb":[0.6,0.6,0.6],"xyz":[0.302764673312200472,0.318546778125089636,0.346915837696716189],"hpluv":[0,6.68977504875838914e-12,63.2225945523589843],"hsluv":[0,3.10313074237261963e-12,63.2225945523589843]},"#9999aa":{"lch":[63.7187933641432238,13.6904464527836414,265.874320218190064],"luv":[63.7187933641432238,-0.984952144759020598,-13.6549695477167123],"rgb":[0.6,0.6,0.66666666666666663],"xyz":[0.317822366277453,0.324569855311190758,0.42621968731371479],"hpluv":[265.874320218190064,27.2639887848552753,63.7187933641432238],"hsluv":[265.874320218190064,14.5770868731616492,63.7187933641432238]},"#9999bb":{"lch":[64.276118203606174,27.8450519356751158,265.874320218183641],"luv":[64.276118203606174,-2.00329797275791854,-27.7728953213882335],"rgb":[0.6,0.6,0.733333333333333282],"xyz":[0.334959958384789647,0.331424892154125517,0.516477672412356537],"hpluv":[265.874320218183641,54.9715165011475904,64.276118203606174],"hsluv":[265.874320218183641,30.0955931685464577,64.276118203606174]},"#9999cc":{"lch":[64.8943980299807635,42.2483295275786332,265.874320218181538],"luv":[64.8943980299807635,-3.03953438803302189,-42.138848804575062],"rgb":[0.6,0.6,0.8],"xyz":[0.354252333828511401,0.339141842331614318,0.618084183082626692],"hpluv":[265.874320218181538,82.6117192029769,64.8943980299807635],"hsluv":[265.874320218181538,46.4456834766813316,64.8943980299807635]},"#9999dd":{"lch":[65.5730481583578353,56.7175687031348,265.874320218180458],"luv":[65.5730481583578353,-4.08051637559571567,-56.570592941061804],"rgb":[0.6,0.6,0.866666666666666696],"xyz":[0.375770659379144889,0.347749172551867824,0.73141403098263269],"hpluv":[265.874320218180458,109.756831209262941,65.5730481583578353],"hsluv":[265.874320218180458,63.5568222493012627,65.5730481583578353]},"#9999ee":{"lch":[66.311113738117,71.1055788100052695,265.874320218179832],"luv":[66.311113738117,-5.11565437949467672,-70.9213185027987691],"rgb":[0.6,0.6,0.933333333333333348],"xyz":[0.399582839645319654,0.357274044658337842,0.856824847051155913],"hpluv":[265.874320218179832,136.068212717368169,66.311113738117],"hsluv":[265.874320218179832,81.4020980414818922,66.311113738117]},"#9999ff":{"lch":[67.1073146704137145,85.2999068143523829,265.874320218179378],"luv":[67.1073146704137145,-6.13685802391602486,-85.0788638624864149],"rgb":[0.6,0.6,1],"xyz":[0.425753888055151,0.367742464022270565,0.994659035342937758],"hpluv":[265.874320218179378,161.293929533565688,67.1073146704137145],"hsluv":[265.874320218179378,99.9999999999983,67.1073146704137145]},"#bb9900":{"lch":[64.4418646198176219,74.1135014806344117,66.2793330800256228],"luv":[64.4418646198176219,29.8142337654579457,67.8522112145111],"rgb":[0.733333333333333282,0.6,0],"xyz":[0.318837934233495934,0.333482016491941036,0.047575234714223362],"hpluv":[66.2793330800256228,145.938057142603384,64.4418646198176219],"hsluv":[66.2793330800256228,100.000000000002416,64.4418646198176219]},"#bb9911":{"lch":[64.4743890579801331,72.806990252212529,65.9899074816349],"luv":[64.4743890579801331,29.6249863695688624,66.5072778888794147],"rgb":[0.733333333333333282,0.6,0.0666666666666666657],"xyz":[0.319849599733133039,0.333886682691795889,0.0529033396789789917],"hpluv":[65.9899074816349,143.29306400111571,64.4743890579801331],"hsluv":[65.9899074816349,98.0367215419372542,64.4743890579801331]},"#bb9922":{"lch":[64.5346112536789,70.4161712525116599,65.4311312102869636],"luv":[64.5346112536789,29.2781077929992222,64.0408430450799671],"rgb":[0.733333333333333282,0.6,0.133333333333333331],"xyz":[0.321724957871610096,0.334636825947186689,0.0627802258749581843],"hpluv":[65.4311312102869636,138.458312961065701,64.5346112536789],"hsluv":[65.4311312102869636,94.4406497380354892,64.5346112536789]},"#bb9933":{"lch":[64.6335704733000398,66.566957174521292,64.4427367566729146],"luv":[64.6335704733000398,28.7178476591491503,60.0536844273559396],"rgb":[0.733333333333333282,0.6,0.2],"xyz":[0.324812708604067801,0.335871926240169816,0.0790423797325693345],"hpluv":[64.4427367566729146,130.689255588928205,64.6335704733000398],"hsluv":[64.4427367566729146,88.6394107340449153,64.6335704733000398]},"#bb9944":{"lch":[64.7760175449466828,61.1991201001527685,62.8442649593615386],"luv":[64.7760175449466828,27.9319304868930693,54.4530950480162872],"rgb":[0.733333333333333282,0.6,0.266666666666666663],"xyz":[0.329270703848286717,0.337655124337857382,0.102521154685455973],"hpluv":[62.8442649593615386,119.886494259466,64.7760175449466828],"hsluv":[62.8442649593615386,80.5164965868838607,64.7760175449466828]},"#bb9955":{"lch":[64.965753761967747,54.3684881208399204,60.3198292286154],"luv":[64.965753761967747,26.9209928274273445,47.235501963369849],"rgb":[0.733333333333333282,0.6,0.333333333333333315],"xyz":[0.335233117887648702,0.340040089953602243,0.133923201959429888],"hpluv":[60.3198292286154,106.194518749025775,64.965753761967747],"hsluv":[60.3198292286154,70.0945405394646883,64.965753761967747]},"#bb9966":{"lch":[65.2058459998609,46.2670609228556557,56.2614414361724258],"luv":[65.2058459998609,25.6969192719684436,38.4747874116176689],"rgb":[0.733333333333333282,0.6,0.4],"xyz":[0.342818113661156887,0.343074088263005561,0.17387084636657385],"hpluv":[56.2614414361724258,90.0377647384168,65.2058459998609],"hsluv":[56.2614414361724258,57.5177389460533064,65.2058459998609]},"#bb9977":{"lch":[65.4987393303808147,37.2952826673053153,49.3796729345645886],"luv":[65.4987393303808147,24.280853083902965,28.3086255892461871],"rgb":[0.733333333333333282,0.6,0.466666666666666674],"xyz":[0.352132126681358792,0.346799693471086357,0.222924648272971759],"hpluv":[49.3796729345645886,72.2537327682772172,65.4987393303808147],"hsluv":[49.3796729345645886,43.0302399575574199,65.4987393303808147]},"#bb9988":{"lch":[65.8463246780106601,28.3139420599436384,36.7022131699001193],"luv":[65.8463246780106601,22.7007755052872291,16.9220006628175241],"rgb":[0.733333333333333282,0.6,0.533333333333333326],"xyz":[0.363272543783302593,0.351255860311863954,0.281597511676543899],"hpluv":[36.7022131699001193,54.564242001153282,65.8463246780106601],"hsluv":[36.7022131699001193,26.9495650592517677,65.8463246780106601]},"#bb9999":{"lch":[66.2499853133799377,21.4719543680734333,12.1770506300627517],"luv":[66.2499853133799377,20.9888452793887552,4.52914983440691099],"rgb":[0.733333333333333282,0.6,0.6],"xyz":[0.376329507892375292,0.356478645955493112,0.350364189317661834],"hpluv":[12.1770506300627517,41.1268186121042731,66.2499853133799377],"hsluv":[12.1770506300627517,20.948078856310218,66.2499853133799377]},"#bb99aa":{"lch":[66.7106335886793715,21.0368039825091344,335.738246937474969],"luv":[66.7106335886793715,19.1787866223333445,-8.64414631375011489],"rgb":[0.733333333333333282,0.6,0.66666666666666663],"xyz":[0.391387200857627848,0.362501723141594234,0.429668038934660435],"hpluv":[335.738246937474969,40.0151105801343192,66.7106335886793715],"hsluv":[335.738246937474969,22.766845509204984,66.7106335886793715]},"#bb99bb":{"lch":[67.2287438260669887,28.2861274819753,307.715012949249171],"luv":[67.2287438260669887,17.3035955220760833,-22.3761165070024362],"rgb":[0.733333333333333282,0.6,0.733333333333333282],"xyz":[0.408524792964964523,0.369356759984529,0.519926024033302125],"hpluv":[307.715012949249171,53.3897422679679323,67.2287438260669887],"hsluv":[307.715012949249171,24.5905380245485432,67.2287438260669887]},"#bb99cc":{"lch":[67.8043844715017343,39.5775547497090656,292.889275489017223],"luv":[67.8043844715017343,15.393749985076461,-36.4611478338680044],"rgb":[0.733333333333333282,0.6,0.8],"xyz":[0.427817168408686221,0.377073710162017794,0.621532534703572281],"hpluv":[292.889275489017223,74.0679810995506642,67.8043844715017343],"hsluv":[292.889275489017223,42.0187450252511,67.8043844715017343]},"#bb99dd":{"lch":[68.4372510447458353,52.4777928084534082,284.879936967142157],"luv":[68.4372510447458353,13.4760025497769718,-50.718005612655638],"rgb":[0.733333333333333282,0.6,0.866666666666666696],"xyz":[0.449335493959319821,0.385681040382271301,0.734862382603578279],"hpluv":[284.879936967142157,97.3021261982971737,68.4372510447458353],"hsluv":[284.879936967142157,60.4059975969609724,68.4372510447458353]},"#bb99ee":{"lch":[69.1267004581107898,66.0165196934359244,280.096152477623832],"luv":[69.1267004581107898,11.5727364631099334,-64.9942508472035456],"rgb":[0.733333333333333282,0.6,0.933333333333333348],"xyz":[0.47314767422549453,0.395205912488741318,0.860273198672101502],"hpluv":[280.096152477623832,121.184234531677617,69.1267004581107898],"hsluv":[280.096152477623832,79.7264365589122548,69.1267004581107898]},"#bb99ff":{"lch":[69.8717866786541,79.7596884688517207,276.986638727898821],"luv":[69.8717866786541,9.70179942494587877,-79.1674364405365765],"rgb":[0.733333333333333282,0.6,1],"xyz":[0.499318722635325951,0.405674331852674042,0.998107386963883347],"hpluv":[276.986638727898821,144.850809586534439,69.8717866786541],"hsluv":[276.986638727898821,99.9999999999980247,69.8717866786541]},"#880000":{"lch":[27.3946073685119416,92.1289276169810876,12.1770506300617765],"luv":[27.3946073685119416,90.0560691570773,19.4330571920800175],"rgb":[0.533333333333333326,0,0],"xyz":[0.101531161901381561,0.0523520053554009795,0.00475927321412716],"hpluv":[12.1770506300617765,426.746789183125316,27.3946073685119416],"hsluv":[12.1770506300617765,100.000000000002245,27.3946073685119416]},"#880011":{"lch":[27.5061298630582485,89.4551794237446529,10.4692299831444977],"luv":[27.5061298630582485,87.9659862388495242,16.254672889999533],"rgb":[0.533333333333333326,0,0.0666666666666666657],"xyz":[0.10254282740101868,0.0527566715552558324,0.0100873781788827915],"hpluv":[10.4692299831444977,412.68181181873,27.5061298630582485],"hsluv":[10.4692299831444977,99.9999999999965,27.5061298630582485]},"#880022":{"lch":[27.711363673312789,85.0234292319238421,7.23413932290422057],"luv":[27.711363673312789,84.3466296586470463,10.7065206104973338],"rgb":[0.533333333333333326,0,0.133333333333333331],"xyz":[0.104418185539495709,0.0535068148106466537,0.0199642643748619876],"hpluv":[7.23413932290422057,389.331950846774873,27.711363673312789],"hsluv":[7.23413932290422057,99.9999999999967,27.711363673312789]},"#880033":{"lch":[28.0451389930846,79.0521177396887396,1.75350406004841131],"luv":[28.0451389930846,79.0150993176991392,2.41896650323101259],"rgb":[0.533333333333333326,0,0.2],"xyz":[0.107505936271953442,0.0547419151036297666,0.0362264182324731343],"hpluv":[1.75350406004841131,357.680479105960103,28.0451389930846],"hsluv":[1.75350406004841131,99.9999999999969589,28.0451389930846]},"#880044":{"lch":[28.5182895144164306,72.8806899851902585,353.674121255230034],"luv":[28.5182895144164306,72.4369406321056459,-8.0302306678086488],"rgb":[0.533333333333333326,0,0.266666666666666663],"xyz":[0.111963931516172316,0.0565251132013173396,0.0597051931853597728],"hpluv":[353.674121255230034,324.286096087098713,28.5182895144164306],"hsluv":[353.674121255230034,99.9999999999972857,28.5182895144164306]},"#880055":{"lch":[29.1358047874334787,68.1690091719341922,343.056201782139055],"luv":[29.1358047874334787,65.2098664506571453,-19.866734230132252],"rgb":[0.533333333333333326,0,0.333333333333333315],"xyz":[0.117926345555534315,0.0589100788170621725,0.0911072404593336743],"hpluv":[343.056201782139055,296.892542908362316,29.1358047874334787],"hsluv":[343.056201782139055,99.9999999999977405,29.1358047874334787]},"#880066":{"lch":[29.8977347275108087,66.3157421691867768,330.790160549998632],"luv":[29.8977347275108087,57.8829185884671915,-32.3627161272186115],"rgb":[0.533333333333333326,0,0.4],"xyz":[0.125511341329042486,0.0619440771264654841,0.13105488486647765],"hpluv":[330.790160549998632,281.460643767249167,29.8977347275108087],"hsluv":[330.790160549998632,99.9999999999981384,29.8977347275108087]},"#880077":{"lch":[30.8000475559674527,67.8890879971799,318.512376228514142],"luv":[30.8000475559674527,50.8556366042998462,-44.9736866918894549],"rgb":[0.533333333333333326,0,0.466666666666666674],"xyz":[0.13482535434924442,0.0656696823345463,0.180108686772875559],"hpluv":[318.512376228514142,279.697068124812404,30.8000475559674527],"hsluv":[318.512376228514142,99.9999999999984652,30.8000475559674527]},"#880088":{"lch":[31.8355421357531156,72.5162027692933862,307.715012949243601],"luv":[31.8355421357531156,44.3606514294377803,-57.3649045046986288],"rgb":[0.533333333333333326,0,0.533333333333333326],"xyz":[0.14596577145118822,0.0701258491753239,0.238781550176447727],"hpluv":[307.715012949243601,289.042783730483279,31.8355421357531156],"hsluv":[307.715012949243601,99.9999999999987921,31.8355421357531156]},"#880099":{"lch":[32.9947769935272675,79.3376809512942,299.026215263792551],"luv":[32.9947769935272675,38.4954159686478121,-69.3726932454703444],"rgb":[0.533333333333333326,0,0.6],"xyz":[0.159022735560260947,0.0753486348189530558,0.307548227817565634],"hpluv":[299.026215263792551,305.122076286487129,32.9947769935272675],"hsluv":[299.026215263792551,99.9999999999991189,32.9947769935272675]},"#8800aa":{"lch":[34.2669429307518527,87.5167556566874651,292.341813883439613],"luv":[34.2669429307518527,33.2678552259606306,-80.9470958672197298],"rgb":[0.533333333333333326,0,0.66666666666666663],"xyz":[0.174080428525513475,0.0813717120050541642,0.386852077434564234],"hpluv":[292.341813883439613,324.082197305514,34.2669429307518527],"hsluv":[292.341813883439613,99.9999999999993605,34.2669429307518527]},"#8800bb":{"lch":[35.6406160405817047,96.4510237672048589,287.271351738157534],"luv":[35.6406160405817047,28.6360630376966157,-92.1019862947753296],"rgb":[0.533333333333333326,0,0.733333333333333282],"xyz":[0.19121802063285015,0.0882267488479889228,0.477110062533206],"hpluv":[287.271351738157534,343.400533998367337,35.6406160405817047],"hsluv":[287.271351738157534,99.999999999999531,35.6406160405817047]},"#8800cc":{"lch":[37.1043554501127346,105.765919518381835,283.413875530142832],"luv":[37.1043554501127346,24.5359458020369345,-102.880596300606314],"rgb":[0.533333333333333326,0,0.8],"xyz":[0.210510396076571876,0.0959436990254777244,0.578716573203476137],"hpluv":[283.413875530142832,361.709723992276565,37.1043554501127346],"hsluv":[283.413875530142832,99.9999999999998,37.1043554501127346]},"#8800dd":{"lch":[38.6471386159700145,115.245648848701009,280.44740978906907],"luv":[38.6471386159700145,20.8978330626497737,-113.335079087825761],"rgb":[0.533333333333333326,0,0.866666666666666696],"xyz":[0.23202872162720542,0.104551029245731258,0.692046421103482134],"hpluv":[280.44740978906907,378.39598449622531,38.6471386159700145],"hsluv":[280.44740978906907,99.9999999999998863,38.6471386159700145]},"#8800ee":{"lch":[40.258648150966188,124.7713904223,278.13468614008417],"luv":[40.258648150966188,17.6552208530237813,-123.515962711485074],"rgb":[0.533333333333333326,0,0.933333333333333348],"xyz":[0.255840901893380157,0.114075901352201275,0.817457237172005358],"hpluv":[278.13468614008417,393.273926011730225,40.258648150966188],"hsluv":[278.13468614008417,99.9999999999999858,40.258648150966188]},"#8800ff":{"lch":[41.9294357887748674,134.280036872974534,276.305800055850909],"luv":[41.9294357887748674,14.7486383519278057,-133.467621426964229],"rgb":[0.533333333333333326,0,1],"xyz":[0.282011950303211578,0.124544320716133985,0.955291425463787203],"hpluv":[276.305800055850909,406.37947026199555,41.9294357887748674],"hsluv":[276.305800055850909,100.000000000000171,41.9294357887748674]},"#aa0000":{"lch":[35.0982840320529732,118.036634932245676,12.1770506300617765],"luv":[35.0982840320529732,115.380864984340803,24.8978549596859438],"rgb":[0.66666666666666663,0,0],"xyz":[0.165771937912151307,0.08547615548595483,0.00777055958963192815],"hpluv":[12.1770506300617765,426.746789183125145,35.0982840320529732],"hsluv":[12.1770506300617765,100.000000000002217,35.0982840320529732]},"#aa0011":{"lch":[35.178794604810534,115.883637018633408,11.1343823918443601],"luv":[35.178794604810534,113.702354404428164,22.3783808966644813],"rgb":[0.66666666666666663,0,0.0666666666666666657],"xyz":[0.166783603411788439,0.0858808216858096829,0.0130986645543875596],"hpluv":[11.1343823918443601,418.004049663923468,35.178794604810534],"hsluv":[11.1343823918443601,99.9999999999964473,35.178794604810534]},"#aa0022":{"lch":[35.327373324777,112.154849255399441,9.17432067350408431],"luv":[35.327373324777,110.720144559212301,17.8818287736043224],"rgb":[0.66666666666666663,0,0.133333333333333331],"xyz":[0.16865896155026544,0.0866309649412005,0.0229755507503667557],"hpluv":[9.17432067350408431,402.852473647417696,35.327373324777],"hsluv":[9.17432067350408431,99.9999999999965752,35.327373324777]},"#aa0033":{"lch":[35.5701485089931921,106.706281850707128,5.8788523359554592],"luv":[35.5701485089931921,106.14508040487398,10.9294323844098908],"rgb":[0.66666666666666663,0,0.2],"xyz":[0.171746712282723202,0.0878660652341836101,0.0392377046079779],"hpluv":[5.8788523359554592,380.665602767339294,35.5701485089931921],"hsluv":[5.8788523359554592,99.9999999999967741,35.5701485089931921]},"#aa0044":{"lch":[35.9166782648329104,100.198740700315142,1.0062433800652546],"luv":[35.9166782648329104,100.183288799466339,1.75962588401964615],"rgb":[0.66666666666666663,0,0.266666666666666663],"xyz":[0.176204707526942062,0.0896492633318711901,0.0627164795608645409],"hpluv":[1.0062433800652546,354.001763490246503,35.9166782648329104],"hsluv":[1.0062433800652546,99.999999999997,35.9166782648329104]},"#aa0055":{"lch":[36.3730398367095,93.6502679946689369,354.384147096436777],"luv":[36.3730398367095,93.2007806216229113,-9.16445235643848832],"rgb":[0.66666666666666663,0,0.333333333333333315],"xyz":[0.182167121566304047,0.092034228947616023,0.0941185268348384424],"hpluv":[354.384147096436777,326.714758289773386,36.3730398367095],"hsluv":[354.384147096436777,99.9999999999973,36.3730398367095]},"#aa0066":{"lch":[36.9423385777606228,88.2319659172366926,346.039412913085584],"luv":[36.9423385777606228,85.6257622699194,-21.2863488018886251],"rgb":[0.66666666666666663,0,0.4],"xyz":[0.189752117339812232,0.0950682272570193415,0.134066171241982418],"hpluv":[346.039412913085584,303.068568849792825,36.9423385777606228],"hsluv":[346.039412913085584,99.9999999999976126,36.9423385777606228]},"#aa0077":{"lch":[37.6250775946346891,84.9907340508927689,336.365700313169],"luv":[37.6250775946346891,77.8619577045834319,-34.0725757306260348],"rgb":[0.66666666666666663,0,0.466666666666666674],"xyz":[0.199066130360014137,0.0987938324651001509,0.183119973148380327],"hpluv":[336.365700313169,286.637826777930513,37.6250775946346891],"hsluv":[336.365700313169,99.9999999999979536,37.6250775946346891]},"#aa0088":{"lch":[38.4195160158879432,84.5572797483387717,326.161033183527252],"luv":[38.4195160158879432,70.2337789048813761,-47.0866208086656215],"rgb":[0.66666666666666663,0,0.533333333333333326],"xyz":[0.210206547461958,0.103249999305877749,0.241792836551952495],"hpluv":[326.161033183527252,279.279102381419364,38.4195160158879432],"hsluv":[326.161033183527252,99.9999999999982379,38.4195160158879432]},"#aa0099":{"lch":[39.3220484546604681,86.9871636461465272,316.374304421046759],"luv":[39.3220484546604681,62.9667468975572859,-60.0162929906574334],"rgb":[0.66666666666666663,0,0.6],"xyz":[0.223263511571030693,0.108472784949506906,0.310559514193070374],"hpluv":[316.374304421046759,280.710309296009257,39.3220484546604681],"hsluv":[316.374304421046759,99.9999999999986,39.3220484546604681]},"#aa00aa":{"lch":[40.3276007574525863,91.8597353001339627,307.715012949243601],"luv":[40.3276007574525863,56.1937545325413,-72.6668626056414411],"rgb":[0.66666666666666663,0,0.66666666666666663],"xyz":[0.238321204536283249,0.114495862135608,0.389863363810069],"hpluv":[307.715012949243601,289.042783730483393,40.3276007574525863],"hsluv":[307.715012949243601,99.9999999999988205,40.3276007574525863]},"#aa00bb":{"lch":[41.4300227805658849,98.5480850422065089,300.471226581677797],"luv":[41.4300227805658849,49.974285465742625,-84.9370111180893304],"rgb":[0.66666666666666663,0,0.733333333333333282],"xyz":[0.255458796643619868,0.121350898978542759,0.480121348908710721],"hpluv":[300.471226581677797,301.836908489583834,41.4300227805658849],"hsluv":[300.471226581677797,99.9999999999990621,41.4300227805658849]},"#aa00cc":{"lch":[42.6224565622471445,106.453892931925211,294.601049164416338],"luv":[42.6224565622471445,44.3164832708711813,-96.7909119228886681],"rgb":[0.66666666666666663,0,0.8],"xyz":[0.274751172087341622,0.129067849156031561,0.581727859578980877],"hpluv":[294.601049164416338,316.929304470761622,42.6224565622471445],"hsluv":[294.601049164416338,99.9999999999992895,42.6224565622471445]},"#aa00dd":{"lch":[43.8976622887243266,115.112632227118652,289.907671140995035],"luv":[43.8976622887243266,39.1964773946494063,-108.233794436426436],"rgb":[0.66666666666666663,0,0.866666666666666696],"xyz":[0.296269497637975165,0.137675179376285095,0.695057707478986875],"hpluv":[289.907671140995035,332.752186796280228,43.8976622887243266],"hsluv":[289.907671140995035,99.9999999999994174,43.8976622887243266]},"#aa00ee":{"lch":[45.2482911917969233,124.202454763835647,286.162342623679535],"luv":[45.2482911917969233,34.5729825657367655,-119.293581746345012],"rgb":[0.66666666666666663,0,0.933333333333333348],"xyz":[0.320081677904149875,0.14720005148275514,0.820468523547510098],"hpluv":[286.162342623679535,348.311106794177135,45.2482911917969233],"hsluv":[286.162342623679535,99.9999999999996589,45.2482911917969233]},"#aa00ff":{"lch":[46.667101462293175,133.514790614533382,283.159905061129905],"luv":[46.667101462293175,30.397247590160724,-130.008486845225434],"rgb":[0.66666666666666663,0,1],"xyz":[0.346252726313981296,0.157668470846687836,0.958302711839291943],"hpluv":[283.159905061129905,363.042841924949244,46.667101462293175],"hsluv":[283.159905061129905,99.9999999999998153,46.667101462293175]},"#881100":{"lch":[28.4751123640698864,88.1761994811112,13.8943544232398857],"luv":[28.4751123640698864,85.5961768878489124,21.1739617718743069],"rgb":[0.533333333333333326,0.0666666666666666657,0],"xyz":[0.103535562162309969,0.0563608058772578496,0.00542740663443661096],"hpluv":[13.8943544232398857,392.939109149716501,28.4751123640698864],"hsluv":[13.8943544232398857,100.000000000002331,28.4751123640698864]},"#881111":{"lch":[28.5813012406410962,85.6429421929893522,12.1770506300617782],"luv":[28.5813012406410962,83.7160154193071548,18.0649469909557752],"rgb":[0.533333333333333326,0.0666666666666666657,0.0666666666666666657],"xyz":[0.104547227661947087,0.0567654720771127,0.0107555115991922433],"hpluv":[12.1770506300617782,380.232213605760478,28.5813012406410962],"hsluv":[12.1770506300617782,89.1001931926906536,28.5813012406410962]},"#881122":{"lch":[28.776819878520115,81.4294437186752589,8.91447414891876377],"luv":[28.776819878520115,80.445837197505071,12.6183034487767767],"rgb":[0.533333333333333326,0.0666666666666666657,0.133333333333333331],"xyz":[0.106422585800424116,0.0575156153325035238,0.0206323977951714393],"hpluv":[8.91447414891876377,359.069069298387092,28.776819878520115],"hsluv":[8.91447414891876377,89.5522119422979,28.776819878520115]},"#881133":{"lch":[29.0950676619922959,75.7256767264573227,3.35964558590209394],"luv":[29.0950676619922959,75.5955308554484162,4.43777313107212557],"rgb":[0.533333333333333326,0.0666666666666666657,0.2],"xyz":[0.10951033653288185,0.0587507156254866367,0.0368945516527825826],"hpluv":[3.35964558590209394,330.265430862114329,29.0950676619922959],"hsluv":[3.35964558590209394,90.2199940579986475,29.0950676619922959]},"#881144":{"lch":[29.5467689283324617,69.8105982852884779,355.112641815866198],"luv":[29.5467689283324617,69.5567752183087435,-5.94765955478224484],"rgb":[0.533333333333333326,0.0666666666666666657,0.266666666666666663],"xyz":[0.113968331777100723,0.0605339137231742097,0.0603733266056692211],"hpluv":[355.112641815866198,299.81315922456514,29.5467689283324617],"hsluv":[355.112641815866198,91.0462468049379083,29.5467689283324617]},"#881155":{"lch":[30.1372440361953267,65.3247498846549,344.189828060851937],"luv":[30.1372440361953267,62.8534910411243928,-17.7977979378353552],"rgb":[0.533333333333333326,0.0666666666666666657,0.333333333333333315],"xyz":[0.119930745816462722,0.0629188793389190426,0.0917753738796431295],"hpluv":[344.189828060851937,275.05120204756264,30.1372440361953267],"hsluv":[344.189828060851937,91.9552565263170294,30.1372440361953267]},"#881166":{"lch":[30.8672249177773494,63.7021552959616173,331.50461515751158],"luv":[30.8672249177773494,55.9849923977636479,-30.3915319714745138],"rgb":[0.533333333333333326,0.0666666666666666657,0.4],"xyz":[0.127515741589970893,0.0659528776483223611,0.131723018286787091],"hpluv":[331.50461515751158,261.876101180723595,30.8672249177773494],"hsluv":[331.50461515751158,92.8754029221989299,30.8672249177773494]},"#881177":{"lch":[31.7336031237729514,65.5512880923603376,318.81152503011009],"luv":[31.7336031237729514,49.3304506912780525,-43.1680206305895737],"rgb":[0.533333333333333326,0.0666666666666666657,0.466666666666666674],"xyz":[0.136829754610172827,0.0696784828564031705,0.180776820193185],"hpluv":[318.81152503011009,262.120610410187965,31.7336031237729514],"hsluv":[318.81152503011009,93.7528273751248094,31.7336031237729514]},"#881188":{"lch":[32.7302234117729114,70.4946015177073377,307.715012949243658],"luv":[32.7302234117729114,43.1239685223607268,-55.7656900075914663],"rgb":[0.533333333333333326,0.0666666666666666657,0.533333333333333326],"xyz":[0.147970171712116627,0.0741346496971807684,0.239449683596757168],"hpluv":[307.715012949243658,273.304143969878908,32.7302234117729114],"hsluv":[307.715012949243658,94.5549099834012736,32.7302234117729114]},"#881199":{"lch":[33.8487030992268245,77.6382380820710836,298.861624073140206],"luv":[33.8487030992268245,37.4756592651389795,-67.9946393117248249],"rgb":[0.533333333333333326,0.0666666666666666657,0.6],"xyz":[0.161027135821189354,0.0793574353408099259,0.308216361237875103],"hpluv":[298.861624073140206,291.053592363859707,33.8487030992268245],"hsluv":[298.861624073140206,95.267111116431,33.8487030992268245]},"#8811aa":{"lch":[35.0792182273937954,86.1162494337963551,292.107316515455238],"luv":[35.0792182273937954,32.4092110837954692,-79.7850327659882623],"rgb":[0.533333333333333326,0.0666666666666666657,0.66666666666666663],"xyz":[0.176084828786441883,0.0853805125269110343,0.387520210854873703],"hpluv":[292.107316515455238,311.511817997128389,35.0792182273937954],"hsluv":[292.107316515455238,95.8874450484264571,35.0792182273937954]},"#8811bb":{"lch":[36.4111998559147381,95.3124415598142,287.019214731984619],"luv":[36.4111998559147381,27.8972267898096504,-91.1383906678789515],"rgb":[0.533333333333333326,0.0666666666666666657,0.733333333333333282],"xyz":[0.193222420893778557,0.0922355493698457929,0.47777819595351545],"hpluv":[287.019214731984619,332.16504711372977,36.4111998559147381],"hsluv":[287.019214731984619,96.4212920970111753,36.4111998559147381]},"#8811cc":{"lch":[37.8339039869932847,104.849214202707898,283.169050576302368],"luv":[37.8339039869932847,23.8872658659353974,-102.091900993053514],"rgb":[0.533333333333333326,0.0666666666666666657,0.8],"xyz":[0.212514796337500284,0.0999524995473346,0.579384706623785606],"hpluv":[283.169050576302368,351.660305548048939,37.8339039869932847],"hsluv":[283.169050576302368,96.8775739500717776,37.8339039869932847]},"#8811dd":{"lch":[39.3368423655390274,114.513051177954694,280.22024610097435],"luv":[39.3368423655390274,20.3183376083265372,-112.696069349906494],"rgb":[0.533333333333333326,0.0666666666666666657,0.866666666666666696],"xyz":[0.234033121888133827,0.108559829767588129,0.692714554523791604],"hpluv":[280.22024610097435,369.398236331583689,39.3368423655390274],"hsluv":[280.22024610097435,97.2663289333616348,39.3368423655390274]},"#8811ee":{"lch":[40.9100807353410261,124.189527798253138,277.928390028110698],"luv":[40.9100807353410261,17.130123009315259,-123.002429652583771],"rgb":[0.533333333333333326,0.0666666666666666657,0.933333333333333348],"xyz":[0.257845302154308564,0.118084701874058146,0.818125370592314827],"hpluv":[277.928390028110698,385.206818333834917,40.9100807353410261],"hsluv":[277.928390028110698,97.5973562787359867,40.9100807353410261]},"#8811ff":{"lch":[42.5444231432324926,133.820472646418182,276.120297984259253],"luv":[42.5444231432324926,14.2674470621751119,-133.057727523202459],"rgb":[0.533333333333333326,0.0666666666666666657,1],"xyz":[0.28401635056414,0.128553121237990842,0.955959558884096672],"hpluv":[276.120297984259253,399.134479754608662,42.5444231432324926],"hsluv":[276.120297984259253,99.9999999999993605,42.5444231432324926]},"#aa1100":{"lch":[35.8849415951509485,114.659477700983,13.2232466646238507],"luv":[35.8849415951509485,111.619416231509064,26.2278810962561089],"rgb":[0.66666666666666663,0.0666666666666666657,0],"xyz":[0.167776338173079714,0.0894849560078117,0.00843869300994137816],"hpluv":[13.2232466646238507,405.449754626827882,35.8849415951509485],"hsluv":[13.2232466646238507,100.000000000002245,35.8849415951509485]},"#aa1111":{"lch":[35.9630348414680086,112.584844162769954,12.1770506300617871],"luv":[35.9630348414680086,110.051736997450746,23.747890832642895],"rgb":[0.66666666666666663,0.0666666666666666657,0.0666666666666666657],"xyz":[0.168788003672716846,0.089889622207666553,0.0137667979746970096],"hpluv":[12.1770506300617871,397.249101663635656,35.9630348414680086],"hsluv":[12.1770506300617871,93.0877775141683514,35.9630348414680086]},"#aa1122":{"lch":[36.1071812157442409,108.986817867719594,10.2082214608018411],"luv":[36.1071812157442409,107.261576994584843,19.3152936702042],"rgb":[0.66666666666666663,0.0666666666666666657,0.133333333333333331],"xyz":[0.170663361811193848,0.0906397654630573674,0.0236436841706762074],"hpluv":[10.2082214608018411,383.018466712830786,36.1071812157442409],"hsluv":[10.2082214608018411,93.272361347425246,36.1071812157442409]},"#aa1133":{"lch":[36.3427932754706546,103.718469067724868,6.89182233030552727],"luv":[36.3427932754706546,102.969049051934846,12.4457126390109512],"rgb":[0.66666666666666663,0.0666666666666666657,0.2],"xyz":[0.173751112543651609,0.0918748657560404802,0.0399058380282873507],"hpluv":[6.89182233030552727,362.140519718911037,36.3427932754706546],"hsluv":[6.89182233030552727,93.5557024333493388,36.3427932754706546]},"#aa1144":{"lch":[36.6792659124992824,97.4113439982971698,1.97455903872184],"luv":[36.6792659124992824,97.3535035649005778,3.35637947697775552],"rgb":[0.66666666666666663,0.0666666666666666657,0.266666666666666663],"xyz":[0.178209107787870469,0.0936580638537280602,0.0633846129811739822],"hpluv":[1.97455903872184,336.99870087691761,36.6792659124992824],"hsluv":[1.97455903872184,93.9250914747756696,36.6792659124992824]},"#aa1155":{"lch":[37.1226754299384396,91.055498296574811,355.267689161716703],"luv":[37.1226754299384396,90.7450919896636634,-7.51212685096688926],"rgb":[0.66666666666666663,0.0666666666666666657,0.333333333333333315],"xyz":[0.184171521827232454,0.0960430294694729,0.0947866602551479],"hpluv":[355.267689161716703,311.247759321881176,37.1226754299384396],"hsluv":[355.267689161716703,94.3576556410013154,37.1226754299384396]},"#aa1166":{"lch":[37.6762679798416,85.8108023849569577,346.783206271719791],"luv":[37.6762679798416,83.5378398512485205,-19.6194576616503156],"rgb":[0.66666666666666663,0.0666666666666666657,0.4],"xyz":[0.191756517600740639,0.0990770277788762116,0.134734304662291859],"hpluv":[346.783206271719791,289.010360822200312,37.6762679798416],"hsluv":[346.783206271719791,94.8263018378468558,37.6762679798416]},"#aa1177":{"lch":[38.3408051028578285,82.7345113545946163,336.916515476294876],"luv":[38.3408051028578285,76.110335477500783,-32.4378822148708],"rgb":[0.66666666666666663,0.0666666666666666657,0.466666666666666674],"xyz":[0.201070530620942545,0.102802632986957021,0.183788106568689769],"hpluv":[336.916515476294876,273.819772016881302,38.3408051028578285],"hsluv":[336.916515476294876,95.3051408978498387,38.3408051028578285]},"#aa1188":{"lch":[39.1148927869010379,82.477083595297529,326.495944929629673],"luv":[39.1148927869010379,68.7732486834780445,-45.5270203714912753],"rgb":[0.66666666666666663,0.0666666666666666657,0.533333333333333326],"xyz":[0.212210947722886401,0.107258799827734619,0.242460969972261936],"hpluv":[326.495944929629673,267.565723971153261,39.1148927869010379],"hsluv":[326.495944929629673,95.7730681487448,39.1148927869010379]},"#aa1199":{"lch":[39.9953287808464424,85.1038505069809617,316.515705271857257],"luv":[39.9953287808464424,61.7482074461545665,-58.5647013848890552],"rgb":[0.66666666666666663,0.0666666666666666657,0.6],"xyz":[0.2252679118319591,0.112481585471363776,0.311227647613379843],"hpluv":[316.515705271857257,270.00963724100518,39.9953287808464424],"hsluv":[316.515705271857257,96.2151887572794,39.9953287808464424]},"#aa11aa":{"lch":[40.9774666162921406,90.1875437006381588,307.715012949243601],"luv":[40.9774666162921406,55.1708175083225498,-71.3440532505540261],"rgb":[0.66666666666666663,0.0666666666666666657,0.66666666666666663],"xyz":[0.240325604797211656,0.118504662657464871,0.390531497230378444],"hpluv":[307.715012949243601,279.28060733669264,40.9774666162921406],"hsluv":[307.715012949243601,96.6225842874192864,40.9774666162921406]},"#aa11bb":{"lch":[42.0555802442747719,97.087212137786878,300.384453602166161],"luv":[42.0555802442747719,49.106684193967304,-83.7523750598249705],"rgb":[0.66666666666666663,0.0666666666666666657,0.733333333333333282],"xyz":[0.257463196904548275,0.12535969950039963,0.48078948232902019],"hpluv":[300.384453602166161,292.939359498794147,42.0555802442747719],"hsluv":[300.384453602166161,96.9911870522472697,42.0555802442747719]},"#aa11cc":{"lch":[43.2232098485165395,105.192683835863036,294.469145625450437],"luv":[43.2232098485165395,43.5711419401365,-95.7447456658814247],"rgb":[0.66666666666666663,0.0666666666666666657,0.8],"xyz":[0.276755572348270029,0.133076649677888431,0.582395992999290346],"hpluv":[294.469145625450437,308.821726609797679,43.2232098485165395],"hsluv":[294.469145625450437,97.3204020480748255,43.2232098485165395]},"#aa11dd":{"lch":[44.4734721926781518,114.032755796715193,289.757274940509092],"luv":[44.4734721926781518,38.5472014936014489,-107.320001172218454],"rgb":[0.66666666666666663,0.0666666666666666657,0.866666666666666696],"xyz":[0.298273897898903573,0.141683979898141965,0.695725840899296344],"hpluv":[289.757274940509092,325.362808980276498,44.4734721926781518],"hsluv":[289.757274940509092,97.611854654502622,44.4734721926781518]},"#aa11ee":{"lch":[45.7993244881172,123.283094749558884,286.008743686799619],"luv":[45.7993244881172,33.9995108001485136,-118.502129585840351],"rgb":[0.66666666666666663,0.0666666666666666657,0.933333333333333348],"xyz":[0.322086078165078282,0.151208852004612,0.821136656967819567],"hpluv":[286.008743686799619,341.573194884792258,45.7993244881172],"hsluv":[286.008743686799619,97.8684161167955153,45.7993244881172]},"#aa11ff":{"lch":[47.1937769411101868,132.735165800167636,283.011169167098501],"luv":[47.1937769411101868,29.8841269734434611,-129.327348983241365],"rgb":[0.66666666666666663,0.0666666666666666657,1],"xyz":[0.348257126574909703,0.161677271368544706,0.958970845259601412],"hpluv":[283.011169167098501,356.89510187446183,47.1937769411101868],"hsluv":[283.011169167098501,99.9999999999993321,47.1937769411101868]},"#882200":{"lch":[30.3496916993887922,81.7292062801124786,17.2000641303745212],"luv":[30.3496916993887922,78.0741152618852254,24.1680716080335465],"rgb":[0.533333333333333326,0.133333333333333331,0],"xyz":[0.107251185897077911,0.0637920533467938311,0.00666594787935922105],"hpluv":[17.2000641303745212,341.713647377264522,30.3496916993887922],"hsluv":[17.2000641303745212,100.000000000002359,30.3496916993887922]},"#882211":{"lch":[30.4474919309639347,79.3871193031655338,15.4743840495427136],"luv":[30.4474919309639347,76.5093230935452908,21.181080969170015],"rgb":[0.533333333333333326,0.133333333333333331,0.0666666666666666657],"xyz":[0.108262851396715029,0.064196719546648684,0.0119940528441148525],"hpluv":[15.4743840495427136,330.855109199112462,30.4474919309639347],"hsluv":[15.4743840495427136,90.2707057474005,30.4474919309639347]},"#882222":{"lch":[30.6277058928754826,75.4670009360781648,12.1770506300618102],"luv":[30.6277058928754826,73.7690281561900321,15.9185022906448506],"rgb":[0.533333333333333326,0.133333333333333331,0.133333333333333331],"xyz":[0.110138209535192058,0.0649468628020395,0.0218709390400940486],"hpluv":[12.1770506300618102,312.666930334371557,30.6277058928754826],"hsluv":[12.1770506300618102,73.2675530922876277,30.6277058928754826]},"#882233":{"lch":[30.9214262019897674,70.1124269978110135,6.50693872003014],"luv":[30.9214262019897674,69.6607724946186266,7.94538828354938],"rgb":[0.533333333333333326,0.133333333333333331,0.2],"xyz":[0.113225960267649792,0.0661819630950226112,0.0381330928977051953],"hpluv":[6.50693872003014,287.723152758323693,30.9214262019897674],"hsluv":[6.50693872003014,74.8097141082451458,30.9214262019897674]},"#882244":{"lch":[31.3391119188553589,64.5127804411509,357.965654494967],"luv":[31.3391119188553589,64.472119792654567,-2.29011128326569047],"rgb":[0.533333333333333326,0.133333333333333331,0.266666666666666663],"xyz":[0.117683955511868665,0.0679651611927101912,0.0616118678505918338],"hpluv":[357.965654494967,261.215173773686786,31.3391119188553589],"hsluv":[357.965654494967,76.7464797952550839,31.3391119188553589]},"#882255":{"lch":[31.8864840032734449,60.2907989794282599,346.464164292394514],"luv":[31.8864840032734449,58.6161449596217778,-14.1112717942230379],"rgb":[0.533333333333333326,0.133333333333333331,0.333333333333333315],"xyz":[0.123646369551230664,0.0703501268084550241,0.0930139151245657353],"hpluv":[346.464164292394514,239.929545755427228,31.8864840032734449],"hsluv":[346.464164292394514,78.9147131880069566,31.8864840032734449]},"#882266":{"lch":[32.565220274416383,58.9629659850378189,332.945096803324191],"luv":[32.565220274416383,52.5107124518348698,-26.8189566455043362],"rgb":[0.533333333333333326,0.133333333333333331,0.4],"xyz":[0.131231365324738836,0.0733841251178583426,0.132961559531709711],"hpluv":[332.945096803324191,229.754818264706444,32.565220274416383],"hsluv":[332.945096803324191,81.1505919454384923,32.565220274416383]},"#882277":{"lch":[33.3735533542235316,61.2256527964903086,319.411642653163199],"luv":[33.3735533542235316,46.4949769025583564,-39.8346291960518499],"rgb":[0.533333333333333326,0.133333333333333331,0.466666666666666674],"xyz":[0.140545378344940741,0.077109730325939152,0.18201536143810762],"hpluv":[319.411642653163199,232.79320602780777,33.3735533542235316],"hsluv":[319.411642653163199,83.3222334130424116,33.3735533542235316]},"#882288":{"lch":[34.3068967831130962,66.691064714973308,307.715012949243771],"luv":[34.3068967831130962,40.7972144472485709,-52.7568517461189046],"rgb":[0.533333333333333326,0.133333333333333331,0.533333333333333326],"xyz":[0.151685795446884597,0.0815658971667167498,0.240688224841679788],"hpluv":[307.715012949243771,246.675229855048,34.3068967831130962],"hsluv":[307.715012949243771,85.3421167175917,34.3068967831130962]},"#882299":{"lch":[35.3585028262625087,74.3915148492043699,298.539568373309862],"luv":[35.3585028262625087,35.5417034620318262,-65.3520068289902554],"rgb":[0.533333333333333326,0.133333333333333331,0.6],"xyz":[0.164742759555957297,0.0867886828103459074,0.309454902482797667],"hpluv":[298.539568373309862,266.973934190138948,35.3585028262625087],"hsluv":[298.539568373309862,87.1641407220543556,35.3585028262625087]},"#8822aa":{"lch":[36.5201138266519365,83.3993900511107142,291.653660077047903],"luv":[36.5201138266519365,30.7739719973965897,-77.5140045953036463],"rgb":[0.533333333333333326,0.133333333333333331,0.66666666666666663],"xyz":[0.179800452521209853,0.092811759996447,0.388758752099796268],"hpluv":[291.653660077047903,289.781114528802732,36.5201138266519365],"hsluv":[291.653660077047903,88.7734689989794532,36.5201138266519365]},"#8822bb":{"lch":[37.7825623664262196,93.0686060696910857,286.53575696187113],"luv":[37.7825623664262196,26.4885972028076893,-89.2195026548722],"rgb":[0.533333333333333326,0.133333333333333331,0.733333333333333282],"xyz":[0.196938044628546471,0.0996667968393817605,0.479016737198438],"hpluv":[286.53575696187113,312.57276028475934,37.7825623664262196],"hsluv":[286.53575696187113,90.1753980157506874,37.7825623664262196]},"#8822cc":{"lch":[39.1362858369643476,103.012880313051866,282.702767559286599],"luv":[39.1362858369643476,22.6518448072254479,-100.491529181421669],"rgb":[0.533333333333333326,0.133333333333333331,0.8],"xyz":[0.216230420072268226,0.107383747016870562,0.580623247868708225],"hpluv":[282.702767559286599,334.003678399645651,39.1362858369643476],"hsluv":[282.702767559286599,91.3862929083300628,39.1362858369643476]},"#8822dd":{"lch":[40.5717373677475379,113.020349666590874,279.789793007972776],"luv":[40.5717373677475379,19.2172965257181652,-111.374570495248548],"rgb":[0.533333333333333326,0.133333333333333331,0.866666666666666696],"xyz":[0.237748745622901769,0.115991077237124096,0.693953095768714223],"hpluv":[279.789793007972776,353.486121759760863,40.5717373677475379],"hsluv":[279.789793007972776,92.4273238443811209,40.5717373677475379]},"#8822ee":{"lch":[42.0796906219744145,122.982600065668066,277.538986095624125],"luv":[42.0796906219744145,16.1354126197819454,-121.919515986988074],"rgb":[0.533333333333333326,0.133333333333333331,0.933333333333333348],"xyz":[0.261560925889076534,0.125515949343594141,0.819363911837237446],"hpluv":[277.538986095624125,370.860397035002336,42.0796906219744145],"hsluv":[277.538986095624125,93.320628909539181,42.0796906219744145]},"#8822ff":{"lch":[43.6514473624058752,132.848943476626658,275.771185477405766],"luv":[43.6514473624058752,13.3587518063908028,-132.175585994657865],"rgb":[0.533333333333333326,0.133333333333333331,1],"xyz":[0.2877319742989079,0.135984368707526837,0.957198100129019291],"hpluv":[275.771185477405766,386.188007357759091,43.6514473624058752],"hsluv":[275.771185477405766,99.9999999999994,43.6514473624058752]},"#ffaa00":{"lch":[76.0766826449234799,103.646966048157225,46.9849230608437125],"luv":[76.0766826449234799,70.7070052858721,75.7839889059127785],"rgb":[1,0.66666666666666663,0],"xyz":[0.556131758114240538,0.500120923568095,0.0672444716650198171],"hpluv":[46.9849230608437125,173.218766512771339,76.0766826449234799],"hsluv":[46.9849230608437125,100.0000000000028,76.0766826449234799]},"#ffaa11":{"lch":[76.1015101579349533,102.726050652762069,46.6846637022245687],"luv":[76.1015101579349533,70.4714195905473275,74.7423608377930719],"rgb":[1,0.66666666666666663,0.0666666666666666657],"xyz":[0.557143423613877697,0.500525589767949919,0.0725725766297754538],"hpluv":[46.6846637022245687,171.896872437304751,76.1015101579349533],"hsluv":[46.6846637022245687,100.000000000002771,76.1015101579349533]},"#ffaa22":{"lch":[76.1474983763177,101.038792737361192,46.1176753587789605],"luv":[76.1474983763177,70.0380208569547591,72.8252241483965719],"rgb":[1,0.66666666666666663,0.133333333333333331],"xyz":[0.559018781752354643,0.501275733023340719,0.0824494628257546464],"hpluv":[46.1176753587789605,169.470349592440897,76.1474983763177],"hsluv":[46.1176753587789605,100.0000000000028,76.1474983763177]},"#ffaa33":{"lch":[76.2231174741888395,98.3169656691378577,45.1538509265191337],"luv":[76.2231174741888395,69.3336656617894533,69.7070193329597885],"rgb":[1,0.66666666666666663,0.2],"xyz":[0.56210653248481246,0.502510833316323846,0.0987116166833657827],"hpluv":[45.1538509265191337,165.543337136749699,76.2231174741888395],"hsluv":[45.1538509265191337,100.000000000002927,76.2231174741888395]},"#ffaa44":{"lch":[76.3320756204529118,94.5107446089494516,43.6926927141772694],"luv":[76.3320756204529118,68.3364903114306514,65.2870962629968119],"rgb":[1,0.66666666666666663,0.266666666666666663],"xyz":[0.56656452772903132,0.504294031414011412,0.122190391636252421],"hpluv":[43.6926927141772694,160.025535099593441,76.3320756204529118],"hsluv":[43.6926927141772694,100.000000000003,76.3320756204529118]},"#ffaa55":{"lch":[76.4774026026215,89.6489515946998807,41.6012791226812411],"luv":[76.4774026026215,67.0379860163697288,59.5217855318358247],"rgb":[1,0.66666666666666663,0.333333333333333315],"xyz":[0.572526941768393249,0.506678997029756162,0.153592438910226337],"hpluv":[41.6012791226812411,152.933128718005122,76.4774026026215],"hsluv":[41.6012791226812411,100.000000000003,76.4774026026215]},"#ffaa66":{"lch":[76.6616205587261,83.8466863985853905,38.6944265301345354],"luv":[76.6616205587261,65.4416029270402788,52.418159318716242],"rgb":[1,0.66666666666666663,0.4],"xyz":[0.58011193754190149,0.50971299533915948,0.193540083317370298],"hpluv":[38.6944265301345354,144.405277715469396,76.6616205587261],"hsluv":[38.6944265301345354,100.000000000003197,76.6616205587261]},"#ffaa77":{"lch":[76.8868341725165,77.3210793721064533,34.7099370327462324],"luv":[76.8868341725165,63.5614296008349058,44.0283315873505927],"rgb":[1,0.66666666666666663,0.466666666666666674],"xyz":[0.58942595056210334,0.513438600547240331,0.242593885223768208],"hpluv":[34.7099370327462324,134.738986801151128,76.8868341725165],"hsluv":[34.7099370327462324,100.000000000003354,76.8868341725165]},"#ffaa88":{"lch":[77.1547840912050873,70.4186738688562741,29.282319230158226],"luv":[77.1547840912050873,61.4205932059712723,34.4427112706728948],"rgb":[1,0.66666666666666663,0.533333333333333326],"xyz":[0.600566367664047251,0.517894767388017874,0.301266748627340375],"hpluv":[29.282319230158226,124.451835787871019,77.1547840912050873],"hsluv":[29.282319230158226,100.000000000003638,77.1547840912050873]},"#ffaa99":{"lch":[77.466881654564645,63.658531214354845,21.9370110659791244],"luv":[77.466881654564645,59.0493431107362383,23.7820031654092716],"rgb":[1,0.66666666666666663,0.6],"xyz":[0.613623331773119896,0.523117553031647087,0.370033426268458254],"hpluv":[21.9370110659791244,114.385173247539697,77.466881654564645],"hsluv":[21.9370110659791244,100.000000000003624,77.466881654564645]},"#ffaaaa":{"lch":[77.8242336850598,57.783013099698,12.1770506300621957],"luv":[77.8242336850598,56.482921905318662,12.1883606739193855],"rgb":[1,0.66666666666666663,0.66666666666666663],"xyz":[0.628681024738372507,0.529140630217748154,0.44933727588545691],"hpluv":[12.1770506300621957,105.841692205508735,77.8242336850598],"hsluv":[12.1770506300621957,100.000000000003837,77.8242336850598]},"#ffaabb":{"lch":[78.227662021793833,53.7597014753195,359.804273109779956],"luv":[78.227662021793833,53.7593877986938224,-0.183647012281759531],"rgb":[1,0.66666666666666663,0.733333333333333282],"xyz":[0.64581861684570907,0.535995667060682912,0.539595260984098601],"hpluv":[359.804273109779956,100.661858044669231,78.227662021793833],"hsluv":[359.804273109779956,100.000000000004135,78.227662021793833]},"#ffaacc":{"lch":[78.6777204654413254,52.5946111834740293,345.492217824016791],"luv":[78.6777204654413254,50.9175596191628586,-13.1755549397286202],"rgb":[1,0.66666666666666663,0.8],"xyz":[0.665110992289430825,0.543712617238171769,0.641201771654368757],"hpluv":[345.492217824016791,100.966318741741958,78.6777204654413254],"hsluv":[345.492217824016791,100.000000000004306,78.6777204654413254]},"#ffaadd":{"lch":[79.1747106956411244,54.8892328831665353,330.97422205899818],"luv":[79.1747106956411244,47.9952274547753177,-26.6324243745640352],"rgb":[1,0.66666666666666663,0.866666666666666696],"xyz":[0.686629317840064424,0.552319947458425275,0.754531619554374755],"hpluv":[330.97422205899818,108.36723319715793,79.1747106956411244],"hsluv":[330.97422205899818,100.000000000004704,79.1747106956411244]},"#ffaaee":{"lch":[79.718698064048283,60.5009523664383337,318.094564198374599],"luv":[79.718698064048283,45.0277239197174595,-40.4087777080146822],"rgb":[1,0.66666666666666663,0.933333333333333348],"xyz":[0.710441498106239133,0.561844819564895293,0.879942435622898],"hpluv":[318.094564198374599,123.247069988098687,79.718698064048283],"hsluv":[318.094564198374599,100.000000000004945,79.718698064048283]},"#ffaaff":{"lch":[80.3095277487323074,68.733917080261989,307.715012949245647],"luv":[80.3095277487323074,42.0468973903394,-54.3728772187255203],"rgb":[1,0.66666666666666663,1],"xyz":[0.736612546516070554,0.572313238928828,1.01777662391468],"hpluv":[307.715012949245647,144.979279509576116,80.3095277487323074],"hsluv":[307.715012949245647,100.000000000005301,80.3095277487323074]},"#aa2200":{"lch":[37.2831780533064929,108.910935722579069,15.2092016225530191],"luv":[37.2831780533064929,105.096262108869439,28.5721474641225],"rgb":[0.66666666666666663,0.133333333333333331,0],"xyz":[0.171491961907847656,0.0969162034773476816,0.00967723425486398912],"hpluv":[15.2092016225530191,370.67892165569458,37.2831780533064929],"hsluv":[15.2092016225530191,100.000000000002217,37.2831780533064929]},"#aa2211":{"lch":[37.3572350214345619,106.95640568906397,14.158492547926917],"luv":[37.3572350214345619,103.707370245599336,26.1620732103901794],"rgb":[0.66666666666666663,0.133333333333333331,0.0666666666666666657],"xyz":[0.172503627407484789,0.0973208696772025345,0.0150053392196196206],"hpluv":[14.158492547926917,363.305022455593,37.3572350214345619],"hsluv":[14.158492547926917,93.5777596020973732,37.3572350214345619]},"#aa2222":{"lch":[37.4939757158163331,103.55828406892158,12.1770506300617907],"luv":[37.4939757158163331,101.228270350344232,21.8438888748564],"rgb":[0.66666666666666663,0.133333333333333331,0.133333333333333331],"xyz":[0.17437898554596179,0.0980710129325933488,0.0248822254155988166],"hpluv":[12.1770506300617907,350.479546677114797,37.4939757158163331],"hsluv":[12.1770506300617907,82.128221128038831,37.4939757158163331]},"#aa2233":{"lch":[37.7176061419824791,98.5638584928897359,8.82735266140639],"luv":[37.7176061419824791,97.3963926843060506,15.125372494284127],"rgb":[0.66666666666666663,0.133333333333333331,0.2],"xyz":[0.177466736278419523,0.0993061132255764617,0.0411443792732099634],"hpluv":[8.82735266140639,331.598763076121088,37.7176061419824791],"hsluv":[8.82735266140639,82.8309253801110401,37.7176061419824791]},"#aa2244":{"lch":[38.0372287502177358,92.5577577991589209,3.83362915136278648],"luv":[38.0372287502177358,92.350650343690134,6.18836892123021798],"rgb":[0.66666666666666663,0.133333333333333331,0.266666666666666663],"xyz":[0.181924731522638411,0.101089311323264042,0.0646231542260966],"hpluv":[3.83362915136278648,308.775819843535,38.0372287502177358],"hsluv":[3.83362915136278648,83.7532195801290698,38.0372287502177358]},"#aa2255":{"lch":[38.4588905236098242,86.4856662057644172,356.973865768881865],"luv":[38.4588905236098242,86.3650670431288603,-4.56570407393633459],"rgb":[0.66666666666666663,0.133333333333333331,0.333333333333333315],"xyz":[0.187887145562000424,0.103474276939008875,0.0960252015000705],"hpluv":[356.973865768881865,285.355803984318584,38.4588905236098242],"hsluv":[356.973865768881865,84.8422496447961,38.4588905236098242]},"#aa2266":{"lch":[38.9860395203518237,81.4924101374980268,348.227712846231327],"luv":[38.9860395203518237,79.7783138580272464,-16.6262908668256522],"rgb":[0.66666666666666663,0.133333333333333331,0.4],"xyz":[0.195472141335508581,0.106508275248412193,0.135972845907214479],"hpluv":[348.227712846231327,265.245100213362434,38.9860395203518237],"hsluv":[348.227712846231327,86.0332228090823747,38.9860395203518237]},"#aa2277":{"lch":[39.619833929041036,78.6591168776988354,337.990195281021442],"luv":[39.619833929041036,72.9264197190586572,-29.4787037526953952],"rgb":[0.66666666666666663,0.133333333333333331,0.466666666666666674],"xyz":[0.204786154355710515,0.110233880456493,0.185026647813612388],"hpluv":[337.990195281021442,251.92759566726761,39.619833929041036],"hsluv":[337.990195281021442,87.2621982611374278,39.619833929041036]},"#aa2288":{"lch":[40.3594266716885386,78.6767938432408,327.148786779116733],"luv":[40.3594266716885386,66.0949636498191637,-42.6789605025813046],"rgb":[0.66666666666666663,0.133333333333333331,0.533333333333333326],"xyz":[0.215926571457654315,0.1146900472972706,0.243699511217184556],"hpluv":[327.148786779116733,247.366561360315984,40.3594266716885386],"hsluv":[327.148786779116733,88.4751585260979283,40.3594266716885386]},"#aa2299":{"lch":[41.2022629883412748,81.6302410017403162,316.790315261789033],"luv":[41.2022629883412748,59.4964385039503,-55.8898027492302489],"rgb":[0.66666666666666663,0.133333333333333331,0.6],"xyz":[0.228983535566727042,0.119912832940899758,0.312466188858302463],"hpluv":[316.790315261789033,251.402351399829286,41.2022629883412748],"hsluv":[316.790315261789033,89.6322731802278554,41.2022629883412748]},"#aa22aa":{"lch":[42.1443943233873242,87.0780915666379229,307.715012949243715],"luv":[42.1443943233873242,53.2686588598376076,-68.8842798769212834],"rgb":[0.66666666666666663,0.133333333333333331,0.66666666666666663],"xyz":[0.24404122853197957,0.125935910127000866,0.391770038475301063],"hpluv":[307.715012949243715,262.185344504614818,42.1443943233873242],"hsluv":[307.715012949243715,90.7081440057972515,42.1443943233873242]},"#aa22bb":{"lch":[43.1807973125030387,94.3504956605328573,300.218008125398399],"luv":[43.1807973125030387,47.4858085519839577,-81.5298351375283801],"rgb":[0.66666666666666663,0.133333333333333331,0.733333333333333282],"xyz":[0.261178820639316245,0.132790946969935625,0.48202802357394281],"hpluv":[300.218008125398399,277.263598469343151,43.1807973125030387],"hsluv":[300.218008125398399,91.6896384965505291,43.1807973125030387]},"#aa22cc":{"lch":[44.3056820912093627,102.813108633557576,294.217612554784239],"luv":[44.3056820912093627,42.1742864712375294,-93.764944769021767],"rgb":[0.66666666666666663,0.133333333333333331,0.8],"xyz":[0.280471196083037944,0.140507897147424426,0.583634534244213],"hpluv":[294.217612554784239,294.461411899371626,44.3056820912093627],"hsluv":[294.217612554784239,92.5728114271618097,44.3056820912093627]},"#aa22dd":{"lch":[45.5127751844210451,111.980933923074502,289.471886144522102],"luv":[45.5127751844210451,37.3282042805071441,-105.576203414769125],"rgb":[0.66666666666666663,0.133333333333333331,0.866666666666666696],"xyz":[0.301989521633671543,0.14911522736767796,0.696964382144219],"hpluv":[289.471886144522102,312.212361278410071,45.5127751844210451],"hsluv":[289.471886144522102,93.3598993754704622,45.5127751844210451]},"#aa22ee":{"lch":[46.7955661660676938,121.524022862348417,285.718434714393425],"luv":[46.7955661660676938,32.9220942551774698,-116.979587289842115],"rgb":[0.66666666666666663,0.133333333333333331,0.933333333333333348],"xyz":[0.325801701899846252,0.158640099474147978,0.822375198212742187],"hpluv":[285.718434714393425,329.531365671141714,46.7955661660676938],"hsluv":[285.718434714393425,94.0568560040361348,46.7955661660676938]},"#aa22ff":{"lch":[48.1475121680676921,131.233078667623346,282.730941389390409],"luv":[48.1475121680676921,28.9202258451599548,-128.006802450680539],"rgb":[0.66666666666666663,0.133333333333333331,1],"xyz":[0.351972750309677673,0.169108518838080701,0.960209386504524],"hpluv":[282.730941389390409,345.866733454918517,48.1475121680676921],"hsluv":[282.730941389390409,99.9999999999992,48.1475121680676921]},"#883300":{"lch":[33.1414787667816597,73.2165592554870841,22.9600016117944072],"luv":[33.1414787667816597,67.4161530625393084,28.5609323282788417],"rgb":[0.533333333333333326,0.2,0],"xyz":[0.113368907986088716,0.076027497524815621,0.00870518857569610102],"hpluv":[22.9600016117944072,280.334636286210525,33.1414787667816597],"hsluv":[22.9600016117944072,100.000000000002245,33.1414787667816597]},"#883311":{"lch":[33.2285118286029402,71.0572306739368287,21.2511434941679589],"luv":[33.2285118286029402,66.2253841559006844,25.7551650053430592],"rgb":[0.533333333333333326,0.2,0.0666666666666666657],"xyz":[0.114380573485725834,0.0764321637246704738,0.0140332935404517325],"hpluv":[21.2511434941679589,271.354302974885854,33.2285118286029402],"hsluv":[21.2511434941679589,91.7325092821930355,33.2285118286029402]},"#883322":{"lch":[33.389038834633638,67.403958774683133,17.9527330699243208],"luv":[33.389038834633638,64.1221355411587126,20.7760774002325519],"rgb":[0.533333333333333326,0.2,0.133333333333333331],"xyz":[0.116255931624202863,0.0771823069800612882,0.0239101797364309268],"hpluv":[17.9527330699243208,256.165602847605,33.389038834633638],"hsluv":[17.9527330699243208,77.1564226992543354,33.389038834633638]},"#883333":{"lch":[33.6510932573449324,62.3280121609532785,12.1770506300618564],"luv":[33.6510932573449324,60.9256605799824484,13.1470522486492083],"rgb":[0.533333333333333326,0.2,0.2],"xyz":[0.119343682356660596,0.0784174072730444,0.04017233359404207],"hpluv":[12.1770506300618564,235.030067027939708,33.6510932573449324],"hsluv":[12.1770506300618564,55.0748296144977,33.6510932573449324]},"#883344":{"lch":[34.0246284162643136,56.9037682047597428,3.23132728809417369],"luv":[34.0246284162643136,56.8132965471078748,3.20751794249172528],"rgb":[0.533333333333333326,0.2,0.266666666666666663],"xyz":[0.12380167760087947,0.080200605370731981,0.0636511085469287086],"hpluv":[3.23132728809417369,212.220318588139889,34.0246284162643136],"hsluv":[3.23132728809417369,58.083398150148156,34.0246284162643136]},"#883355":{"lch":[34.5156618951709859,52.7529688087382524,350.767304332875],"luv":[34.5156618951709859,52.0695471674777721,-8.46392201697997137],"rgb":[0.533333333333333326,0.2,0.333333333333333315],"xyz":[0.129764091640241469,0.0825855709864768139,0.0950531558209026239],"hpluv":[350.767304332875,193.941176615342812,34.5156618951709859],"hsluv":[350.767304332875,61.5291535706030714,34.5156618951709859]},"#883366":{"lch":[35.1268460128593318,51.5738240122621576,335.705329263136434],"luv":[35.1268460128593318,47.0065260432940519,-21.2189969741481157],"rgb":[0.533333333333333326,0.2,0.4],"xyz":[0.137349087413749654,0.0856195692958801324,0.135000800228046586],"hpluv":[335.705329263136434,186.307141954737205,35.1268460128593318],"hsluv":[335.705329263136434,65.1713869724459869,35.1268460128593318]},"#883377":{"lch":[35.8579115963162849,54.2604071268956929,320.552373035814298],"luv":[35.8579115963162849,41.9001950458929713,-34.4755773946224],"rgb":[0.533333333333333326,0.2,0.466666666666666674],"xyz":[0.14666310043395156,0.0893451745039609418,0.184054602134444495],"hpluv":[320.552373035814298,192.015984070736607,35.8579115963162849],"hsluv":[320.552373035814298,68.798738775930957,35.8579115963162849]},"#883388":{"lch":[36.7061150242973682,60.4128011412536097,307.715012949244056],"luv":[36.7061150242973682,36.9565850245806402,-47.7903480323547711],"rgb":[0.533333333333333326,0.2,0.533333333333333326],"xyz":[0.157803517535895388,0.0938013413447385397,0.242727465538016662],"hpluv":[307.715012949244056,208.847787272345244,36.7061150242973682],"hsluv":[307.715012949244056,72.2549736675254479,36.7061150242973682]},"#883399":{"lch":[37.6667130487112445,68.9141309342046213,297.955533412138379],"luv":[37.6667130487112445,32.3059919210196611,-60.8726566564636684],"rgb":[0.533333333333333326,0.2,0.6],"xyz":[0.170860481644968087,0.0990241269883677,0.311494143179134542],"hpluv":[297.955533412138379,232.161331922109071,37.6667130487112445],"hsluv":[297.955533412138379,75.4431641885032604,37.6667130487112445]},"#8833aa":{"lch":[38.7334497692602824,78.7159372772915162,290.848124870138179],"luv":[38.7334497692602824,28.0143748789862741,-73.5621749378178436],"rgb":[0.533333333333333326,0.2,0.66666666666666663],"xyz":[0.185918174610220643,0.105047204174468806,0.390797992796133142],"hpluv":[290.848124870138179,257.878905714084965,38.7334497692602824],"hsluv":[290.848124870138179,78.3166072053086282,38.7334497692602824]},"#8833bb":{"lch":[39.8990272727434743,89.1142300257769193,285.691107407551272],"luv":[39.8990272727434743,24.1010351313191435,-85.7932753698447073],"rgb":[0.533333333333333326,0.2,0.733333333333333282],"xyz":[0.20305576671755729,0.111902241017403564,0.481055977894774889],"hpluv":[285.691107407551272,283.415812953045702,39.8990272727434743],"hsluv":[285.691107407551272,80.8649153118493444,39.8990272727434743]},"#8833cc":{"lch":[41.1555326498064318,99.7027359993818578,281.897918690971494],"luv":[41.1555326498064318,20.5555775093346966,-97.560769774639283],"rgb":[0.533333333333333326,0.2,0.8],"xyz":[0.222348142161279017,0.119619191194892366,0.5826624885650451],"hpluv":[281.897918690971494,307.410130900702256,41.1555326498064318],"hsluv":[281.897918690971494,83.1006969987668356,41.1555326498064318]},"#8833dd":{"lch":[42.4948021164729042,110.266949448261684,279.053462184119098],"luv":[42.4948021164729042,17.3511661022166734,-108.893237510502843],"rgb":[0.533333333333333326,0.2,0.866666666666666696],"xyz":[0.24386646771191256,0.1282265214151459,0.695992336465051098],"hpluv":[279.053462184119098,329.267506795456711,42.4948021164729042],"hsluv":[279.053462184119098,85.0491409670088103,42.4948021164729042]},"#8833ee":{"lch":[43.9087129541284185,120.703343561802441,276.877390721452173],"luv":[43.9087129541284185,14.4536316684396038,-119.834843341123431],"rgb":[0.533333333333333326,0.2,0.933333333333333348],"xyz":[0.267678647978087325,0.137751393521615917,0.821403152533574321],"hpluv":[276.877390721452173,348.825254458779511,43.9087129541284185],"hsluv":[276.877390721452173,90.7214777394212177,43.9087129541284185]},"#8833ff":{"lch":[45.3894029264418037,130.969293653816607,275.181129330284705],"luv":[45.3894029264418037,11.8271264623124566,-130.43417864894198],"rgb":[0.533333333333333326,0.2,1],"xyz":[0.293849696387918691,0.148219812885548641,0.959237340825356166],"hpluv":[275.181129330284705,366.146040402293636,45.3894029264418037],"hsluv":[275.181129330284705,99.9999999999993179,45.3894029264418037]},"#ffbb00":{"lch":[80.0686585320779614,99.7432534700870832,55.1804439586775146],"luv":[80.0686585320779614,56.9527800089419642,81.8846595037867928],"rgb":[1,0.733333333333333282,0],"xyz":[0.590086256022839262,0.568029919385293569,0.0785626376345524291],"hpluv":[55.1804439586775146,207.400278899961506,80.0686585320779614],"hsluv":[55.1804439586775146,100.000000000004661,80.0686585320779614]},"#ffbb11":{"lch":[80.0914663159454,98.8408701901197304,54.9443852376931758],"luv":[80.0914663159454,56.7713575947746136,80.9106332739172558],"rgb":[1,0.733333333333333282,0.0666666666666666657],"xyz":[0.591097921522476422,0.568434585585148477,0.0838907425993080658],"hpluv":[54.9443852376931758,205.801067903733326,80.0914663159454],"hsluv":[54.9443852376931758,100.000000000004746,80.0914663159454]},"#ffbb22":{"lch":[80.1337172522408849,97.1832370837577173,54.4980435584705063],"luv":[80.1337172522408849,56.4372945908461148,79.11645435270664],"rgb":[1,0.733333333333333282,0.133333333333333331],"xyz":[0.592973279660953367,0.569184728840539278,0.0937676287952872584],"hpluv":[54.4980435584705063,202.856099527528187,80.1337172522408849],"hsluv":[54.4980435584705063,100.00000000000469,80.1337172522408849]},"#ffbb33":{"lch":[80.2032020182086569,94.4967793168558643,53.7374633716008248],"luv":[80.2032020182086569,55.8935303906135772,76.1941898161015558],"rgb":[1,0.733333333333333282,0.2],"xyz":[0.596061030393411184,0.570419829133522405,0.110029782652898395],"hpluv":[53.7374633716008248,198.062979410590685,80.2032020182086569],"hsluv":[53.7374633716008248,100.000000000004576,80.2032020182086569]},"#ffbb44":{"lch":[80.3033451682561,90.7120739700224874,52.5796541788809932],"luv":[80.3033451682561,55.1219083097901148,72.0434284874749835],"rgb":[1,0.733333333333333282,0.266666666666666663],"xyz":[0.60051902563763,0.57220302723121,0.133508557605785033],"hpluv":[52.5796541788809932,191.266883403483888,80.3033451682561],"hsluv":[52.5796541788809932,100.000000000004732,80.3033451682561]},"#ffbb55":{"lch":[80.4369584648287343,85.824023801574981,50.9113466162360169],"luv":[80.4369584648287343,54.1139445833304435,66.614143116349922],"rgb":[1,0.733333333333333282,0.333333333333333315],"xyz":[0.606481439676992,0.57458799284695472,0.164910604879758949],"hpluv":[50.9113466162360169,182.412290123698938,80.4369584648287343],"hsluv":[50.9113466162360169,100.000000000004846,80.4369584648287343]},"#ffbb66":{"lch":[80.6063993458739532,79.8959983704508545,48.5678239065140147],"luv":[80.6063993458739532,52.8698192869345931,59.9011916757752374],"rgb":[1,0.733333333333333282,0.4],"xyz":[0.614066435450500214,0.577621991156358,0.20485824928690291],"hpluv":[48.5678239065140147,171.553596694327723,80.6063993458739532],"hsluv":[48.5678239065140147,100.000000000004945,80.6063993458739532]},"#ffbb77":{"lch":[80.8136549908608828,73.0715029906331353,45.3006510664637219],"luv":[80.8136549908608828,51.397517928562209,51.9397699272266067],"rgb":[1,0.733333333333333282,0.466666666666666674],"xyz":[0.623380448470702064,0.58134759636443889,0.253912051193300847],"hpluv":[45.3006510664637219,158.885762577352,80.8136549908608828],"hsluv":[45.3006510664637219,100.000000000005144,80.8136549908608828]},"#ffbb88":{"lch":[81.0603921498240823,65.5982066090816,40.7273497798256443],"luv":[81.0603921498240823,49.7118280718431649,42.8002203275083914],"rgb":[1,0.733333333333333282,0.533333333333333326],"xyz":[0.634520865572646,0.585803763205216432,0.312584914596873],"hpluv":[40.7273497798256443,144.809180382553194,81.0603921498240823],"hsluv":[40.7273497798256443,100.0000000000054,81.0603921498240823]},"#ffbb99":{"lch":[81.347989327564818,57.8755898316684423,34.2609783084776538],"luv":[81.347989327564818,47.8331272298795724,32.5818329406692087],"rgb":[1,0.733333333333333282,0.6],"xyz":[0.64757782968171862,0.591026548848845645,0.381351592237990866],"hpluv":[34.2609783084776538,130.060421106466862,81.347989327564818],"hsluv":[34.2609783084776538,100.000000000005514,81.347989327564818]},"#ffbbaa":{"lch":[81.6775593509345725,50.5427251754064883,25.056975338279841],"luv":[81.6775593509345725,45.7860019440054415,21.405819165362459],"rgb":[1,0.733333333333333282,0.66666666666666663],"xyz":[0.662635522646971231,0.597049626034946712,0.460655441854989522],"hpluv":[25.056975338279841,115.96007016550756,81.6775593509345725],"hsluv":[25.056975338279841,100.000000000005954,81.6775593509345725]},"#ffbbbb":{"lch":[82.0499666293022,44.6012959670408264,12.1770506300623094],"luv":[82.0499666293022,43.5977873399533138,9.40789779917804125],"rgb":[1,0.733333333333333282,0.733333333333333282],"xyz":[0.679773114754307795,0.603904662877881471,0.550913426953631213],"hpluv":[12.1770506300623094,104.793068167285782,82.0499666293022],"hsluv":[12.1770506300623094,100.000000000006168,82.0499666293022]},"#ffbbcc":{"lch":[82.4658415859876,41.4263127316455169,355.474040938847054],"luv":[82.4658415859876,41.2971323922898534,-3.26898190783910625],"rgb":[1,0.733333333333333282,0.8],"xyz":[0.699065490198029549,0.611621613055370328,0.652519937623901369],"hpluv":[355.474040938847054,100.004408983591958,82.4658415859876],"hsluv":[355.474040938847054,100.000000000006509,82.4658415859876]},"#ffbbdd":{"lch":[82.9255937413379,42.2590852539423381,337.045135839305544],"luv":[82.9255937413379,38.9126886018087319,-16.4812909773061058],"rgb":[1,0.733333333333333282,0.866666666666666696],"xyz":[0.720583815748663148,0.620228943275623834,0.765849785523907367],"hpluv":[337.045135839305544,105.181583048825317,82.9255937413379],"hsluv":[337.045135839305544,100.000000000006992,82.9255937413379]},"#ffbbee":{"lch":[83.4294243398036315,47.2826492521794748,320.476273654572083],"luv":[83.4294243398036315,36.4719970678196077,-30.0905691237235686],"rgb":[1,0.733333333333333282,0.933333333333333348],"xyz":[0.744395996014837857,0.629753815382093851,0.89126060159243059],"hpluv":[320.476273654572083,121.793886282549721,83.4294243398036315],"hsluv":[320.476273654572083,100.000000000007375,83.4294243398036315]},"#ffbbff":{"lch":[83.9773390427358493,55.5806936350452148,307.715012949246614],"luv":[83.9773390427358493,34.0006189291922496,-43.9678452665650781],"rgb":[1,0.733333333333333282,1],"xyz":[0.770567044424669279,0.640222234746026575,1.02909478988421244],"hpluv":[307.715012949246614,148.765749509941259,83.9773390427358493],"hsluv":[307.715012949246614,100.00000000000793,83.9773390427358493]},"#aa3300":{"lch":[39.4372171279304595,100.717281062042773,18.6056676884160446],"luv":[39.4372171279304595,95.4534790945485838,32.1341568004684959],"rgb":[0.66666666666666663,0.2,0],"xyz":[0.177609683996858475,0.109151647655369471,0.0117164749512008691],"hpluv":[18.6056676884160446,324.068678498457416,39.4372171279304595],"hsluv":[18.6056676884160446,100.00000000000226,39.4372171279304595]},"#aa3311":{"lch":[39.5056415087576553,98.9056898290362199,17.5539290045831464],"luv":[39.5056415087576553,94.2999972712563,29.8302865423477179],"rgb":[0.66666666666666663,0.2,0.0666666666666666657],"xyz":[0.178621349496495607,0.109556313855224324,0.0170445799159565023],"hpluv":[17.5539290045831464,317.688492914835,39.5056415087576553],"hsluv":[17.5539290045831464,94.2489803369173558,39.5056415087576553]},"#aa3322":{"lch":[39.6320377265530155,95.7434230458582789,15.5633947922033684],"luv":[39.6320377265530155,92.2329117474569102,25.688383505468213],"rgb":[0.66666666666666663,0.2,0.133333333333333331],"xyz":[0.180496707634972609,0.110306457110615139,0.0269214661119356949],"hpluv":[15.5633947922033684,306.55039093266322,39.6320377265530155],"hsluv":[15.5633947922033684,83.9544037116345123,39.6320377265530155]},"#aa3333":{"lch":[39.8389046640011415,91.0660982539230162,12.1770506300618351],"luv":[39.8389046640011415,89.0171529654153488,19.2088711049089049],"rgb":[0.66666666666666663,0.2,0.2],"xyz":[0.18358445836743037,0.111541557403598252,0.0431836199695468381],"hpluv":[12.1770506300618351,290.060550373943784,39.8389046640011415],"hsluv":[12.1770506300618351,67.9701775681036366,39.8389046640011415]},"#aa3344":{"lch":[40.1348956250933142,85.3951569144799691,7.07959423789482756],"luv":[40.1348956250933142,84.7440953003879116,10.5247867516366789],"rgb":[0.66666666666666663,0.2,0.266666666666666663],"xyz":[0.18804245361164923,0.113324755501285832,0.0666623949224334766],"hpluv":[7.07959423789482756,269.991710008472637,40.1348956250933142],"hsluv":[7.07959423789482756,69.5294395234689659,40.1348956250933142]},"#aa3355":{"lch":[40.5259588707466,79.61783322386637,359.98582832830067],"luv":[40.5259588707466,79.6178307884273693,-0.0196928603108827253],"rgb":[0.66666666666666663,0.2,0.333333333333333315],"xyz":[0.194004867651011215,0.115709721117030664,0.098064442196407392],"hpluv":[359.98582832830067,249.296614878837403,40.5259588707466],"hsluv":[359.98582832830067,71.3920974276079079,40.5259588707466]},"#aa3366":{"lch":[41.0157539995587683,74.8661602955128558,350.806369630673316],"luv":[41.0157539995587683,73.9044320805857,-11.9614746682639641],"rgb":[0.66666666666666663,0.2,0.4],"xyz":[0.2015898634245194,0.118743719426433983,0.138012086603551354],"hpluv":[350.806369630673316,231.619002340768361,41.0157539995587683],"hsluv":[350.806369630673316,73.4562780141226597,41.0157539995587683]},"#aa3377":{"lch":[41.6059173351841167,72.2728884464882668,339.921631600955322],"luv":[41.6059173351841167,67.8804264173117531,-24.8116527825629412],"rgb":[0.66666666666666663,0.2,0.466666666666666674],"xyz":[0.210903876444721305,0.122469324634514792,0.187065888509949263],"hpluv":[339.921631600955322,220.424384448141751,41.6059173351841167],"hsluv":[339.921631600955322,75.6166865764569138,41.6059173351841167]},"#aa3388":{"lch":[42.296293156356171,72.6091331125239918,328.324027314743319],"luv":[42.296293156356171,61.7926517819245191,-38.1281313089174],"rgb":[0.66666666666666663,0.2,0.533333333333333326],"xyz":[0.222044293546665161,0.12692549147529239,0.24573875191352143],"hpluv":[328.324027314743319,217.83530631356345,42.296293156356171],"hsluv":[328.324027314743319,77.7798333688196237,42.296293156356171]},"#aa3399":{"lch":[43.0851702185186838,75.9982874692542794,317.281450106519685],"luv":[43.0851702185186838,55.835561651799118,-51.5570533805758799],"rgb":[0.66666666666666663,0.2,0.6],"xyz":[0.235101257655737861,0.132148277118921548,0.314505429554639337],"hpluv":[317.281450106519685,223.828466633931441,43.0851702185186838],"hsluv":[317.281450106519685,79.8726039522015441,43.0851702185186838]},"#aa33aa":{"lch":[43.9695321467927229,81.9717995507402861,307.715012949243828],"luv":[43.9695321467927229,50.1449646844158607,-64.8448798162617521],"rgb":[0.66666666666666663,0.2,0.66666666666666663],"xyz":[0.250158950620990417,0.138171354305022642,0.393809279171637938],"hpluv":[307.715012949243828,236.565795567314069,43.9695321467927229],"hsluv":[307.715012949243828,81.8445603498948628,43.9695321467927229]},"#aa33bb":{"lch":[44.9453163823579231,89.8045713491188593,299.92695612823394],"luv":[44.9453163823579231,44.8030997809084,-77.8302208992172],"rgb":[0.66666666666666663,0.2,0.733333333333333282],"xyz":[0.267296542728327036,0.145026391147957401,0.484067264270279685],"hpluv":[299.92695612823394,253.543994890590483,44.9453163823579231],"hsluv":[299.92695612823394,83.6659201788580305,44.9453163823579231]},"#aa33cc":{"lch":[46.0076707905516145,98.8168321279874249,293.782406660809556],"luv":[46.0076707905516145,39.8493034294229815,-90.425656359246986],"rgb":[0.66666666666666663,0.2,0.8],"xyz":[0.28658891817204879,0.152743341325446202,0.585673774940549841],"hpluv":[293.782406660809556,272.546121846523647,46.0076707905516145],"hsluv":[293.782406660809556,85.323407183561244,46.0076707905516145]},"#aa33dd":{"lch":[47.1511962508372804,108.497592079042477,288.982430572084695],"luv":[47.1511962508372804,35.2919015872993782,-102.597315604759743],"rgb":[0.66666666666666663,0.2,0.866666666666666696],"xyz":[0.308107243722682334,0.161350671545699736,0.699003622840555838],"hpluv":[288.982430572084695,291.989148013150611,47.1511962508372804],"hsluv":[288.982430572084695,86.8156421407842771,47.1511962508372804]},"#aa33ee":{"lch":[48.3701654903461247,118.505438755587946,285.224041333998457],"luv":[48.3701654903461247,31.1188262963008349,-114.346655677352729],"rgb":[0.66666666666666663,0.2,0.933333333333333348],"xyz":[0.331919423988857099,0.170875543652169781,0.824414438909079061],"hpluv":[285.224041333998457,310.885191630161273,48.3701654903461247],"hsluv":[285.224041333998457,89.3017266962351215,48.3701654903461247]},"#aa33ff":{"lch":[49.6587116356326135,128.627945638670809,282.256374557143658],"luv":[49.6587116356326135,27.305962831451918,-125.696192436653462],"rgb":[0.66666666666666663,0.2,1],"xyz":[0.358090472398688464,0.181343963016102477,0.962248627200860907],"hpluv":[282.256374557143658,328.684490794403757,49.6587116356326135],"hsluv":[282.256374557143658,99.9999999999991616,49.6587116356326135]},"#884400":{"lch":[36.685747441671559,64.5393704655657814,31.8123524502136021],"luv":[36.685747441671559,54.844205976921188,34.0212200082916922],"rgb":[0.533333333333333326,0.266666666666666663,0],"xyz":[0.122201478469054756,0.093692638490747937,0.0116493787366846978],"hpluv":[31.8123524502136021,223.237258003095718,36.685747441671559],"hsluv":[31.8123524502136021,100.000000000002245,36.685747441671559]},"#884411":{"lch":[36.7614898568215622,62.4864851085245405,30.2058215583615599],"luv":[36.7614898568215622,54.0023006087270119,31.4374354899146],"rgb":[0.533333333333333326,0.266666666666666663,0.0666666666666666657],"xyz":[0.123213143968691874,0.0940973046906027899,0.016977483701440331],"hpluv":[30.2058215583615599,215.691146343233044,36.7614898568215622],"hsluv":[30.2058215583615599,93.206231917801162,36.7614898568215622]},"#884422":{"lch":[36.9013237077522405,58.9550348899468375,27.0578850153250627],"luv":[36.9013237077522405,52.5022536375556825,26.8180816214102],"rgb":[0.533333333333333326,0.266666666666666663,0.133333333333333331],"xyz":[0.125088502107168903,0.0948474479459936,0.0268543698974195236],"hpluv":[27.0578850153250627,202.730122118290922,36.9013237077522405],"hsluv":[27.0578850153250627,81.1214838671569822,36.9013237077522405]},"#884433":{"lch":[37.1299605496210461,53.9021323280231357,21.3870333458705382],"luv":[37.1299605496210461,50.1903435049312,19.6562785990819577],"rgb":[0.533333333333333326,0.266666666666666663,0.2],"xyz":[0.128176252839626637,0.0960825482389767171,0.0431165237550306668],"hpluv":[21.3870333458705382,184.213216030002656,37.1299605496210461],"hsluv":[21.3870333458705382,62.5495295304316272,37.1299605496210461]},"#884444":{"lch":[37.4566279620983806,48.2433933618324389,12.1770506300619505],"luv":[37.4566279620983806,47.157939219998795,10.1761373608750691],"rgb":[0.533333333333333326,0.266666666666666663,0.266666666666666663],"xyz":[0.132634248083845524,0.0978657463366643,0.0665952987079173],"hpluv":[12.1770506300619505,163.436290620587812,37.4566279620983806],"hsluv":[12.1770506300619505,38.2981887065726,37.4566279620983806]},"#884455":{"lch":[37.8873893879065804,43.5926938841600631,358.470393497241901],"luv":[37.8873893879065804,43.5771602849424937,-1.16364151632571566],"rgb":[0.533333333333333326,0.266666666666666663,0.333333333333333315],"xyz":[0.138596662123207509,0.10025071195240913,0.0979973459818912207],"hpluv":[358.470393497241901,146.001848007416612,37.8873893879065804],"hsluv":[358.470393497241901,42.6300163695831245,37.8873893879065804]},"#884466":{"lch":[38.425613648805637,41.9872152878557756,340.815857604715632],"luv":[38.425613648805637,39.6555541095459816,-13.7972198610307206],"rgb":[0.533333333333333326,0.266666666666666663,0.4],"xyz":[0.146181657896715694,0.103284710261812449,0.137944990389035183],"hpluv":[340.815857604715632,138.655016432961,38.425613648805637],"hsluv":[340.815857604715632,47.3337116796912767,38.425613648805637]},"#884477":{"lch":[39.0722986805963117,44.7783217464764363,322.645837420375756],"luv":[39.0722986805963117,35.5943002873345478,-27.1688035343115608],"rgb":[0.533333333333333326,0.266666666666666663,0.466666666666666674],"xyz":[0.1554956709169176,0.107010315469893258,0.186998792295433092],"hpluv":[322.645837420375756,145.424700121889231,39.0722986805963117],"hsluv":[322.645837420375756,52.1510622716411,39.0722986805963117]},"#884488":{"lch":[39.8263740522966856,51.5911203050634839,307.71501294924451],"luv":[39.8263740522966856,31.5600599218946343,-40.8118403414738609],"rgb":[0.533333333333333326,0.266666666666666663,0.533333333333333326],"xyz":[0.166636088018861428,0.111466482310670856,0.245671655699005259],"hpluv":[307.71501294924451,164.377933698467302,39.8263740522966856],"hsluv":[307.71501294924451,56.8697587177058,39.8263740522966856]},"#884499":{"lch":[40.6850187117946192,61.0189075542410393,296.969581150574243],"luv":[40.6850187117946192,27.6731358367265301,-54.3829443123034295],"rgb":[0.533333333333333326,0.266666666666666663,0.6],"xyz":[0.179693052127934128,0.116689267954300013,0.314438333340123166],"hpluv":[296.969581150574243,190.313341437332326,40.6850187117946192],"hsluv":[296.969581150574243,61.3383523001243134,40.6850187117946192]},"#8844aa":{"lch":[41.643995358805,71.7935926347933417,289.536616505740085],"luv":[41.643995358805,24.0084388126510113,-67.6602897510042141],"rgb":[0.533333333333333326,0.266666666666666663,0.66666666666666663],"xyz":[0.194750745093186683,0.122712345140401108,0.393742182957121767],"hpluv":[289.536616505740085,218.762371943685849,41.643995358805],"hsluv":[289.536616505740085,65.4647221474276506,41.643995358805]},"#8844bb":{"lch":[42.6979882651059626,83.1164887776927515,284.352541737053286],"luv":[42.6979882651059626,20.6035404121657031,-80.5223250360828757],"rgb":[0.533333333333333326,0.266666666666666663,0.733333333333333282],"xyz":[0.21188833720052333,0.129567381983335866,0.484000168055763513],"hpluv":[284.352541737053286,247.012596783276,42.6979882651059626],"hsluv":[284.352541737053286,69.2054262339616741,42.6979882651059626]},"#8844cc":{"lch":[43.840927241858644,94.5481620176080924,280.647262826657595],"luv":[43.840927241858644,17.4689172853010533,-92.9203522904814463],"rgb":[0.533333333333333326,0.266666666666666663,0.8],"xyz":[0.231180712644245057,0.137284332160824668,0.585606678726033669],"hpluv":[280.647262826657595,273.660859280114778,43.840927241858644],"hsluv":[280.647262826657595,72.5522514276637764,43.840927241858644]},"#8844dd":{"lch":[45.0662821798681108,105.864396975636453,277.925647559652191],"luv":[45.0662821798681108,14.5974213234566292,-104.853163222292139],"rgb":[0.533333333333333326,0.266666666666666663,0.866666666666666696],"xyz":[0.2526990381948786,0.145891662381078202,0.698936526626039667],"hpluv":[277.925647559652191,298.083215805211921,45.0662821798681108],"hsluv":[277.925647559652191,79.9664783418063649,45.0662821798681108]},"#8844ee":{"lch":[46.3673172023828,116.961454232737537,275.874868362231723],"luv":[46.3673172023828,11.97173240994087,-116.347150370524886],"rgb":[0.533333333333333326,0.266666666666666663,0.933333333333333348],"xyz":[0.276511218461053365,0.155416534487548247,0.82434734269456289],"hpluv":[275.874868362231723,320.088534026972411,46.3673172023828],"hsluv":[275.874868362231723,89.9071832422553,46.3673172023828]},"#8844ff":{"lch":[47.7372988913525091,127.801124524511906,274.29427304351259],"luv":[47.7372988913525091,9.5696272486796623,-127.442338585146516],"rgb":[0.533333333333333326,0.266666666666666663,1],"xyz":[0.302682266870884731,0.165884953851480943,0.962181530986344735],"hpluv":[274.29427304351259,339.716123682654541,47.7372988913525091],"hsluv":[274.29427304351259,99.9999999999992468,47.7372988913525091]},"#ffcc00":{"lch":[84.1983464973243,98.3335943421723613,63.5926937648685069],"luv":[84.1983464973243,43.7338065737115329,88.0729807536005751],"rgb":[1,0.8,0],"xyz":[0.628309999332456237,0.644477406004528408,0.0913038854044243842],"hpluv":[63.5926937648685069,267.385577483165775,84.1983464973243],"hsluv":[63.5926937648685069,100.000000000007688,84.1983464973243]},"#ffcc11":{"lch":[84.2193135631731877,97.4576917861448777,63.4272907637844199],"luv":[84.2193135631731877,43.5960552023901897,87.1629833075564164],"rgb":[1,0.8,0.0666666666666666657],"xyz":[0.629321664832093397,0.644882072204383316,0.0966319903691800208],"hpluv":[63.4272907637844199,265.403720884510847,84.2193135631731877],"hsluv":[63.4272907637844199,100.000000000007645,84.2193135631731877]},"#ffcc22":{"lch":[84.2581577251319516,95.845309095571892,63.1144413478925301],"luv":[84.2581577251319516,43.342199386504106,85.4855369519677168],"rgb":[1,0.8,0.133333333333333331],"xyz":[0.631197022970570343,0.645632215459774117,0.106508876565159213],"hpluv":[63.1144413478925301,261.744085553517664,84.2581577251319516],"hsluv":[63.1144413478925301,100.00000000000766,84.2581577251319516]},"#ffcc33":{"lch":[84.3220485899852719,93.2224175872051148,62.5809741236821822],"luv":[84.3220485899852719,42.9284172035605494,82.7500461462124832],"rgb":[1,0.8,0.2],"xyz":[0.63428477370302816,0.646867315752757244,0.12277103042277035],"hpluv":[62.5809741236821822,255.758846695652977,84.3220485899852719],"hsluv":[62.5809741236821822,100.000000000007859,84.3220485899852719]},"#ffcc44":{"lch":[84.41414885501203,89.5051620308737,61.7678249437873745],"luv":[84.41414885501203,42.3400226901080785,78.8574442191356439],"rgb":[1,0.8,0.266666666666666663],"xyz":[0.638742768947247,0.64865051385044481,0.146249805375657],"hpluv":[61.7678249437873745,247.206609954939694,84.41414885501203],"hsluv":[61.7678249437873745,100.000000000007887,84.41414885501203]},"#ffcc55":{"lch":[84.5370662928161,84.6613331238571476,60.5932597011580469],"luv":[84.5370662928161,41.569242864558305,73.7532329730438221],"rgb":[1,0.8,0.333333333333333315],"xyz":[0.644705182986609,0.651035479466189559,0.177651852649630904],"hpluv":[60.5932597011580469,235.935294148211483,84.5370662928161],"hsluv":[60.5932597011580469,100.000000000008015,84.5370662928161]},"#ffcc66":{"lch":[84.6930007913096,78.7104448491835456,58.9357730127494222],"luv":[84.6930007913096,40.6144802919859131,67.4225342075500151],"rgb":[1,0.8,0.4],"xyz":[0.65229017876011719,0.654069477775592878,0.217599497056774865],"hpluv":[58.9357730127494222,221.881579382217893,84.6930007913096],"hsluv":[58.9357730127494222,100.000000000008285,84.6930007913096]},"#ffcc77":{"lch":[84.8838226897762809,71.7288671198513441,56.6053668146737863],"luv":[84.8838226897762809,39.4797505573258718,59.8863897244492378],"rgb":[1,0.8,0.466666666666666674],"xyz":[0.661604191780319,0.657795082983673729,0.266653298963172802],"hpluv":[56.6053668146737863,205.087229042099608,84.8838226897762809],"hsluv":[56.6053668146737863,100.000000000008399,84.8838226897762809]},"#ffcc88":{"lch":[85.1111193079521371,63.8628893840605159,53.2910582019814285],"luv":[85.1111193079521371,38.1740592359010691,51.1977523133063457],"rgb":[1,0.8,0.533333333333333326],"xyz":[0.672744608882263,0.662251249824451271,0.325326162366744942],"hpluv":[53.2910582019814285,185.743844227516831,85.1111193079521371],"hsluv":[53.2910582019814285,100.000000000008683,85.1111193079521371]},"#ffcc99":{"lch":[85.3762249003348899,55.3594884395636555,48.4608196634464292],"luv":[85.3762249003348899,36.710650975629143,41.436711563970924],"rgb":[1,0.8,0.6],"xyz":[0.685801572991335595,0.667474035468080484,0.394092840007862821],"hpluv":[48.4608196634464292,164.300705026796521,85.3762249003348899],"hsluv":[48.4608196634464292,100.000000000008811,85.3762249003348899]},"#ffccaa":{"lch":[85.6802414041430467,46.6394331206389836,41.1740083194267896],"luv":[85.6802414041430467,35.1061374539925311,30.7049806200222122],"rgb":[1,0.8,0.66666666666666663],"xyz":[0.700859265956588207,0.673497112654181551,0.473396689624861478],"hpluv":[41.1740083194267896,141.724192848301414,85.6802414041430467],"hsluv":[41.1740083194267896,100.000000000009393,85.6802414041430467]},"#ffccbb":{"lch":[86.0240539433014106,38.4677176438646384,29.8042196075727404],"luv":[86.0240539433014106,33.3795484258888635,19.1199123327444944],"rgb":[1,0.8,0.733333333333333282],"xyz":[0.71799685806392477,0.68035214949711631,0.563654674723503168],"hpluv":[29.8042196075727404,120.116808153279436,86.0240539433014106],"hsluv":[29.8042196075727404,100.000000000009621,86.0240539433014106]},"#ffcccc":{"lch":[86.4083433793485,32.2775975377643,12.1770506300627517],"luv":[86.4083433793485,31.5513664521307504,6.80841962670093892],"rgb":[1,0.8,0.8],"xyz":[0.737289233507646524,0.688069099674605167,0.665261185393773324],"hpluv":[12.1770506300627517,103.973607583717524,86.4083433793485],"hsluv":[12.1770506300627517,100.000000000010388,86.4083433793485]},"#ffccdd":{"lch":[86.8335972965778637,30.2635044437543748,348.373924949033096],"luv":[86.8335972965778637,29.6426074465171432,-6.09881340826452867],"rgb":[1,0.8,0.866666666666666696],"xyz":[0.758807559058280123,0.696676429894858673,0.778591033293779322],"hpluv":[348.373924949033096,100.994037434302086,86.8335972965778637],"hsluv":[348.373924949033096,100.000000000011042,86.8335972965778637]},"#ffccee":{"lch":[87.3001202800073344,33.8382691858854301,324.868297683069],"luv":[87.3001202800073344,27.6740002852911822,-19.4724977777928352],"rgb":[1,0.8,0.933333333333333348],"xyz":[0.782619739324454833,0.70620130200132869,0.904001849362302545],"hpluv":[324.868297683069,117.528800717138253,87.3001202800073344],"hsluv":[324.868297683069,100.000000000011482,87.3001202800073344]},"#ffccff":{"lch":[87.8080440143565255,41.9549825399590404,307.715012949248376],"luv":[87.8080440143565255,25.6653035474654807,-33.1890456889728],"rgb":[1,0.8,1],"xyz":[0.808790787734286254,0.716669721365261414,1.0418360376540845],"hpluv":[307.715012949248376,152.433043069806,87.8080440143565255],"hsluv":[307.715012949248376,100.000000000012506,87.8080440143565255]},"#aa4400":{"lch":[42.2796461632011074,91.196234940608619,23.7609213617016479],"luv":[42.2796461632011074,83.4659581293579578,36.7448921741641357],"rgb":[0.66666666666666663,0.266666666666666663,0],"xyz":[0.186442254479824487,0.126816788621301801,0.0146606651121894659],"hpluv":[23.7609213617016479,273.706361359402308,42.2796461632011074],"hsluv":[23.7609213617016479,100.000000000002331,42.2796461632011074]},"#aa4411":{"lch":[42.3415695164373815,89.5099073241138399,22.7237862619920179],"luv":[42.3415695164373815,82.5619515402106572,34.5766925405446202],"rgb":[0.66666666666666663,0.266666666666666663,0.0666666666666666657],"xyz":[0.18745391997946162,0.127221454821156654,0.0199887700769451],"hpluv":[22.7237862619920179,268.252316854423896,42.3415695164373815],"hsluv":[22.7237862619920179,95.0030043013494634,42.3415695164373815]},"#aa4422":{"lch":[42.4560124733741162,86.5487219398638,20.7501492775311753],"luv":[42.4560124733741162,80.9346773489764075,30.663647399501361],"rgb":[0.66666666666666663,0.266666666666666663,0.133333333333333331],"xyz":[0.189329278117938621,0.127971598076547483,0.0298656562729242916],"hpluv":[20.7501492775311753,258.678767688655569,42.4560124733741162],"hsluv":[20.7501492775311753,86.0172479577967692,42.4560124733741162]},"#aa4433":{"lch":[42.643470741830761,82.1252826930209494,17.3597256589108966],"luv":[42.643470741830761,78.3845002494828691,24.5037176372775498],"rgb":[0.66666666666666663,0.266666666666666663,0.2],"xyz":[0.192417028850396354,0.129206698369530582,0.0461278101305354349],"hpluv":[17.3597256589108966,244.378874013338617,42.643470741830761],"hsluv":[17.3597256589108966,71.9602068881057733,42.643470741830761]},"#aa4444":{"lch":[42.9120210749329871,76.685866981555165,12.1770506300619239],"luv":[42.9120210749329871,74.9604702767477704,16.1756017075590073],"rgb":[0.66666666666666663,0.266666666666666663,0.266666666666666663],"xyz":[0.196875024094615242,0.130989896467218175,0.0696065850834220734],"hpluv":[12.1770506300619239,226.764824908056937,42.9120210749329871],"hsluv":[12.1770506300619239,53.1380271992519795,42.9120210749329871]},"#aa4455":{"lch":[43.2674147484635299,71.0489272172787594,4.80785478807657096],"luv":[43.2674147484635299,70.7989329223205,5.9549270177674023],"rgb":[0.66666666666666663,0.266666666666666663,0.333333333333333315],"xyz":[0.202837438133977255,0.133374862082963,0.101008632357395989],"hpluv":[4.80785478807657096,208.370342069187018,43.2674147484635299],"hsluv":[4.80785478807657096,55.6796565441877931,43.2674147484635299]},"#aa4466":{"lch":[43.7134526285125489,66.3411716499448261,355.020980864279068],"luv":[43.7134526285125489,66.0908363196155477,-5.75781299290188],"rgb":[0.66666666666666663,0.266666666666666663,0.4],"xyz":[0.210422433907485412,0.136408860392366299,0.140956276764539951],"hpluv":[355.020980864279068,192.578302395247789,43.7134526285125489],"hsluv":[355.020980864279068,58.5402216503940949,43.7134526285125489]},"#aa4477":{"lch":[44.252209356870793,63.7921835342278598,343.127789968560137],"luv":[44.252209356870793,61.046215168807521,-18.5149208377531842],"rgb":[0.66666666666666663,0.266666666666666663,0.466666666666666674],"xyz":[0.219736446927687346,0.140134465600447122,0.19001007867093786],"hpluv":[343.127789968560137,182.924482874911519,44.252209356870793],"hsluv":[343.127789968560137,61.5848400189491372,44.252209356870793]},"#aa4488":{"lch":[44.8842146397509367,64.3242328637060865,330.281311898752961],"luv":[44.8842146397509367,55.8636578331810938,-31.8882214461946916],"rgb":[0.66666666666666663,0.266666666666666663,0.533333333333333326],"xyz":[0.230876864029631146,0.14459063244122472,0.248682942074510027],"hpluv":[330.281311898752961,181.852933643495049,44.8842146397509367],"hsluv":[330.281311898752961,64.6866121014520274,44.8842146397509367]},"#aa4499":{"lch":[45.6086312393750077,68.1395242873703779,318.091147538790551],"luv":[45.6086312393750077,50.7100032224043318,-45.5136281051387854],"rgb":[0.66666666666666663,0.266666666666666663,0.6],"xyz":[0.243933828138703873,0.149813418084853878,0.317449619715627906],"hpluv":[318.091147538790551,189.579504981677246,45.6086312393750077],"hsluv":[318.091147538790551,67.7395528675925,45.6086312393750077]},"#aa44aa":{"lch":[46.4234422285949293,74.7240378323112822,307.715012949244056],"luv":[46.4234422285949293,45.7112599542092468,-59.1114417296972476],"rgb":[0.66666666666666663,0.266666666666666663,0.66666666666666663],"xyz":[0.258991521103956401,0.155836495270954972,0.396753469332626507],"hpluv":[307.715012949244056,204.25011915803762,46.4234422285949293],"hsluv":[307.715012949244056,70.6643205278868862,46.4234422285949293]},"#aa44bb":{"lch":[47.3256474704596144,83.2556513741305224,299.464802712285689],"luv":[47.3256474704596144,40.9525224701243289,-72.4872015535482177],"rgb":[0.66666666666666663,0.266666666666666663,0.733333333333333282],"xyz":[0.276129113211293076,0.162691532113889731,0.487011454431268254],"hpluv":[299.464802712285689,223.2320179514779,47.3256474704596144],"hsluv":[299.464802712285689,73.4081717041738244,47.3256474704596144]},"#aa44cc":{"lch":[48.311463406953564,92.9774863668884564,293.103270963637385],"luv":[48.311463406953564,36.4834012629607827,-85.5206080625642073],"rgb":[0.66666666666666663,0.266666666666666663,0.8],"xyz":[0.29542148865501483,0.170408482291378532,0.58861796510153841],"hpluv":[293.103270963637385,244.211962975346665,48.311463406953564],"hsluv":[293.103270963637385,75.9413806031634806,48.311463406953564]},"#aa44dd":{"lch":[49.376518181476186,103.335675962773564,288.229438001673088],"luv":[49.376518181476186,32.3257723855767125,-98.1494083851717676],"rgb":[0.66666666666666663,0.266666666666666663,0.866666666666666696],"xyz":[0.316939814205648318,0.179015812511632066,0.701947813001544407],"hpluv":[288.229438001673088,265.563967984367252,49.376518181476186],"hsluv":[288.229438001673088,78.2521754793284572,49.376518181476186]},"#aa44ee":{"lch":[50.5160343838387149,113.969241853628489,284.471970959088878],"luv":[50.5160343838387149,28.4816380653286,-110.35299897060564],"rgb":[0.66666666666666663,0.266666666666666663,0.933333333333333348],"xyz":[0.340751994471823083,0.188540684618102111,0.82735862907006763],"hpluv":[284.471970959088878,286.284434407824506,50.5160343838387149],"hsluv":[284.471970959088878,88.5420288112715355,50.5160343838387149]},"#aa44ff":{"lch":[51.7249932896939271,124.658572052901789,281.540806859048416],"luv":[51.7249932896939271,24.9399169363974949,-122.138282816953421],"rgb":[0.66666666666666663,0.266666666666666663,1],"xyz":[0.366923042881654449,0.199009103982034807,0.965192817361849476],"hpluv":[281.540806859048416,305.816582895375404,51.7249932896939271],"hsluv":[281.540806859048416,99.9999999999991189,51.7249932896939271]},"#885500":{"lch":[40.7868302215615941,57.8204075903908716,44.0255445375638317],"luv":[40.7868302215615941,41.5746091122878738,40.1839695784202107],"rgb":[0.533333333333333326,0.333333333333333315,0],"xyz":[0.134014735183400707,0.117319151919440201,0.0155871309747999068],"hpluv":[44.0255445375638317,179.887306981779091,40.7868302215615941],"hsluv":[44.0255445375638317,100.000000000002402,40.7868302215615941]},"#885511":{"lch":[40.8520464566488215,55.8013246771799061,42.6953812551229817],"luv":[40.8520464566488215,41.012258348334349,37.838901951530346],"rgb":[0.533333333333333326,0.333333333333333315,0.0666666666666666657],"xyz":[0.135026400683037839,0.117723818119295054,0.0209152359395555383],"hpluv":[42.6953812551229817,173.328515822040885,40.8520464566488215],"hsluv":[42.6953812551229817,94.5141207032234121,40.8520464566488215]},"#885522":{"lch":[40.9725457623763205,52.2529579480882163,40.0436802938645613],"luv":[40.9725457623763205,40.0024704692244413,33.6180601862079769],"rgb":[0.533333333333333326,0.333333333333333315,0.133333333333333331],"xyz":[0.136901758821514841,0.118473961374685868,0.0307921221355347344],"hpluv":[40.0436802938645613,161.829338044896133,40.9725457623763205],"hsluv":[40.0436802938645613,84.6783920295854813,40.9725457623763205]},"#885533":{"lch":[41.169842808691,46.965215190705,35.0963808532685348],"luv":[41.169842808691,38.426283274472091,27.0028182162390955],"rgb":[0.533333333333333326,0.333333333333333315,0.2],"xyz":[0.139989509553972602,0.119709061667668981,0.0470542759931458776],"hpluv":[35.0963808532685348,144.75595347357384,41.169842808691],"hsluv":[35.0963808532685348,69.3663942781120113,41.169842808691]},"#885544":{"lch":[41.4523140669009891,40.5881659839312263,26.5063976077417607],"luv":[41.4523140669009891,36.321721997537459,18.1144066718387258],"rgb":[0.533333333333333326,0.333333333333333315,0.266666666666666663],"xyz":[0.144447504798191462,0.121492259765356561,0.0705330509460325161],"hpluv":[26.5063976077417607,124.248162385526584,41.4523140669009891],"hsluv":[26.5063976077417607,49.0053368988820708,41.4523140669009891]},"#885555":{"lch":[41.8258216452066449,34.5587016635497619,12.1770506300621708],"luv":[41.8258216452066449,33.7811467851905647,7.28958040957408926],"rgb":[0.533333333333333326,0.333333333333333315,0.333333333333333315],"xyz":[0.150409918837553447,0.123877225381101394,0.101935098220006432],"hpluv":[12.1770506300621708,104.846095879990827,41.8258216452066449],"hsluv":[12.1770506300621708,24.5686900376428454,41.8258216452066449]},"#885566":{"lch":[42.2941086985740071,31.3312262907584227,350.801819307985852],"luv":[42.2941086985740071,30.9283487442626033,-5.00829160852097477],"rgb":[0.533333333333333326,0.333333333333333315,0.4],"xyz":[0.157994914611061632,0.126911223690504699,0.141882742627150393],"hpluv":[350.801819307985852,94.0019456509277092,42.2941086985740071],"hsluv":[350.801819307985852,29.8132814869556348,42.2941086985740071]},"#885577":{"lch":[42.8590433503379202,33.3514130793808121,326.760730108285],"luv":[42.8590433503379202,27.8947491372056646,-18.2811302977648822],"rgb":[0.533333333333333326,0.333333333333333315,0.466666666666666674],"xyz":[0.167308927631263538,0.130636828898585522,0.190936544533548302],"hpluv":[326.760730108285,98.7440857113442263,42.8590433503379202],"hsluv":[326.760730108285,35.3342565461126838,42.8590433503379202]},"#885588":{"lch":[43.5208237898043535,40.5407907233736822,307.71501294924542],"luv":[43.5208237898043535,24.8001938501248809,-32.0703304858651137],"rgb":[0.533333333333333326,0.333333333333333315,0.533333333333333326],"xyz":[0.178449344733207393,0.13509299573936312,0.24960940793712047],"hpluv":[307.71501294924542,118.204615389413121,43.5208237898043535],"hsluv":[307.71501294924542,40.8951968507306276,43.5208237898043535]},"#885599":{"lch":[44.278184332936334,50.8805981998246,295.296495298175159],"luv":[44.278184332936334,21.7414099229374891,-46.0015909261276477],"rgb":[0.533333333333333326,0.333333333333333315,0.6],"xyz":[0.191506308842280093,0.140315781382992277,0.318376085578238377],"hpluv":[295.296495298175159,145.814841874582299,44.278184332936334],"hsluv":[295.296495298175159,46.3068912836000735,44.278184332936334]},"#8855aa":{"lch":[45.1286132569148819,62.6826496939872868,287.441560465434577],"luv":[45.1286132569148819,18.7880516159354372,-59.8006997378464717],"rgb":[0.533333333333333326,0.333333333333333315,0.66666666666666663],"xyz":[0.206564001807532649,0.146338858569093372,0.397679935195237],"hpluv":[287.441560465434577,176.252255995348207,45.1286132569148819],"hsluv":[287.441560465434577,51.4349240401982044,45.1286132569148819]},"#8855bb":{"lch":[46.0685799041538857,75.0110486022347374,282.303621490188448],"luv":[46.0685799041538857,15.9842650126874819,-73.2882029006783284],"rgb":[0.533333333333333326,0.333333333333333315,0.733333333333333282],"xyz":[0.223701593914869268,0.15319389541202813,0.487937920293878724],"hpluv":[282.303621490188448,206.613996430434867,46.0685799041538857],"hsluv":[282.303621490188448,56.1963190544194191,46.0685799041538857]},"#8855cc":{"lch":[47.0937627302438173,87.3889723072186229,278.789341148015808],"luv":[47.0937627302438173,13.3532090014702405,-86.3627482788434406],"rgb":[0.533333333333333326,0.333333333333333315,0.8],"xyz":[0.242993969358591022,0.160910845589516932,0.58954443096414888],"hpluv":[278.789341148015808,235.468364438494291,47.0937627302438173],"hsluv":[278.789341148015808,67.0071532265272083,47.0937627302438173]},"#8855dd":{"lch":[48.1992684502362323,99.579643468316263,276.285619014825784],"luv":[48.1992684502362323,10.9024601244232162,-98.9810171523426163],"rgb":[0.533333333333333326,0.333333333333333315,0.866666666666666696],"xyz":[0.264512294909224566,0.169518175809770466,0.702874278864154878],"hpluv":[276.285619014825784,262.161822059859048,48.1992684502362323],"hsluv":[276.285619014825784,77.9008511174594673,48.1992684502362323]},"#8855ee":{"lch":[49.3798334670730128,111.473561000814087,274.439637972028379],"luv":[49.3798334670730128,8.62903279282213198,-111.139077714648238],"rgb":[0.533333333333333326,0.333333333333333315,0.933333333333333348],"xyz":[0.288324475175399275,0.179043047916240511,0.828285094932678101],"hpluv":[274.439637972028379,286.45841220928196,49.3798334670730128],"hsluv":[274.439637972028379,88.8665998649397295,49.3798334670730128]},"#8855ff":{"lch":[50.6300011250937416,123.030386306339324,273.039422554437692],"luv":[50.6300011250937416,6.52344684402536235,-122.857318039912712],"rgb":[0.533333333333333326,0.333333333333333315,1],"xyz":[0.314495523585230696,0.189511467280173207,0.96611928322446],"hpluv":[273.039422554437692,308.349875308867752,50.6300011250937416],"hsluv":[273.039422554437692,99.9999999999992,50.6300011250937416]},"#ffdd00":{"lch":[88.435570144315335,99.3071523162376195,71.7429005549186911],"luv":[88.435570144315335,31.1110916577435432,94.3080615696447211],"rgb":[1,0.866666666666666696,0],"xyz":[0.670943989879631442,0.729745387098879927,0.105515215586815703],"hpluv":[71.7429005549186911,382.363935262913174,88.435570144315335],"hsluv":[71.7429005549186911,100.000000000012946,88.435570144315335]},"#ffdd11":{"lch":[88.454870819445,98.4678340856778,71.6448189166009826],"luv":[88.454870819445,31.0081800872079896,93.4580500395971683],"rgb":[1,0.866666666666666696,0.0666666666666666657],"xyz":[0.671955655379268602,0.730150053298734836,0.110843320551571339],"hpluv":[71.6448189166009826,379.826472639876158,88.454870819445],"hsluv":[71.6448189166009826,100.00000000001296,88.454870819445]},"#ffdd22":{"lch":[88.4906302718539735,96.9204819130462,71.4594307996413],"luv":[88.4906302718539735,30.8183922605744947,91.8901872494037093],"rgb":[1,0.866666666666666696,0.133333333333333331],"xyz":[0.673831013517745547,0.730900196554125636,0.120720206747550532],"hpluv":[71.4594307996413,375.129750349680876,88.4906302718539735],"hsluv":[71.4594307996413,100.00000000001296,88.4906302718539735]},"#ffdd33":{"lch":[88.5494544369894641,94.3967280931520776,71.1436744567929793],"luv":[88.5494544369894641,30.5086598694284135,89.330643945199526],"rgb":[1,0.866666666666666696,0.2],"xyz":[0.676918764250203364,0.732135296847108763,0.136982360605161668],"hpluv":[71.1436744567929793,367.416320973762822,88.5494544369894641],"hsluv":[71.1436744567929793,100.000000000013216,88.5494544369894641]},"#ffdd44":{"lch":[88.6342662809689301,90.8049878425315455,70.6631891871382152],"luv":[88.6342662809689301,30.0674100616276441,85.6825342136204284],"rgb":[1,0.866666666666666696,0.266666666666666663],"xyz":[0.681376759494422224,0.733918494944796329,0.160461135558048307],"hpluv":[70.6631891871382152,356.322085242203968,88.6342662809689301],"hsluv":[70.6631891871382152,100.000000000013173,88.6342662809689301]},"#ffdd55":{"lch":[88.7474847112806486,86.0957791731635353,69.970644696948483],"luv":[88.7474847112806486,29.4879375414461293,80.8884709398435433],"rgb":[1,0.866666666666666696,0.333333333333333315],"xyz":[0.687339173533784153,0.736303460560541079,0.191863182832022222],"hpluv":[69.970644696948483,341.559684906391112,88.7474847112806486],"hsluv":[69.970644696948483,100.000000000013429,88.7474847112806486]},"#ffdd66":{"lch":[88.8911610589964454,80.258955992054581,68.9956984045855819],"luv":[88.8911610589964454,28.7678627944319345,74.9260307715235427],"rgb":[1,0.866666666666666696,0.4],"xyz":[0.694924169307292394,0.739337458869944397,0.231810827239166184],"hpluv":[68.9956984045855819,322.902183683526573,88.8911610589964454],"hsluv":[68.9956984045855819,100.000000000013586,88.8911610589964454]},"#ffdd77":{"lch":[89.0670520916409885,73.323747836811151,67.6276760217336346],"luv":[89.0670520916409885,27.9087592291374555,67.8046691248198812],"rgb":[1,0.866666666666666696,0.466666666666666674],"xyz":[0.704238182327494244,0.743063064078025248,0.280864629145564093],"hpluv":[67.6276760217336346,300.178104609939055,89.0670520916409885],"hsluv":[67.6276760217336346,100.000000000014367,89.0670520916409885]},"#ffdd88":{"lch":[89.2766635023192379,65.3617696880632622,65.6822421460803554],"luv":[89.2766635023192379,26.9157684368328205,59.5625918359016637],"rgb":[1,0.866666666666666696,0.533333333333333326],"xyz":[0.715378599429438156,0.747519230918802791,0.339537492549136233],"hpluv":[65.6822421460803554,273.280966903928913,89.2766635023192379],"hsluv":[65.6822421460803554,100.00000000001468,89.2766635023192379]},"#ffdd99":{"lch":[89.5212778802452362,56.4966374008110606,62.8311838382076928],"luv":[89.5212778802452362,25.7971434460875209,50.2630821540094814],"rgb":[1,0.866666666666666696,0.6],"xyz":[0.7284355635385108,0.752742016562432,0.408304170190254168],"hpluv":[62.8311838382076928,242.212083001239,89.5212778802452362],"hsluv":[62.8311838382076928,100.000000000014893,89.5212778802452362]},"#ffddaa":{"lch":[89.8019739344538408,46.9317870748453103,58.439957868293348],"luv":[89.8019739344538408,24.5637119196041205,39.9902074859498],"rgb":[1,0.866666666666666696,0.66666666666666663],"xyz":[0.743493256503763411,0.75876509374853307,0.487608019807252768],"hpluv":[58.439957868293348,207.216087370130765,89.8019739344538408],"hsluv":[58.439957868293348,100.000000000015916,89.8019739344538408]},"#ffddbb":{"lch":[90.1196406145249114,37.0342016806554142,51.1553076529108282],"luv":[90.1196406145249114,23.228278171915747,28.8440494260352231],"rgb":[1,0.866666666666666696,0.733333333333333282],"xyz":[0.7606308486111,0.765620130591467829,0.57786600490589457],"hpluv":[51.1553076529108282,169.207898233907059,90.1196406145249114],"hsluv":[51.1553076529108282,100.00000000001647,90.1196406145249114]},"#ffddcc":{"lch":[90.4749882420216665,27.6093496047032829,37.8361109659034085],"luv":[90.4749882420216665,21.8049964890922183,16.9357111957368183],"rgb":[1,0.866666666666666696,0.8],"xyz":[0.779923224054821729,0.773337080768956686,0.679472515576164726],"hpluv":[37.8361109659034085,131.228146902908946,90.4749882420216665],"hsluv":[37.8361109659034085,100.000000000017565,90.4749882420216665]},"#ffdddd":{"lch":[90.8685579434819743,20.7762078419716971,12.1770506300632935],"luv":[90.8685579434819743,20.3087527298379129,4.38239373528981613],"rgb":[1,0.866666666666666696,0.866666666666666696],"xyz":[0.801441549605455328,0.781944410989210192,0.792802363476170724],"hpluv":[12.1770506300632935,103.332662997484363,90.8685579434819743],"hsluv":[12.1770506300632935,100.000000000018645,90.8685579434819743]},"#ffddee":{"lch":[91.3007301977477255,20.6730653908416642,335.121130580225611],"luv":[91.3007301977477255,18.7545890012647547,-8.69718483462634318],"rgb":[1,0.866666666666666696,0.933333333333333348],"xyz":[0.82525372987163,0.791469283095680209,0.918213179544694],"hpluv":[335.121130580225611,108.301670079840079,91.3007301977477255],"hsluv":[335.121130580225611,100.000000000019696,91.3007301977477255]},"#ffddff":{"lch":[91.7717330140538081,28.0468143452174594,307.715012949251673],"luv":[91.7717330140538081,17.1571994583452359,-22.1868046744377736],"rgb":[1,0.866666666666666696,1],"xyz":[0.851424778281461458,0.801937702459612933,1.05604736783647568],"hpluv":[307.715012949251673,155.925616416863875,91.7717330140538081],"hsluv":[307.715012949251673,100.000000000021274,91.7717330140538081]},"#aa5500":{"lch":[45.6948541105979729,81.8101604081173406,31.0178153240564285],"luv":[45.6948541105979729,70.1118895783240674,42.1571498770823254],"rgb":[0.66666666666666663,0.333333333333333315,0],"xyz":[0.198255511194170453,0.150443302049994065,0.0185984173503046732],"hpluv":[31.0178153240564285,227.184802334875343,45.6948541105979729],"hsluv":[31.0178153240564285,100.000000000002132,45.6948541105979729]},"#aa5511":{"lch":[45.7501207141343542,80.2053049231342357,30.0334267749456458],"luv":[45.7501207141343542,69.4364235827854088,40.1431690060082786],"rgb":[0.66666666666666663,0.333333333333333315,0.0666666666666666657],"xyz":[0.199267176693807585,0.150847968249848918,0.0239265223150603029],"hpluv":[30.0334267749456458,222.459100300712947,45.7501207141343542],"hsluv":[30.0334267749456458,95.7485290168496874,45.7501207141343542]},"#aa5522":{"lch":[45.8523093955831129,77.3637164970789826,28.1463245173948593],"luv":[45.8523093955831129,68.2151287979892231,36.4943945464800308],"rgb":[0.66666666666666663,0.333333333333333315,0.133333333333333331],"xyz":[0.201142534832284586,0.151598111505239747,0.0338034085110395],"hpluv":[28.1463245173948593,214.099393521154866,45.8523093955831129],"hsluv":[28.1463245173948593,88.0687786146531835,45.8523093955831129]},"#aa5533":{"lch":[46.0198296754266707,73.057054041475979,24.8605966968797674],"luv":[46.0198296754266707,66.2871018342682845,30.7140566456547255],"rgb":[0.66666666666666663,0.333333333333333315,0.2],"xyz":[0.20423028556474232,0.152833211798222846,0.0500655623686506457],"hpluv":[24.8605966968797674,201.444992058953261,46.0198296754266707],"hsluv":[24.8605966968797674,75.9647480733224683,46.0198296754266707]},"#aa5544":{"lch":[46.260105303202792,67.6400753638857,19.7251402693972757],"luv":[46.260105303202792,63.6711277752059743,22.829088529013422],"rgb":[0.66666666666666663,0.333333333333333315,0.266666666666666663],"xyz":[0.208688280808961207,0.154616409895910439,0.0735443373215372842],"hpluv":[19.7251402693972757,185.539675327038225,46.260105303202792],"hsluv":[19.7251402693972757,59.5831884891410581,46.260105303202792]},"#aa5555":{"lch":[46.5785950143652201,61.8404850960729462,12.1770506300619488],"luv":[46.5785950143652201,60.4491026496292108,13.0442165641410206],"rgb":[0.66666666666666663,0.333333333333333315,0.333333333333333315],"xyz":[0.21465069484832322,0.157001375511655272,0.1049463845955112],"hpluv":[12.1770506300619488,168.471262237657498,46.5785950143652201],"hsluv":[12.1770506300619488,39.4780386186733381,46.5785950143652201]},"#aa5566":{"lch":[46.9791292969753727,56.7719582569154682,1.70455911852653919],"luv":[46.9791292969753727,56.7468364589401801,1.68872621441415594],"rgb":[0.66666666666666663,0.333333333333333315,0.4],"xyz":[0.222235690621831378,0.160035373821058563,0.144894029002655161],"hpluv":[1.70455911852653919,153.34451205140752,46.9791292969753727],"hsluv":[1.70455911852653919,42.9013314457092818,46.9791292969753727]},"#aa5577":{"lch":[47.4641008255870247,53.815805251865207,348.374645401059922],"luv":[47.4641008255870247,52.7118371029350072,-10.8444974129891012],"rgb":[0.66666666666666663,0.333333333333333315,0.466666666666666674],"xyz":[0.231549703642033311,0.163760979029139386,0.193947830909053071],"hpluv":[348.374645401059922,143.874527939012694,47.4641008255870247],"hsluv":[348.374645401059922,46.6096363259647291,47.4641008255870247]},"#aa5588":{"lch":[48.0346061313586716,54.1759936988691209,333.519859036575326],"luv":[48.0346061313586716,48.4923339918738,-24.1564036495598238],"rgb":[0.66666666666666663,0.333333333333333315,0.533333333333333326],"xyz":[0.242690120743977111,0.168217145869916984,0.252620694312625238],"hpluv":[333.519859036575326,143.117248614217317,48.0346061313586716],"hsluv":[333.519859036575326,50.4580944804944309,48.0346061313586716]},"#aa5599":{"lch":[48.6905763376225,58.2309730669685877,319.412334073918828],"luv":[48.6905763376225,44.2212637341432782,-37.885697275903027],"rgb":[0.66666666666666663,0.333333333333333315,0.6],"xyz":[0.255747084853049866,0.173439931513546142,0.321387371953743117],"hpluv":[319.412334073918828,151.756904292295189,48.6905763376225],"hsluv":[319.412334073918828,54.3174516364451492,48.6905763376225]},"#aa55aa":{"lch":[49.4309115490906095,65.3990862514302904,307.715012949244453],"luv":[49.4309115490906095,40.0068668547544135,-51.7348150377284242],"rgb":[0.66666666666666663,0.333333333333333315,0.66666666666666663],"xyz":[0.270804777818302367,0.179463008699647236,0.400691221570741718],"hpluv":[307.715012949244453,167.885190443837445,49.4309115490906095],"hsluv":[307.715012949244453,58.0831627335764651,49.4309115490906095]},"#aa55bb":{"lch":[50.2536225490081137,74.6889496830887651,298.754319252296796],"luv":[50.2536225490081137,35.9294822147829578,-65.4790921786531896],"rgb":[0.66666666666666663,0.333333333333333315,0.733333333333333282],"xyz":[0.287942369925639041,0.186318045542582,0.490949206669383464],"hpluv":[298.754319252296796,188.594188212432869,50.2536225490081137],"hsluv":[298.754319252296796,61.6784311565058445,50.2536225490081137]},"#aa55cc":{"lch":[51.1559779262539394,85.2173265065914194,292.086991032215337],"luv":[51.1559779262539394,32.0428980728004476,-78.9635702082114],"rgb":[0.66666666666666663,0.333333333333333315,0.8],"xyz":[0.307234745369360795,0.194034995720070796,0.59255571733965362],"hpluv":[292.086991032215337,211.383381159177,51.1559779262539394],"hsluv":[292.086991032215337,65.0527897247966536,51.1559779262539394]},"#aa55dd":{"lch":[52.1346521614624407,96.3659410029227,287.126655540846059],"luv":[52.1346521614624407,28.3783197098194826,-92.0927008824589137],"rgb":[0.66666666666666663,0.333333333333333315,0.866666666666666696],"xyz":[0.328753070919994284,0.20264232594032433,0.705885565239659618],"hpluv":[287.126655540846059,234.550526854663673,52.1346521614624407],"hsluv":[287.126655540846059,75.3446722268955256,52.1346521614624407]},"#aa55ee":{"lch":[53.1858694266106227,107.745747725204239,283.388779775386126],"luv":[53.1858694266106227,24.9493252566021582,-104.817352199450397],"rgb":[0.66666666666666663,0.333333333333333315,0.933333333333333348],"xyz":[0.352565251186169049,0.212167198046794375,0.831296381308182841],"hpluv":[283.388779775386126,257.065149407391289,53.1858694266106227],"hsluv":[283.388779775386126,87.5522298773574335,53.1858694266106227]},"#aa55ff":{"lch":[54.3055382240479361,119.125691570750178,280.523377624217346],"luv":[54.3055382240479361,21.7567225446561139,-117.12205350114192],"rgb":[0.66666666666666663,0.333333333333333315,1],"xyz":[0.378736299596000414,0.222635617410727071,0.969130569599964686],"hpluv":[280.523377624217346,278.356033354379861,54.3055382240479361],"hsluv":[280.523377624217346,99.999999999999,54.3055382240479361]},"#886600":{"lch":[45.272583339231268,54.7393681124008964,58.6614018365849361],"luv":[45.272583339231268,28.4696504737342408,46.7533680417607513],"rgb":[0.533333333333333326,0.4,0],"xyz":[0.149042792889247183,0.147375267331133541,0.020596483543415256],"hpluv":[58.6614018365849361,153.427719347991228,45.272583339231268],"hsluv":[58.6614018365849361,100.000000000002288,45.272583339231268]},"#886611":{"lch":[45.3286132830504442,52.7569286908504935,57.8019218571504112],"luv":[45.3286132830504442,28.1114182485843394,44.6434954830448234],"rgb":[0.533333333333333326,0.4,0.0666666666666666657],"xyz":[0.150054458388884315,0.147779933530988394,0.0259245885081708857],"hpluv":[57.8019218571504112,147.688404254652824,45.3286132830504442],"hsluv":[57.8019218571504112,95.5933263309827765,45.3286132830504442]},"#886622":{"lch":[45.4322079122274616,49.2027541487777427,56.0700181971155658],"luv":[45.4322079122274616,27.4639619392241023,40.8245246197174367],"rgb":[0.533333333333333326,0.4,0.133333333333333331],"xyz":[0.151929816527361317,0.148530076786379223,0.0358014747041500853],"hpluv":[56.0700181971155658,137.424731357888106,45.4322079122274616],"hsluv":[56.0700181971155658,87.640709221506242,45.4322079122274616]},"#886633":{"lch":[45.6020177209920377,43.6934420281053448,52.7580970187872822],"luv":[45.6020177209920377,26.4424624059276816,34.7838045385277539],"rgb":[0.533333333333333326,0.4,0.2],"xyz":[0.155017567259819078,0.149765177079362322,0.0520636285617612285],"hpluv":[52.7580970187872822,121.582627853675135,45.6020177209920377],"hsluv":[52.7580970187872822,75.126145239043538,45.6020177209920377]},"#886644":{"lch":[45.8455444844743383,36.5157977851307862,46.6690567683987183],"luv":[45.8455444844743383,25.057552877875338,26.56167411246971],"rgb":[0.533333333333333326,0.4,0.266666666666666663],"xyz":[0.159475562504037938,0.151548375177049915,0.0755424035146478601],"hpluv":[46.6690567683987183,101.07016738030697,45.8455444844743383],"hsluv":[46.6690567683987183,58.2269221932267413,45.8455444844743383]},"#886655":{"lch":[46.1682850891648,28.5288655346450497,35.057100942904512],"luv":[46.1682850891648,23.3531590809093643,16.3867669061227161],"rgb":[0.533333333333333326,0.4,0.333333333333333315],"xyz":[0.165437976543399923,0.153933340792794748,0.106944450788621775],"hpluv":[35.057100942904512,78.4115584201214517,46.1682850891648],"hsluv":[35.057100942904512,37.5458750067509825,46.1682850891648]},"#886666":{"lch":[46.5740725388720946,21.8884171395184417,12.1770506300623786],"luv":[46.5740725388720946,21.3959378301945833,4.61699569417310141],"rgb":[0.533333333333333326,0.4,0.4],"xyz":[0.173022972316908108,0.156967339102198039,0.146892095195765737],"hpluv":[12.1770506300623786,59.6361320849851921,46.5740725388720946],"hsluv":[12.1770506300623786,13.9745942082290213,46.5740725388720946]},"#886677":{"lch":[47.0652698878111053,20.9860757761626395,336.621799391030947],"luv":[47.0652698878111053,19.2632377900225293,-8.32724722389627559],"rgb":[0.533333333333333326,0.4,0.466666666666666674],"xyz":[0.18233698533711,0.160692944310278862,0.195945897102163646],"hpluv":[336.621799391030947,56.5809206524471051,47.0652698878111053],"hsluv":[336.621799391030947,19.7183189325496855,47.0652698878111053]},"#886688":{"lch":[47.6429159175320649,27.8420771343032278,307.715012949247239],"luv":[47.6429159175320649,17.0319546757823481,-22.0248445868429776],"rgb":[0.533333333333333326,0.4,0.533333333333333326],"xyz":[0.193477402439053869,0.16514911115105646,0.254618760505735842],"hpluv":[307.715012949247239,74.1553731862279335,47.6429159175320649],"hsluv":[307.715012949247239,25.6555006249089494,47.6429159175320649]},"#886699":{"lch":[48.306860672000596,39.0046617113806562,292.251886736336132],"luv":[48.306860672000596,14.770249996667463,-36.0999078981538304],"rgb":[0.533333333333333326,0.4,0.6],"xyz":[0.206534366548126569,0.170371896794685618,0.323385438146853721],"hpluv":[292.251886736336132,102.458272059709785,48.306860672000596],"hsluv":[292.251886736336132,31.5854767603208231,48.306860672000596]},"#8866aa":{"lch":[49.0559053000777112,51.7871044207240132,284.005102499462396],"luv":[49.0559053000777112,12.5329093477081912,-50.2476901714407305],"rgb":[0.533333333333333326,0.4,0.66666666666666663],"xyz":[0.221592059513379125,0.176394973980786712,0.402689287763852322],"hpluv":[284.005102499462396,133.958310232957899,49.0559053000777112],"hsluv":[284.005102499462396,39.6059098285329867,49.0559053000777112]},"#8866bb":{"lch":[49.8879495217490074,65.0723394771694501,279.16089377463328],"luv":[49.8879495217490074,10.3599978518109275,-64.242352148271],"rgb":[0.533333333333333326,0.4,0.733333333333333282],"xyz":[0.238729651620715744,0.183250010823721471,0.492947272862494068],"hpluv":[279.16089377463328,165.516042277675325,49.8879495217490074],"hsluv":[279.16089377463328,51.4342030459355897,49.8879495217490074]},"#8866cc":{"lch":[50.800144438276476,78.3702679805165161,276.063171305995638],"luv":[50.800144438276476,8.2778522611756955,-77.9318680982312912],"rgb":[0.533333333333333326,0.4,0.8],"xyz":[0.258022027064437498,0.190966961001210273,0.594553783532764224],"hpluv":[276.063171305995638,195.760791019658512,50.800144438276476],"hsluv":[276.063171305995638,63.370404435102877,50.800144438276476]},"#8866dd":{"lch":[51.7890458420015278,91.4433004674113903,273.951375062119212],"luv":[51.7890458420015278,6.3013441888180548,-91.225929766636682],"rgb":[0.533333333333333326,0.4,0.866666666666666696],"xyz":[0.279540352615071042,0.199574291221463807,0.707883631432770222],"hpluv":[273.951375062119212,224.054313572832513,51.7890458420015278],"hsluv":[273.951375062119212,75.4110532620532,51.7890458420015278]},"#8866ee":{"lch":[52.8507624936088831,104.176067138923727,272.440799986921],"luv":[52.8507624936088831,4.4365578942807,-104.081554170680207],"rgb":[0.533333333333333326,0.4,0.933333333333333348],"xyz":[0.303352532881245751,0.209099163327933851,0.833294447501293445],"hpluv":[272.440799986921,250.124381092910085,52.8507624936088831],"hsluv":[272.440799986921,87.5962217171162365,52.8507624936088831]},"#8866ff":{"lch":[53.9810943197935273,116.520298408763196,271.319576027424205],"luv":[53.9810943197935273,2.6833355157121912,-116.48939716462327],"rgb":[0.533333333333333326,0.4,1],"xyz":[0.329523581291077172,0.219567582691866547,0.97112863579307529],"hpluv":[271.319576027424205,273.904539658900717,53.9810943197935273],"hsluv":[271.319576027424205,99.9999999999990621,53.9810943197935273]},"#ffee00":{"lch":[92.75564548426334,102.358730475882979,79.2433869538170228],"luv":[92.75564548426334,19.1039702538988,100.560171167180329],"rgb":[1,0.933333333333333348,0],"xyz":[0.718122766220146147,0.824102939779910892,0.121241474366986887],"hpluv":[79.2433869538170228,651.393632104361359,92.75564548426334],"hsluv":[79.2433869538170228,100.000000000024428,92.75564548426334]},"#ffee11":{"lch":[92.7734436379168,101.564402459740549,79.2015044483446218],"luv":[92.7734436379168,19.0286516433192254,99.765917344759373],"rgb":[1,0.933333333333333348,0.0666666666666666657],"xyz":[0.719134431719783307,0.824507605979765801,0.12656957933174251],"hpluv":[79.2015044483446218,648.021125158270593,92.7734436379168],"hsluv":[79.2015044483446218,100.000000000024428,92.7734436379168]},"#ffee22":{"lch":[92.8064212727168183,100.098587827824673,79.1224559985664797],"luv":[92.8064212727168183,18.8896613956421291,98.3000914418838079],"rgb":[1,0.933333333333333348,0.133333333333333331],"xyz":[0.721009789858260253,0.825257749235156601,0.136446465527721716],"hpluv":[79.1224559985664797,641.762708667564539,92.8064212727168183],"hsluv":[79.1224559985664797,100.000000000024357,92.8064212727168183]},"#ffee33":{"lch":[92.8606749716073665,97.7038183815635506,78.9881622996309147],"luv":[92.8606749716073665,18.6625824309063972,95.9048702796014396],"rgb":[1,0.933333333333333348,0.2],"xyz":[0.72409754059071807,0.826492849528139728,0.152708619385332867],"hpluv":[78.9881622996309147,631.438241912838748,92.8606749716073665],"hsluv":[78.9881622996309147,100.000000000024599,92.8606749716073665]},"#ffee44":{"lch":[92.9389094487226828,94.2867391890675606,78.7846200921967181],"luv":[92.9389094487226828,18.3385503337116411,92.4861436030564192],"rgb":[1,0.933333333333333348,0.266666666666666663],"xyz":[0.728555535834936929,0.828276047625827294,0.176187394338219505],"hpluv":[78.7846200921967181,616.484076987319668,92.9389094487226828],"hsluv":[78.7846200921967181,100.000000000025381,92.9389094487226828]},"#ffee55":{"lch":[93.0433700241155179,89.7896797607108,78.4929149488566082],"luv":[93.0433700241155179,17.9120631143144244,87.984911129805738],"rgb":[1,0.933333333333333348,0.333333333333333315],"xyz":[0.734517949874298859,0.830661013241572,0.207589441612193393],"hpluv":[78.4929149488566082,596.384103057951847,93.0433700241155179],"hsluv":[78.4929149488566082,100.000000000025906,93.0433700241155179]},"#ffee66":{"lch":[93.1759694096933,84.1867368500463,78.0854442567743661],"luv":[93.1759694096933,17.3805845725397461,82.3730656305550895],"rgb":[1,0.933333333333333348,0.4],"xyz":[0.7421029456478071,0.833695011550975362,0.247537086019337382],"hpluv":[78.0854442567743661,570.62648367707834,93.1759694096933],"hsluv":[78.0854442567743661,100.000000000026517,93.1759694096933]},"#ffee77":{"lch":[93.3383558005883742,77.4816602435733586,77.5195453952684659],"luv":[93.3383558005883742,16.7442947506152713,75.6507519288807515],"rgb":[1,0.933333333333333348,0.466666666666666674],"xyz":[0.751416958668009,0.837420616759056213,0.296590887925735291],"hpluv":[77.5195453952684659,538.663675570032183,93.3383558005883742],"hsluv":[77.5195453952684659,100.00000000002693,93.3383558005883742]},"#ffee88":{"lch":[93.5319535615141433,69.7063855050026433,76.7254067288761235],"luv":[93.5319535615141433,16.0058531534094222,67.8438858336072599],"rgb":[1,0.933333333333333348,0.533333333333333326],"xyz":[0.762557375769952861,0.841876783599833756,0.355263751329307431],"hpluv":[76.7254067288761235,499.867858345774721,93.5319535615141433],"hsluv":[76.7254067288761235,100.000000000028109,93.5319535615141433]},"#ffee99":{"lch":[93.7579894103796647,60.9203426164438397,75.5807218945013517],"luv":[93.7579894103796647,15.1701259512809905,59.0013171304435744],"rgb":[1,0.933333333333333348,0.6],"xyz":[0.775614339879025505,0.847099569243463,0.424030428970425366],"hpluv":[75.5807218945013517,453.479030486808085,93.7579894103796647],"hsluv":[75.5807218945013517,100.000000000029459,93.7579894103796647]},"#ffeeaa":{"lch":[94.0175103342715204,51.2122166590618946,73.8511258956299],"luv":[94.0175103342715204,14.2438643230739057,49.191497886124175],"rgb":[1,0.933333333333333348,0.66666666666666663],"xyz":[0.790672032844278116,0.853122646429564,0.503334278587424],"hpluv":[73.8511258956299,398.552269307706354,94.0175103342715204],"hsluv":[73.8511258956299,100.00000000003169,94.0175103342715204]},"#ffeebb":{"lch":[94.3113965930375855,40.7102572776027571,71.0277189369888],"luv":[94.3113965930375855,13.2353397134719373,38.4987120599845625],"rgb":[1,0.933333333333333348,0.733333333333333282],"xyz":[0.80780962495161468,0.859977683272498794,0.593592263686065658],"hpluv":[71.0277189369888,333.94796839081863,94.3113965930375855],"hsluv":[71.0277189369888,100.000000000032855,94.3113965930375855]},"#ffeecc":{"lch":[94.6403717602024841,29.6267857036886042,65.7803861656043125],"luv":[94.6403717602024841,12.1539519061426287,27.0190281874729799],"rgb":[1,0.933333333333333348,0.8],"xyz":[0.827102000395336434,0.867694633449987651,0.695198774356335814],"hpluv":[65.7803861656043125,258.601677072085806,94.6403717602024841],"hsluv":[65.7803861656043125,100.000000000035726,94.6403717602024841]},"#ffeedd":{"lch":[95.0050109981125814,18.4911495042727,53.4580761074439366],"luv":[95.0050109981125814,11.0098304435300403,14.8561853648264481],"rgb":[1,0.933333333333333348,0.866666666666666696],"xyz":[0.84862032594597,0.876301963670241157,0.808528622256341811],"hpluv":[53.4580761074439366,173.670551799097524,95.0050109981125814],"hsluv":[53.4580761074439366,100.000000000039279,95.0050109981125814]},"#ffeeee":{"lch":[95.4057483293867,10.0393308083340358,12.1770506300655121],"luv":[95.4057483293867,9.81345048674430487,2.11762900985580904],"rgb":[1,0.933333333333333348,0.933333333333333348],"xyz":[0.872432506212144743,0.885826835776711174,0.933939438324865],"hpluv":[12.1770506300655121,102.829227108855335,95.4057483293867],"hsluv":[12.1770506300655121,100.000000000042746,95.4057483293867]},"#ffeeff":{"lch":[95.8428833991312104,14.017983351086059,307.715012949261848],"luv":[95.8428833991312104,8.57528179129596,-11.0891117512266888],"rgb":[1,0.933333333333333348,1],"xyz":[0.898603554621976164,0.896295255140643898,1.07177362661664688],"hpluv":[307.715012949261848,159.207478793902965,95.8428833991312104],"hsluv":[307.715012949261848,100.000000000047876,95.8428833991312104]},"#aa6600":{"lch":[49.5566255632669623,74.0434564420528574,40.5370999312324685],"luv":[49.5566255632669623,56.2719368465296,48.1238253407432595],"rgb":[0.66666666666666663,0.4,0],"xyz":[0.213283568900016929,0.180499417461687406,0.0236077699189200241],"hpluv":[40.5370999312324685,189.593866720893345,49.5566255632669623],"hsluv":[40.5370999312324685,100.000000000002302,49.5566255632669623]},"#aa6611":{"lch":[49.6055800152373934,72.4782904829715449,39.6736286483530876],"luv":[49.6055800152373934,55.7860674256664097,46.2711278500211662],"rgb":[0.66666666666666663,0.4,0.0666666666666666657],"xyz":[0.214295234399654061,0.180904083661542259,0.0289358748836756538],"hpluv":[39.6736286483530876,185.402990863318706,49.6055800152373934],"hsluv":[39.6736286483530876,96.4267217319678878,49.6055800152373934]},"#aa6622":{"lch":[49.6961357673044404,69.6784302133091,38.0044715349972151],"luv":[49.6961357673044404,54.9040042209680124,42.902610147809348],"rgb":[0.66666666666666663,0.4,0.133333333333333331],"xyz":[0.216170592538131062,0.181654226916933087,0.0388127610796548533],"hpluv":[38.0044715349972151,177.916023719914563,49.6961357673044404],"hsluv":[38.0044715349972151,89.9454244119252593,49.6961357673044404]},"#aa6633":{"lch":[49.8446929303716502,65.3554895773238798,35.0519229290669685],"luv":[49.8446929303716502,53.5020897896209959,37.5348692023167061],"rgb":[0.66666666666666663,0.4,0.2],"xyz":[0.219258343270588796,0.182889327209916186,0.055074914937266],"hpluv":[35.0519229290669685,166.380518722129068,49.8446929303716502],"hsluv":[35.0519229290669685,79.6601301034586,49.8446929303716502]},"#aa6644":{"lch":[50.0579996788189163,59.7471791719702878,30.3078082111971625],"luv":[50.0579996788189163,51.5813401714318687,30.1511320703974341],"rgb":[0.66666666666666663,0.4,0.266666666666666663],"xyz":[0.223716338514807683,0.18467252530760378,0.0785536898901526282],"hpluv":[30.3078082111971625,151.454869534606559,50.0579996788189163],"hsluv":[30.3078082111971625,65.6016329960131,50.0579996788189163]},"#aa6655":{"lch":[50.3411543587309183,53.4384070136854916,23.0123473649378063],"luv":[50.3411543587309183,49.1858121787411307,20.8906492114991877],"rgb":[0.66666666666666663,0.4,0.333333333333333315],"xyz":[0.229678752554169696,0.187057490923348613,0.109955737164126544],"hpluv":[23.0123473649378063,134.70064023894011,50.3411543587309183],"hsluv":[23.0123473649378063,48.1262851503794238,50.3411543587309183]},"#aa6666":{"lch":[50.6979081899742283,47.4599132867605107,12.1770506300620198],"luv":[50.6979081899742283,46.3920870859415544,10.0108753362152232],"rgb":[0.66666666666666663,0.4,0.4],"xyz":[0.237263748327677854,0.190091489232751903,0.149903381571270505],"hpluv":[12.1770506300620198,118.788999996072334,50.6979081899742283],"hsluv":[12.1770506300620198,27.8359446414257086,50.6979081899742283]},"#aa6677":{"lch":[51.1308297914663399,43.3502150416948382,357.146673366158041],"luv":[51.1308297914663399,43.29647113668576,-2.15794607701909591],"rgb":[0.66666666666666663,0.4,0.466666666666666674],"xyz":[0.246577761347879787,0.193817094440832727,0.198957183477668414],"hpluv":[357.146673366158041,107.584013476394517,51.1308297914663399],"hsluv":[357.146673366158041,31.9217683762365354,51.1308297914663399]},"#aa6688":{"lch":[51.6414184020027,42.8134625942885876,339.120025752150127],"luv":[51.6414184020027,40.0018640870324234,-15.2592086582212207],"rgb":[0.66666666666666663,0.4,0.533333333333333326],"xyz":[0.257718178449823587,0.198273261281610325,0.257630046881240582],"hpluv":[339.120025752150127,105.201399585535427,51.6414184020027],"hsluv":[339.120025752150127,36.2396804223311,51.6414184020027]},"#aa6699":{"lch":[52.2302006219705675,46.6703467022409342,321.661853982703349],"luv":[52.2302006219705675,36.6065194780657563,-28.949680361091449],"rgb":[0.66666666666666663,0.4,0.6],"xyz":[0.270775142558896342,0.203496046925239482,0.326396724522358461],"hpluv":[321.661853982703349,113.385797667979,52.2302006219705675],"hsluv":[321.661853982703349,40.6514838109423,52.2302006219705675]},"#aa66aa":{"lch":[52.8968256208086274,54.2656136904176165,307.715012949245079],"luv":[52.8968256208086274,33.1961393674155048,-42.9275338250028753],"rgb":[0.66666666666666663,0.4,0.66666666666666663],"xyz":[0.285832835524148843,0.209519124111340577,0.405700574139357117],"hpluv":[307.715012949245079,130.177052782763241,52.8968256208086274],"hsluv":[307.715012949245079,45.0372955528084091,52.8968256208086274]},"#aa66bb":{"lch":[53.6401644756464293,64.2916348467718848,297.653919381785329],"luv":[53.6401644756464293,29.8396642728746109,-56.9474209016772193],"rgb":[0.66666666666666663,0.4,0.733333333333333282],"xyz":[0.302970427631485517,0.216374160954275335,0.495958559237998808],"hpluv":[297.653919381785329,152.091062924306783,53.6401644756464293],"hsluv":[297.653919381785329,49.3013965401631964,53.6401644756464293]},"#aa66cc":{"lch":[54.4584144535918853,75.6506824974921699,290.576693925999962],"luv":[54.4584144535918853,26.5882539678026326,-70.824363839571447],"rgb":[0.66666666666666663,0.4,0.8],"xyz":[0.322262803075207271,0.224091111131764137,0.597565069908269],"hpluv":[290.576693925999962,176.273563499159138,54.4584144535918853],"hsluv":[290.576693925999962,59.8478295858589107,54.4584144535918853]},"#aa66dd":{"lch":[55.3492064676394619,87.6329338161637423,285.539109011475546],"luv":[55.3492064676394619,23.4765185392287,-84.4297587732275],"rgb":[0.66666666666666663,0.4,0.866666666666666696],"xyz":[0.343781128625840759,0.232698441352017671,0.710894917808275],"hpluv":[285.539109011475546,200.907097340780666,55.3492064676394619],"hsluv":[285.539109011475546,72.9499123576365,55.3492064676394619]},"#aa66ee":{"lch":[56.3097127205812171,99.8160041995885337,281.866291349003632],"luv":[56.3097127205812171,20.525011879724925,-97.6829492885499775],"rgb":[0.66666666666666663,0.4,0.933333333333333348],"xyz":[0.367593308892015525,0.242223313458487716,0.836305733876798185],"hpluv":[281.866291349003632,224.934563930918017,56.3097127205812171],"hsluv":[281.866291349003632,86.3166325899195215,56.3097127205812171]},"#aa66ff":{"lch":[57.3367512293125543,111.956114799504135,279.118878442970129],"luv":[57.3367512293125543,17.7431860168323468,-110.541173283857603],"rgb":[0.66666666666666663,0.4,1],"xyz":[0.39376435730184689,0.252691732822420412,0.97413992216858],"hpluv":[279.118878442970129,247.773048158040382,57.3367512293125543],"hsluv":[279.118878442970129,99.9999999999988631,57.3367512293125543]},"#887700":{"lch":[50.0114915023736586,55.8665567864094825,73.357205010908],"luv":[50.0114915023736586,16.0004093344436384,53.5262465366231766],"rgb":[0.533333333333333326,0.466666666666666674,0],"xyz":[0.167496530942664812,0.184282743437969299,0.0267477295612209565],"hpluv":[73.357205010908,141.749463920516746,50.0114915023736586],"hsluv":[73.357205010908,100.000000000002359,50.0114915023736586]},"#887711":{"lch":[50.0597743565714524,53.993823922257576,73.0031869817398302],"luv":[50.0597743565714524,15.783394234863108,51.6354286142242103],"rgb":[0.533333333333333326,0.466666666666666674,0.0666666666666666657],"xyz":[0.168508196442301944,0.184687409637824151,0.0320758345259765862],"hpluv":[73.0031869817398302,136.865669051735267,50.0597743565714524],"hsluv":[73.0031869817398302,96.4507191106164328,50.0597743565714524]},"#887722":{"lch":[50.1490916772086592,50.5946145563497751,72.2920831328592755],"luv":[50.1490916772086592,15.3890953737340599,48.1974145124374616],"rgb":[0.533333333333333326,0.466666666666666674,0.133333333333333331],"xyz":[0.170383554580778945,0.18543755289321498,0.0419527207219557857],"hpluv":[72.2920831328592755,128.020802989304741,50.1490916772086592],"hsluv":[72.2920831328592755,90.012010730737714,50.1490916772086592]},"#887733":{"lch":[50.2956280558193356,45.1970113165044083,70.9372107781068735],"luv":[50.2956280558193356,14.7615306672340392,42.718462569532349],"rgb":[0.533333333333333326,0.466666666666666674,0.2],"xyz":[0.173471305313236679,0.186672653186198079,0.058214874579566929],"hpluv":[70.9372107781068735,114.029917097227894,50.2956280558193356],"hsluv":[70.9372107781068735,79.7918184760720237,50.2956280558193356]},"#887744":{"lch":[50.5060566549544916,37.8272673959478567,68.4411772520018076],"luv":[50.5060566549544916,13.89986571870684,35.1809023711225777],"rgb":[0.533333333333333326,0.466666666666666674,0.266666666666666663],"xyz":[0.177929300557455566,0.188455851283885673,0.0816936495324535605],"hpluv":[68.4411772520018076,95.0387759917387598,50.5060566549544916],"hsluv":[68.4411772520018076,65.8173762074568316,50.5060566549544916]},"#887755":{"lch":[50.7854328179731453,28.7445471843262688,63.5083223958924279],"luv":[50.7854328179731453,12.8220173934607509,25.7263456945161408],"rgb":[0.533333333333333326,0.466666666666666674,0.333333333333333315],"xyz":[0.183891714596817579,0.190840816899630505,0.113095696806427476],"hpluv":[63.5083223958924279,71.82169329487634,50.7854328179731453],"hsluv":[63.5083223958924279,48.4385690265679756,50.7854328179731453]},"#887766":{"lch":[51.1374932189691549,18.6360854649452037,51.6613245975388082],"luv":[51.1374932189691549,11.5601245482137447,14.6173596072111405],"rgb":[0.533333333333333326,0.466666666666666674,0.4],"xyz":[0.191476710370325737,0.193874815209033796,0.153043341213571438],"hpluv":[51.6613245975388082,46.2439140208651,51.1374932189691549],"hsluv":[51.6613245975388082,28.2492665088726049,51.1374932189691549]},"#887777":{"lch":[51.5648179079599629,10.388802862097231,12.1770506300635812],"luv":[51.5648179079599629,10.1550595801770775,2.19134429758843829],"rgb":[0.533333333333333326,0.466666666666666674,0.466666666666666674],"xyz":[0.20079072339052767,0.197600420417114619,0.202097143119969347],"hpluv":[12.1770506300635812,25.5653264810281158,51.5648179079599629],"hsluv":[12.1770506300635812,5.9907484084339373,51.5648179079599629]},"#887788":{"lch":[52.0689409540354262,14.1414171783799034,307.715012949252923],"luv":[52.0689409540354262,8.65079050214889378,-11.1867557182995974],"rgb":[0.533333333333333326,0.466666666666666674,0.533333333333333326],"xyz":[0.21193114049247147,0.202056587257892217,0.260770006523541542],"hpluv":[307.715012949252923,34.4630346227371902,52.0689409540354262],"hsluv":[307.715012949252923,11.9231603633022036,52.0689409540354262]},"#887799":{"lch":[52.6504441343355154,26.1446518461971777,285.73365348909897],"luv":[52.6504441343355154,7.08953673880610147,-25.1650807467009763],"rgb":[0.533333333333333326,0.466666666666666674,0.6],"xyz":[0.224988104601544198,0.207279372901521375,0.329536684164659421],"hpluv":[285.73365348909897,63.0115482025775862,52.6504441343355154],"hsluv":[285.73365348909897,20.7849368541844512,52.6504441343355154]},"#8877aa":{"lch":[53.3090485775123142,39.8165287152511951,277.951975125090712],"luv":[53.3090485775123142,5.50833871717125412,-39.4336678931764482],"rgb":[0.533333333333333326,0.466666666666666674,0.66666666666666663],"xyz":[0.240045797566796726,0.213302450087622469,0.408840533781658],"hpluv":[277.951975125090712,94.7767450693341118,53.3090485775123142],"hsluv":[277.951975125090712,33.2193336653547036,53.3090485775123142]},"#8877bb":{"lch":[54.043710164283695,53.8841311835491,274.190220195010625],"luv":[54.043710164283695,3.93720379281895738,-53.7400969453883732],"rgb":[0.533333333333333326,0.466666666666666674,0.733333333333333282],"xyz":[0.2571833896741334,0.220157486930557228,0.499098518880299769],"hpluv":[274.190220195010625,126.518797380186697,54.043710164283695],"hsluv":[274.190220195010625,46.027457746288988,54.043710164283695]},"#8877cc":{"lch":[54.8527197178713095,67.9360625264533695,272.023364737824068],"luv":[54.8527197178713095,2.39862107173988059,-67.8937052203839215],"rgb":[0.533333333333333326,0.466666666666666674,0.8],"xyz":[0.276475765117855099,0.22787443710804603,0.600705029550569924],"hpluv":[272.023364737824068,157.159823716941304,54.8527197178713095],"hsluv":[272.023364737824068,59.1220253911564413,54.8527197178713095]},"#8877dd":{"lch":[55.7338064566187228,81.7667290312133,270.636302714775695],"luv":[55.7338064566187228,0.90804807322034331,-81.7616867803042595],"rgb":[0.533333333333333326,0.466666666666666674,0.866666666666666696],"xyz":[0.297994090668488698,0.236481767328299564,0.714034877450575922],"hpluv":[270.636302714775695,186.164661983392193,55.7338064566187228],"hsluv":[270.636302714775695,72.4679508704990809,55.7338064566187228]},"#8877ee":{"lch":[56.6842419440431939,95.2620356561917419,269.684203716511661],"luv":[56.6842419440431939,-0.525051666249150784,-95.2605886928551229],"rgb":[0.533333333333333326,0.466666666666666674,0.933333333333333348],"xyz":[0.321806270934663408,0.246006639434769608,0.839445693519099145],"hpluv":[269.684203716511661,213.253830698535069,56.6842419440431939],"hsluv":[269.684203716511661,86.076772525698,56.6842419440431939]},"#8877ff":{"lch":[57.7009414002340577,108.362660778640901,268.997474997449615],"luv":[57.7009414002340577,-1.89596396936046907,-108.346073171359961],"rgb":[0.533333333333333326,0.466666666666666674,1],"xyz":[0.347977319344494829,0.256475058798702304,0.977279881810881],"hpluv":[268.997474997449615,238.306609639193027,57.7009414002340577],"hsluv":[268.997474997449615,99.9999999999988631,57.7009414002340577]},"#ffff00":{"lch":[97.1385593417967357,107.085608846920664,85.8743202181747307],"luv":[97.1385593417967357,7.70421917727499928,106.808111250898],"rgb":[1,1,0],"xyz":[0.76997513864982,0.92780768463926,0.138525598510210984],"hpluv":[85.8743202181747307,1784.23591835690763,97.1385593417967357],"hsluv":[85.8743202181747307,100.000000000072717,97.1385593417967357]},"#ffff11":{"lch":[97.1550055288865337,106.340968495662651,85.8743202181747307],"luv":[97.1550055288865337,7.65064640931757278,106.065400532478591],"rgb":[1,1,0.0666666666666666657],"xyz":[0.770986804149457194,0.928212350839114908,0.143853703474966621],"hpluv":[85.8743202181747307,1782.29032599077573,97.1550055288865337],"hsluv":[85.8743202181747307,100.000000000072447,97.1550055288865337]},"#ffff22":{"lch":[97.1854797367251564,104.966044999604463,85.8743202181747],"luv":[97.1854797367251564,7.5517282439387623,104.694039961158666],"rgb":[1,1,0.133333333333333331],"xyz":[0.77286216228793414,0.928962494094505709,0.1537305896709458],"hpluv":[85.8743202181747,1778.69938503976459,97.1854797367251564],"hsluv":[85.8743202181747,100.00000000007401,97.1854797367251564]},"#ffff33":{"lch":[97.2356193677236291,102.717517786777336,85.8743202181746312],"luv":[97.2356193677236291,7.38995910744871409,102.451339496695468],"rgb":[1,1,0.2],"xyz":[0.775949913020392,0.930197594387488835,0.16999274352855695],"hpluv":[85.8743202181746312,1772.83090468185333,97.2356193677236291],"hsluv":[85.8743202181746312,100.000000000075445,97.2356193677236291]},"#ffff44":{"lch":[97.3079311184623776,99.5042093292491,85.874320218174546],"luv":[97.3079311184623776,7.15877927938833114,99.2463578851537704],"rgb":[1,1,0.266666666666666663],"xyz":[0.780407908264610817,0.931980792485176401,0.193471518481443588],"hpluv":[85.874320218174546,1764.45330998562531,97.3079311184623776],"hsluv":[85.874320218174546,100.000000000077918,97.3079311184623776]},"#ffff55":{"lch":[97.4045015397841212,95.2663481722239283,85.8743202181744323],"luv":[97.4045015397841212,6.8538885331141568,95.0194785612246875],"rgb":[1,1,0.333333333333333315],"xyz":[0.786370322303972746,0.934365758100921151,0.224873565755417504],"hpluv":[85.8743202181744323,1753.42077174454698,97.4045015397841212],"hsluv":[85.8743202181744323,100.000000000080163,97.4045015397841212]},"#ffff66":{"lch":[97.5271149532436539,89.9715947326486258,85.8743202181742333],"luv":[97.5271149532436539,6.47296021391862286,89.7384457454272706],"rgb":[1,1,0.4],"xyz":[0.793955318077481,0.93739975641032447,0.264821210162561438],"hpluv":[85.8743202181742333,1739.66322518688298,97.5271149532436539],"hsluv":[85.8743202181742333,100.000000000084981,97.5271149532436539]},"#ffff77":{"lch":[97.6773170086398608,83.6127156419164663,85.8743202181740202],"luv":[97.6773170086398608,6.01547392080898469,83.3960448134325389],"rgb":[1,1,0.466666666666666674],"xyz":[0.803269331097682837,0.941125361618405321,0.313875012068959403],"hpluv":[85.8743202181740202,1723.18045161093028,97.6773170086398608],"hsluv":[85.8743202181740202,100.00000000009112,97.6773170086398608]},"#ffff88":{"lch":[97.8564527859654589,76.2055692953657342,85.8743202181736791],"luv":[97.8564527859654589,5.48257057790026181,76.0080930657330214],"rgb":[1,1,0.533333333333333326],"xyz":[0.814409748199626748,0.945581528459182863,0.372547875472531542],"hpluv":[85.8743202181736791,1704.03672017478311,97.8564527859654589],"hsluv":[85.8743202181736791,100.000000000099803,97.8564527859654589]},"#ffff99":{"lch":[98.0656913545514612,67.7868897983338741,85.8743202181732102],"luv":[98.0656913545514612,4.87689300155069283,67.6112294162950889],"rgb":[1,1,0.6],"xyz":[0.827466712308699393,0.950804314102812076,0.441314553113649422],"hpluv":[85.8743202181732102,1682.35465810463256,98.0656913545514612],"hsluv":[85.8743202181732102,100.000000000112891,98.0656913545514612]},"#ffffaa":{"lch":[98.3060425431328611,58.4116937234916094,85.8743202181725707],"luv":[98.3060425431328611,4.20239933084915052,58.260327869924204],"rgb":[1,1,0.66666666666666663],"xyz":[0.842524405273952,0.956827391288913143,0.520618402730648078],"hpluv":[85.8743202181725707,1658.30791632356272,98.3060425431328611],"hsluv":[85.8743202181725707,100.000000000127613,98.3060425431328611]},"#ffffbb":{"lch":[98.5783690162300559,48.1503065934375414,85.8743202181715759],"luv":[98.5783690162300559,3.46414909943131732,48.0255317103199246],"rgb":[1,1,0.733333333333333282],"xyz":[0.859661997381288567,0.963682428131847901,0.610876387829289769],"hpluv":[85.8743202181715759,1632.1126639545671,98.5783690162300559],"hsluv":[85.8743202181715759,100.000000000152809,98.5783690162300559]},"#ffffcc":{"lch":[98.8833954570195317,37.0851031688938804,85.8743202181698706],"luv":[98.8833954570195317,2.66806871718659799,36.9890022353654899],"rgb":[1,1,0.8],"xyz":[0.878954372825010322,0.971399378309336758,0.712482898499559925],"hpluv":[85.8743202181698706,1604.018210645404,98.8833954570195317],"hsluv":[85.8743202181698706,100.00000000019709,98.8833954570195317]},"#ffffdd":{"lch":[99.2217159651800245,25.3071072074552177,85.8743202181663889],"luv":[99.2217159651800245,1.82070684164607655,25.2415273271332552],"rgb":[1,1,0.866666666666666696],"xyz":[0.900472698375643921,0.980006708529590265,0.825812746399565922],"hpluv":[85.8743202181663889,1574.29719653830034,99.2217159651800245],"hsluv":[85.8743202181663889,100.000000000286278,99.2217159651800245]},"#ffffee":{"lch":[99.5938003805277248,12.9126149352850259,85.8743202181558161],"luv":[99.5938003805277248,0.928991455386458775,12.8791536733888243],"rgb":[1,1,0.933333333333333348],"xyz":[0.92428487864181863,0.989531580636060282,0.951223562468089145],"hpluv":[85.8743202181558161,1543.23583838085528,99.5938003805277248],"hsluv":[85.8743202181558161,100.000000000556355,99.5938003805277248]},"#ffffff":{"lch":[99.99999999999973,5.29610712429325706e-12,0],"luv":[99.99999999999973,4.97935026544381416e-12,1.80411241501587473e-12],"rgb":[1,1,1],"xyz":[0.95045592705165,0.999999999999993,1.0890577507598711],"hpluv":[0,0,100],"hsluv":[0,0,100]},"#aa7700":{"lch":[53.7507838912622304,69.116848270999057,51.9676330333141223],"luv":[53.7507838912622304,42.5833417137676875,54.4407726194696622],"rgb":[0.66666666666666663,0.466666666666666674,0],"xyz":[0.231737306953434558,0.217406893568523163,0.0297590159367257245],"hpluv":[51.9676330333141223,163.169299961930307,53.7507838912622304],"hsluv":[51.9676330333141223,100.000000000002359,53.7507838912622304]},"#aa7711":{"lch":[53.7940335015026,67.5786316453491906,51.3090056740019378],"luv":[53.7940335015026,42.244752971039,52.7470596476588653],"rgb":[0.66666666666666663,0.466666666666666674,0.0666666666666666657],"xyz":[0.23274897245307169,0.217811559768378016,0.0350871209014813543],"hpluv":[51.3090056740019378,159.40965108533166,53.7940335015026],"hsluv":[51.3090056740019378,97.0120153186068,53.7940335015026]},"#aa7722":{"lch":[53.874065271669366,64.7981771198060272,50.0272013346139],"luv":[53.874065271669366,41.6278947732915157,49.6580520640260588],"rgb":[0.66666666666666663,0.466666666666666674,0.133333333333333331],"xyz":[0.234624330591548691,0.218561703023768844,0.0449640070974605538],"hpluv":[50.0272013346139,152.623836787181489,53.874065271669366],"hsluv":[50.0272013346139,91.5730337049880632,53.874065271669366]},"#aa7733":{"lch":[54.0054384284815,60.4215101577181812,47.7291529037971785],"luv":[54.0054384284815,40.6416884431496115,44.7103125713654705],"rgb":[0.66666666666666663,0.466666666666666674,0.2],"xyz":[0.237712081324006452,0.219796803316751943,0.0612261609550717],"hpluv":[47.7291529037971785,141.968961696257139,54.0054384284815],"hsluv":[47.7291529037971785,82.890357503842381,54.0054384284815]},"#aa7744":{"lch":[54.1942453736720324,54.5501661616690754,43.9413891432679051],"luv":[54.1942453736720324,39.2788485799816911,37.8535689532252277],"rgb":[0.66666666666666663,0.466666666666666674,0.266666666666666663],"xyz":[0.242170076568225312,0.221580001414439537,0.0847049359079583286],"hpluv":[43.9413891432679051,127.726858599491337,54.1942453736720324],"hsluv":[43.9413891432679051,70.9191698542686453,54.1942453736720324]},"#aa7755":{"lch":[54.4451912879813307,47.55778496198932,37.8352816528713],"luv":[54.4451912879813307,37.5600659479400178,29.1716361638701045],"rgb":[0.66666666666666663,0.466666666666666674,0.333333333333333315],"xyz":[0.248132490607587297,0.22396496703018437,0.116106983181932244],"hpluv":[37.8352816528713,110.841250641501858,54.4451912879813307],"hsluv":[37.8352816528713,55.8697139193963039,54.4451912879813307]},"#aa7766":{"lch":[54.7618668139504621,40.2221891209492881,27.9562221290694595],"luv":[54.7618668139504621,35.5285027246357359,18.8560333004309904],"rgb":[0.66666666666666663,0.466666666666666674,0.4],"xyz":[0.255717486381095482,0.226998965339587661,0.156054627589076206],"hpluv":[27.9562221290694595,93.2023334238246264,54.7618668139504621],"hsluv":[27.9562221290694595,38.157009054435612,54.7618668139504621]},"#aa7777":{"lch":[55.1468928183874851,34.0080558607991321,12.1770506300622881],"luv":[55.1468928183874851,33.2428902595124569,7.17343088244713467],"rgb":[0.66666666666666663,0.466666666666666674,0.466666666666666674],"xyz":[0.265031499401297388,0.230724570547668484,0.205108429495474115],"hpluv":[12.1770506300622881,78.2528356679829074,55.1468928183874851],"hsluv":[12.1770506300622881,20.6006796366476941,55.1468928183874851]},"#aa7788":{"lch":[55.6020140468043849,31.2700131437067519,349.739442339375785],"luv":[55.6020140468043849,30.7699397165362107,-5.56996695217490778],"rgb":[0.66666666666666663,0.466666666666666674,0.533333333333333326],"xyz":[0.276171916503241244,0.235180737388446082,0.263781292899046282],"hpluv":[349.739442339375785,71.363619208349732,55.6020140468043849],"hsluv":[349.739442339375785,23.0952607722130772,55.6020140468043849]},"#aa7799":{"lch":[56.1281730235999845,34.0192547961324365,325.92167501088062],"luv":[56.1281730235999845,28.1772086346441704,-19.0618627223027133],"rgb":[0.66666666666666663,0.466666666666666674,0.6],"xyz":[0.289228880612313943,0.240403523032075239,0.332547970540164162],"hpluv":[325.92167501088062,76.9100717288581706,56.1281730235999845],"hsluv":[325.92167501088062,27.5449434619861648,56.1281730235999845]},"#aa77aa":{"lch":[56.7255784680210127,41.7295245342496131,307.715012949246272],"luv":[56.7255784680210127,25.5273831431779215,-33.0106941416859],"rgb":[0.66666666666666663,0.466666666666666674,0.66666666666666663],"xyz":[0.304286573577566499,0.246426600218176334,0.411851820157162818],"hpluv":[307.715012949246272,93.3477446513022642,56.7255784680210127],"hsluv":[307.715012949246272,32.2954766233998285,56.7255784680210127]},"#aa77bb":{"lch":[57.3937746480490176,52.417961949749369,295.873528074876958],"luv":[57.3937746480490176,22.8744713506946127,-47.1635589771554891],"rgb":[0.66666666666666663,0.466666666666666674,0.733333333333333282],"xyz":[0.321424165684903118,0.25328163706111112,0.502109805255804509],"hpluv":[295.873528074876958,115.892323381948941,57.3937746480490176],"hsluv":[295.873528074876958,41.7229864085831679,57.3937746480490176]},"#aa77cc":{"lch":[58.1317139736185,64.5762938068646548,288.286403622885132],"luv":[58.1317139736185,20.2619194712353625,-61.3151885031081],"rgb":[0.66666666666666663,0.466666666666666674,0.8],"xyz":[0.340716541128624872,0.260998587238599922,0.603716315926074665],"hpluv":[288.286403622885132,140.961111207958226,58.1317139736185],"hsluv":[288.286403622885132,55.678510160825347,58.1317139736185]},"#aa77dd":{"lch":[58.9378328182195759,77.3666791836153,283.242275299631103],"luv":[58.9378328182195759,17.7223199365118553,-75.3095108466943088],"rgb":[0.66666666666666663,0.466666666666666674,0.866666666666666696],"xyz":[0.362234866679258416,0.269605917458853428,0.717046163826080662],"hpluv":[283.242275299631103,166.570895286205939,58.9378328182195759],"hsluv":[283.242275299631103,70.0408478070886105,58.9378328182195759]},"#aa77ee":{"lch":[59.8101292792768646,90.3373867943789151,279.736895248195651],"luv":[59.8101292792768646,15.2782276108220607,-89.0360556960445138],"rgb":[0.66666666666666663,0.466666666666666674,0.933333333333333348],"xyz":[0.386047046945433125,0.279130789565323445,0.842456979894603886],"hpluv":[279.736895248195651,191.660275847677298,59.8101292792768646],"hsluv":[279.736895248195651,84.8029379630096685,59.8101292792768646]},"#aa77ff":{"lch":[60.7462409754246551,103.238062985892157,277.202485092995744],"luv":[60.7462409754246551,12.9436026905507742,-102.423438716283115],"rgb":[0.66666666666666663,0.466666666666666674,1],"xyz":[0.412218095355264547,0.289599208929256169,0.980291168186385731],"hpluv":[277.202485092995744,215.655115976047284,60.7462409754246551],"hsluv":[277.202485092995744,99.999999999998721,60.7462409754246551]},"#888800":{"lch":[54.9099926918455452,60.532810441385358,85.8743202181747449],"luv":[54.9099926918455452,4.35500198466006783,60.375948006191166],"rgb":[0.533333333333333326,0.533333333333333326,0],"xyz":[0.189568900667635265,0.228427482887910871,0.0341051861362109063],"hpluv":[85.8743202181747449,139.887458074797593,54.9099926918455452],"hsluv":[85.8743202181747449,100.000000000002331,54.9099926918455452]},"#888811":{"lch":[54.9518410557904673,58.8347385736240369,85.8743202181746739],"luv":[54.9518410557904673,4.23283507550337568,58.6822764576347353],"rgb":[0.533333333333333326,0.533333333333333326,0.0666666666666666657],"xyz":[0.190580566167272397,0.228832149087765724,0.039433291100966536],"hpluv":[85.8743202181746739,135.85978011465275,54.9518410557904673],"hsluv":[85.8743202181746739,97.1207726442580395,54.9518410557904673]},"#888822":{"lch":[55.0292864560463215,55.7361292450240882,85.8743202181745602],"luv":[55.0292864560463215,4.00990721741558787,55.5916967480373643],"rgb":[0.533333333333333326,0.533333333333333326,0.133333333333333331],"xyz":[0.192455924305749398,0.229582292343156552,0.0493101772969457355],"hpluv":[85.8743202181745602,128.523412903997382,55.0292864560463215],"hsluv":[85.8743202181745602,91.8762944675706,55.0292864560463215]},"#888833":{"lch":[55.1564325013520573,50.7686053645684225,85.8743202181742902],"luv":[55.1564325013520573,3.65252126093227947,50.6370455210582335],"rgb":[0.533333333333333326,0.533333333333333326,0.2],"xyz":[0.195543675038207132,0.230817392636139651,0.0655723311545568788],"hpluv":[85.8743202181742902,116.798802852822334,55.1564325013520573],"hsluv":[85.8743202181742902,83.4948353914423,55.1564325013520573]},"#888844":{"lch":[55.3392041906722767,43.8756115710196184,85.8743202181737786],"luv":[55.3392041906722767,3.15660835961073616,43.7619139708837039],"rgb":[0.533333333333333326,0.533333333333333326,0.266666666666666663],"xyz":[0.20000167028242602,0.232600590733827245,0.0890511061074435173],"hpluv":[85.8743202181737786,100.607324583255647,55.3392041906722767],"hsluv":[85.8743202181737786,71.9201892491773833,55.3392041906722767]},"#888855":{"lch":[55.5822005995452173,35.1333862553221152,85.8743202181729],"luv":[55.5822005995452173,2.5276534453655044,35.0423429271758167],"rgb":[0.533333333333333326,0.533333333333333326,0.333333333333333315],"xyz":[0.205964084321788032,0.234985556349572078,0.120453153381417433],"hpluv":[85.8743202181729,80.2090919262666233,55.5822005995452173],"hsluv":[85.8743202181729,57.3383011101545321,55.5822005995452173]},"#888866":{"lch":[55.8889601924437187,24.7258905438507242,85.874320218171],"luv":[55.8889601924437187,1.778891507033598,24.6618168064052092],"rgb":[0.533333333333333326,0.533333333333333326,0.4],"xyz":[0.21354908009529619,0.238019554658975369,0.160400797788561394],"hpluv":[85.874320218171,56.1390732800859524,55.8889601924437187],"hsluv":[85.874320218171,40.1315986813270698,55.8889601924437187]},"#888877":{"lch":[56.2621011123828509,12.9137749110131566,85.8743202181651668],"luv":[56.2621011123828509,0.929074909242871283,12.8803106431998842],"rgb":[0.533333333333333326,0.533333333333333326,0.466666666666666674],"xyz":[0.222863093115498123,0.241745159867056192,0.209454599694959304],"hpluv":[85.8743202181651668,29.1257147579972724,56.2621011123828509],"hsluv":[85.8743202181651668,20.8208192205656601,56.2621011123828509]},"#888888":{"lch":[56.703410756754252,2.95076376078202623e-12,0],"luv":[56.703410756754252,2.78254170310414444e-12,9.82073542272051e-13],"rgb":[0.533333333333333326,0.533333333333333326,0.533333333333333326],"xyz":[0.234003510217441923,0.24620132670783379,0.268127463098531471],"hpluv":[0,6.60335407213460764e-12,56.703410756754252],"hsluv":[0,2.14018342731852893e-12,56.703410756754252]},"#888899":{"lch":[57.2139150634865246,13.7029898302256612,265.874320218188814],"luv":[57.2139150634865246,-0.985854571612734376,-13.6674804207248872],"rgb":[0.533333333333333326,0.533333333333333326,0.6],"xyz":[0.247060474326514651,0.251424112351462947,0.33689414073964935],"hpluv":[265.874320218188814,30.3915601408835876,57.2139150634865246],"hsluv":[265.874320218188814,12.5386286039598396,57.2139150634865246]},"#8888aa":{"lch":[57.7939415002624486,27.9001972781706051,265.874320218182902],"luv":[57.7939415002624486,-2.00726537612613365,-27.8278977623291475],"rgb":[0.533333333333333326,0.533333333333333326,0.66666666666666663],"xyz":[0.262118167291767179,0.25744718953756407,0.416197990356647951],"hpluv":[265.874320218182902,61.2582077856443377,57.7939415002624486],"hsluv":[265.874320218182902,25.8334660761224093,57.7939415002624486]},"#8888bb":{"lch":[58.4431822360017605,42.3326731508362428,265.874320218181083],"luv":[58.4431822360017605,-3.04560244672749647,-42.2229738629578222],"rgb":[0.533333333333333326,0.533333333333333326,0.733333333333333282],"xyz":[0.279255759399103853,0.264302226380498828,0.506455975455289753],"hpluv":[265.874320218181083,91.9138937804104756,58.4431822360017605],"hsluv":[265.874320218181083,39.7348050695490116,58.4431822360017605]},"#8888cc":{"lch":[59.1607600358786812,56.7874726838639603,265.874320218180117],"luv":[59.1607600358786812,-4.0855455816182138,-56.6403157752595448],"rgb":[0.533333333333333326,0.533333333333333326,0.8],"xyz":[0.298548134842825608,0.27201917655798763,0.608062486125559909],"hpluv":[265.874320218180117,121.803038601679276,59.1607600358786812],"hsluv":[265.874320218180117,54.1372084350884322,59.1607600358786812]},"#8888dd":{"lch":[59.9452971965242654,71.1002375720468649,265.874320218179605],"luv":[59.9452971965242654,-5.11527010687093497,-70.9159911059223447],"rgb":[0.533333333333333326,0.533333333333333326,0.866666666666666696],"xyz":[0.320066460393459096,0.280626506778241136,0.721392334025565907],"hpluv":[265.874320218179605,150.506501481916018,59.9452971965242654],"hsluv":[265.874320218179605,68.9826297466640881,59.9452971965242654]},"#8888ee":{"lch":[60.7949865781877747,85.1524606014505,265.874320218179207],"luv":[60.7949865781877747,-6.12625008179143,-84.9317997361231676],"rgb":[0.533333333333333326,0.533333333333333326,0.933333333333333348],"xyz":[0.343878640659633861,0.290151378884711153,0.84680315009408913],"hpluv":[265.874320218179207,177.733282428962553,60.7949865781877747],"hsluv":[265.874320218179207,84.2595641984559194,60.7949865781877747]},"#8888ff":{"lch":[61.7076631467729726,98.8655769196339,265.874320218179],"luv":[61.7076631467729726,-7.11283319838656247,-98.6093804034077408],"rgb":[0.533333333333333326,0.533333333333333326,1],"xyz":[0.370049689069465226,0.300619798248643877,0.984637338385871],"hpluv":[265.874320218179,203.303722842755434,61.7076631467729726],"hsluv":[265.874320218179,99.9999999999986073,61.7076631467729726]},"#aa8800":{"lch":[58.1840377660698493,67.6904417424552634,64.2288134226940173],"luv":[58.1840377660698493,29.4303340948507071,60.9577832467208225],"rgb":[0.66666666666666663,0.533333333333333326,0],"xyz":[0.253809676678405038,0.261551633018464735,0.0371164725117156744],"hpluv":[64.2288134226940173,147.625988392398114,58.1840377660698493],"hsluv":[64.2288134226940173,100.000000000002373,58.1840377660698493]},"#aa8811":{"lch":[58.2222766199063955,66.2027965316335809,63.8264905250604926],"luv":[58.2222766199063955,29.2014551434886229,59.4145208354969085],"rgb":[0.66666666666666663,0.533333333333333326,0.0666666666666666657],"xyz":[0.254821342178042143,0.261956299218319588,0.0424445774764713041],"hpluv":[63.8264905250604926,144.286759049554206,58.2222766199063955],"hsluv":[63.8264905250604926,97.5015111084285877,58.2222766199063955]},"#aa8822":{"lch":[58.2930572278629,63.4916551128893474,63.0419050459203],"luv":[58.2930572278629,28.7832252220538578,56.5925455761676304],"rgb":[0.66666666666666663,0.533333333333333326,0.133333333333333331],"xyz":[0.2566967003165192,0.262706442473710389,0.0523214636724505036],"hpluv":[63.0419050459203,138.209896631886636,58.2930572278629],"hsluv":[63.0419050459203,92.9399945222758106,58.2930572278629]},"#aa8833":{"lch":[58.4093035212624585,59.1585039849960737,61.628621374019076],"luv":[58.4093035212624585,28.1112178941065629,52.0527426967384628],"rgb":[0.66666666666666663,0.533333333333333326,0.2],"xyz":[0.259784451048976905,0.263941542766693515,0.0685836175300616468],"hpluv":[61.628621374019076,128.521114132395894,58.4093035212624585],"hsluv":[61.628621374019076,85.621599137751673,58.4093035212624585]},"#aa8844":{"lch":[58.5764981609594315,53.1878639814319953,59.2736460930020499],"luv":[58.5764981609594315,27.1757201885359478,45.7212106919940453],"rgb":[0.66666666666666663,0.533333333333333326,0.266666666666666663],"xyz":[0.264242446293195821,0.265724740864381082,0.0920623924829482854],"hpluv":[59.2736460930020499,115.22015920662389,58.5764981609594315],"hsluv":[59.2736460930020499,75.4571473133808581,58.5764981609594315]},"#aa8855":{"lch":[58.7989500318507083,45.736161182952344,55.3795129841665315],"luv":[58.7989500318507083,25.9844527075537677,37.6378088793954433],"rgb":[0.66666666666666663,0.533333333333333326,0.333333333333333315],"xyz":[0.270204860332557806,0.268109706480125942,0.123464439756922201],"hpluv":[55.3795129841665315,98.7027982667044483,58.7989500318507083],"hsluv":[55.3795129841665315,62.5553187882680319,58.7989500318507083]},"#aa8866":{"lch":[59.0800404303715112,37.1980666756204,48.681601920545944],"luv":[59.0800404303715112,24.5597583059268025,27.9376884576795419],"rgb":[0.66666666666666663,0.533333333333333326,0.4],"xyz":[0.277789856106066,0.271143704789529261,0.163412084164066163],"hpluv":[48.681601920545944,79.8948730878687883,59.0800404303715112],"hsluv":[48.681601920545944,47.1909371341698645,59.0800404303715112]},"#aa8877":{"lch":[59.4223523155875881,28.4467220316745042,36.2691810942760355],"luv":[59.4223523155875881,22.9350730451589406,16.8285001934390941],"rgb":[0.66666666666666663,0.533333333333333326,0.466666666666666674],"xyz":[0.287103869126267897,0.274869309997610056,0.212465886070464072],"hpluv":[36.2691810942760355,60.7465636644032,59.4223523155875881],"hsluv":[36.2691810942760355,29.7643761063162415,59.4223523155875881]},"#aa8888":{"lch":[59.8277504540149323,21.6376696880998622,12.1770506300627677],"luv":[59.8277504540149323,21.1508320810015036,4.56410471095846049],"rgb":[0.66666666666666663,0.533333333333333326,0.533333333333333326],"xyz":[0.298244286228211697,0.279325476838387654,0.271138749474036211],"hpluv":[12.1770506300627677,45.8930730764781174,59.8277504540149323],"hsluv":[12.1770506300627677,15.9793094134510145,59.8277504540149323]},"#aa8899":{"lch":[60.2974403890441693,21.076671863141442,335.972081494736813],"luv":[60.2974403890441693,19.2503183610400761,-8.58203587880762697],"rgb":[0.66666666666666663,0.533333333333333326,0.6],"xyz":[0.311301250337284396,0.284548262482016812,0.339905427115154146],"hpluv":[335.972081494736813,44.3549898137704872,60.2974403890441693],"hsluv":[335.972081494736813,18.3674189175529285,60.2974403890441693]},"#aa88aa":{"lch":[60.8320193568852119,28.2409959286201691,307.715012949248376],"luv":[60.8320193568852119,17.2759870010776844,-22.3404145928166677],"rgb":[0.66666666666666663,0.533333333333333326,0.66666666666666663],"xyz":[0.326358943302536952,0.290571339668117934,0.419209276732152747],"hpluv":[307.715012949248376,58.9097393716334068,60.8320193568852119],"hsluv":[307.715012949248376,20.7885743891348937,60.8320193568852119]},"#aa88bb":{"lch":[61.4315255818646904,39.5305448534603343,292.718173175904553],"luv":[61.4315255818646904,15.2666424694527869,-36.4635928581008],"rgb":[0.66666666666666663,0.533333333333333326,0.733333333333333282],"xyz":[0.343496535409873627,0.297426376511052692,0.509467261830794493],"hpluv":[292.718173175904553,81.6546320542196185,61.4315255818646904],"hsluv":[292.718173175904553,35.3775178816614826,61.4315255818646904]},"#aa88cc":{"lch":[62.0954889075932783,52.4408733717370339,284.64164926901276],"luv":[62.0954889075932783,13.2556230251873277,-50.737891739849438],"rgb":[0.66666666666666663,0.533333333333333326,0.8],"xyz":[0.362788910853595326,0.305143326688541494,0.611073772501064649],"hpluv":[284.64164926901276,107.164068097081099,62.0954889075932783],"hsluv":[284.64164926901276,50.6369924233865092,62.0954889075932783]},"#aa88dd":{"lch":[62.8229837406334894,65.9589053782665644,279.83800714750987],"luv":[62.8229837406334894,11.2699451472508105,-64.988964717689413],"rgb":[0.66666666666666663,0.533333333333333326,0.866666666666666696],"xyz":[0.384307236404228925,0.313750656908795,0.724403620401070647],"hpluv":[279.83800714750987,133.227600809414753,62.8229837406334894],"hsluv":[279.83800714750987,66.50088929558828,62.8229837406334894]},"#aa88ee":{"lch":[63.6126841134072,79.6308922643202237,276.728713669089302],"luv":[63.6126841134072,9.33022805769535,-79.0823990986816767],"rgb":[0.66666666666666663,0.533333333333333326,0.933333333333333348],"xyz":[0.408119416670403634,0.323275529015265,0.84981443646959387],"hpluv":[276.728713669089302,158.846330872338797,63.6126841134072],"hsluv":[276.728713669089302,82.9476730407324112,63.6126841134072]},"#aa88ff":{"lch":[64.4629200033750323,93.219110130063271,274.584640952303687],"luv":[64.4629200033750323,7.4511637136690565,-92.9208407880221756],"rgb":[0.66666666666666663,0.533333333333333326,1],"xyz":[0.434290465080235055,0.333743948379197741,0.987648624761375715],"hpluv":[274.584640952303687,183.499254977583263,64.4629200033750323],"hsluv":[274.584640952303687,99.999999999998451,64.4629200033750323]},"#889900":{"lch":[59.9037942457991477,67.5360782410098892,95.4734085527772578],"luv":[59.9037942457991477,-6.44184579214223074,67.2281524881211396],"rgb":[0.533333333333333326,0.6,0],"xyz":[0.215438501120102766,0.280166683792846538,0.0427283862870331613],"hpluv":[95.4734085527772578,143.060860652479761,59.9037942457991477],"hsluv":[95.4734085527772578,100.000000000002359,59.9037942457991477]},"#889911":{"lch":[59.9403212197486,66.0293008977046867,95.6505578181906628],"luv":[59.9403212197486,-6.50131434341495318,65.7084582747741166],"rgb":[0.533333333333333326,0.6,0.0666666666666666657],"xyz":[0.216450166619739898,0.280571349992701391,0.048056491251788791],"hpluv":[95.6505578181906628,139.783837686775883,59.9403212197486],"hsluv":[95.6505578181906628,97.642419329775592,59.9403212197486]},"#889922":{"lch":[60.0079397017320275,63.2737960078627495,95.9966659299995655],"luv":[60.0079397017320275,-6.6102508868722456,62.9275602932231308],"rgb":[0.533333333333333326,0.6,0.133333333333333331],"xyz":[0.218325524758216899,0.281321493248092191,0.0579333774477679905],"hpluv":[95.9966659299995655,133.799503075015934,60.0079397017320275],"hsluv":[95.9966659299995655,93.3344688530494864,60.0079397017320275]},"#889933":{"lch":[60.1190111745068521,58.8410136656902196,96.6225595920901696],"luv":[60.1190111745068521,-6.78603238946032139,58.4483930798370039],"rgb":[0.533333333333333326,0.6,0.2],"xyz":[0.221413275490674633,0.282556593541075318,0.0741955313053791338],"hpluv":[96.6225595920901696,124.196009967059197,60.1190111745068521],"hsluv":[96.6225595920901696,86.4129060235578,60.1190111745068521]},"#889944":{"lch":[60.2788030378330859,52.6619605596060651,97.6740140778758104],"luv":[60.2788030378330859,-7.03230554676784081,52.1903129773946],"rgb":[0.533333333333333326,0.6,0.266666666666666663],"xyz":[0.22587127073489352,0.284339791638762884,0.0976743062582657723],"hpluv":[97.6740140778758104,110.859197411007315,60.2788030378330859],"hsluv":[97.6740140778758104,76.7791514013919,60.2788030378330859]},"#889955":{"lch":[60.491478208304315,44.7890969420590679,99.4433583384469557],"luv":[60.491478208304315,-7.34865909500015935,44.1821277711999301],"rgb":[0.533333333333333326,0.6,0.333333333333333315],"xyz":[0.231833684774255533,0.286724757254507745,0.129076353532239674],"hpluv":[99.4433583384469557,93.954467458231008,60.491478208304315],"hsluv":[99.4433583384469557,64.5165507795669555,60.491478208304315]},"#889966":{"lch":[60.7603321241253269,35.3998784596055387,102.614945913325585],"luv":[60.7603321241253269,-7.73125582812020351,34.5453191948634597],"rgb":[0.533333333333333326,0.6,0.4],"xyz":[0.23941868054776369,0.289758755563911063,0.169023997939383636],"hpluv":[102.614945913325585,73.9300429237522394,60.7603321241253269],"hsluv":[102.614945913325585,49.862982431557576,60.7603321241253269]},"#889977":{"lch":[61.0879169406466644,24.8557994274465628,109.198389045907604],"luv":[61.0879169406466644,-8.17358342252196,23.4734594640953418],"rgb":[0.533333333333333326,0.6,0.466666666666666674],"xyz":[0.248732693567965624,0.293484360771991859,0.218077799845781545],"hpluv":[109.198389045907604,51.6311437806165543,61.0879169406466644],"hsluv":[109.198389045907604,33.1759220302134779,61.0879169406466644]},"#889988":{"lch":[61.4761176658877702,14.1684419896747276,127.715012949229816],"luv":[61.4761176658877702,-8.66732250724137,11.2081340539023326],"rgb":[0.533333333333333326,0.6,0.533333333333333326],"xyz":[0.259873110669909424,0.297940527612769457,0.276750663249353712],"hpluv":[127.715012949229816,29.2452265306994263,61.4761176658877702],"hsluv":[127.715012949229816,14.8910328511789984,61.4761176658877702]},"#889999":{"lch":[61.9262069462763094,9.41507553536713537,192.177050630058915],"luv":[61.9262069462763094,-9.20324067004397861,-1.98595279549067061],"rgb":[0.533333333333333326,0.6,0.6],"xyz":[0.272930074778982124,0.303163313256398614,0.345517340890471647],"hpluv":[192.177050630058915,19.2925065058214678,61.9262069462763094],"hsluv":[192.177050630058915,19.2169899754877207,61.9262069462763094]},"#8899aa":{"lch":[62.4388911462841207,18.6148502867865133,238.334617604481764],"luv":[62.4388911462841207,-9.77200531832159669,-15.8436284751369474],"rgb":[0.533333333333333326,0.6,0.66666666666666663],"xyz":[0.28798776774423468,0.309186390442499737,0.424821190507470248],"hpluv":[238.334617604481764,37.8306403353000036,62.4388911462841207],"hsluv":[238.334617604481764,23.6900457250072343,62.4388911462841207]},"#8899bb":{"lch":[63.0143540484962,31.8509402607766567,251.009167860858838],"luv":[63.0143540484962,-10.3648329189902189,-30.1173145226625429],"rgb":[0.533333333333333326,0.6,0.733333333333333282],"xyz":[0.305125359851571354,0.316041427285434495,0.515079175606111939],"hpluv":[251.009167860858838,64.1389868285616132,63.0143540484962],"hsluv":[251.009167860858838,32.2218698989210282,63.0143540484962]},"#8899cc":{"lch":[63.6523012354060143,45.9199042321153357,256.173658840600297],"luv":[63.6523012354060143,-10.9739341944061159,-44.5893526863026821],"rgb":[0.533333333333333326,0.6,0.8],"xyz":[0.324417735295293053,0.323758377462923297,0.616685686276382095],"hpluv":[256.173658840600297,91.543221315317254,63.6523012354060143],"hsluv":[256.173658840600297,48.1563502503440546,63.6523012354060143]},"#8899dd":{"lch":[64.3520063546654,60.2052734177332738,258.898139298145679],"luv":[64.3520063546654,-11.5927562398827622,-59.0786166905309358],"rgb":[0.533333333333333326,0.6,0.866666666666666696],"xyz":[0.345936060845926652,0.332365707683176803,0.730015534176388092],"hpluv":[258.898139298145679,118.716686841439611,64.3520063546654],"hsluv":[258.898139298145679,64.7736147673059435,64.3520063546654]},"#8899ee":{"lch":[65.1123593572591091,74.4513212160393465,260.556144021857],"luv":[65.1123593572591091,-12.2160522582942246,-73.442271874149526],"rgb":[0.533333333333333326,0.6,0.933333333333333348],"xyz":[0.369748241112101361,0.34189057978964682,0.855426350244911315],"hpluv":[260.556144021857,145.093615685215838,65.1123593572591091],"hsluv":[260.556144021857,82.0482136329290626,65.1123593572591091]},"#8899ff":{"lch":[65.9319161385595862,88.5102230179824829,261.65889869963604],"luv":[65.9319161385595862,-12.8398242875011679,-87.5739601191992],"rgb":[0.533333333333333326,0.6,1],"xyz":[0.395919289521932782,0.352358999153579544,0.993260538536693161],"hpluv":[261.65889869963604,170.348009793708229,65.9319161385595862],"hsluv":[261.65889869963604,99.9999999999983373,65.9319161385595862]},"#aa9900":{"lch":[62.7844580943873609,69.6780489210530618,75.8779002673010297],"luv":[62.7844580943873609,17.0006834702273615,67.5722373685362072],"rgb":[0.66666666666666663,0.6,0],"xyz":[0.279679277130872483,0.313290833923400402,0.0457396726625379293],"hpluv":[75.8779002673010297,140.82610179048271,62.7844580943873609],"hsluv":[75.8779002673010297,100.000000000002217,62.7844580943873609]},"#aa9911":{"lch":[62.8183644916567232,68.2796688580209548,75.7117398414304],"luv":[62.8183644916567232,16.8514534980901978,66.1675274916835576],"rgb":[0.66666666666666663,0.6,0.0666666666666666657],"xyz":[0.280690942630509588,0.313695500123255255,0.0510677776272935591],"hpluv":[75.7117398414304,137.925354096716262,62.8183644916567232],"hsluv":[75.7117398414304,97.9039601429264792,62.8183644916567232]},"#aa9922":{"lch":[62.8811408657966098,65.7186920323652259,75.3888160486312415],"luv":[62.8811408657966098,16.5780820569936154,63.5933461751813311],"rgb":[0.66666666666666663,0.6,0.133333333333333331],"xyz":[0.282566300768986645,0.314445643378646056,0.0609446638232727586],"hpluv":[75.3888160486312415,132.619634057532949,62.8811408657966098],"hsluv":[75.3888160486312415,94.0678156084237287,62.8811408657966098]},"#aa9933":{"lch":[62.984284118013818,61.5887344728930373,74.8105333616033477],"luv":[62.984284118013818,16.1369729495721401,59.4371122952427768],"rgb":[0.66666666666666663,0.6,0.2],"xyz":[0.28565405150144435,0.315680743671629183,0.0772068176808839],"hpluv":[74.8105333616033477,124.08189266143988,62.984284118013818],"hsluv":[74.8105333616033477,87.8877322232676335,62.984284118013818]},"#aa9944":{"lch":[63.1327254984845325,55.810649390305,73.8551623649617284],"luv":[63.1327254984845325,15.5190685808424753,53.6095802609072862],"rgb":[0.66666666666666663,0.6,0.266666666666666663],"xyz":[0.290112046745663266,0.317463941769316749,0.10068559263377054],"hpluv":[73.8551623649617284,112.176494362550613,63.1327254984845325],"hsluv":[73.8551623649617284,79.2518346201028407,63.1327254984845325]},"#aa9955":{"lch":[63.330394330910508,48.4114193249398497,72.2912631539462893],"luv":[63.330394330910508,14.725704471349518,46.1174495053405593],"rgb":[0.66666666666666663,0.6,0.333333333333333315],"xyz":[0.296074460785025251,0.319848907385061609,0.132087639907744442],"hpluv":[72.2912631539462893,97.0007181904759,63.330394330910508],"hsluv":[72.2912631539462893,68.2014618333714253,63.330394330910508]},"#aa9966":{"lch":[63.5804407621292285,39.5252766283835086,69.6158026784446662],"luv":[63.5804407621292285,13.7671883687516523,37.0501284339143524],"rgb":[0.66666666666666663,0.6,0.4],"xyz":[0.303659456558533436,0.322882905694464928,0.172035284314888404],"hpluv":[69.6158026784446662,78.8843243984218105,63.5804407621292285],"hsluv":[69.6158026784446662,54.9106459007729129,63.5804407621292285]},"#aa9977":{"lch":[63.8853523521207762,29.4269320044373437,64.5162682653354835],"luv":[63.8853523521207762,12.6610788645847681,26.563911782313685],"rgb":[0.66666666666666663,0.6,0.466666666666666674],"xyz":[0.312973469578735342,0.326608510902545723,0.221089086221286313],"hpluv":[64.5162682653354835,58.4497984351079,63.8853523521207762],"hsluv":[64.5162682653354835,39.6604297676390303,63.8853523521207762]},"#aa9988":{"lch":[64.2470245358341288,18.7498828458428441,52.4386898809200943],"luv":[64.2470245358341288,11.4301164327749429,14.8630597477787205],"rgb":[0.66666666666666663,0.6,0.533333333333333326],"xyz":[0.324113886680679142,0.331064677743323321,0.279761949624858508],"hpluv":[52.4386898809200943,37.0326564248891472,64.2470245358341288],"hsluv":[52.4386898809200943,22.8076315183033955,64.2470245358341288]},"#aa9999":{"lch":[64.6668097656484,10.3324715423982241,12.1770506300641514],"luv":[64.6668097656484,10.0999956892392,2.17946214737001709],"rgb":[0.66666666666666663,0.6,0.6],"xyz":[0.337170850789751841,0.336287463386952479,0.348528627265976387],"hpluv":[12.1770506300641514,20.2750581327120152,64.6668097656484],"hsluv":[12.1770506300641514,9.39861318597140283,64.6668097656484]},"#aa99aa":{"lch":[65.1455571833188,14.2173372068657535,307.715012949255367],"luv":[65.1455571833188,8.69723339065650514,-11.2468132643064216],"rgb":[0.66666666666666663,0.6,0.66666666666666663],"xyz":[0.352228543755004397,0.342310540573053601,0.427832476882975],"hpluv":[307.715012949255367,27.6931773999722353,65.1455571833188],"hsluv":[307.715012949255367,11.6506794595111955,65.1455571833188]},"#aa99bb":{"lch":[65.6836488991384186,26.2061362707181722,286.054514249721478],"luv":[65.6836488991384186,7.24735484809431529,-25.1840708771488],"rgb":[0.66666666666666663,0.6,0.733333333333333282],"xyz":[0.369366135862341072,0.34916557741598836,0.51809046198161679],"hpluv":[286.054514249721478,50.6273330900370553,65.6836488991384186],"hsluv":[286.054514249721478,27.5721610485895,65.6836488991384186]},"#aa99cc":{"lch":[66.2810360009151651,39.8419200501833544,278.33213307587846],"luv":[66.2810360009151651,5.77353773601307907,-39.4213756139487757],"rgb":[0.66666666666666663,0.6,0.8],"xyz":[0.388658511306062771,0.356882527593477161,0.619696972651887],"hpluv":[278.33213307587846,76.2764194246967,66.2810360009151651],"hsluv":[278.33213307587846,44.416066179202609,66.2810360009151651]},"#aa99dd":{"lch":[66.937275739096421,53.9476968390211695,274.567192844176702],"luv":[66.937275739096421,4.29575598209881182,-53.7763932853180151],"rgb":[0.66666666666666663,0.6,0.866666666666666696],"xyz":[0.41017683685669637,0.365489857813730668,0.733026820551892944],"hpluv":[274.567192844176702,102.269045280662851,66.937275739096421],"hsluv":[274.567192844176702,62.1125641321495365,66.937275739096421]},"#aa99ee":{"lch":[67.6515703211096309,68.1578213039093299,272.380002942583644],"luv":[67.6515703211096309,2.83038594926376286,-68.0990273078393358],"rgb":[0.66666666666666663,0.6,0.933333333333333348],"xyz":[0.433989017122871079,0.375014729920200685,0.858437636620416167],"hpluv":[272.380002942583644,127.843056183363871,67.6515703211096309],"hsluv":[272.380002942583644,80.63443597048024,67.6515703211096309]},"#aa99ff":{"lch":[68.4228071241374778,82.2834014236355387,270.968064044661787],"luv":[68.4228071241374778,1.39018638405132466,-82.2716569157370543],"rgb":[0.66666666666666663,0.6,1],"xyz":[0.4601600655327025,0.385483149284133408,0.996271824912198],"hpluv":[270.968064044661787,152.598644218259693,68.4228071241374778],"hsluv":[270.968064044661787,99.9999999999981668,68.4228071241374778]},"#770000":{"lch":[23.4140868272264697,78.7423116347599432,12.177050630061796],"luv":[23.4140868272264697,76.9706458719381317,16.6093743302492847],"rgb":[0.466666666666666674,0,0],"xyz":[0.0760757904266185919,0.0392265794387260461,0.00356605267624767169],"hpluv":[12.177050630061796,426.746789183125429,23.4140868272264697],"hsluv":[12.177050630061796,100.000000000002359,23.4140868272264697]},"#770011":{"lch":[23.5491569362977273,75.7570426868466456,9.89164947332394462],"luv":[23.5491569362977273,74.6308667748156864,13.0139633123970793],"rgb":[0.466666666666666674,0,0.0666666666666666657],"xyz":[0.0770874559262557102,0.0396312456385809,0.00889415764100330228],"hpluv":[9.89164947332394462,408.213135586655085,23.5491569362977273],"hsluv":[9.89164947332394462,99.9999999999965183,23.5491569362977273]},"#770022":{"lch":[23.7971287372198219,70.9964864167640854,5.53723409440817704],"luv":[23.7971287372198219,70.6651956613751224,6.85063542055327357],"rgb":[0.466666666666666674,0,0.133333333333333331],"xyz":[0.0789628140647327392,0.0403813888939717203,0.0187710438369825],"hpluv":[5.53723409440817704,378.574731225432288,23.7971287372198219],"hsluv":[5.53723409440817704,99.9999999999967741,23.7971287372198219]},"#770033":{"lch":[24.198804347572846,65.0463245726941182,358.140059561726389],"luv":[24.198804347572846,65.0120550988218895,-2.11116845467566527],"rgb":[0.466666666666666674,0,0.2],"xyz":[0.0820505647971904728,0.0416164891869548331,0.0350331976945936416],"hpluv":[358.140059561726389,341.089366306392606,24.198804347572846],"hsluv":[358.140059561726389,99.9999999999971578,24.198804347572846]},"#770044":{"lch":[24.764944554878376,59.7650645123016702,347.391874641304071],"luv":[24.764944554878376,58.3238787679626398,-13.0456161839744915],"rgb":[0.466666666666666674,0,0.266666666666666663],"xyz":[0.0865085600414093464,0.0433996872846424062,0.0585119726474802801],"hpluv":[347.391874641304071,306.231145677972847,24.764944554878376],"hsluv":[347.391874641304071,99.9999999999975557,24.764944554878376]},"#770055":{"lch":[25.4983947844981387,57.0853266397623571,333.997796644431901],"luv":[25.4983947844981387,51.3069893372134587,-25.0265331742018731],"rgb":[0.466666666666666674,0,0.333333333333333315],"xyz":[0.0924709740807713454,0.0457846529003872391,0.0899140199214541885],"hpluv":[333.997796644431901,284.086748448009075,25.4983947844981387],"hsluv":[333.997796644431901,99.999999999998,25.4983947844981387]},"#770066":{"lch":[26.3955149445472088,58.0812929265372375,320.022905340944305],"luv":[26.3955149445472088,44.5077732621065394,-37.3161453966930949],"rgb":[0.466666666666666674,0,0.4],"xyz":[0.100055969854279517,0.0488186512097905506,0.129861664328598164],"hpluv":[320.022905340944305,279.219318659546161,26.3955149445472088],"hsluv":[320.022905340944305,99.9999999999984,26.3955149445472088]},"#770077":{"lch":[27.4476614837194361,62.5213221502200156,307.715012949243601],"luv":[27.4476614837194361,38.2464397320582776,-49.4583215569799322],"rgb":[0.466666666666666674,0,0.466666666666666674],"xyz":[0.109369982874481436,0.052544256417871367,0.178915466234996073],"hpluv":[307.715012949243601,289.04278373048345,27.4476614837194361],"hsluv":[307.715012949243601,99.9999999999988631,27.4476614837194361]},"#770088":{"lch":[28.6427236217895711,69.3985842918787341,298.067280282401043],"luv":[28.6427236217895711,32.6525926425722872,-61.2370124633397808],"rgb":[0.466666666666666674,0,0.533333333333333326],"xyz":[0.120510399976425264,0.0570004232586489579,0.237588329638568241],"hpluv":[298.067280282401043,307.450798390810235,28.6427236217895711],"hsluv":[298.067280282401043,99.9999999999991473,28.6427236217895711]},"#770099":{"lch":[29.9665727349335924,77.70857748467688,290.909274437861086],"luv":[29.9665727349335924,27.7333531267432782,-72.5912125469701],"rgb":[0.466666666666666674,0,0.6],"xyz":[0.133567364085497964,0.0622232089022781223,0.30635500727968612],"hpluv":[290.909274437861086,329.057057444315717,29.9665727349335924],"hsluv":[290.909274437861086,99.9999999999993605,29.9665727349335924]},"#7700aa":{"lch":[31.4042918618800115,86.7647813143177,285.668616902051383],"luv":[31.4042918618800115,23.4328336498598695,-83.5405864455078415],"rgb":[0.466666666666666674,0,0.66666666666666663],"xyz":[0.14862505705075052,0.0682462860883792238,0.385658856896684721],"hpluv":[285.668616902051383,350.585377409449279,31.4042918618800115],"hsluv":[285.668616902051383,99.9999999999996447,31.4042918618800115]},"#7700bb":{"lch":[32.9411141237069387,96.170393631615,281.802895608829544],"luv":[32.9411141237069387,19.6712233173334745,-94.1370680681067853],"rgb":[0.466666666666666674,0,0.733333333333333282],"xyz":[0.165762649158087166,0.0751013229313139824,0.475916841995326467],"hpluv":[281.802895608829544,370.460950364720645,32.9411141237069387],"hsluv":[281.802895608829544,99.9999999999998295,32.9411141237069387]},"#7700cc":{"lch":[34.5630635499026226,105.713400517707811,278.906152205018032],"luv":[34.5630635499026226,16.3661753747823724,-104.438840249301762],"rgb":[0.466666666666666674,0,0.8],"xyz":[0.185055024601808893,0.082818273108802784,0.577523352665596623],"hpluv":[278.906152205018032,388.112061604616713,34.5630635499026226],"hsluv":[278.906152205018032,99.9999999999998721,34.5630635499026226]},"#7700dd":{"lch":[36.2573361534597964,115.285120662302717,276.696107756350386],"luv":[36.2573361534597964,13.4426218553338188,-114.498711624961956],"rgb":[0.466666666666666674,0,0.866666666666666696],"xyz":[0.206573350152442436,0.091425603329056318,0.690853200565602621],"hpluv":[276.696107756350386,403.475057258468723,36.2573361534597964],"hsluv":[276.696107756350386,100.000000000000156,36.2573361534597964]},"#7700ee":{"lch":[38.012479203832,124.831519574090535,274.979891409884715],"luv":[38.012479203832,10.8361388436516783,-124.360308676593633],"rgb":[0.466666666666666674,0,0.933333333333333348],"xyz":[0.230385530418617201,0.100950475435526349,0.816264016634125844],"hpluv":[274.979891409884715,416.713325299391272,38.012479203832],"hsluv":[274.979891409884715,100.000000000000156,38.012479203832]},"#7700ff":{"lch":[39.8184284160989037,134.326708962856742,273.625091115001112],"luv":[39.8184284160989037,8.49315165227522861,-134.057939398617776],"rgb":[0.466666666666666674,0,1],"xyz":[0.256556578828448567,0.111418894799459045,0.954098204925907689],"hpluv":[273.625091115001112,428.072753406140123,39.8184284160989037],"hsluv":[273.625091115001112,100.000000000000313,39.8184284160989037]},"#771100":{"lch":[24.7134353555624457,74.5310598854495794,14.479461840222152],"luv":[24.7134353555624457,72.1637543524892351,18.6352205622059],"rgb":[0.466666666666666674,0.0666666666666666657,0],"xyz":[0.078080190687547,0.0432353799605829231,0.00423418609655712257],"hpluv":[14.479461840222152,382.686818993669249,24.7134353555624457],"hsluv":[14.479461840222152,100.000000000002174,24.7134353555624457]},"#771111":{"lch":[24.8400617115613187,71.7342088143168723,12.1770506300618244],"luv":[24.8400617115613187,70.1202221387804912,15.1311321924069837],"rgb":[0.466666666666666674,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0790918561871841175,0.043640046160437776,0.00956229106131275403],"hpluv":[12.1770506300618244,366.448517223619376,24.8400617115613187],"hsluv":[12.1770506300618244,85.8702458957174173,24.8400617115613187]},"#771122":{"lch":[25.0727380413203562,67.2476760425649616,7.76714475492354417],"luv":[25.0727380413203562,66.6307123231625,9.0883501491595],"rgb":[0.466666666666666674,0.0666666666666666657,0.133333333333333331],"xyz":[0.0809672143256611465,0.0443901894158286,0.0194391772572919501],"hpluv":[7.76714475492354417,340.341449223453765,25.0727380413203562],"hsluv":[7.76714475492354417,86.6206298981217,25.0727380413203562]},"#771133":{"lch":[25.4501908259833556,61.6001849310061189,0.209311103178295294],"luv":[25.4501908259833556,61.599773884646936,0.225035318388215971],"rgb":[0.466666666666666674,0.0666666666666666657,0.2],"xyz":[0.0840549650581188801,0.0456252897088117101,0.0357013311149031],"hpluv":[0.209311103178295294,307.135699817562568,25.4501908259833556],"hsluv":[0.209311103178295294,87.6964449022470802,25.4501908259833556]},"#771144":{"lch":[25.9833113937366775,56.5829308746863688,349.098656617234155],"luv":[25.9833113937366775,55.5618510799655,-10.7008771106518541],"rgb":[0.466666666666666674,0.0666666666666666657,0.266666666666666663],"xyz":[0.0885129603023377537,0.0474084878064992832,0.0591801060677897353],"hpluv":[349.098656617234155,276.331419289390624,25.9833113937366775],"hsluv":[349.098656617234155,88.9762099121112442,25.9833113937366775]},"#771155":{"lch":[26.6758393728738312,54.157242934368746,335.112354986374442],"luv":[26.6758393728738312,49.127918835603694,-22.7915456504066185],"rgb":[0.466666666666666674,0.0666666666666666657,0.333333333333333315],"xyz":[0.0944753743416997527,0.0497934534222441161,0.0905821533417636438],"hpluv":[335.112354986374442,257.618934567198892,26.6758393728738312],"hsluv":[335.112354986374442,90.3225181656420375,26.6758393728738312]},"#771166":{"lch":[27.5255776115618076,55.4731266930874796,320.490705765847224],"luv":[27.5255776115618076,42.7987039146097388,-35.2921907557026557],"rgb":[0.466666666666666674,0.0666666666666666657,0.4],"xyz":[0.102060370115207924,0.0528274517316474276,0.130529797748907606],"hpluv":[320.490705765847224,255.732268141411282,27.5255776115618076],"hsluv":[320.490705765847224,91.6238582413064364,27.5255776115618076]},"#771177":{"lch":[28.525624322061,60.3055315504910538,307.715012949243658],"luv":[28.525624322061,36.8909645322892956,-47.7054909990940672],"rgb":[0.466666666666666674,0.0666666666666666657,0.466666666666666674],"xyz":[0.111374383135409843,0.056553056939728244,0.179583599655305515],"hpluv":[307.715012949243658,268.263334170626,28.525624322061],"hsluv":[307.715012949243658,92.8109433172232201,28.525624322061]},"#771188":{"lch":[29.665668786552871,67.5901402176946,297.828537901307072],"luv":[29.665668786552871,31.5529142063876336,-59.77324367751811],"rgb":[0.466666666666666674,0.0666666666666666657,0.533333333333333326],"xyz":[0.122514800237353672,0.0610092237805058418,0.238256463058877682],"hpluv":[297.828537901307072,289.113605882780575,29.665668786552871],"hsluv":[297.828537901307072,93.8529472884676892,29.665668786552871]},"#771199":{"lch":[30.9332504381216253,76.2730393291315494,290.583951381139741],"luv":[30.9332504381216253,26.816032696200331,-71.4036197887723461],"rgb":[0.466666666666666674,0.0666666666666666657,0.6],"xyz":[0.135571764346426371,0.066232009424135,0.307023140699995589],"hpluv":[290.583951381139741,312.885056330098905,30.9332504381216253],"hsluv":[290.583951381139741,94.745562802664864,30.9332504381216253]},"#7711aa":{"lch":[32.3148680584756391,85.6471240548678452,285.332056603477554],"luv":[32.3148680584756391,22.6461849228904,-82.5989114172104166],"rgb":[0.466666666666666674,0.0666666666666666657,0.66666666666666663],"xyz":[0.150629457311678927,0.0722550866102361078,0.38632699031699419],"hpluv":[285.332056603477554,336.317699636744408,32.3148680584756391],"hsluv":[285.332056603477554,95.4992611083078771,32.3148680584756391]},"#7711bb":{"lch":[33.796865882550442,95.3131880713117,281.486339493443666],"luv":[33.796865882550442,18.9801244444786903,-93.4042755787407],"rgb":[0.466666666666666674,0.0666666666666666657,0.733333333333333282],"xyz":[0.167767049419015574,0.0791101234531708664,0.476584975415635936],"hpluv":[281.486339493443666,357.862255189103962,33.796865882550442],"hsluv":[281.486339493443666,96.130904738193,33.796865882550442]},"#7711cc":{"lch":[35.36607449089243,105.064609202725904,278.619980375929231],"luv":[35.36607449089243,15.7470979978009513,-103.877817707002151],"rgb":[0.466666666666666674,0.0666666666666666657,0.8],"xyz":[0.1870594248627373,0.086827073630659668,0.578191486085906092],"hpluv":[278.619980375929231,376.971848031202455,35.36607449089243],"hsluv":[278.619980375929231,96.6587778670915441,35.36607449089243]},"#7711dd":{"lch":[37.0102245888209,114.800572621107989,276.441726024966442],"luv":[37.0102245888209,12.8797770828984923,-114.075776641796878],"rgb":[0.466666666666666674,0.0666666666666666657,0.866666666666666696],"xyz":[0.208577750413370844,0.0954344038509132,0.69152133398591209],"hpluv":[276.441726024966442,393.605954910771402,37.0102245888209],"hsluv":[276.441726024966442,97.1000737310191084,37.0102245888209]},"#7711ee":{"lch":[38.7181742300654648,124.475046910670883,274.755182332196796],"luv":[38.7181742300654648,10.3187754184265525,-124.046604859938796],"rgb":[0.466666666666666674,0.0666666666666666657,0.933333333333333348],"xyz":[0.232389930679545609,0.104959275957383219,0.816932150054435313],"hpluv":[274.755182332196796,407.949828918098,38.7181742300654648],"hsluv":[274.755182332196796,97.4698666617264706,38.7181742300654648]},"#7711ff":{"lch":[40.4799968781786,134.069342311184641,273.42679883886251],"luv":[40.4799968781786,8.01376323316973682,-133.829623576382744],"rgb":[0.466666666666666674,0.0666666666666666657,1],"xyz":[0.258560979089377,0.115427695321315929,0.954766338346217158],"hpluv":[273.42679883886251,420.269946860795244,40.4799968781786],"hsluv":[273.42679883886251,99.99999999999946,40.4799968781786]},"#772200":{"lch":[26.9238486490213944,67.8779226750429814,18.9619118830866213],"luv":[26.9238486490213944,64.1945131058521241,22.0562207502031953],"rgb":[0.466666666666666674,0.133333333333333331,0],"xyz":[0.0817958144223149414,0.0506666274301188907,0.00547272734147973266],"hpluv":[18.9619118830866213,319.912145739235086,26.9238486490213944],"hsluv":[18.9619118830866213,100.000000000002203,26.9238486490213944]},"#772211":{"lch":[27.0378210495853537,65.3114997865878451,16.6506371445360628],"luv":[27.0378210495853537,62.5729698674152957,18.7140440938083152],"rgb":[0.466666666666666674,0.133333333333333331,0.0666666666666666657],"xyz":[0.0828074799219520596,0.0510712936299737436,0.0108008323062353633],"hpluv":[16.6506371445360628,306.518925183772069,27.0378210495853537],"hsluv":[16.6506371445360628,87.77659617077137,27.0378210495853537]},"#772222":{"lch":[27.2475131582451553,61.1491638550902934,12.1770506300618262],"luv":[27.2475131582451553,59.7733358183195094,12.8983939049434628],"rgb":[0.466666666666666674,0.133333333333333331,0.133333333333333331],"xyz":[0.0846828380604290887,0.0518214368853645649,0.0206777185022145593],"hpluv":[12.1770506300618262,284.775733052529233,27.2475131582451553],"hsluv":[12.1770506300618262,66.7317810633447,27.2475131582451553]},"#772233":{"lch":[27.5884028886125066,55.830319472153235,4.36926883706767555],"luv":[27.5884028886125066,55.668063043001986,4.25339034219168255],"rgb":[0.466666666666666674,0.133333333333333331,0.2],"xyz":[0.0877705887928868222,0.0530565371783476777,0.0369398723598257],"hpluv":[4.36926883706767555,256.792821962959806,27.5884028886125066],"hsluv":[4.36926883706767555,69.0869865520346,27.5884028886125066]},"#772244":{"lch":[28.0713586292933357,51.0577981227000137,352.597218961633928],"luv":[28.0713586292933357,50.6322267647614197,-6.57847717790113862],"rgb":[0.466666666666666674,0.133333333333333331,0.266666666666666663],"xyz":[0.0922285840371057,0.0548397352760352508,0.0604186473127123411],"hpluv":[352.597218961633928,230.801153887638264,28.0713586292933357],"hsluv":[352.597218961633928,71.9536276136468871,28.0713586292933357]},"#772255":{"lch":[28.7011983995690869,48.8793621784160877,337.425357822166575],"luv":[28.7011983995690869,45.134235573623549,-18.7641367015226166],"rgb":[0.466666666666666674,0.133333333333333331,0.333333333333333315],"xyz":[0.0981909980764677,0.0572247008917800837,0.0918206945866862495],"hpluv":[337.425357822166575,216.105005327694982,28.7011983995690869],"hsluv":[337.425357822166575,75.0482997779786416,28.7011983995690869]},"#772266":{"lch":[29.4776386596593341,50.6214045611569148,321.457127980188602],"luv":[29.4776386596593341,39.5931335065919541,-31.5421999688275427],"rgb":[0.466666666666666674,0.133333333333333331,0.4],"xyz":[0.105775993849975866,0.0602586992011833952,0.131768338993830225],"hpluv":[321.457127980188602,217.911839443782668,29.4776386596593341],"hsluv":[321.457127980188602,78.1196257410634871,29.4776386596593341]},"#772277":{"lch":[30.3962065887853328,56.0773495547330114,307.715012949243828],"luv":[30.3962065887853328,34.3044404103525125,-44.3607315225559375],"rgb":[0.466666666666666674,0.133333333333333331,0.466666666666666674],"xyz":[0.115090006870177786,0.0639843044092642116,0.180822140900228134],"hpluv":[307.715012949243828,234.103236488433623,30.3962065887853328],"hsluv":[307.715012949243828,80.9925899090149,30.3962065887853328]},"#772288":{"lch":[31.4492100235983827,64.0564791390884,297.353574907339521],"luv":[31.4492100235983827,29.432687880373738,-56.8941948166328118],"rgb":[0.466666666666666674,0.133333333333333331,0.533333333333333326],"xyz":[0.126230423972121614,0.0684404712500418094,0.239495004303800302],"hpluv":[297.353574907339521,258.459589193709576,31.4492100235983827],"hsluv":[297.353574907339521,83.5725358287189692,31.4492100235983827]},"#772299":{"lch":[32.6267183371791276,73.3979299617999885,289.947447059718741],"luv":[32.6267183371791276,25.040297814612174,-68.9944896932561136],"rgb":[0.466666666666666674,0.133333333333333331,0.6],"xyz":[0.139287388081194341,0.073663256893670967,0.308261681944918209],"hpluv":[289.947447059718741,285.462946683821,32.6267183371791276],"hsluv":[289.947447059718741,85.8272099061853169,32.6267183371791276]},"#7722aa":{"lch":[33.91747454857272,83.3484305918169213,284.681710760769079],"luv":[33.91747454857272,21.1245907707188039,-80.6269963900962],"rgb":[0.466666666666666674,0.133333333333333331,0.66666666666666663],"xyz":[0.154345081046446869,0.0796863340797720754,0.38756553156191681],"hpluv":[284.681710760769079,311.826661765562392,33.91747454857272],"hsluv":[284.681710760769079,87.7639475735253,33.91747454857272]},"#7722bb":{"lch":[35.3096729107126137,93.4985765466947,280.880145280973409],"luv":[35.3096729107126137,17.6483381470917493,-91.8178630599952186],"rgb":[0.466666666666666674,0.133333333333333331,0.733333333333333282],"xyz":[0.171482673153783516,0.086541370922706834,0.477823516660558556],"hpluv":[280.880145280973409,336.008784107710085,35.3096729107126137],"hsluv":[280.880145280973409,89.410850129911168,35.3096729107126137]},"#7722cc":{"lch":[36.7915673195940158,103.646851370476796,278.075561058441508],"luv":[36.7915673195940158,14.5601992392030191,-102.619054746808203],"rgb":[0.466666666666666674,0.133333333333333331,0.8],"xyz":[0.19077504859750527,0.0942583211001956356,0.579430027330828712],"hpluv":[278.075561058441508,357.476214898523438,36.7915673195940158],"hsluv":[278.075561058441508,90.8041771911133395,36.7915673195940158]},"#7722dd":{"lch":[38.351906528896663,113.703099806952181,275.960131804992216],"luv":[38.351906528896663,11.8065226659589069,-113.088465053903391],"rgb":[0.466666666666666674,0.133333333333333331,0.866666666666666696],"xyz":[0.212293374148138814,0.10286565132044917,0.69275987523083471],"hpluv":[275.960131804992216,376.205095027198126,38.351906528896663],"hsluv":[275.960131804992216,91.9810564333708101,38.351906528896663]},"#7722ee":{"lch":[39.9802139341708269,123.633267676123751,274.331320845995606],"luv":[39.9802139341708269,9.33725773346982812,-123.280170726255989],"rgb":[0.466666666666666674,0.133333333333333331,0.933333333333333348],"xyz":[0.236105554414313523,0.112390523426919187,0.818170691299357933],"hpluv":[274.331320845995606,392.400507860275241,39.9802139341708269],"hsluv":[274.331320845995606,92.975835565241681,39.9802139341708269]},"#7722ff":{"lch":[41.6669409214524222,133.430100966175758,273.053819065229],"luv":[41.6669409214524222,7.10835060884393233,-133.240621416539511],"rgb":[0.466666666666666674,0.133333333333333331,1],"xyz":[0.262276602824144944,0.122858942790851897,0.956004879591139778],"hpluv":[273.053819065229,406.351179140502,41.6669409214524222],"hsluv":[273.053819065229,99.9999999999994,41.6669409214524222]},"#eeaa00":{"lch":[74.1441199778221716,94.3993067628715323,52.9277228913731435],"luv":[74.1441199778221716,56.9059790518510553,75.3189130661151438],"rgb":[0.933333333333333348,0.66666666666666663,0],"xyz":[0.496332043879122442,0.469286695915611562,0.0644413600602487119],"hpluv":[52.9277228913731435,161.559096825574699,74.1441199778221716],"hsluv":[52.9277228913731435,100.00000000000226,74.1441199778221716]},"#eeaa11":{"lch":[74.170022976797469,93.4032488378738748,52.6298301838218165],"luv":[74.170022976797469,56.6922374254564474,74.2304325001913412],"rgb":[0.933333333333333348,0.66666666666666663,0.0666666666666666657],"xyz":[0.497343709378759546,0.469691362115466415,0.0697694650250043485],"hpluv":[52.6298301838218165,159.798572537124,74.170022976797469],"hsluv":[52.6298301838218165,98.6103970010943698,74.170022976797469]},"#eeaa22":{"lch":[74.2180009061856794,91.5777923210439866,52.06484069365154],"luv":[74.2180009061856794,56.2992155036066038,72.2280442769616],"rgb":[0.933333333333333348,0.66666666666666663,0.133333333333333331],"xyz":[0.499219067517236603,0.470441505370857216,0.0796463512209835411],"hpluv":[52.06484069365154,156.574215350823607,74.2180009061856794],"hsluv":[52.06484069365154,96.0561964998804427,74.2180009061856794]},"#eeaa33":{"lch":[74.296884894391,88.6315089581908353,51.0969321655322659],"luv":[74.296884894391,55.6610065739707096,68.9738843866158646],"rgb":[0.933333333333333348,0.66666666666666663,0.2],"xyz":[0.502306818249694365,0.471676605663840343,0.0959085050785946913],"hpluv":[51.0969321655322659,151.375944062314744,74.296884894391],"hsluv":[51.0969321655322659,91.9112466174575786,74.296884894391]},"#eeaa44":{"lch":[74.4105324975616,84.5080331915566,49.6113532778883268],"luv":[74.4105324975616,54.7585847399730952,64.3669563610119582],"rgb":[0.933333333333333348,0.66666666666666663,0.266666666666666663],"xyz":[0.506764813493913224,0.473459803761527909,0.11938728003148133],"hpluv":[49.6113532778883268,144.112916810009352,74.4105324975616],"hsluv":[49.6113532778883268,86.056132752536,74.4105324975616]},"#eeaa55":{"lch":[74.5620870475656545,79.2349762990306203,47.4460085751506284],"luv":[74.5620870475656545,53.5853993814341081,58.3676832008958897],"rgb":[0.933333333333333348,0.66666666666666663,0.333333333333333315],"xyz":[0.512727227533275154,0.475844769377272769,0.150789327305455245],"hpluv":[47.4460085751506284,134.846041865267,74.5620870475656545],"hsluv":[47.4460085751506284,78.4547380743125302,74.5620870475656545]},"#eeaa66":{"lch":[74.7541548019056705,72.9335579755352512,44.3584242628533616],"luv":[74.7541548019056705,52.1460491859645643,50.9911113162453518],"rgb":[0.933333333333333348,0.66666666666666663,0.4],"xyz":[0.520312223306783395,0.478878767686676088,0.190736971712599179],"hpluv":[44.3584242628533616,123.803063546095515,74.7541548019056705],"hsluv":[44.3584242628533616,69.1456590086766,74.7541548019056705]},"#eeaa77":{"lch":[74.988898345165353,65.8409092602829702,39.9757578623994689],"luv":[74.988898345165353,50.4549646902964213,42.3003767160737851],"rgb":[0.933333333333333348,0.66666666666666663,0.466666666666666674],"xyz":[0.529626236326985245,0.482604372894756883,0.239790773618997088],"hpluv":[39.9757578623994689,111.41359114675457,74.988898345165353],"hsluv":[39.9757578623994689,69.3768546233612398,74.988898345165353]},"#eeaa88":{"lch":[75.268091919562039,58.355059996267,33.7246537035848917],"luv":[75.268091919562039,48.5347963512250544,32.3988668060016],"rgb":[0.933333333333333348,0.66666666666666663,0.533333333333333326],"xyz":[0.540766653428929156,0.487060539735534481,0.298463637022569284],"hpluv":[33.7246537035848917,98.3800275430836706,75.268091919562039],"hsluv":[33.7246537035848917,69.7313730072723388,75.268091919562039]},"#eeaa99":{"lch":[75.5931575717450102,51.1191249468368198,24.7740386445795764],"luv":[75.5931575717450102,46.4145012045046172,21.4209946843594],"rgb":[0.933333333333333348,0.66666666666666663,0.6],"xyz":[0.5538236175380018,0.492283325379163639,0.367230314663687163],"hpluv":[24.7740386445795764,85.8104641434512274,75.5931575717450102],"hsluv":[24.7740386445795764,70.1099573125584925,75.5931575717450102]},"#eeaaaa":{"lch":[75.9651912478537,45.142946910964838,12.1770506300622827],"luv":[75.9651912478537,44.1272513869876164,9.52215001119964199],"rgb":[0.933333333333333348,0.66666666666666663,0.66666666666666663],"xyz":[0.568881310503254412,0.498306402565264761,0.446534164280685764],"hpluv":[12.1770506300622827,75.4075094474617771,75.9651912478537],"hsluv":[12.1770506300622827,70.5013292017584661,75.9651912478537]},"#eeaabb":{"lch":[76.3849837125259512,41.8257198613105743,355.706426922992932],"luv":[76.3849837125259512,41.7083375548448743,-3.13136077895000353],"rgb":[0.933333333333333348,0.66666666666666663,0.733333333333333282],"xyz":[0.586018902610591,0.505161439408199464,0.53679214937932751],"hpluv":[355.706426922992932,71.0120800923082243,76.3849837125259512],"hsluv":[355.706426922992932,70.8933377227291857,76.3849837125259512]},"#eeaacc":{"lch":[76.8530390510081,42.4751513806234229,337.329003704434115],"luv":[76.8530390510081,39.1932374848878169,-16.3715796507258275],"rgb":[0.933333333333333348,0.66666666666666663,0.8],"xyz":[0.605311278054312729,0.512878389585688321,0.638398660049597666],"hpluv":[337.329003704434115,73.8860979443606283,76.8530390510081],"hsluv":[337.329003704434115,71.273377003825658,76.8530390510081]},"#eeaadd":{"lch":[77.3695923472492666,47.3596417233686893,320.637369166639587],"luv":[77.3695923472492666,36.6159833837478814,-30.0367345929437413],"rgb":[0.933333333333333348,0.66666666666666663,0.866666666666666696],"xyz":[0.626829603604946328,0.521485719805941828,0.751728507949603664],"hpluv":[320.637369166639587,84.6581146126829,77.3695923472492666],"hsluv":[320.637369166639587,71.6287050870027144,77.3695923472492666]},"#eeaaee":{"lch":[77.9346274334411078,55.5926087174301244,307.715012949246329],"luv":[77.9346274334411078,34.00790779424905,-43.9772708506012506],"rgb":[0.933333333333333348,0.66666666666666663,0.933333333333333348],"xyz":[0.650641783871121,0.531010591912411845,0.877139324018126887],"hpluv":[307.715012949246329,102.440850498764817,77.9346274334411078],"hsluv":[307.715012949246329,71.9466349992656,77.9346274334411078]},"#eeaaff":{"lch":[78.5478951631237123,66.0054362136172,298.40296943037481],"luv":[78.5478951631237123,31.3967924706888546,-58.0599606639755166],"rgb":[0.933333333333333348,0.66666666666666663,1],"xyz":[0.676812832280952459,0.541479011276344568,1.01497351230990884],"hpluv":[298.40296943037481,125.797711632464541,78.5478951631237123],"hsluv":[298.40296943037481,99.9999999999967457,78.5478951631237123]},"#773300":{"lch":[30.1331354048611715,59.6402239078303253,26.8671398719653283],"luv":[30.1331354048611715,53.2024709950710601,26.952799257122777],"rgb":[0.466666666666666674,0.2,0],"xyz":[0.0879135365113257461,0.0629020716081407,0.0075119680378166135],"hpluv":[26.8671398719653283,251.150628123644026,30.1331354048611715],"hsluv":[26.8671398719653283,100.000000000002174,30.1331354048611715]},"#773311":{"lch":[30.23185303241101,57.2493346092074376,24.6191658238461528],"luv":[30.23185303241101,52.0451874365790204,23.8492091669378929],"rgb":[0.466666666666666674,0.2,0.0666666666666666657],"xyz":[0.0889252020109628644,0.0633067378079955473,0.012840073002572245],"hpluv":[24.6191658238461528,240.295148301589592,30.23185303241101],"hsluv":[24.6191658238461528,89.9983576544591131,30.23185303241101]},"#773322":{"lch":[30.4137421865898716,53.2944669038914185,20.1857997859538507],"luv":[30.4137421865898716,50.0210446853216055,18.3900867632275506],"rgb":[0.466666666666666674,0.2,0.133333333333333331],"xyz":[0.0908005601494399,0.0640568810633863617,0.022716959198551441],"hpluv":[20.1857997859538507,222.35740076876786,30.4137421865898716],"hsluv":[20.1857997859538507,72.5478159849102,30.4137421865898716]},"#773333":{"lch":[30.7101510688592612,48.0738359215612618,12.1770506300619186],"luv":[30.7101510688592612,46.9921967440780932,10.1403720532853221],"rgb":[0.466666666666666674,0.2,0.2],"xyz":[0.093888310881897627,0.0652919813563694745,0.0389791130561625843],"hpluv":[12.1770506300619186,198.639745699191,30.7101510688592612],"hsluv":[12.1770506300619186,46.5474493854848177,30.7101510688592612]},"#773344":{"lch":[31.1315732769052218,43.177963340605487,359.450637080068248],"luv":[31.1315732769052218,43.1759786068728815,-0.413992248148033204],"rgb":[0.466666666666666674,0.2,0.266666666666666663],"xyz":[0.0983463061261165,0.0670751794540570545,0.0624578880090492228],"hpluv":[359.450637080068248,175.995032884643848,31.1315732769052218],"hsluv":[359.450637080068248,50.753084379908266,31.1315732769052218]},"#773355":{"lch":[31.6836931484193158,40.8566925980369149,342.103665666318761],"luv":[31.6836931484193158,38.8798033655970627,-12.5550874271345432],"rgb":[0.466666666666666674,0.2,0.333333333333333315],"xyz":[0.1043087201654785,0.0694601450698018874,0.0938599352830231382],"hpluv":[342.103665666318761,163.631433468067485,31.6836931484193158],"hsluv":[342.103665666318761,55.4419897041632623,31.6836931484193158]},"#773366":{"lch":[32.368092831934419,42.8604868736005429,323.403106692152903],"luv":[32.368092831934419,34.4105334223914952,-25.55262265656037],"rgb":[0.466666666666666674,0.2,0.4],"xyz":[0.111893715938986671,0.0724941433792052,0.1338075796901671],"hpluv":[323.403106692152903,168.027093700417197,32.368092831934419],"hsluv":[323.403106692152903,60.2559031079253913,32.368092831934419]},"#773377":{"lch":[33.18286532501061,49.0630735877418189,307.715012949244226],"luv":[33.18286532501061,30.0135669321659,-38.8119954380674201],"rgb":[0.466666666666666674,0.2,0.466666666666666674],"xyz":[0.12120772895918859,0.0762197485872860153,0.182861381596565],"hpluv":[307.715012949244226,187.620458725202155,33.18286532501061],"hsluv":[307.715012949244226,64.9109644958811458,33.18286532501061]},"#773388":{"lch":[34.1232577260479,58.0074356166469371,296.464975996700218],"luv":[34.1232577260479,25.8510525803809479,-51.9286594021626868],"rgb":[0.466666666666666674,0.2,0.533333333333333326],"xyz":[0.132348146061132432,0.0806759154280636132,0.241534245000137177],"hpluv":[296.464975996700218,215.711106662248483,34.1232577260479],"hsluv":[296.464975996700218,69.2226633917654226,34.1232577260479]},"#773399":{"lch":[35.1823459678372572,68.3160830057283,288.793689920994325],"luv":[35.1823459678372572,22.0088074868374761,-64.6737936899706369],"rgb":[0.466666666666666674,0.2,0.6],"xyz":[0.145405110170205132,0.0858987010716927707,0.310300922641255084],"hpluv":[288.793689920994325,246.398176299420243,35.1823459678372572],"hsluv":[288.793689920994325,73.0971646513407,35.1823459678372572]},"#7733aa":{"lch":[36.3517007299652,79.1457370086552316,283.529620316849901],"luv":[36.3517007299652,18.5159885211015585,-76.9493720294691741],"rgb":[0.466666666666666674,0.2,0.66666666666666663],"xyz":[0.160462803135457688,0.0919217782577938791,0.389604772258253684],"hpluv":[283.529620316849901,276.275338575971432,36.3517007299652],"hsluv":[283.529620316849901,76.5077273075914093,36.3517007299652]},"#7733bb":{"lch":[37.6219984216960484,90.0609255961329183,279.823655256592],"luv":[37.6219984216960484,15.3658639022925581,-88.7404110074345596],"rgb":[0.466666666666666674,0.2,0.733333333333333282],"xyz":[0.177600395242794307,0.0987768151007286377,0.479862757356895431],"hpluv":[279.823655256592,303.762299466947354,37.6219984216960484],"hsluv":[279.823655256592,79.4699002038008615,37.6219984216960484]},"#7733cc":{"lch":[38.9835424310364687,100.85881095677091,277.137789072490136],"luv":[38.9835424310364687,12.5323059717609908,-100.077175492935524],"rgb":[0.466666666666666674,0.2,0.8],"xyz":[0.196892770686516061,0.106493765278217439,0.581469268027165587],"hpluv":[277.137789072490136,328.300745951509327,38.9835424310364687],"hsluv":[277.137789072490136,82.0218198813884,38.9835424310364687]},"#7733dd":{"lch":[40.4266769703902469,111.457640409912926,275.137669231249674],"luv":[40.4266769703902469,9.98093438608736,-111.009848907770674],"rgb":[0.466666666666666674,0.2,0.866666666666666696],"xyz":[0.218411096237149605,0.115101095498470973,0.694799115927171584],"hpluv":[275.137669231249674,349.849394775278881,40.4266769703902469],"hsluv":[275.137669231249674,84.2108753320266459,40.4266769703902469]},"#7733ee":{"lch":[41.9420918590451066,121.83559331992231,273.612094072304103],"luv":[41.9420918590451066,7.67578650940870766,-121.593561100411392],"rgb":[0.466666666666666674,0.2,0.933333333333333348],"xyz":[0.242223276503324342,0.12462596760494099,0.820209931995694808],"hpluv":[273.612094072304103,368.606867281158145,41.9420918590451066],"hsluv":[273.612094072304103,91.3228806729277665,41.9420918590451066]},"#7733ff":{"lch":[43.521028110395612,131.998699032970592,272.424037139620168],"luv":[43.521028110395612,5.58285979872954208,-131.88058319125102],"rgb":[0.466666666666666674,0.2,1],"xyz":[0.268394324913155735,0.135094386968873714,0.958044120287476653],"hpluv":[272.424037139620168,384.866252510120546,43.521028110395612],"hsluv":[272.424037139620168,99.9999999999993605,43.521028110395612]},"#eebb00":{"lch":[78.2979307719844115,92.4506686575273307,61.8965912674010781],"luv":[78.2979307719844115,43.5502151824584587,81.5506277890334275],"rgb":[0.933333333333333348,0.733333333333333282,0],"xyz":[0.530286541787721277,0.537195691732810121,0.0757595260297813378],"hpluv":[61.8965912674010781,173.778692590363192,78.2979307719844115],"hsluv":[61.8965912674010781,100.000000000002373,78.2979307719844115]},"#eebb11":{"lch":[78.3216028454340858,91.4822746680663528,61.6861071172261504],"luv":[78.3216028454340858,43.3901974999079059,80.5375523551748],"rgb":[0.933333333333333348,0.733333333333333282,0.0666666666666666657],"xyz":[0.531298207287358437,0.537600357932665,0.0810876309945369744],"hpluv":[61.6861071172261504,172.182825477748111,78.3216028454340858],"hsluv":[61.6861071172261504,98.7812238781787642,78.3216028454340858]},"#eebb22":{"lch":[78.3654531575016335,89.702527227679937,61.2866058237147371],"luv":[78.3654531575016335,43.0956539167563477,78.672155204492924],"rgb":[0.933333333333333348,0.733333333333333282,0.133333333333333331],"xyz":[0.533173565425835383,0.53835050118805583,0.090964517190516167],"hpluv":[61.2866058237147371,169.241982225815036,78.3654531575016335],"hsluv":[61.2866058237147371,96.5386826089343,78.3654531575016335]},"#eebb33":{"lch":[78.4375634156200192,86.8156112143301897,60.6012126372659665],"luv":[78.4375634156200192,42.6165086308843897,75.6358614853528906],"rgb":[0.933333333333333348,0.733333333333333282,0.2],"xyz":[0.5362613161582932,0.539585601481039,0.107226671048127303],"hpluv":[60.6012126372659665,164.44952499458185,78.4375634156200192],"hsluv":[60.6012126372659665,92.89304460263088,78.4375634156200192]},"#eebb44":{"lch":[78.5414800230656,82.7424491039972878,59.5464137785053],"luv":[78.5414800230656,41.9372005918819397,71.3273025583039839],"rgb":[0.933333333333333348,0.733333333333333282,0.266666666666666663],"xyz":[0.540719311402512059,0.541368799578726523,0.130705446001013942],"hpluv":[59.5464137785053,157.640041580932575,78.5414800230656],"hsluv":[59.5464137785053,87.729612164687,78.5414800230656]},"#eebb55":{"lch":[78.6801087960333,77.4695312482544,58.0014729567720551],"luv":[78.6801087960333,41.0509080282697809,65.6989438414256455],"rgb":[0.933333333333333348,0.733333333333333282,0.333333333333333315],"xyz":[0.546681725441874,0.543753765194471272,0.162107493274987857],"hpluv":[58.0014729567720551,148.738759066450825,78.6801087960333],"hsluv":[58.0014729567720551,81.0022494643358613,78.6801087960333]},"#eebb66":{"lch":[78.8558787138066748,71.0520814803831229,55.7790951769469174],"luv":[78.8558787138066748,39.9586324736418845,58.7512210386423703],"rgb":[0.933333333333333348,0.733333333333333282,0.4],"xyz":[0.55426672121538223,0.546787763503874591,0.202055137682131819],"hpluv":[55.7790951769469174,137.768430134850121,78.8558787138066748],"hsluv":[55.7790951769469174,72.7264864885570574,78.8558787138066748]},"#eebb77":{"lch":[79.0708286262536,63.6259938562226566,52.5733668905169],"luv":[79.0708286262536,38.6683825737350801,50.5274507898760348],"rgb":[0.933333333333333348,0.733333333333333282,0.466666666666666674],"xyz":[0.56358073423558408,0.550513368711955442,0.251108939588529756],"hpluv":[52.5733668905169,124.876553308513152,79.0708286262536],"hsluv":[52.5733668905169,64.3532422469102841,79.0708286262536]},"#eebb88":{"lch":[79.3266586201773833,55.4370708593257149,47.8613800964459557],"luv":[79.3266586201773833,37.1942049853437169,41.1079060640423961],"rgb":[0.933333333333333348,0.733333333333333282,0.533333333333333326],"xyz":[0.574721151337528,0.554969535552733,0.309781802992101896],"hpluv":[47.8613800964459557,110.403075040931697,79.3266586201773833],"hsluv":[47.8613800964459557,64.6428486235092379,79.3266586201773833]},"#eebb99":{"lch":[79.6247632766216071,46.9114913521919519,40.7190885070752131],"luv":[79.6247632766216071,35.5550187983100727,30.6027557441907163],"rgb":[0.933333333333333348,0.733333333333333282,0.6],"xyz":[0.587778115446600635,0.560192321196362197,0.378548480633219775],"hpluv":[40.7190885070752131,95.0436922052712845,79.6247632766216071],"hsluv":[40.7190885070752131,64.94797236425741,79.6247632766216071]},"#eebbaa":{"lch":[79.9662551563314,38.821829319770238,29.5464132636418633],"luv":[79.9662551563314,33.7733033676501,19.1441482278540249],"rgb":[0.933333333333333348,0.733333333333333282,0.66666666666666663],"xyz":[0.602835808411853247,0.566215398382463264,0.457852330250218431],"hpluv":[29.5464132636418633,80.2381481795300573,79.9662551563314],"hsluv":[29.5464132636418633,65.2570717669902081,79.9662551563314]},"#eebbbb":{"lch":[80.3519829843595,32.6073830473385868,12.1770506300627979],"luv":[80.3519829843595,31.8737319395561,6.87798236703069765],"rgb":[0.933333333333333348,0.733333333333333282,0.733333333333333282],"xyz":[0.61997340051918981,0.573070435225398,0.548110315348860122],"hpluv":[12.1770506300627979,68.9527679352530498,80.3519829843595],"hsluv":[12.1770506300627979,65.5572779496269646,80.3519829843595]},"#eebbcc":{"lch":[80.7825470949933,30.4869713003172755,348.56539147946927],"luv":[80.7825470949933,29.8818538307637169,-6.04402437976891349],"rgb":[0.933333333333333348,0.733333333333333282,0.8],"xyz":[0.639265775962911564,0.58078738540288688,0.649716826019130278],"hpluv":[348.56539147946927,66.1649916626687542,80.7825470949933],"hsluv":[348.56539147946927,65.8346704867411,80.7825470949933]},"#eebbdd":{"lch":[81.2583136554081165,33.9595526191752555,325.014354592586812],"luv":[81.2583136554081165,27.8229160969035512,-19.4714291709468021],"rgb":[0.933333333333333348,0.733333333333333282,0.866666666666666696],"xyz":[0.660784101513545163,0.589394715623140386,0.763046673919136276],"hpluv":[325.014354592586812,75.8902298772919721,81.2583136554081165],"hsluv":[325.014354592586812,66.0744631525984119,81.2583136554081165]},"#eebbee":{"lch":[81.7794285687783429,42.0458499431423576,307.715012949247921],"luv":[81.7794285687783429,25.7208902583653902,-33.2609275540891716],"rgb":[0.933333333333333348,0.733333333333333282,0.933333333333333348],"xyz":[0.684596281779719873,0.598919587729610403,0.888457489987659499],"hpluv":[307.715012949247921,97.0917602325266245,81.7794285687783429],"hsluv":[307.715012949247921,66.2610602343042103,81.7794285687783429]},"#eebbff":{"lch":[82.3458315671937697,52.842459086223478,296.523687653639684],"luv":[82.3458315671937697,23.5977388768935938,-47.2807804734349446],"rgb":[0.933333333333333348,0.733333333333333282,1],"xyz":[0.710767330189551294,0.609388007093543127,1.02629167827944134],"hpluv":[296.523687653639684,126.563624284615543,82.3458315671937697],"hsluv":[296.523687653639684,99.9999999999958504,82.3458315671937697]},"#774400":{"lch":[34.1007355557283631,52.2824067620925845,38.9690248280103901],"luv":[34.1007355557283631,40.6488429776156863,32.8804139483986475],"rgb":[0.466666666666666674,0.266666666666666663,0],"xyz":[0.0967461069942917862,0.0805672125740730105,0.0104561581988052085],"hpluv":[38.9690248280103901,194.549962435525771,34.1007355557283631],"hsluv":[38.9690248280103901,100.000000000002302,34.1007355557283631]},"#774411":{"lch":[34.1844760931178726,49.9480603042207,37.0032460066389604],"luv":[34.1844760931178726,39.8885915773263164,30.0617529450848728],"rgb":[0.466666666666666674,0.266666666666666663,0.0666666666666666657],"xyz":[0.0977577724939289,0.0809718787739278634,0.0157842631635608383],"hpluv":[37.0032460066389604,185.408237524396696,34.1844760931178726],"hsluv":[37.0032460066389604,92.0774266797174477,34.1844760931178726]},"#774422":{"lch":[34.3389737161705639,45.9687551907429608,33.0232295817012798],"luv":[34.3389737161705639,38.542488289151045,25.0520069109664867],"rgb":[0.466666666666666674,0.266666666666666663,0.133333333333333331],"xyz":[0.0996331306324059335,0.0817220220293186778,0.0256611493595400378],"hpluv":[33.0232295817012798,169.869245826721482,34.3389737161705639],"hsluv":[33.0232295817012798,78.0803941927279794,34.3389737161705639]},"#774433":{"lch":[34.5913049894652787,40.4066166426811861,25.4401077009201266],"luv":[34.5913049894652787,36.4885814660887746,17.357364174931714],"rgb":[0.466666666666666674,0.266666666666666663,0.2],"xyz":[0.102720881364863667,0.0829571223223017906,0.041923303217151181],"hpluv":[25.4401077009201266,148.226163260119392,34.5913049894652787],"hsluv":[25.4401077009201266,56.8050953227402715,34.5913049894652787]},"#774444":{"lch":[34.9512320153617324,34.6101233100924119,12.1770506300620909],"luv":[34.9512320153617324,33.8314114683579277,7.30042694631360689],"rgb":[0.466666666666666674,0.266666666666666663,0.266666666666666663],"xyz":[0.107178876609082541,0.0847403204199893706,0.0654020781700378195],"hpluv":[12.1770506300620909,125.655060642768362,34.9512320153617324],"hsluv":[12.1770506300620909,29.4448754689639038,34.9512320153617324]},"#774455":{"lch":[35.4248138391838907,31.0799263948782318,351.580242092888511],"luv":[35.4248138391838907,30.7449438027498871,-4.55085214842230634],"rgb":[0.466666666666666674,0.266666666666666663,0.333333333333333315],"xyz":[0.11314129064844454,0.0871252860357342,0.0968041254440117349],"hpluv":[351.580242092888511,111.329877567225012,35.4248138391838907],"hsluv":[351.580242092888511,35.0525071981411855,35.4248138391838907]},"#774466":{"lch":[36.0149447056398699,32.55773059028094,327.386935336661793],"luv":[36.0149447056398699,27.4243377055297302,-17.5474078599198116],"rgb":[0.466666666666666674,0.266666666666666663,0.4],"xyz":[0.120726286421952711,0.090159284345137522,0.136751769851155697],"hpluv":[327.386935336661793,114.712488009680612,36.0149447056398699],"hsluv":[327.386935336661793,41.0162201785438469,36.0149447056398699]},"#774477":{"lch":[36.7217587051522898,39.3078830273429531,307.715012949244965],"luv":[36.7217587051522898,24.0459818745983789,-31.0950224919964064],"rgb":[0.466666666666666674,0.266666666666666663,0.466666666666666674],"xyz":[0.130040299442154617,0.0938848895532183314,0.185805571757553606],"hpluv":[307.715012949244965,135.82994003022975,36.7217587051522898],"hsluv":[307.715012949244965,46.9930223744603381,36.7217587051522898]},"#774488":{"lch":[37.5430301686231331,49.3077922843884906,294.880307130505798],"luv":[37.5430301686231331,20.7449732069104158,-44.731470651041306],"rgb":[0.466666666666666674,0.266666666666666663,0.533333333333333326],"xyz":[0.141180716544098472,0.0983410563939959292,0.244478435161125773],"hpluv":[294.880307130505798,166.657768282509579,37.5430301686231331],"hsluv":[294.880307130505798,52.7229750286883814,37.5430301686231331]},"#774499":{"lch":[38.4745988052595678,60.7540316024919775,286.849160899925266],"luv":[38.4745988052595678,17.609743748149274,-58.1459309073396042],"rgb":[0.466666666666666674,0.266666666666666663,0.6],"xyz":[0.154237680653171172,0.103563842037625087,0.313245112802243653],"hpluv":[286.849160899925266,200.373520820200838,38.4745988052595678],"hsluv":[286.849160899925266,58.0391908614757739,38.4745988052595678]},"#7744aa":{"lch":[39.5108096650206306,72.6607854160185695,281.662296555210446],"luv":[39.5108096650206306,14.6878600390207232,-71.1607792589909423],"rgb":[0.466666666666666674,0.266666666666666663,0.66666666666666663],"xyz":[0.169295373618423728,0.109586919223726181,0.392548962419242253],"hpluv":[281.662296555210446,233.358425064810547,39.5108096650206306],"hsluv":[281.662296555210446,62.855979622580108,39.5108096650206306]},"#7744bb":{"lch":[40.6449442050895,84.5532389367896684,278.156646558388104],"luv":[40.6449442050895,11.9964108827533504,-83.6978873128468],"rgb":[0.466666666666666674,0.266666666666666663,0.733333333333333282],"xyz":[0.186432965725760347,0.11644195606666094,0.482806947517884],"hpluv":[278.156646558388104,263.975148792079324,40.6449442050895],"hsluv":[278.156646558388104,67.1480450168623832,40.6449442050895]},"#7744cc":{"lch":[41.8696179576200223,96.2178725735773099,275.685728840067554],"luv":[41.8696179576200223,9.53248740063005151,-95.7445073439828747],"rgb":[0.466666666666666674,0.266666666666666663,0.8],"xyz":[0.205725341169482101,0.124158906244149742,0.584413458188154156],"hpluv":[275.685728840067554,291.605746800226,41.8696179576200223],"hsluv":[275.685728840067554,71.7563947172966721,41.8696179576200223]},"#7744dd":{"lch":[43.1771261833787037,107.572507589609089,273.881356516641858],"luv":[43.1771261833787037,7.28165300546471084,-107.325774717094461],"rgb":[0.466666666666666674,0.266666666666666663,0.866666666666666696],"xyz":[0.227243666720115645,0.132766236464403276,0.697743306088160153],"hpluv":[273.881356516641858,316.145413845169799,43.1771261833787037],"hsluv":[273.881356516641858,81.1040313116107683,43.1771261833787037]},"#7744ee":{"lch":[44.5597272061305958,118.600491111934247,272.524492751992966],"luv":[44.5597272061305958,5.22393127379498168,-118.485387428318177],"rgb":[0.466666666666666674,0.266666666666666663,0.933333333333333348],"xyz":[0.251055846986290354,0.14229110857087332,0.823154122156683377],"hpluv":[272.524492751992966,337.740615485066769,44.5597272061305958],"hsluv":[272.524492751992966,90.4775463334620866,44.5597272061305958]},"#7744ff":{"lch":[46.0098610845945188,129.316457315512423,271.478956563127554],"luv":[46.0098610845945188,3.33763127257498882,-129.273378350389976],"rgb":[0.466666666666666674,0.266666666666666663,1],"xyz":[0.277226895396121775,0.152759527934806016,0.960988310448465222],"hpluv":[271.478956563127554,356.649979093308843,46.0098610845945188],"hsluv":[271.478956563127554,99.9999999999992752,46.0098610845945188]},"#eecc00":{"lch":[82.5742071813858161,93.0890420253441278,70.6743105766144737],"luv":[82.5742071813858161,30.8066573410433797,87.8437226480516529],"rgb":[0.933333333333333348,0.8,0],"xyz":[0.568510285097338142,0.613643178352045071,0.088500773799653279],"hpluv":[70.6743105766144737,226.330948640265689,82.5742071813858161],"hsluv":[70.6743105766144737,100.000000000002331,82.5742071813858161]},"#eecc11":{"lch":[82.5958706312260773,92.1609271203023,70.5494354113464226],"luv":[82.5958706312260773,30.6889817522442812,86.9012248859824297],"rgb":[0.933333333333333348,0.8,0.0666666666666666657],"xyz":[0.569521950596975302,0.6140478445519,0.0938288787644089156],"hpluv":[70.5494354113464226,224.395635781555484,82.5958706312260773],"hsluv":[70.5494354113464226,98.9293851282895389,82.5958706312260773]},"#eecc22":{"lch":[82.636003730849751,90.4517890224530277,70.3125751850760849],"luv":[82.636003730849751,30.4721781878481224,85.1643851257694848],"rgb":[0.933333333333333348,0.8,0.133333333333333331],"xyz":[0.571397308735452247,0.61479798780729078,0.103705764960388108],"hpluv":[70.3125751850760849,220.820363432361461,82.636003730849751],"hsluv":[70.3125751850760849,96.9576791715233668,82.636003730849751]},"#eecc33":{"lch":[82.7020112487531,87.6695564091762236,69.9066450473675332],"luv":[82.7020112487531,30.1189443150749909,82.3334701948554084],"rgb":[0.933333333333333348,0.8,0.2],"xyz":[0.574485059467910064,0.616033088100273907,0.119967918817999258],"hpluv":[69.9066450473675332,214.968262161852493,82.7020112487531],"hsluv":[69.9066450473675332,93.7473974454290726,82.7020112487531]},"#eecc44":{"lch":[82.7971553193909102,83.7217279628800242,69.2828434677537786],"luv":[82.7971553193909102,29.6169744667019792,78.3081257375581],"rgb":[0.933333333333333348,0.8,0.266666666666666663],"xyz":[0.578943054712128924,0.617816286197961473,0.143446693770885897],"hpluv":[69.2828434677537786,206.594355258371763,82.7971553193909102],"hsluv":[69.2828434677537786,89.1900904304584685,82.7971553193909102]},"#eecc55":{"lch":[82.9241214704336471,78.5673404382155098,68.3706518767947387],"luv":[82.9241214704336471,28.9599810639926183,73.0352413585910085],"rgb":[0.933333333333333348,0.8,0.333333333333333315],"xyz":[0.584905468751490853,0.620201251813706222,0.174848741044859812],"hpluv":[68.3706518767947387,195.532369916851508,82.9241214704336471],"hsluv":[68.3706518767947387,83.2339277722755497,82.9241214704336471]},"#eecc66":{"lch":[83.0851700146488241,72.2150018940459688,67.0599726095305186],"luv":[83.0851700146488241,28.1470538355007811,66.503758231685552],"rgb":[0.933333333333333348,0.8,0.4],"xyz":[0.592490464524999094,0.623235250123109541,0.214796385452003746],"hpluv":[67.0599726095305186,181.688085793908328,83.0851700146488241],"hsluv":[67.0599726095305186,75.8779818086204898,83.0851700146488241]},"#eecc77":{"lch":[83.2822165713090925,64.7250307453925586,65.1677162202921778],"luv":[83.2822165713090925,27.1821511319325673,58.740618526133936],"rgb":[0.933333333333333348,0.8,0.466666666666666674],"xyz":[0.601804477545200944,0.626960855331190392,0.263850187358401655],"hpluv":[65.1677162202921778,165.044758034407693,83.2822165713090925],"hsluv":[65.1677162202921778,67.1675472191497533,83.2822165713090925]},"#eecc88":{"lch":[83.5168798492942699,56.2182636624862511,62.3679934299132839],"luv":[83.5168798492942699,26.0735255024375405,49.8062690541919793],"rgb":[0.933333333333333348,0.8,0.533333333333333326],"xyz":[0.612944894647144856,0.631417022171967934,0.322523050761973851],"hpluv":[62.3679934299132839,145.689263900370548,83.5168798492942699],"hsluv":[62.3679934299132839,57.1887031148042198,83.5168798492942699]},"#eecc99":{"lch":[83.79051243806407,46.9027423702446598,58.0311593919332083],"luv":[83.79051243806407,24.8330316313984234,39.7892923013655633],"rgb":[0.933333333333333348,0.8,0.6],"xyz":[0.6260018587562175,0.636639807815597147,0.39128972840309173],"hpluv":[58.0311593919332083,123.89218615802821,83.79051243806407],"hsluv":[58.0311593919332083,56.9799526918745158,83.79051243806407]},"#eeccaa":{"lch":[84.1042222244633,37.1556922719042646,50.8162292091241454],"luv":[84.1042222244633,23.475329457535171,28.8002495660129298],"rgb":[0.933333333333333348,0.8,0.66666666666666663],"xyz":[0.641059551721470111,0.642662885001698214,0.470593578020090331],"hpluv":[50.8162292091241454,100.353156070069275,84.1042222244633],"hsluv":[50.8162292091241454,57.1375361174420533,84.1042222244633]},"#eeccbb":{"lch":[84.4588885299527,27.7950211383377486,37.6158086991229084],"luv":[84.4588885299527,22.0170273242058485,16.9650731765535063],"rgb":[0.933333333333333348,0.8,0.733333333333333282],"xyz":[0.658197143828806674,0.649517921844633,0.560851563118732077],"hpluv":[37.6158086991229084,77.0182985337263517,84.4588885299527],"hsluv":[37.6158086991229084,57.2612530554736736,84.4588885299527]},"#eecccc":{"lch":[84.8551753311588897,20.9471233587290264,12.1770506300631585],"luv":[84.8551753311588897,20.4758227261490333,4.41844550641173317],"rgb":[0.933333333333333348,0.8,0.8],"xyz":[0.677489519272528429,0.65723487202212183,0.662458073789002233],"hpluv":[12.1770506300631585,59.764130158742411,84.8551753311588897],"hsluv":[12.1770506300631585,57.3329985994000637,84.8551753311588897]},"#eeccdd":{"lch":[85.2935429882433596,20.7797326136980232,335.241604291037675],"luv":[85.2935429882433596,18.8696973425293919,-8.70240252448279],"rgb":[0.933333333333333348,0.8,0.866666666666666696],"xyz":[0.699007844823162,0.665842202242375336,0.775787921689008231],"hpluv":[335.241604291037675,61.2821093808529582,85.2935429882433596],"hsluv":[335.241604291037675,57.3323512744098664,85.2935429882433596]},"#eeccee":{"lch":[85.7742593547863805,28.14328338963319,307.715012949251047],"luv":[85.7742593547863805,17.2162128855465397,-22.2631177921859056],"rgb":[0.933333333333333348,0.8,0.933333333333333348],"xyz":[0.722820025089336737,0.675367074348845353,0.901198737757531454],"hpluv":[307.715012949251047,86.153290074940827,85.7742593547863805],"hsluv":[307.715012949251047,57.2362127773837557,85.7742593547863805]},"#eeccff":{"lch":[86.2974107975625344,39.333162863939684,293.258584701896098],"luv":[86.2974107975625344,15.5319389668875889,-36.1366375415599919],"rgb":[0.933333333333333348,0.8,1],"xyz":[0.748991073499168158,0.685835493712778077,1.03903292604931341],"hpluv":[293.258584701896098,125.558261528980708,86.2974107975625344],"hsluv":[293.258584701896098,99.9999999999940314,86.2974107975625344]},"#775500":{"lch":[38.5848153490983421,48.2339285723334328,54.8056311564330656],"luv":[38.5848153490983421,27.7997213245256276,39.4168410682499868],"rgb":[0.466666666666666674,0.333333333333333315,0],"xyz":[0.108559363708637752,0.104193726002765275,0.0143939104369204193],"hpluv":[54.8056311564330656,158.626424871442595,38.5848153490983421],"hsluv":[54.8056311564330656,100.000000000002302,38.5848153490983421]},"#775511":{"lch":[38.6553893217116595,45.9150245993572952,53.4685955296553956],"luv":[38.6553893217116595,27.3315290852913257,36.8941323494598521],"rgb":[0.466666666666666674,0.333333333333333315,0.0666666666666666657],"xyz":[0.10957102920827487,0.104598392202620127,0.0197220154016760491],"hpluv":[53.4685955296553956,150.724584795248319,38.6553893217116595],"hsluv":[53.4685955296553956,93.8009130268131344,38.6553893217116595]},"#775522":{"lch":[38.7857346943923531,41.8305053308362176,50.7011784026830412],"luv":[38.7857346943923531,26.4939762066725,32.3706719268134577],"rgb":[0.466666666666666674,0.333333333333333315,0.133333333333333331],"xyz":[0.111446387346751899,0.105348535458010942,0.0295989015976552486],"hpluv":[50.7011784026830412,136.854920013655288,38.7857346943923531],"hsluv":[50.7011784026830412,82.7342982429400138,38.7857346943923531]},"#775533":{"lch":[38.9990050188249739,35.7224202133018096,45.1472123185964946],"luv":[38.9990050188249739,25.1945818654867857,25.3243825298663161],"rgb":[0.466666666666666674,0.333333333333333315,0.2],"xyz":[0.114534138079209633,0.106583635750994055,0.0458610554552663918],"hpluv":[45.1472123185964946,116.232257903435652,38.9990050188249739],"hsluv":[45.1472123185964946,65.6272728324870656,38.9990050188249739]},"#775544":{"lch":[39.3040305977305735,28.372964966311546,34.1730058033032336],"luv":[39.3040305977305735,23.4742392428959334,15.9369141601135258],"rgb":[0.466666666666666674,0.333333333333333315,0.266666666666666663],"xyz":[0.118992133323428506,0.108366833848681635,0.0693398304081530303],"hpluv":[34.1730058033032336,91.6024225041024,39.3040305977305735],"hsluv":[34.1730058033032336,43.1049791856067799,39.3040305977305735]},"#775555":{"lch":[39.7068052905653701,21.9117916496410494,12.1770506300624941],"luv":[39.7068052905653701,21.4187864245998618,4.62192615633957704],"rgb":[0.466666666666666674,0.333333333333333315,0.333333333333333315],"xyz":[0.124954547362790505,0.110751799464426468,0.100741877682126946],"hpluv":[12.1770506300624941,70.0248633547080601,39.7068052905653701],"hsluv":[12.1770506300624941,16.4089959502104463,39.7068052905653701]},"#775566":{"lch":[40.21091767922141,20.7753835118276839,337.09176723456028],"luv":[40.21091767922141,19.1368182791551824,-8.08694912894311],"rgb":[0.466666666666666674,0.333333333333333315,0.4],"xyz":[0.132539543136298676,0.113785797773829786,0.140689522089270908],"hpluv":[337.09176723456028,65.5608222190156482,40.21091767922141],"hsluv":[337.09176723456028,22.8015335286909036,40.21091767922141]},"#775577":{"lch":[40.8178321801082404,27.3616881241227183,307.715012949246557],"luv":[40.8178321801082404,16.7380842217685313,-21.6448264854847388],"rgb":[0.466666666666666674,0.333333333333333315,0.466666666666666674],"xyz":[0.141853556156500582,0.117511402981910595,0.189743323995668817],"hpluv":[307.715012949246557,85.0613515767839,40.8178321801082404],"hsluv":[307.715012949246557,29.4286369924042717,40.8178321801082404]},"#775588":{"lch":[41.5271394874135922,38.3484586217177892,291.922773984013077],"luv":[41.5271394874135922,14.317648223710199,-35.5754020076188269],"rgb":[0.466666666666666674,0.333333333333333315,0.533333333333333326],"xyz":[0.152993973258444438,0.121967569822688193,0.248416187399240984],"hpluv":[291.922773984013077,117.180466459805771,41.5271394874135922],"hsluv":[291.922773984013077,36.0000576829853429,41.5271394874135922]},"#775599":{"lch":[42.336815252734,50.9328741768069335,283.566916489070877],"luv":[42.336815252734,11.9478768110398388,-49.5116744982298442],"rgb":[0.466666666666666674,0.333333333333333315,0.6],"xyz":[0.166050937367517137,0.127190355466317351,0.317182865040358863],"hpluv":[283.566916489070877,152.657914615048412,42.336815252734],"hsluv":[283.566916489070877,42.2975255710275704,42.336815252734]},"#7755aa":{"lch":[43.2434937800222059,63.9392804809027098,278.705184193400783],"luv":[43.2434937800222059,9.67722671121172517,-63.202712533524668],"rgb":[0.466666666666666674,0.333333333333333315,0.66666666666666663],"xyz":[0.181108630332769693,0.133213432652418445,0.396486714657357464],"hpluv":[278.705184193400783,187.623095354238075,43.2434937800222059],"hsluv":[278.705184193400783,48.1780536314011272,43.2434937800222059]},"#7755bb":{"lch":[44.2427493107278096,76.8690732738289171,275.624120681329657],"luv":[44.2427493107278096,7.53331271169703509,-76.4990432983646116],"rgb":[0.466666666666666674,0.333333333333333315,0.733333333333333282],"xyz":[0.198246222440106312,0.140068469495353204,0.486744699755999211],"hpluv":[275.624120681329657,220.469676556121556,44.2427493107278096],"hsluv":[275.624120681329657,58.1137757976744496,44.2427493107278096]},"#7755cc":{"lch":[45.3293721892173949,89.4999308488430785,273.541003165926895],"luv":[45.3293721892173949,5.52776894932058127,-89.3290624175056536],"rgb":[0.466666666666666674,0.333333333333333315,0.8],"xyz":[0.217538597883828067,0.147785419672842,0.588351210426269366],"hpluv":[273.541003165926895,250.543028147628775,45.3293721892173949],"hsluv":[273.541003165926895,68.560007412736141,45.3293721892173949]},"#7755dd":{"lch":[46.4976270234735622,101.740884988783861,272.062259876532949],"luv":[46.4976270234735622,3.66119191329505167,-101.674988822595736],"rgb":[0.466666666666666674,0.333333333333333315,0.866666666666666696],"xyz":[0.23905692343446161,0.15639274989309554,0.701681058326275364],"hpluv":[272.062259876532949,277.654072578046794,46.4976270234735622],"hsluv":[272.062259876532949,78.9623412233913911,46.4976270234735622]},"#7755ee":{"lch":[47.7414825998049253,113.569026574645434,270.972372145675877],"luv":[47.7414825998049253,1.92729827623402139,-113.552672000560818],"rgb":[0.466666666666666674,0.333333333333333315,0.933333333333333348],"xyz":[0.26286910370063632,0.165917621999565584,0.827091874394798587],"hpluv":[270.972372145675877,301.858443342198598,47.7414825998049253],"hsluv":[270.972372145675877,89.4067229175139175,47.7414825998049253]},"#7755ff":{"lch":[49.0548071408334749,124.996939079083958,270.144864217432826],"luv":[49.0548071408334749,0.31603661949764611,-124.996539552082652],"rgb":[0.466666666666666674,0.333333333333333315,1],"xyz":[0.289040152110467741,0.17638604136349828,0.964926062686580432],"hpluv":[270.144864217432826,323.338286172745597,49.0548071408334749],"hsluv":[270.144864217432826,99.9999999999992184,49.0548071408334749]},"#eedd00":{"lch":[86.9434330779808562,96.0018853881048528,78.7633058197047831],"luv":[86.9434330779808562,18.7071720605167293,94.1615829920517],"rgb":[0.933333333333333348,0.866666666666666696,0],"xyz":[0.611144275644513346,0.69891115944639659,0.102712103982044597],"hpluv":[78.7633058197047831,323.365375109368927,86.9434330779808562],"hsluv":[78.7633058197047831,100.000000000002331,86.9434330779808562]},"#eedd11":{"lch":[86.9632971622836,95.1251800329902153,78.7103442402005555],"luv":[86.9632971622836,18.6225708681111755,93.2845095960255293],"rgb":[0.933333333333333348,0.866666666666666696,0.0666666666666666657],"xyz":[0.612155941144150506,0.699315825646251499,0.108040208946800234],"hpluv":[78.7103442402005555,320.953864246165836,86.9632971622836],"hsluv":[78.7103442402005555,99.0572185708442134,86.9632971622836]},"#eedd22":{"lch":[87.0000996195567,93.508678235103929,78.6100630695382421],"luv":[87.0000996195567,18.466577094457584,91.6671066178629559],"rgb":[0.933333333333333348,0.866666666666666696,0.133333333333333331],"xyz":[0.614031299282627452,0.700065968901642299,0.117917095142779427],"hpluv":[78.6100630695382421,316.490280961531141,87.0000996195567],"hsluv":[78.6100630695382421,97.3195837272491104,87.0000996195567]},"#eedd33":{"lch":[87.0606371109171704,90.8714304533391157,78.438725785200063],"luv":[87.0606371109171704,18.2120693177914781,89.0277339024194561],"rgb":[0.933333333333333348,0.866666666666666696,0.2],"xyz":[0.617119050015085269,0.701301069194625426,0.134179249000390577],"hpluv":[78.438725785200063,309.159510866930361,87.0606371109171704],"hsluv":[78.438725785200063,94.4866487647953335,87.0606371109171704]},"#eedd44":{"lch":[87.1479139339873399,87.1163282896156375,78.1766823729436737],"luv":[87.1479139339873399,17.8496481580416315,85.2680755927926839],"rgb":[0.933333333333333348,0.866666666666666696,0.266666666666666663],"xyz":[0.621577045259304128,0.703084267292313,0.157658023953277215],"hpluv":[78.1766823729436737,298.614243514229941,87.1479139339873399],"hsluv":[78.1766823729436737,90.4569971269957449,87.1479139339873399]},"#eedd55":{"lch":[87.2644132886328,82.1887294441124823,77.7961103956051119],"luv":[87.2644132886328,17.3739699699556027,80.3313912186301],"rgb":[0.933333333333333348,0.866666666666666696,0.333333333333333315],"xyz":[0.627539459298666058,0.705469232908057742,0.189060071227251103],"hpluv":[77.7961103956051119,284.577035202400168,87.2644132886328],"hsluv":[77.7961103956051119,85.1762064326895114,87.2644132886328]},"#eedd66":{"lch":[87.4122373516825775,76.0722975624531,77.2543738936701],"luv":[87.4122373516825775,16.7832968217641607,74.1978126646801428],"rgb":[0.933333333333333348,0.866666666666666696,0.4],"xyz":[0.635124455072174299,0.70850323121746106,0.229007715634395093],"hpluv":[77.2543738936701,266.820521177772889,87.4122373516825775],"hsluv":[77.2543738936701,78.6319742502837187,87.4122373516825775]},"#eedd77":{"lch":[87.5931821049200323,68.7867162946957,76.4818073814204666],"luv":[87.5931821049200323,16.0791769624109904,66.8810317415814524],"rgb":[0.933333333333333348,0.866666666666666696,0.466666666666666674],"xyz":[0.644438468092376149,0.712228836425541911,0.278061517540793],"hpluv":[76.4818073814204666,245.153905791490757,87.5931821049200323],"hsluv":[76.4818073814204666,70.850552214552053,87.5931821049200323]},"#eedd88":{"lch":[87.8087818591101694,60.3863988515096,75.3563176494847],"luv":[87.8087818591101694,15.266108392374667,58.4248500280990655],"rgb":[0.933333333333333348,0.866666666666666696,0.533333333333333326],"xyz":[0.65557888519432006,0.716685003266319454,0.336734380944365141],"hpluv":[75.3563176494847,219.413652035392374,87.8087818591101694],"hsluv":[75.3563176494847,61.8928475378351,87.8087818591101694]},"#eedd99":{"lch":[88.0603378936253165,50.9615259485641658,73.6438422487017164],"luv":[88.0603378936253165,14.3511385044238935,48.8990996914362483],"rgb":[0.933333333333333348,0.866666666666666696,0.6],"xyz":[0.668635849303392704,0.721907788909948667,0.405501058585483076],"hpluv":[73.6438422487017164,189.463858183723431,88.0603378936253165],"hsluv":[73.6438422487017164,51.8496821371243328,88.0603378936253165]},"#eeddaa":{"lch":[88.3489381850503719,40.6474355343677374,70.8361013393810595],"luv":[88.3489381850503719,13.3433963411670824,38.3948927541556],"rgb":[0.933333333333333348,0.866666666666666696,0.66666666666666663],"xyz":[0.683693542268645316,0.727930866096049733,0.484804908202481677],"hpluv":[70.8361013393810595,155.230940371192503,88.3489381850503719],"hsluv":[70.8361013393810595,42.897511243529749,88.3489381850503719]},"#eeddbb":{"lch":[88.6754719765582422,29.6681200622416164,65.6052069824857256],"luv":[88.6754719765582422,12.2535763784239329,27.0193858917206811],"rgb":[0.933333333333333348,0.866666666666666696,0.733333333333333282],"xyz":[0.700831134375981879,0.734785902938984492,0.575062893301123368],"hpluv":[65.6052069824857256,116.881954111652547,88.6754719765582422],"hsluv":[65.6052069824857256,42.5880034653653823,88.6754719765582422]},"#eeddcc":{"lch":[89.0406413623298,18.5684245799280596,53.3136761054906927],"luv":[89.0406413623298,11.093403559257359,14.8903589228712931],"rgb":[0.933333333333333348,0.866666666666666696,0.8],"xyz":[0.720123509819703633,0.742502853116473349,0.676669403971393524],"hpluv":[53.3136761054906927,75.8171941810365837,89.0406413623298],"hsluv":[53.3136761054906927,42.1389745374101,89.0406413623298]},"#eedddd":{"lch":[89.4449712115231677,10.1024117660870978,12.1770506300652031],"luv":[89.4449712115231677,9.87511215198720294,2.13093488339032255],"rgb":[0.933333333333333348,0.866666666666666696,0.866666666666666696],"xyz":[0.741641835370337232,0.751110183336726855,0.789999251871399522],"hpluv":[12.1770506300652031,42.9711785560074802,89.4449712115231677],"hsluv":[12.1770506300652031,41.5103310668104939,89.4449712115231677]},"#eeddee":{"lch":[89.8888182614484919,14.0763196099440542,307.715012949260654],"luv":[89.8888182614484919,8.61096808409750203,-11.1352594229299271],"rgb":[0.933333333333333348,0.866666666666666696,0.933333333333333348],"xyz":[0.765454015636511942,0.760635055443196872,0.915410067939922745],"hpluv":[307.715012949260654,62.7286135322124423,89.8888182614484919],"hsluv":[307.715012949260654,40.6526002298302203,89.8888182614484919]},"#eeddff":{"lch":[90.3723799019863776,25.8444533047225526,286.436741223308786],"luv":[90.3723799019863776,7.31285770395748802,-24.7882609075678033],"rgb":[0.933333333333333348,0.866666666666666696,1],"xyz":[0.791625064046343363,0.771103474807129596,1.05324425623170459],"hpluv":[286.436741223308786,121.429851146909542,90.3723799019863776],"hsluv":[286.436741223308786,99.9999999999912461,90.3723799019863776]},"#776600":{"lch":[43.3967364031710616,48.7618731822316747,71.5665709091534836],"luv":[43.3967364031710616,15.4186312136361749,46.2599836547520695],"rgb":[0.466666666666666674,0.4,0],"xyz":[0.123587421414484214,0.134249841414458615,0.0194032630055357667],"hpluv":[71.5665709091534836,142.581321953300886,43.3967364031710616],"hsluv":[71.5665709091534836,100.000000000002203,43.3967364031710616]},"#776611":{"lch":[43.4563559440565683,46.5521225716425278,71.0105555334865812],"luv":[43.4563559440565683,15.1477793781447385,44.0186880294754204],"rgb":[0.466666666666666674,0.4,0.0666666666666666657],"xyz":[0.124599086914121332,0.134654507614313468,0.0247313679702914],"hpluv":[71.0105555334865812,135.933189968578517,43.4563559440565683],"hsluv":[71.0105555334865812,95.1446041192036,43.4563559440565683]},"#776622":{"lch":[43.5665595032511135,42.5748985848782695,69.8598868578742582],"luv":[43.5665595032511135,14.6592646006394602,39.9715892964128727],"rgb":[0.466666666666666674,0.4,0.133333333333333331],"xyz":[0.126474445052598361,0.135404650869704296,0.0346082541662705925],"hpluv":[69.8598868578742582,124.005139157578384,43.5665595032511135],"hsluv":[69.8598868578742582,86.4059851293991699,43.5665595032511135]},"#776633":{"lch":[43.7471247164395862,36.3538810550032,67.535659471968259],"luv":[43.7471247164395862,13.8911218179866047,33.5952586297408544],"rgb":[0.466666666666666674,0.4,0.2],"xyz":[0.129562195785056095,0.136639751162687395,0.0508704080238817358],"hpluv":[67.535659471968259,105.448545621014873,43.7471247164395862],"hsluv":[67.535659471968259,72.7162107178341,43.7471247164395862]},"#776644":{"lch":[44.0059094002531381,28.0798421405657628,62.7556004259007807],"luv":[44.0059094002531381,12.8545871201011757,24.9647175952547435],"rgb":[0.466666666666666674,0.4,0.266666666666666663],"xyz":[0.134020191029274982,0.138422949260375,0.0743491829767683743],"hpluv":[62.7556004259007807,80.969785387169,44.0059094002531381],"hsluv":[62.7556004259007807,54.3487361937933,44.0059094002531381]},"#776655":{"lch":[44.348573895236818,18.4503377813959695,51.0995937541716287],"luv":[44.348573895236818,11.5862323365157813,14.3587668165439446],"rgb":[0.466666666666666674,0.4,0.333333333333333315],"xyz":[0.139982605068636967,0.140807914876119822,0.10575123025074229],"hpluv":[51.0995937541716287,52.7914984191523473,44.348573895236818],"hsluv":[51.0995937541716287,32.0544530960382303,44.348573895236818]},"#776666":{"lch":[44.7789425039584543,10.3722772339139464,12.177050630063178],"luv":[44.7789425039584543,10.1389057710203723,2.18785849257654696],"rgb":[0.466666666666666674,0.4,0.4],"xyz":[0.147567600842145152,0.143841913185523113,0.145698874657886251],"hpluv":[12.177050630063178,29.3927086392471182,44.7789425039584543],"hsluv":[12.177050630063178,6.88762268030489189,44.7789425039584543]},"#776677":{"lch":[45.2992151274866899,14.0123007519981453,307.715012949251729],"luv":[45.2992151274866899,8.57180555029232849,-11.0846164558105222],"rgb":[0.466666666666666674,0.4,0.466666666666666674],"xyz":[0.156881613862347058,0.147567518393603936,0.194752676564284161],"hpluv":[307.715012949251729,39.2516664249610088,45.2992151274866899],"hsluv":[307.715012949251729,13.5798811229143528,45.2992151274866899]},"#776688":{"lch":[45.9101336093725934,25.9566305949561666,285.511882327844],"luv":[45.9101336093725934,6.94179491604529719,-25.0111606125461954],"rgb":[0.466666666666666674,0.4,0.533333333333333326],"xyz":[0.168022030964290886,0.152023685234381534,0.253425539967856328],"hpluv":[285.511882327844,71.7429261821633304,45.9101336093725934],"hsluv":[285.511882327844,20.4210179876919788,45.9101336093725934]},"#776699":{"lch":[46.6111419677041781,39.5636276789354753,277.694853057332239],"luv":[46.6111419677041781,5.29745753469698322,-39.2073663842078446],"rgb":[0.466666666666666674,0.4,0.6],"xyz":[0.181078995073363613,0.157246470878010691,0.322192217608974207],"hpluv":[277.694853057332239,107.707436484347127,46.6111419677041781],"hsluv":[277.694853057332239,30.3115853005661187,46.6111419677041781]},"#7766aa":{"lch":[47.4005539940279945,53.5010996637438936,273.94010537559177],"luv":[47.4005539940279945,3.67625443841083355,-53.3746458398921959],"rgb":[0.466666666666666674,0.4,0.66666666666666663],"xyz":[0.196136688038616142,0.163269548064111786,0.401496067225972808],"hpluv":[273.94010537559177,143.224929654224553,47.4005539940279945],"hsluv":[273.94010537559177,41.7476492103462178,47.4005539940279945]},"#7766bb":{"lch":[48.2757296522395052,67.3356727079262356,271.790784098674919],"luv":[48.2757296522395052,2.10423911354751,-67.3027859511178],"rgb":[0.466666666666666674,0.4,0.733333333333333282],"xyz":[0.213274280145952788,0.170124584907046544,0.491754052324614555],"hpluv":[271.790784098674919,176.992833999799871,48.2757296522395052],"hsluv":[271.790784098674919,53.26174830093764,48.2757296522395052]},"#7766cc":{"lch":[49.2332558923506838,80.8618894300095263,270.423298283194697],"luv":[49.2332558923506838,0.597398061184884921,-80.8596826468393886],"rgb":[0.466666666666666674,0.4,0.8],"xyz":[0.232566655589674542,0.177841535084535346,0.59336056299488471],"hpluv":[270.423298283194697,208.412927467485218,49.2332558923506838],"hsluv":[270.423298283194697,64.812294986267446,49.2332558923506838]},"#7766dd":{"lch":[50.2691251722936698,93.9789905273776327,269.490145829531343],"luv":[50.2691251722936698,-0.836273601566472236,-93.9752696564806769],"rgb":[0.466666666666666674,0.4,0.866666666666666696],"xyz":[0.254084981140308086,0.18644886530478888,0.706690410894890708],"hpluv":[269.490145829531343,237.229544488008315,50.2691251722936698],"hsluv":[269.490145829531343,76.411365903071939,50.2691251722936698]},"#7766ee":{"lch":[51.378904811117593,106.647241299318011,268.82087794331261],"luv":[51.378904811117593,-2.19459861633770803,-106.624658562961542],"rgb":[0.466666666666666674,0.4,0.933333333333333348],"xyz":[0.277897161406482796,0.195973737411258925,0.832101226963413931],"hpluv":[268.82087794331261,263.392927722023558,51.378904811117593],"hsluv":[268.82087794331261,88.1124589032604177,51.378904811117593]},"#7766ff":{"lch":[52.5578914047646748,118.864223743766644,268.322642340607558],"luv":[52.5578914047646748,-3.47930230784918848,-118.81329109850806],"rgb":[0.466666666666666674,0.4,1],"xyz":[0.304068209816314217,0.206442156775191621,0.969935415255195776],"hpluv":[268.322642340607558,286.980608281330717,52.5578914047646748],"hsluv":[268.322642340607558,99.9999999999990621,52.5578914047646748]},"#eeee00":{"lch":[91.3819857871042416,100.73955854358779,85.8743202181747591],"luv":[91.3819857871042416,7.24765584469138,100.478505862268193],"rgb":[0.933333333333333348,0.933333333333333348,0],"xyz":[0.658323051985028163,0.793268712127427555,0.118438362762215782],"hpluv":[85.8743202181747591,533.074105620447313,91.3819857871042416],"hsluv":[85.8743202181747591,100.000000000002302,91.3819857871042416]},"#eeee11":{"lch":[91.4002420948697,99.9206079899190485,85.8743202181747449],"luv":[91.4002420948697,7.18873686735402107,99.6616775060856526],"rgb":[0.933333333333333348,0.933333333333333348,0.0666666666666666657],"xyz":[0.659334717484665322,0.793673378327282464,0.123766467726971419],"hpluv":[85.8743202181747449,529.940172906192515,91.4002420948697],"hsluv":[85.8743202181747449,99.1672499526241182,91.4002420948697]},"#eeee22":{"lch":[91.4340680155716,98.4094794247264559,85.8743202181747],"luv":[91.4340680155716,7.08001949817026599,98.1544648222952105],"rgb":[0.933333333333333348,0.933333333333333348,0.133333333333333331],"xyz":[0.661210075623142268,0.794423521582673264,0.133643353922950597],"hpluv":[85.8743202181747,524.128135432551403,91.4340680155716],"hsluv":[85.8743202181747,97.631382664670781,91.4340680155716]},"#eeee33":{"lch":[91.4897155548310224,95.9410009888260475,85.874320218174617],"luv":[91.4897155548310224,6.90242608380469225,95.6923831080380864],"rgb":[0.933333333333333348,0.933333333333333348,0.2],"xyz":[0.664297826355600085,0.795658621875656391,0.149905507780561748],"hpluv":[85.874320218174617,514.550466890897383,91.4897155548310224],"hsluv":[85.874320218174617,95.1245282264191,91.4897155548310224]},"#eeee44":{"lch":[91.569956182858661,92.4193611961338917,85.8743202181745],"luv":[91.569956182858661,6.64906351605686385,92.1798691594911],"rgb":[0.933333333333333348,0.933333333333333348,0.266666666666666663],"xyz":[0.668755821599819,0.797441819973344,0.173384282733448386],"hpluv":[85.8743202181745,500.701064757674544,91.569956182858661],"hsluv":[85.8743202181745,91.5525623856835438,91.569956182858661]},"#eeee55":{"lch":[91.6770884747666912,87.7855710128071536,85.8743202181743612],"luv":[91.6770884747666912,6.31568785915728625,87.5580868047623682],"rgb":[0.933333333333333348,0.933333333333333348,0.333333333333333315],"xyz":[0.674718235639180874,0.799826785589088707,0.204786330007422301],"hpluv":[85.8743202181743612,482.129233036801622,91.6770884747666912],"hsluv":[85.8743202181743612,86.8606098102410584,91.6770884747666912]},"#eeee66":{"lch":[91.8130678710263197,82.0131153940214261,85.8743202181741481],"luv":[91.8130678710263197,5.90039150181238092,81.8005897091115912],"rgb":[0.933333333333333348,0.933333333333333348,0.4],"xyz":[0.682303231412689115,0.802860783898492,0.244733974414566263],"hpluv":[85.8743202181741481,458.402522986492727,91.8130678710263197],"hsluv":[85.8743202181741481,81.0287908474737435,91.8130678710263197]},"#eeee77":{"lch":[91.9795762822891163,75.1051560234190703,85.8743202181738923],"luv":[91.9795762822891163,5.40340190972927914,74.9105313631138],"rgb":[0.933333333333333348,0.933333333333333348,0.466666666666666674],"xyz":[0.691617244432891,0.806586389106572876,0.2937877763209642],"hpluv":[85.8743202181738923,429.072804464814112,91.9795762822891163],"hsluv":[85.8743202181738923,74.0694118243717838,91.9795762822891163]},"#eeee88":{"lch":[92.1780636375363542,67.0918310376028444,85.8743202181734233],"luv":[92.1780636375363542,4.82688735568056,66.9179718045445497],"rgb":[0.933333333333333348,0.933333333333333348,0.533333333333333326],"xyz":[0.702757661534834877,0.811042555947350419,0.35246063972453634],"hpluv":[85.8743202181734233,393.637417052406249,92.1780636375363542],"hsluv":[85.8743202181734233,66.0241185279663085,92.1780636375363542]},"#eeee99":{"lch":[92.4097746137617264,58.0271343519240759,85.8743202181728549],"luv":[92.4097746137617264,4.17473240419888647,57.8767650309654],"rgb":[0.933333333333333348,0.933333333333333348,0.6],"xyz":[0.715814625643907521,0.816265341590979632,0.421227317365654219],"hpluv":[85.8743202181728549,351.489405737917593,92.4097746137617264],"hsluv":[85.8743202181728549,56.9604957584853295,92.4097746137617264]},"#eeeeaa":{"lch":[92.6757669457712,47.9852530272659195,85.8743202181718885],"luv":[92.6757669457712,3.45227440531043239,47.8609058577161903],"rgb":[0.933333333333333348,0.933333333333333348,0.66666666666666663],"xyz":[0.730872318609160132,0.822288418777080699,0.500531166982652875],"hpluv":[85.8743202181718885,301.850049763156903,92.6757669457712],"hsluv":[85.8743202181718885,46.9680087594427178,92.6757669457712]},"#eeeebb":{"lch":[92.9769247593952741,37.0564456712956627,85.8743202181703253],"luv":[92.9769247593952741,2.66600696822725,36.9604189997225347],"rgb":[0.933333333333333348,0.933333333333333348,0.733333333333333282],"xyz":[0.748009910716496695,0.829143455620015457,0.590789152081294566],"hpluv":[85.8743202181703253,243.673832720465015,92.9769247593952741],"hsluv":[85.8743202181703253,36.1533987495139,92.9769247593952741]},"#eeeecc":{"lch":[93.3139689281547788,25.3426537884513579,85.8743202181670711],"luv":[93.3139689281547788,1.82326422217474082,25.2769817940640493],"rgb":[0.933333333333333348,0.933333333333333348,0.8],"xyz":[0.76730228616021845,0.836860405797504314,0.692395662751564722],"hpluv":[85.8743202181670711,175.509740066336235,93.3139689281547788],"hsluv":[85.8743202181670711,24.635760697738192,93.3139689281547788]},"#eeeedd":{"lch":[93.6874656794852143,12.9530841337210045,85.8743202181571377],"luv":[93.6874656794852143,0.931902991100789779,12.919518001474831],"rgb":[0.933333333333333348,0.933333333333333348,0.866666666666666696],"xyz":[0.788820611710852,0.84546773601775782,0.80572551065157072],"hpluv":[85.8743202181571377,95.2907564198152812,93.6874656794852143],"hsluv":[85.8743202181571377,12.5415797244653469,93.6874656794852143]},"#eeeeee":{"lch":[94.0978342288501466,4.90671076366048496e-12,0],"luv":[94.0978342288501466,4.6515081442594671e-12,1.56182025281704723e-12],"rgb":[0.933333333333333348,0.933333333333333348,0.933333333333333348],"xyz":[0.812632791977026758,0.854992608124227838,0.931136326720093943],"hpluv":[0,3.87295813278393312e-11,94.0978342288501466],"hsluv":[0,3.8714510065860851e-11,94.0978342288501466]},"#eeeeff":{"lch":[94.5453539438838391,13.4050739145486393,265.874320218197],"luv":[94.5453539438838391,-0.964421163933715353,-13.3703365130825738],"rgb":[0.933333333333333348,0.933333333333333348,1],"xyz":[0.838803840386858179,0.865461027488160561,1.06897051501187579],"hpluv":[265.874320218197,114.885858328026472,94.5453539438838391],"hsluv":[265.874320218197,99.999999999981938,94.5453539438838391]},"#777700":{"lch":[48.4055282063088868,53.3622847060179737,85.8743202181747],"luv":[48.4055282063088868,3.83912219020021839,53.2240036999738706],"rgb":[0.466666666666666674,0.466666666666666674,0],"xyz":[0.142041159467901856,0.171157317521294372,0.0255545090233414707],"hpluv":[85.8743202181747,139.887458074797621,48.4055282063088868],"hsluv":[85.8743202181747,100.000000000002331,48.4055282063088868]},"#777711":{"lch":[48.4562461221814829,51.3697569370731628,85.874320218174617],"luv":[48.4562461221814829,3.69577080233359201,51.2366392921178502],"rgb":[0.466666666666666674,0.466666666666666674,0.0666666666666666657],"xyz":[0.143052824967539,0.171561983721149225,0.0308826139880971],"hpluv":[85.874320218174617,134.523163178361983,48.4562461221814829],"hsluv":[85.874320218174617,96.1652781669932324,48.4562461221814829]},"#777722":{"lch":[48.5500530694338579,47.7524066126053768,85.8743202181744323],"luv":[48.5500530694338579,3.43552238949120969,47.6286628324468282],"rgb":[0.466666666666666674,0.466666666666666674,0.133333333333333331],"xyz":[0.144928183106016,0.172312126976540053,0.0407595001840763],"hpluv":[85.8743202181744323,124.808706278838557,48.5500530694338579],"hsluv":[85.8743202181744323,89.2207979160694293,48.5500530694338579]},"#777733":{"lch":[48.7039135074563063,42.0024110114446501,85.874320218174],"luv":[48.7039135074563063,3.02184190658892726,41.8935675523809934],"rgb":[0.466666666666666674,0.466666666666666674,0.2],"xyz":[0.148015933838473723,0.173547227269523152,0.0570216540416874432],"hpluv":[85.874320218174,109.433348296247431,48.7039135074563063],"hsluv":[85.874320218174,78.2295638238963704,48.7039135074563063]},"#777744":{"lch":[48.9247697387985312,34.1210359912247227,85.8743202181732528],"luv":[48.9247697387985312,2.45482042510454956,34.0326160292585],"rgb":[0.466666666666666674,0.466666666666666674,0.266666666666666663],"xyz":[0.152473929082692611,0.175330425367210746,0.0805004289945740747],"hpluv":[85.8743202181732528,88.497855114462908,48.9247697387985312],"hsluv":[85.8743202181732528,63.2636094274766378,48.9247697387985312]},"#777755":{"lch":[49.2178287935421537,24.2815247917763841,85.8743202181716327],"luv":[49.2178287935421537,1.74692184102758041,24.2186025669317253],"rgb":[0.466666666666666674,0.466666666666666674,0.333333333333333315],"xyz":[0.158436343122054624,0.177715390982955579,0.11190247626854799],"hpluv":[85.8743202181716327,62.6026663147617,49.2178287935421537],"hsluv":[85.8743202181716327,44.7521651878825324,49.2178287935421537]},"#777766":{"lch":[49.5868745078829676,12.7836483150604128,85.8743202181664742],"luv":[49.5868745078829676,0.919713018071489197,12.750521252385596],"rgb":[0.466666666666666674,0.466666666666666674,0.4],"xyz":[0.166021338895562781,0.18074938929235887,0.151850120675691952],"hpluv":[85.8743202181664742,32.7135296885410085,49.5868745078829676],"hsluv":[85.8743202181664742,23.385605928338574,49.5868745078829676]},"#777777":{"lch":[50.0344387925380687,2.67192546523751356e-12,0],"luv":[50.0344387925380687,2.52749706171116152e-12,8.66570421158112546e-13],"rgb":[0.466666666666666674,0.466666666666666674,0.466666666666666674],"xyz":[0.175335351915764714,0.184474994500439693,0.200903922582089861],"hpluv":[0,6.77633132918180515e-12,50.0344387925380687],"hsluv":[0,1.94020402484744743e-12,50.0344387925380687]},"#777788":{"lch":[50.5619220099523545,13.6772258441596737,265.874320218187563],"luv":[50.5619220099523545,-0.984000994856362388,-13.6417831984777926],"rgb":[0.466666666666666674,0.466666666666666674,0.533333333333333326],"xyz":[0.186475769017708515,0.188931161341217291,0.259576785985662029],"hpluv":[265.874320218187563,34.3252548472133,50.5619220099523545],"hsluv":[265.874320218187563,11.1797639211738336,50.5619220099523545]},"#777799":{"lch":[51.1696982290560669,27.8798810968622455,265.87432021818239],"luv":[51.1696982290560669,-2.00580373888746255,-27.8076342276045096],"rgb":[0.466666666666666674,0.466666666666666674,0.6],"xyz":[0.199532733126781242,0.194153946984846448,0.328343463626779908],"hpluv":[265.87432021818239,69.1380916549642563,51.1696982290560669],"hsluv":[265.87432021818239,22.9846011782403536,51.1696982290560669]},"#7777aa":{"lch":[51.8572203345112,42.2927406525888614,265.874320218180628],"luv":[51.8572203345112,-3.04272952363285398,-42.1831448442758443],"rgb":[0.466666666666666674,0.466666666666666674,0.66666666666666663],"xyz":[0.21459042609203377,0.200177024170947543,0.407647313243778564],"hpluv":[265.874320218180628,103.489412577951782,51.8572203345112],"hsluv":[265.874320218180628,35.2207148819814435,51.8572203345112]},"#7777bb":{"lch":[52.6231302285762439,56.6671214785474,265.874320218179832],"luv":[52.6231302285762439,-4.07688697591046,-56.5202764435038816],"rgb":[0.466666666666666674,0.466666666666666674,0.733333333333333282],"xyz":[0.231728018199370445,0.207032061013882301,0.497905298342420255],"hpluv":[265.874320218179832,136.645017565491173,52.6231302285762439],"hsluv":[265.874320218179832,47.751077300634,52.6231302285762439]},"#7777cc":{"lch":[53.4653742998309696,70.8221320427834513,265.874320218179378],"luv":[53.4653742998309696,-5.09526194727884452,-70.6386062488075],"rgb":[0.466666666666666674,0.466666666666666674,0.8],"xyz":[0.251020393643092143,0.214749011191371103,0.599511809012690411],"hpluv":[265.874320218179378,168.087613695837888,53.4653742998309696],"hsluv":[265.874320218179378,60.4968982098403671,53.4653742998309696]},"#7777dd":{"lch":[54.3813217092404102,84.6378263199215581,265.874320218179037],"luv":[54.3813217092404102,-6.08922498249284594,-84.4184990584042083],"rgb":[0.466666666666666674,0.466666666666666674,0.866666666666666696],"xyz":[0.272538719193725743,0.223356341411624637,0.712841656912696409],"hpluv":[265.874320218179037,197.494074150637061,54.3813217092404102],"hsluv":[265.874320218179037,73.4330970128385445,54.3813217092404102]},"#7777ee":{"lch":[55.3678819060931,98.0443353361264656,265.874320218178809],"luv":[55.3678819060931,-7.05374939408338086,-97.7902669542745713],"rgb":[0.466666666666666674,0.466666666666666674,0.933333333333333348],"xyz":[0.296350899459900452,0.232881213518094682,0.838252472981219632],"hpluv":[265.874320218178809,224.700440227144242,55.3678819060931],"hsluv":[265.874320218178809,86.5809092876847,55.3678819060931]},"#7777ff":{"lch":[56.4216176153771158,111.010032393554411,265.874320218178696],"luv":[56.4216176153771158,-7.98655981550332,-110.722365194803288],"rgb":[0.466666666666666674,0.466666666666666674,1],"xyz":[0.322521947869731873,0.243349632882027378,0.976086661273001477],"hpluv":[265.874320218178696,249.664056525023511,56.4216176153771158],"hsluv":[265.874320218178696,99.99999999999892,56.4216176153771158]},"#eeff00":{"lch":[95.8710857598618702,106.837421111995667,91.929871543819857],"luv":[95.8710857598618702,-3.59788306357601462,106.776822332015158],"rgb":[0.933333333333333348,1,0],"xyz":[0.710175424414702,0.896973456986776663,0.135722486905439893],"hpluv":[91.929871543819857,1221.941869030823,95.8710857598618702],"hsluv":[91.929871543819857,100.000000000002217,95.8710857598618702]},"#eeff11":{"lch":[95.8879066370154192,106.077593073364397,91.9648080695471748],"luv":[95.8879066370154192,-3.63693915095535747,106.015227330089402],"rgb":[0.933333333333333348,1,0.0666666666666666657],"xyz":[0.71118708991433921,0.897378123186631571,0.14105059187019553],"hpluv":[91.9648080695471748,1218.36968740939687,95.8879066370154192],"hsluv":[91.9648080695471748,99.9999999999846096,95.8879066370154192]},"#eeff22":{"lch":[95.9190746883988083,104.674935415410417,92.0306447189025221],"luv":[95.9190746883988083,-3.7090534526558554,104.609201443781629],"rgb":[0.933333333333333348,1,0.133333333333333331],"xyz":[0.713062448052816156,0.898128266442022372,0.150927478066174708],"hpluv":[92.0306447189025221,1211.72771901411761,95.9190746883988083],"hsluv":[92.0306447189025221,99.9999999999843254,95.9190746883988083]},"#eeff33":{"lch":[95.9703546560603,102.38192729680722,92.1421884898051076],"luv":[95.9703546560603,-3.826988551916231,102.31037677397255],"rgb":[0.933333333333333348,1,0.2],"xyz":[0.716150198785274,0.899363366735005498,0.167189631923785859],"hpluv":[92.1421884898051076,1200.73225066318059,95.9703546560603],"hsluv":[92.1421884898051076,99.9999999999843,95.9703546560603]},"#eeff44":{"lch":[96.0443082677326316,99.1069805797193482,92.3105231291127666],"luv":[96.0443082677326316,-3.99552836231266495,99.0264073504377],"rgb":[0.933333333333333348,1,0.266666666666666663],"xyz":[0.720608194029492832,0.901146564832693064,0.190668406876672497],"hpluv":[92.3105231291127666,1184.71704479359755,96.0443082677326316],"hsluv":[92.3105231291127666,99.999999999984,96.0443082677326316]},"#eeff55":{"lch":[96.1430663154878,94.7914212488158086,92.5502587525383831],"luv":[96.1430663154878,-4.21781218752730513,94.6975374691506744],"rgb":[0.933333333333333348,1,0.333333333333333315],"xyz":[0.726570608068854762,0.903531530448437814,0.222070454150646412],"hpluv":[92.5502587525383831,1163.01160371768833,96.1430663154878],"hsluv":[92.5502587525383831,99.9999999999832312,96.1430663154878]},"#eeff66":{"lch":[96.2684490440968261,89.4056432425818315,92.8821944044194083],"luv":[96.2684490440968261,-4.49554545672610839,89.2925479234763912],"rgb":[0.933333333333333348,1,0.4],"xyz":[0.734155603842363,0.906565528757841133,0.262018098557790347],"hpluv":[92.8821944044194083,1134.86447310352946,96.2684490440968261],"hsluv":[92.8821944044194083,99.9999999999826912,96.2684490440968261]},"#eeff77":{"lch":[96.4220309754045104,82.947030730659,93.3376121292550494],"luv":[96.4220309754045104,-4.82912482473711879,82.8063370791148827],"rgb":[0.933333333333333348,1,0.466666666666666674],"xyz":[0.743469616862564853,0.910291133965922,0.311071900464188311],"hpluv":[93.3376121292550494,1099.34916045901696,96.4220309754045104],"hsluv":[93.3376121292550494,99.9999999999824354,96.4220309754045104]},"#eeff88":{"lch":[96.6051797330544559,75.4384320618763553,93.966065888554354],"luv":[96.6051797330544559,-5.21774760700183382,75.2577713054536446],"rgb":[0.933333333333333348,1,0.533333333333333326],"xyz":[0.754610033964508764,0.914747300806699526,0.369744763867760451],"hpluv":[93.966065888554354,1055.22684316018899,96.6051797330544559],"hsluv":[93.966065888554354,99.9999999999810711,96.6051797330544559]},"#eeff99":{"lch":[96.8190810543072,66.9270103141668926,94.8508818247366],"luv":[96.8190810543072,-5.65953211211599072,66.6872881879637589],"rgb":[0.933333333333333348,1,0.6],"xyz":[0.767666998073581408,0.919970086450328739,0.43851144150887833],"hpluv":[94.8508818247366,1000.72847038880911,96.8190810543072],"hsluv":[94.8508818247366,99.9999999999804,96.8190810543072]},"#eeffaa":{"lch":[97.0647558759300182,57.4841926777339438,96.1432585072641785],"luv":[97.0647558759300182,-6.15165762861061438,57.1540857352402938],"rgb":[0.933333333333333348,1,0.66666666666666663],"xyz":[0.782724691038834,0.925993163636429806,0.517815291125877],"hpluv":[96.1432585072641785,933.191048721381,97.0647558759300182],"hsluv":[96.1432585072641785,99.9999999999786127,97.0647558759300182]},"#eeffbb":{"lch":[97.3430726615411857,47.2094061136043166,98.1473956779809242],"luv":[97.3430726615411857,-6.69052372550339935,46.7329104366258861],"rgb":[0.933333333333333348,1,0.733333333333333282],"xyz":[0.799862283146170583,0.932848200479364564,0.608073276224518677],"hpluv":[98.1473956779809242,848.432918810296883,97.3430726615411857],"hsluv":[98.1473956779809242,99.9999999999760689,97.3430726615411857]},"#eeffcc":{"lch":[97.6547568121604,36.2474903433398126,101.573139749476653],"luv":[97.6547568121604,-7.27192346215819718,35.5105573787715443],"rgb":[0.933333333333333348,1,0.8],"xyz":[0.819154658589892337,0.940565150656853421,0.709679786894788833],"hpluv":[101.573139749476653,739.717147432346792,97.6547568121604],"hsluv":[101.573139749476653,99.999999999972971,97.6547568121604]},"#eeffdd":{"lch":[98.0003982932414743,24.8675243497069864,108.50155795297276],"luv":[98.0003982932414743,-7.89122250686935445,23.5822470225029335],"rgb":[0.933333333333333348,1,0.866666666666666696],"xyz":[0.840672984140525936,0.949172480877106928,0.823009634794794831],"hpluv":[108.50155795297276,596.728870831386416,98.0003982932414743],"hsluv":[108.50155795297276,99.9999999999688072,98.0003982932414743]},"#eeffee":{"lch":[98.3804582036479,13.96608756186059,127.715012949221688],"luv":[98.3804582036479,-8.54353535492541205,11.0480588984987129],"rgb":[0.933333333333333348,1,0.933333333333333348],"xyz":[0.864485164406700646,0.958697352983577,0.948420450863318],"hpluv":[127.715012949221688,414.943064796341446,98.3804582036479],"hsluv":[127.715012949221688,99.9999999999608491,98.3804582036479]},"#eeffff":{"lch":[98.7952747621608438,9.43620053547767768,192.177050630058204],"luv":[98.7952747621608438,-9.22389036737693679,-1.99040876112424892],"rgb":[0.933333333333333348,1,1],"xyz":[0.890656212816532067,0.969165772347509669,1.0862546391551],"hpluv":[192.177050630058204,378.040319927501173,98.7952747621608438],"hsluv":[192.177050630058204,99.999999999948713,98.7952747621608438]},"#778800":{"lch":[53.5249548615687303,60.5938372915660253,96.5029793655947259],"luv":[53.5249548615687303,-6.86254771619202231,60.2039745910497572],"rgb":[0.466666666666666674,0.533333333333333326,0],"xyz":[0.164113529192872309,0.215302056971235917,0.0329119655983314136],"hpluv":[96.5029793655947259,143.651932639250902,53.5249548615687303],"hsluv":[96.5029793655947259,100.000000000002373,53.5249548615687303]},"#778811":{"lch":[53.5684856288310272,58.8481082257442409,96.7583563096261088],"luv":[53.5684856288310272,-6.9253766303469888,58.4391906196240143],"rgb":[0.466666666666666674,0.533333333333333326,0.0666666666666666657],"xyz":[0.165125194692509442,0.21570672317109077,0.0382400705630870433],"hpluv":[96.7583563096261088,139.399900460742,53.5684856288310272],"hsluv":[96.7583563096261088,96.9357421545617,53.5684856288310272]},"#778822":{"lch":[53.6490362820541407,55.6690512282284615,97.2652817371477],"luv":[53.6490362820541407,-7.04010577997538,55.2220986133077147],"rgb":[0.466666666666666674,0.533333333333333326,0.133333333333333331],"xyz":[0.167000552830986443,0.216456866426481598,0.0481169567590662428],"hpluv":[97.2652817371477,131.671329649176641,53.6490362820541407],"hsluv":[97.2652817371477,91.3605066517003337,53.6490362820541407]},"#778833":{"lch":[53.7812573057213,50.5917713326567053,98.2096275165039856],"luv":[53.7812573057213,-7.22426441450666346,50.0733195448945381],"rgb":[0.466666666666666674,0.533333333333333326,0.2],"xyz":[0.170088303563444176,0.217691966719464697,0.064379110616677393],"hpluv":[98.2096275165039856,119.368094402160139,53.7812573057213],"hsluv":[98.2096275165039856,82.4672262716137539,53.7812573057213]},"#778844":{"lch":[53.9712743947247162,43.5928841845235198,99.8805739619221811],"luv":[53.9712743947247162,-7.48032491712259429,42.9462954241638357],"rgb":[0.466666666666666674,0.533333333333333326,0.266666666666666663],"xyz":[0.174546298807663064,0.219475164817152291,0.0878578855695640315],"hpluv":[99.8805739619221811,102.492540276722124,53.9712743947247162],"hsluv":[99.8805739619221811,70.2195807792145672,53.9712743947247162]},"#778855":{"lch":[54.2238135722873,34.8221097745323078,102.954066597198249],"luv":[54.2238135722873,-7.80606678579386326,33.9358903004666175],"rgb":[0.466666666666666674,0.533333333333333326,0.333333333333333315],"xyz":[0.180508712847025077,0.221860130432897124,0.119259932843537933],"hpluv":[102.954066597198249,81.4900057495692636,54.2238135722873],"hsluv":[102.954066597198249,54.8454134878709638,54.2238135722873]},"#778866":{"lch":[54.542475349788262,24.6519214642532667,109.417534351990682],"luv":[54.542475349788262,-8.19552569001744224,23.2497438812554442],"rgb":[0.466666666666666674,0.533333333333333326,0.4],"xyz":[0.188093708620533234,0.224894128742300414,0.159207577250681909],"hpluv":[109.417534351990682,57.3528835536874197,54.542475349788262],"hsluv":[109.417534351990682,36.7830408334215164,54.542475349788262]},"#778877":{"lch":[54.9298804020046703,14.1239929232838151,127.715012949231166],"luv":[54.9298804020046703,-8.6401314869560828,11.1729720300858784],"rgb":[0.466666666666666674,0.533333333333333326,0.466666666666666674],"xyz":[0.197407721640735168,0.228619733950381238,0.208261379157079818],"hpluv":[127.715012949231166,32.6278280107521041,54.9298804020046703],"hsluv":[127.715012949231166,16.6133799052879709,54.9298804020046703]},"#778888":{"lch":[55.3877640712208574,9.3400800844087577,192.177050630059369],"luv":[55.3877640712208574,-9.12993258220805437,-1.97013375878514596],"rgb":[0.466666666666666674,0.533333333333333326,0.533333333333333326],"xyz":[0.208548138742678968,0.233075900791158835,0.266934242560651958],"hpluv":[192.177050630059369,21.3981433643613,55.3877640712208574],"hsluv":[192.177050630059369,21.3143847536295468,55.3877640712208574]},"#778899":{"lch":[55.9170512374386703,18.5603965019494623,238.655736169794807],"luv":[55.9170512374386703,-9.65472976501325597,-15.851640655596027],"rgb":[0.466666666666666674,0.533333333333333326,0.6],"xyz":[0.221605102851751695,0.238298686434788,0.335700920201769892],"hpluv":[238.655736169794807,42.1194135101242679,55.9170512374386703],"hsluv":[238.655736169794807,26.1912729818073053,55.9170512374386703]},"#7788aa":{"lch":[56.5179258756863732,31.8473117719276075,251.310804784322386],"luv":[56.5179258756863732,-10.2049729927717898,-30.1680260095876527],"rgb":[0.466666666666666674,0.533333333333333326,0.66666666666666663],"xyz":[0.236662795817004223,0.244321763620889087,0.415004769818768493],"hpluv":[251.310804784322386,71.5032678590983721,56.5179258756863732],"hsluv":[251.310804784322386,31.1149405392867244,56.5179258756863732]},"#7788bb":{"lch":[57.1899017055338845,45.9393215269311881,256.438388794294667],"luv":[57.1899017055338845,-10.7723499078102041,-44.6584565319768387],"rgb":[0.466666666666666674,0.533333333333333326,0.733333333333333282],"xyz":[0.253800387924340898,0.251176800463823846,0.505262754917410239],"hpluv":[256.438388794294667,101.930593576715296,57.1899017055338845],"hsluv":[256.438388794294667,41.4357647235180622,57.1899017055338845]},"#7788cc":{"lch":[57.9318961804226547,60.1932243037694406,259.131204763586595],"luv":[57.9318961804226547,-11.3500713849249486,-59.1134513595764233],"rgb":[0.466666666666666674,0.533333333333333326,0.8],"xyz":[0.273092763368062652,0.258893750641312648,0.606869265587680395],"hpluv":[259.131204763586595,131.8466774878151,57.9318961804226547],"hsluv":[259.131204763586595,55.5026255722761661,57.9318961804226547]},"#7788dd":{"lch":[58.7423077351926679,74.3397271130694861,260.762999043897821],"luv":[58.7423077351926679,-11.9329115646152975,-73.3757497327060264],"rgb":[0.466666666666666674,0.533333333333333326,0.866666666666666696],"xyz":[0.29461108891869614,0.267501080861566209,0.720199113487686393],"hpluv":[260.762999043897821,160.586593274196787,58.7423077351926679],"hsluv":[260.762999043897821,69.9489143241080598,58.7423077351926679]},"#7788ee":{"lch":[59.6190949291064101,88.2283098571320465,261.84384456781811],"luv":[59.6190949291064101,-12.5170812067924775,-87.3358880318318285],"rgb":[0.466666666666666674,0.533333333333333326,0.933333333333333348],"xyz":[0.318423269184870905,0.277025952968036226,0.845609929556209616],"hpluv":[261.84384456781811,187.785436290663455,59.6190949291064101],"hsluv":[261.84384456781811,84.7689484415743237,59.6190949291064101]},"#7788ff":{"lch":[60.55985551741054,101.77153783075579,262.604380260147],"luv":[60.55985551741054,-13.1000102630052879,-100.924901008354297],"rgb":[0.466666666666666674,0.533333333333333326,1],"xyz":[0.344594317594702271,0.28749437233196895,0.983444117847991461],"hpluv":[262.604380260147,213.245970352856943,60.55985551741054],"hsluv":[262.604380260147,99.9999999999987921,60.55985551741054]},"#779900":{"lch":[58.6994568897504223,69.1976359459353603,103.993850276975294],"luv":[58.6994568897504223,-16.7332165977800322,67.1439668384135899],"rgb":[0.466666666666666674,0.6,0],"xyz":[0.189983129645339782,0.267041257876171612,0.0415351657491536685],"hpluv":[103.993850276975294,149.587912305351722,58.6994568897504223],"hsluv":[103.993850276975294,100.000000000002444,58.6994568897504223]},"#779911":{"lch":[58.7371702745588493,67.6759907780605232,104.326162498332039],"luv":[58.7371702745588493,-16.7458460058928829,65.5714600214076],"rgb":[0.466666666666666674,0.6,0.0666666666666666657],"xyz":[0.190994795144976914,0.267445924076026464,0.0468632707139093],"hpluv":[104.326162498332039,146.20456366036808,58.7371702745588493],"hsluv":[104.326162498332039,97.5197891999702,58.7371702745588493]},"#779922":{"lch":[58.8069803361006223,64.8997387816913,104.97431376012679],"luv":[58.8069803361006223,-16.7691829588827659,62.6958578920751464],"rgb":[0.466666666666666674,0.6,0.133333333333333331],"xyz":[0.192870153283453916,0.268196067331417265,0.0567401569098885],"hpluv":[104.97431376012679,140.04041716275114,58.8069803361006223],"hsluv":[104.97431376012679,92.9911396041894704,58.8069803361006223]},"#779933":{"lch":[58.9216385591388132,60.4528100001228097,106.14237332279157],"luv":[58.9216385591388132,-16.8074000849803582,58.0693855598141369],"rgb":[0.466666666666666674,0.6,0.2],"xyz":[0.195957904015911677,0.269431167624400392,0.0730023107674996341],"hpluv":[106.14237332279157,130.191012221085145,58.9216385591388132],"hsluv":[106.14237332279157,85.724115661044948,58.9216385591388132]},"#779944":{"lch":[59.0865618982540752,54.3006768161790845,108.091337704968765],"luv":[59.0865618982540752,-16.8621369683366211,51.6161974534756354],"rgb":[0.466666666666666674,0.6,0.266666666666666663],"xyz":[0.200415899260130537,0.271214365722087958,0.0964810857203862726],"hpluv":[108.091337704968765,116.615384645059635,59.0865618982540752],"hsluv":[108.091337704968765,75.6282332091309399,59.0865618982540752]},"#779955":{"lch":[59.3060149965037056,46.5647823410072945,111.326222899357617],"luv":[59.3060149965037056,-16.9345685221747893,43.3762532203180413],"rgb":[0.466666666666666674,0.6,0.333333333333333315],"xyz":[0.206378313299492522,0.273599331337832818,0.127883132994360188],"hpluv":[111.326222899357617,99.6318422422000367,59.3060149965037056],"hsluv":[111.326222899357617,62.8087826319283806,59.3060149965037056]},"#779966":{"lch":[59.5833535636433282,37.5662597340720836,116.949978591108717],"luv":[59.5833535636433282,-17.0254963867212936,33.4866591823296957],"rgb":[0.466666666666666674,0.6,0.4],"xyz":[0.213963309073000707,0.276633329647236137,0.16783077740150415],"hpluv":[116.949978591108717,80.0041177209304522,59.5833535636433282],"hsluv":[116.949978591108717,47.5357009492008,59.5833535636433282]},"#779977":{"lch":[59.921152065724,28.0111989307655129,127.71501294923614],"luv":[59.921152065724,-17.1354122862910181,22.1586306282167591],"rgb":[0.466666666666666674,0.6,0.466666666666666674],"xyz":[0.223277322093202613,0.280358934855316932,0.216884579307902059],"hpluv":[127.71501294923614,59.3185968765002301,59.921152065724],"hsluv":[127.71501294923614,30.2037385091367128,59.921152065724]},"#779988":{"lch":[60.3212826107906608,19.7788738743410271,150.794869664161695],"luv":[60.3212826107906608,-17.2645515875173317,9.65086059473676272],"rgb":[0.466666666666666674,0.6,0.533333333333333326],"xyz":[0.234417739195146468,0.28481510169609453,0.275557442711474199],"hpluv":[150.794869664161695,41.6073752981458043,60.3212826107906608],"hsluv":[150.794869664161695,33.5278156565034706,60.3212826107906608]},"#779999":{"lch":[60.7849725890424537,17.8137422376051369,192.177050630060307],"luv":[60.7849725890424537,-17.4129412378011317,-3.75751113860251662],"rgb":[0.466666666666666674,0.6,0.6],"xyz":[0.247474703304219168,0.290037887339723688,0.344324120352592133],"hpluv":[192.177050630060307,37.1876097830212373,60.7849725890424537],"hsluv":[192.177050630060307,37.0420465685486562,60.7849725890424537]},"#7799aa":{"lch":[61.3128540464897895,25.0117677757311512,225.340924984985747],"luv":[61.3128540464897895,-17.5804418295499474,-17.7909131959243076],"rgb":[0.466666666666666674,0.6,0.66666666666666663],"xyz":[0.262532396269471724,0.29606096452582481,0.423627969969590734],"hpluv":[225.340924984985747,51.7645188682129742,61.3128540464897895],"hsluv":[225.340924984985747,40.6599304384258815,61.3128540464897895]},"#7799bb":{"lch":[61.9050111975332129,36.7727368637825478,241.108601392342877],"luv":[61.9050111975332129,-17.766782778670386,-32.1958942436537],"rgb":[0.466666666666666674,0.6,0.733333333333333282],"xyz":[0.279669988376808343,0.302916001368759569,0.513885955068232425],"hpluv":[241.108601392342877,75.37710856774234,61.9050111975332129],"hsluv":[241.108601392342877,44.3026829048042927,61.9050111975332129]},"#7799cc":{"lch":[62.5610290710097274,50.0883036089361084,248.973595844380469],"luv":[62.5610290710097274,-17.971590279241223,-46.7531827927901],"rgb":[0.466666666666666674,0.6,0.8],"xyz":[0.298962363820530097,0.31063295154624837,0.615492465738502581],"hpluv":[248.973595844380469,101.594866952252644,62.5610290710097274],"hsluv":[248.973595844380469,49.5852758814030068,62.5610290710097274]},"#7799dd":{"lch":[63.2800443412030518,63.9273589508424962,253.464421950176984],"luv":[63.2800443412030518,-18.1944086519195096,-61.2835272829234228],"rgb":[0.466666666666666674,0.6,0.866666666666666696],"xyz":[0.320480689371163641,0.319240281766501877,0.728822313638508579],"hpluv":[253.464421950176984,128.191525099113591,63.2800443412030518],"hsluv":[253.464421950176984,65.7895471985927429,63.2800443412030518]},"#7799ee":{"lch":[64.0607982423263138,77.8622331281598292,256.304567564122067],"luv":[64.0607982423263138,-18.434716379612933,-75.6484539148497106],"rgb":[0.466666666666666674,0.6,0.933333333333333348],"xyz":[0.344292869637338406,0.328765153872971894,0.854233129707031802],"hpluv":[256.304567564122067,154.231767587931557,64.0607982423263138],"hsluv":[256.304567564122067,82.5871459557978085,64.0607982423263138]},"#7799ff":{"lch":[64.9016907971027,91.67329289213788,258.23504341307023],"luv":[64.9016907971027,-18.6919383586334327,-89.7474460365571929],"rgb":[0.466666666666666674,0.6,1],"xyz":[0.370463918047169771,0.339233573236904618,0.992067317998813758],"hpluv":[258.23504341307023,179.236372955016122,64.9016907971027],"hsluv":[258.23504341307023,99.9999999999984368,64.9016907971027]},"#660000":{"lch":[19.330201679573328,65.0080772249371819,12.1770506300617765],"luv":[19.330201679573328,63.5454254137925432,13.7123671721378795],"rgb":[0.4,0,0],"xyz":[0.0547936733227042463,0.0282529878070199789,0.00256845343700170745],"hpluv":[12.1770506300617765,426.746789183125202,19.330201679573328],"hsluv":[12.1770506300617765,100.000000000002217,19.330201679573328]},"#660011":{"lch":[19.4980803058243595,61.695772445130423,8.9911342856641614],"luv":[19.4980803058243595,60.9376877881905799,9.641916024853316],"rgb":[0.4,0,0.0666666666666666657],"xyz":[0.0558053388223413716,0.0286576540068748317,0.0078965584017573389],"hpluv":[8.9911342856641614,401.51602003210553,19.4980803058243595],"hsluv":[8.9911342856641614,99.9999999999966178,19.4980803058243595]},"#660022":{"lch":[19.8051492014688648,56.728751528179842,2.87530221933591967],"luv":[19.8051492014688648,56.6573341637173584,2.84565201787440492],"rgb":[0.4,0,0.133333333333333331],"xyz":[0.0576806969608183867,0.029407797262265653,0.0177734445977365332],"hpluv":[2.87530221933591967,363.466537566247382,19.8051492014688648],"hsluv":[2.87530221933591967,99.9999999999968594,19.8051492014688648]},"#660033":{"lch":[20.2995520444984123,51.2727836305606957,352.516911450402631],"luv":[20.2995520444984123,50.836110988726972,-6.67743669143524787],"rgb":[0.4,0,0.2],"xyz":[0.0607684476932761272,0.0306428975552487659,0.0340355984553476765],"hpluv":[352.516911450402631,320.508659944055125,20.2995520444984123],"hsluv":[352.516911450402631,99.9999999999973852,20.2995520444984123]},"#660044":{"lch":[20.9904438433464762,47.7800185043531087,338.095292373375855],"luv":[20.9904438433464762,44.3305689635839855,-17.8250055719836844],"rgb":[0.4,0,0.266666666666666663],"xyz":[0.0652264429374950078,0.0324260956529363389,0.057514373408234315],"hpluv":[338.095292373375855,288.844444062118953,20.9904438433464762],"hsluv":[338.095292373375855,99.999999999997911,20.9904438433464762]},"#660055":{"lch":[21.8759682447435324,48.0792454528985687,322.009867044845],"luv":[21.8759682447435324,37.8920594608334085,-29.5940141436867741],"rgb":[0.4,0,0.333333333333333315],"xyz":[0.071188856976857,0.0348110612686811718,0.0889164206822082304],"hpluv":[322.009867044845,278.887908627948889,21.8759682447435324],"hsluv":[322.009867044845,99.9999999999984,21.8759682447435324]},"#660066":{"lch":[22.9458380566939866,52.2668983658326383,307.715012949243601],"luv":[22.9458380566939866,31.9734565677830815,-41.3464235441515271],"rgb":[0.4,0,0.4],"xyz":[0.0787738527503651781,0.0378450595780844834,0.128864065089352192],"hpluv":[307.715012949243601,289.042783730483393,22.9458380566939866],"hsluv":[307.715012949243601,99.9999999999988,22.9458380566939866]},"#660077":{"lch":[24.1840444716539054,59.1802438936044553,296.875135467660698],"luv":[24.1840444716539054,26.7522904844618061,-52.7884099129864097],"rgb":[0.4,0,0.466666666666666674],"xyz":[0.0880878657705671,0.0415706647861653,0.177917866995750101],"hpluv":[296.875135467660698,310.518260327731298,24.1840444716539054],"hsluv":[296.875135467660698,99.9999999999992326,24.1840444716539054]},"#660088":{"lch":[25.5714349826340381,67.6035320092512819,289.201479741547303],"luv":[25.5714349826340381,22.2341957091879898,-63.8426039670327725],"rgb":[0.4,0,0.533333333333333326],"xyz":[0.0992282828725109256,0.0460268316269428907,0.236590730399322269],"hpluv":[289.201479741547303,335.469941782198191,25.5714349826340381],"hsluv":[289.201479741547303,99.9999999999995168,25.5714349826340381]},"#660099":{"lch":[27.0878540213863559,76.7583277742970296,283.827270614430063],"luv":[27.0878540213863559,18.3449067131383,-74.5339203342523291],"rgb":[0.4,0,0.6],"xyz":[0.112285246981583625,0.0512496172705720551,0.305357408040440148],"hpluv":[283.827270614430063,359.575614235331898,27.0878540213863559],"hsluv":[283.827270614430063,99.9999999999996732,27.0878540213863559]},"#6600aa":{"lch":[28.7136916664512327,86.2331190336617226,280.0081392435834],"luv":[28.7136916664512327,14.9862877024472088,-84.9209161465722246],"rgb":[0.4,0,0.66666666666666663],"xyz":[0.127342939946836181,0.0572726944566731566,0.384661257657438749],"hpluv":[280.0081392435834,381.087223541781498,28.7136916664512327],"hsluv":[280.0081392435834,99.9999999999998863,28.7136916664512327]},"#6600bb":{"lch":[30.4308478844127208,95.8259209373334784,277.232006261077231],"luv":[30.4308478844127208,12.063278317584528,-95.06358103774852],"rgb":[0.4,0,0.733333333333333282],"xyz":[0.144480532054172828,0.0641277312996079152,0.474919242756080495],"hpluv":[277.232006261077231,399.584170303460496,30.4308478844127208],"hsluv":[277.232006261077231,100.000000000000071,30.4308478844127208]},"#6600cc":{"lch":[32.2232190058254631,105.440117399912424,275.16595430901134],"luv":[32.2232190058254631,9.49391256045434,-105.011827817640437],"rgb":[0.4,0,0.8],"xyz":[0.163772907497894554,0.0718446814770967168,0.576525753426350707],"hpluv":[275.16595430901134,415.218107165999243,32.2232190058254631],"hsluv":[275.16595430901134,100.000000000000284,32.2232190058254631]},"#6600dd":{"lch":[34.0768449366564425,115.029794578821409,273.594219506454294],"luv":[34.0768449366564425,7.21119822634443164,-114.803537667557165],"rgb":[0.4,0,0.866666666666666696],"xyz":[0.185291233048528098,0.0804520116973502508,0.689855601326356704],"hpluv":[273.594219506454294,428.341637585051217,34.0768449366564425],"hsluv":[273.594219506454294,100.000000000000313,34.0768449366564425]},"#6600ee":{"lch":[35.9798440153965657,124.573148355199,272.374748889870204],"luv":[35.9798440153965657,5.16172842086039729,-124.466163477612255],"rgb":[0.4,0,0.933333333333333348],"xyz":[0.209103413314702835,0.0899768838038202817,0.815266417394879928],"hpluv":[272.374748889870204,439.343788723350144,35.9798440153965657],"hsluv":[272.374748889870204,100.000000000000313,35.9798440153965657]},"#6600ff":{"lch":[37.9222328155672699,134.059876636217865,271.411957283269032],"luv":[37.9222328155672699,3.30334385288953181,-134.01917192367489],"rgb":[0.4,0,1],"xyz":[0.235274461724534228,0.100445303167752992,0.953100605686661773],"hpluv":[271.411957283269032,448.58447779597617,37.9222328155672699],"hsluv":[271.411957283269032,100.00000000000054,37.9222328155672699]},"#661100":{"lch":[20.9278595225824304,60.6482483509225645,15.3961031612090817],"luv":[20.9278595225824304,58.4717927536604165,16.1015365791022269],"rgb":[0.4,0.0666666666666666657,0],"xyz":[0.0567980735836326536,0.0322617883288768559,0.00323658685731115833],"hpluv":[15.3961031612090817,367.733145903292666,20.9278595225824304],"hsluv":[15.3961031612090817,100.00000000000216,20.9278595225824304]},"#661111":{"lch":[21.0816163302651134,57.5811303886473453,12.1770506300618102],"luv":[21.0816163302651134,56.2855814623301782,12.1457768908291825],"rgb":[0.4,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0578097390832697788,0.0326664545287317087,0.00856469182206678892],"hpluv":[12.1770506300618102,346.589664487627374,21.0816163302651134],"hsluv":[12.1770506300618102,81.2167011616125762,21.0816163302651134]},"#661122":{"lch":[21.363314856368774,52.932385078801687,5.93410154371749865],"luv":[21.363314856368774,52.6487447994206548,5.4723908098767966],"rgb":[0.4,0.0666666666666666657,0.133333333333333331],"xyz":[0.059685097221746794,0.0334165977841225301,0.018441578018045985],"hpluv":[5.93410154371749865,314.406957937895,21.363314856368774],"hsluv":[5.93410154371749865,82.5199513610387356,21.363314856368774]},"#661133":{"lch":[21.8180817632255923,47.7742586248590229,355.183549580278111],"luv":[21.8180817632255923,47.6055578330604661,-4.01131531521171425],"rgb":[0.4,0.0666666666666666657,0.2],"xyz":[0.0627728479542045414,0.0346516980771056429,0.0347037318756571317],"hpluv":[355.183549580278111,277.854041301729922,21.8180817632255923],"hsluv":[355.183549580278111,84.3121175303292603,21.8180817632255923]},"#661144":{"lch":[22.4559756968324393,44.5402485804784689,339.935360677682411],"luv":[22.4559756968324393,41.8369301419790247,-15.2808710453946635],"rgb":[0.4,0.0666666666666666657,0.266666666666666663],"xyz":[0.0672308431984234151,0.036434896174793216,0.0581825068285437702],"hpluv":[339.935360677682411,251.686564911624259,22.4559756968324393],"hsluv":[339.935360677682411,86.3348863624116518,22.4559756968324393]},"#661155":{"lch":[23.2773926977910151,45.1903944783221903,322.792583995755933],"luv":[23.2773926977910151,35.9919645110905364,-27.3267313035930464],"rgb":[0.4,0.0666666666666666657,0.333333333333333315],"xyz":[0.073193257237785414,0.0388198617905380489,0.0895845541025176717],"hpluv":[322.792583995755933,246.349182588766354,23.2773926977910151],"hsluv":[322.792583995755933,88.344826800164725,23.2773926977910151]},"#661166":{"lch":[24.275087751098269,49.8658315110702119,307.715012949243715],"luv":[24.275087751098269,30.5046415204515107,-39.4470277460696508],"rgb":[0.4,0.0666666666666666657,0.4],"xyz":[0.0807782530112935854,0.0418538600999413604,0.129532198509661634],"hpluv":[307.715012949243715,260.664316843383688,24.275087751098269],"hsluv":[307.715012949243715,90.1819147598703239,24.275087751098269]},"#661177":{"lch":[25.4363091503391701,57.3032374709331265,296.512546946797],"luv":[25.4363091503391701,25.5798087859014238,-51.2770358652572114],"rgb":[0.4,0.0666666666666666657,0.466666666666666674],"xyz":[0.0900922660314955,0.0455794653080221768,0.178586000416059543],"hpluv":[296.512546946797,285.867241464858182,25.4363091503391701],"hsluv":[296.512546946797,91.7740463972148461,25.4363091503391701]},"#661188":{"lch":[26.7449145171680129,66.1973281861227179,288.734792076243366],"luv":[26.7449145171680129,21.2617948521868456,-62.6898902427238127],"rgb":[0.4,0.0666666666666666657,0.533333333333333326],"xyz":[0.101232683133439333,0.0500356321487997746,0.23725886381963171],"hpluv":[288.734792076243366,314.078764213635395,26.7449145171680129],"hsluv":[288.734792076243366,93.110372692245349,26.7449145171680129]},"#661199":{"lch":[28.1832309630650286,75.7381406209258614,283.36677781159608],"luv":[28.1832309630650286,17.5094321789343716,-73.6864012521064637],"rgb":[0.4,0.0666666666666666657,0.6],"xyz":[0.114289647242512032,0.0552584177924289321,0.306025541460749617],"hpluv":[283.36677781159608,341.006914961476241,28.1832309630650286],"hsluv":[283.36677781159608,94.2123428080992,28.1832309630650286]},"#6611aa":{"lch":[29.733500038717203,85.5146667147819102,279.591039159426828],"luv":[29.733500038717203,14.2479867443400359,-84.3193518539685],"rgb":[0.4,0.0666666666666666657,0.66666666666666663],"xyz":[0.129347340207764588,0.0612814949785300336,0.385329391077748218],"hpluv":[279.591039159426828,364.950446526832081,29.733500038717203],"hsluv":[279.591039159426828,95.1136535912152254,29.733500038717203]},"#6611bb":{"lch":[31.378866229854367,95.3367425151459287,276.866082014695],"luv":[31.378866229854367,11.3974241300945351,-94.6530147253534153],"rgb":[0.4,0.0666666666666666657,0.733333333333333282],"xyz":[0.146484932315101235,0.0681365318214647853,0.475587376176389964],"hpluv":[276.866082014695,385.533736621086632,31.378866229854367],"hsluv":[276.866082014695,95.8493220980777636,31.378866229854367]},"#6611cc":{"lch":[33.1039576367877899,105.121866511028642,274.848446148865946],"luv":[33.1039576367877899,8.88494143701037409,-104.745714157780327],"rgb":[0.4,0.0666666666666666657,0.8],"xyz":[0.165777307758822962,0.0758534819989535869,0.577193886846660176],"hpluv":[274.848446148865946,402.951217622234481,33.1039576367877899],"hsluv":[274.848446148865946,96.4508528344463372,33.1039576367877899]},"#6611dd":{"lch":[34.8951509835915559,114.837148656435488,273.319244536407894],"luv":[34.8951509835915559,6.64899595047804048,-114.644500803094743],"rgb":[0.4,0.0666666666666666657,0.866666666666666696],"xyz":[0.187295633309456505,0.0844608122192071209,0.690523734746666173],"hpluv":[273.319244536407894,417.596303228590671,34.8951509835915559],"hsluv":[273.319244536407894,96.944722371929771,34.8951509835915559]},"#6611ee":{"lch":[36.7406193088150914,124.471664845310258,272.136065946829319],"luv":[36.7406193088150914,4.63940101804097527,-124.385173182164465],"rgb":[0.4,0.0666666666666666657,0.933333333333333348],"xyz":[0.211107813575631242,0.0939856843256771657,0.815934550815189397],"hpluv":[272.136065946829319,429.895948632666091,36.7406193088150914],"hsluv":[272.136065946829319,97.3524117238680446,36.7406193088150914]},"#6611ff":{"lch":[38.6302462525687815,134.023748920536207,271.203906716280642],"luv":[38.6302462525687815,2.81591803113255,-133.994163605572282],"rgb":[0.4,0.0666666666666666657,1],"xyz":[0.237278861985462636,0.104454103689609862,0.953768739106971242],"hpluv":[271.203906716280642,440.244168299440901,38.6302462525687815],"hsluv":[271.203906716280642,99.999999999999531,38.6302462525687815]},"#662200":{"lch":[23.5697003211059126,54.0433218319152,21.7646438431993481],"luv":[23.5697003211059126,50.1908335966774928,20.038983444740694],"rgb":[0.4,0.133333333333333331,0],"xyz":[0.0605136973184005889,0.0396930357984128235,0.00447512810223376842],"hpluv":[21.7646438431993481,290.955989204018863,23.5697003211059126],"hsluv":[21.7646438431993481,100.000000000002302,23.5697003211059126]},"#662211":{"lch":[23.7037155268300239,51.2256671637292627,18.5481266113504795],"luv":[23.7037155268300239,48.5648418325832196,16.2949413667354186],"rgb":[0.4,0.133333333333333331,0.0666666666666666657],"xyz":[0.0615253628180377071,0.0400977019982676763,0.0098032330669894],"hpluv":[18.5481266113504795,274.227196288753476,23.7037155268300239],"hsluv":[18.5481266113504795,84.4421944630679775,23.7037155268300239]},"#662222":{"lch":[23.9497782760704823,46.8639841586094761,12.177050630061828],"luv":[23.9497782760704823,45.8095660888384515,9.88517404858116],"rgb":[0.4,0.133333333333333331,0.133333333333333331],"xyz":[0.0634007209565147362,0.0408478452536585,0.0196801192629685942],"hpluv":[12.177050630061828,248.300181449835577,23.9497782760704823],"hsluv":[12.177050630061828,58.184428739378582,23.9497782760704823]},"#662233":{"lch":[24.3484354577474491,41.8866591548313139,0.79920805816821483],"luv":[24.3484354577474491,41.8825842907357284,0.584250188216085209],"rgb":[0.4,0.133333333333333331,0.2],"xyz":[0.0664884716889724697,0.0420829455466416105,0.0359422731205797374],"hpluv":[0.79920805816821483,218.295100847162672,24.3484354577474491],"hsluv":[0.79920805816821483,61.8388407102714908,24.3484354577474491]},"#662244":{"lch":[24.9104705449366364,38.7518995195090881,343.921953822216381],"luv":[24.9104705449366364,37.2361321960480467,-10.7322027305005232],"rgb":[0.4,0.133333333333333331,0.266666666666666663],"xyz":[0.0709464669331913433,0.0438661436443291836,0.059421048073466376],"hpluv":[343.921953822216381,197.40147375767063,24.9104705449366364],"hsluv":[343.921953822216381,66.1143919991375,24.9104705449366364]},"#662255":{"lch":[25.6388481254070371,39.7515606661792376,324.488651014584605],"luv":[25.6388481254070371,32.3577893991285421,-23.0902585650003651],"rgb":[0.4,0.133333333333333331,0.333333333333333315],"xyz":[0.0769088809725533423,0.0462511092600740165,0.0908230953474402913],"hpluv":[324.488651014584605,196.74105716675524,25.6388481254070371],"hsluv":[324.488651014584605,70.5303777194930746,25.6388481254070371]},"#662266":{"lch":[26.530115175026431,45.1550068711170525,307.715012949244],"luv":[26.530115175026431,27.6228683191850166,-35.7204674010796381],"rgb":[0.4,0.133333333333333331,0.4],"xyz":[0.0844938767460615137,0.049285107569477328,0.130770739754584253],"hpluv":[307.715012949244,215.976303505553034,26.530115175026431],"hsluv":[307.715012949244,74.7212231760600076,26.530115175026431]},"#662277":{"lch":[27.5758503181253047,53.47184404785515,295.772994892671647],"luv":[27.5758503181253047,23.2499163509258366,-48.1526686233805137],"rgb":[0.4,0.133333333333333331,0.466666666666666674],"xyz":[0.0938078897662634331,0.0530107127775581444,0.179824541660982162],"hpluv":[295.772994892671647,246.056915236342576,27.5758503181253047],"hsluv":[295.772994892671647,78.4792949436714622,27.5758503181253047]},"#662288":{"lch":[28.7641691288539221,63.1969785740596492,287.807032602413699],"luv":[28.7641691288539221,19.3264050913403267,-60.169329123196718],"rgb":[0.4,0.133333333333333331,0.533333333333333326],"xyz":[0.104948306868207261,0.0574668796183357422,0.23849740506455433],"hpluv":[287.807032602413699,278.794247273594806,28.7641691288539221],"hsluv":[287.807032602413699,81.7283139306751565,28.7641691288539221]},"#662299":{"lch":[30.081149723697223,73.446586603294,282.467625610713],"luv":[30.081149723697223,15.8562317990126083,-71.7145800853016766],"rgb":[0.4,0.133333333333333331,0.6],"xyz":[0.118005270977279975,0.0626896652619649,0.307264082705672237],"hpluv":[282.467625610713,309.825038390781458,30.081149723697223],"hsluv":[282.467625610713,84.475317587044259,30.081149723697223]},"#6622aa":{"lch":[31.512047889249807,83.7990879252892569,278.786617054458873],"luv":[31.512047889249807,12.8007301136733549,-82.8156292354725565],"rgb":[0.4,0.133333333333333331,0.66666666666666663],"xyz":[0.133062963942532531,0.068712742448066,0.386567932322670837],"hpluv":[278.786617054458873,337.444217562648532,31.512047889249807],"hsluv":[278.786617054458873,86.7692530837111349,31.512047889249807]},"#6622bb":{"lch":[33.0422299311305281,94.07636648958254,276.16643073789237],"luv":[33.0422299311305281,10.1053888262289746,-93.5320471739658643],"rgb":[0.4,0.133333333333333331,0.733333333333333282],"xyz":[0.150200556049869149,0.0755677792910007529,0.476825917421312584],"hpluv":[276.16643073789237,361.285484259324733,33.0422299311305281],"hsluv":[276.16643073789237,88.6739591516067662,33.0422299311305281]},"#6622cc":{"lch":[34.6578144612334853,104.214655833315277,274.245119058655746],"luv":[34.6578144612334853,7.71433729467952212,-103.928742369761551],"rgb":[0.4,0.133333333333333331,0.8],"xyz":[0.169492931493590904,0.0832847294684895545,0.578432428091582684],"hpluv":[274.245119058655746,381.563613242959605,34.6578144612334853],"hsluv":[274.245119058655746,90.2534916489383079,34.6578144612334853]},"#6622dd":{"lch":[36.346058304563158,114.200305800004017,272.799119030217753],"luv":[36.346058304563158,5.5769048208672336,-114.064052082299],"rgb":[0.4,0.133333333333333331,0.866666666666666696],"xyz":[0.191011257044224447,0.0918920596887430885,0.691762275991588682],"hpluv":[272.799119030217753,398.702789727268566,36.346058304563158],"hsluv":[272.799119030217753,91.5654894217155118,36.346058304563158]},"#6622ee":{"lch":[38.0955422395423,124.039689220569301,271.686141036519132],"luv":[38.0955422395423,3.64980151132168062,-123.985980864222597],"rgb":[0.4,0.133333333333333331,0.933333333333333348],"xyz":[0.214823437310399185,0.101416931795213133,0.817173092060111905],"hpluv":[271.686141036519132,413.167199445381073,38.0955422395423],"hsluv":[271.686141036519132,92.6590152569973498,38.0955422395423]},"#6622ff":{"lch":[39.8962147757429264,133.745689778340022,270.812765394378914],"luv":[39.8962147757429264,1.89717678294479941,-133.732233416399],"rgb":[0.4,0.133333333333333331,1],"xyz":[0.240994485720230578,0.111885351159145829,0.95500728035189375],"hpluv":[270.812765394378914,425.390148773484384,39.8962147757429264],"hsluv":[270.812765394378914,99.99999999999946,39.8962147757429264]},"#ddaa00":{"lch":[72.3107430320736881,86.5721801417344494,59.9465914104400071],"luv":[72.3107430320736881,43.355958426121056,74.9333253195491267],"rgb":[0.866666666666666696,0.66666666666666663,0],"xyz":[0.441922241377765923,0.441231641500849037,0.0618909005679976823],"hpluv":[59.9465914104400071,151.919966798177825,72.3107430320736881],"hsluv":[59.9465914104400071,100.000000000002402,72.3107430320736881]},"#ddaa11":{"lch":[72.3377322217577188,85.4954146103564625,59.6744594052448178],"luv":[72.3377322217577188,43.1676990261245663,73.7971251485224],"rgb":[0.866666666666666696,0.66666666666666663,0.0666666666666666657],"xyz":[0.442933906877403,0.44163630770070389,0.067219005532753312],"hpluv":[59.6744594052448178,149.974443711406025,72.3377322217577188],"hsluv":[59.6744594052448178,98.5180859943944398,72.3377322217577188]},"#ddaa22":{"lch":[72.3877194091470386,83.5208789068112623,59.1557200492863586],"luv":[72.3877194091470386,42.8217010650181038,71.708013019916109],"rgb":[0.866666666666666696,0.66666666666666663,0.133333333333333331],"xyz":[0.444809265015880084,0.44238645095609469,0.0770958917287325],"hpluv":[59.1557200492863586,146.409577733002152,72.3877194091470386],"hsluv":[59.1557200492863586,95.7957425728033911,72.3877194091470386]},"#ddaa33":{"lch":[72.4698996386445771,80.3304907566891,58.2589820164620633],"luv":[72.4698996386445771,42.2603136650720543,68.3158373595774435],"rgb":[0.866666666666666696,0.66666666666666663,0.2],"xyz":[0.44789701574833779,0.443621551249077817,0.0933580455863436548],"hpluv":[58.2589820164620633,140.657238526484292,72.4698996386445771],"hsluv":[58.2589820164620633,91.3821490755410082,72.4698996386445771]},"#ddaa44":{"lch":[72.5882801580772679,75.8571050863154,56.8623293870095949],"luv":[72.5882801580772679,41.467485474955744,63.5196665644635701],"rgb":[0.866666666666666696,0.66666666666666663,0.266666666666666663],"xyz":[0.452355010992556705,0.445404749346765383,0.116836820539230293],"hpluv":[56.8623293870095949,132.607804442486071,72.5882801580772679],"hsluv":[56.8623293870095949,85.1564308385751332,72.5882801580772679]},"#ddaa55":{"lch":[72.7461171317656579,70.1198989219024469,54.780917696258733],"luv":[72.7461171317656579,40.4384565855633085,57.2846528644045065],"rgb":[0.866666666666666696,0.66666666666666663,0.333333333333333315],"xyz":[0.45831742503191869,0.447789714962510244,0.148238867813204195],"hpluv":[54.780917696258733,122.3124851735341,72.7461171317656579],"hsluv":[54.780917696258733,77.0893717991816345,72.7461171317656579]},"#ddaa66":{"lch":[72.9460991959627307,63.2340905833455835,51.7145858463931702],"luv":[72.9460991959627307,39.17852917707404,49.6345954292357661],"rgb":[0.866666666666666696,0.66666666666666663,0.4],"xyz":[0.465902420805426876,0.450823713271913562,0.188186512220348157],"hpluv":[51.7145858463931702,109.998947735143361,72.9460991959627307],"hsluv":[51.7145858463931702,67.2337497701281421,72.9460991959627307]},"#ddaa77":{"lch":[73.1904440644495651,55.4382228560327377,47.150998877343909],"luv":[73.1904440644495651,37.7017926183457632,40.6444508733775294],"rgb":[0.866666666666666696,0.66666666666666663,0.466666666666666674],"xyz":[0.475216433825628781,0.454549318479994358,0.237240314126746066],"hpluv":[47.150998877343909,96.1156803308001173,73.1904440644495651],"hsluv":[47.150998877343909,55.7140089565642214,73.1904440644495651]},"#ddaa88":{"lch":[73.4809558021361511,47.1613293807763228,40.1850915920125189],"luv":[73.4809558021361511,36.0295555463961819,30.4312687229965526],"rgb":[0.866666666666666696,0.66666666666666663,0.533333333333333326],"xyz":[0.486356850927572582,0.459005485320771955,0.295913177530318261],"hpluv":[40.1850915920125189,81.4424009312931645,73.4809558021361511],"hsluv":[40.1850915920125189,45.325944585658668,73.4809558021361511]},"#ddaa99":{"lch":[73.8190624606049539,39.1833139250455389,29.2463480703396321],"luv":[73.8190624606049539,34.1885051927702435,19.1436204212419021],"rgb":[0.866666666666666696,0.66666666666666663,0.6],"xyz":[0.499413815036645281,0.464228270964401113,0.36467985517143614],"hpluv":[29.2463480703396321,67.3553294964948,73.8190624606049539],"hsluv":[29.2463480703396321,46.1073405736803323,73.8190624606049539]},"#ddaaaa":{"lch":[74.2058435914849923,32.9500913661112946,12.1770506300625296],"luv":[74.2058435914849923,32.2087294789219527,6.95027095793437244],"rgb":[0.866666666666666696,0.66666666666666663,0.66666666666666663],"xyz":[0.514471508001897893,0.470251348150502235,0.443983704788434741],"hpluv":[12.1770506300625296,56.3453191386000114,74.2058435914849923],"hsluv":[12.1770506300625296,46.9171896008106,74.2058435914849923]},"#ddaabb":{"lch":[74.6420527030620633,30.7078714289026884,348.787813428378513],"luv":[74.6420527030620633,30.1217754775259223,-5.97093039446416807],"rgb":[0.866666666666666696,0.66666666666666663,0.733333333333333282],"xyz":[0.531609100109234456,0.477106384993437,0.534241689887076543],"hpluv":[348.787813428378513,52.2042025244198,74.6420527030620633],"hsluv":[348.787813428378513,47.7320050944543937,74.6420527030620633]},"#ddaacc":{"lch":[75.1281375044867445,34.0548346014018435,325.184688201169763],"luv":[75.1281375044867445,27.9589055182432595,-19.4430286208394669],"rgb":[0.866666666666666696,0.66666666666666663,0.8],"xyz":[0.55090147555295621,0.484823335170925795,0.635848200557346699],"hpluv":[325.184688201169763,57.5195499622066393,75.1281375044867445],"hsluv":[325.184688201169763,48.5278754329488109,75.1281375044867445]},"#ddaadd":{"lch":[75.6642595524878772,42.092894356631966,307.715012949247466],"luv":[75.6642595524878772,25.749668941594777,-33.2981426616688125],"rgb":[0.866666666666666696,0.66666666666666663,0.866666666666666696],"xyz":[0.572419801103589809,0.493430665391179302,0.749178048457352697],"hpluv":[307.715012949247466,70.5922995729826255,75.6642595524878772],"hsluv":[307.715012949247466,49.2811497501269855,75.6642595524878772]},"#ddaaee":{"lch":[76.2503141773092636,52.9001531738191915,296.399494755977059],"luv":[76.2503141773092636,23.5208512504545659,-47.3834967290038875],"rgb":[0.866666666666666696,0.66666666666666663,0.933333333333333348],"xyz":[0.596231981369764519,0.502955537497649319,0.87458886452587592],"hpluv":[296.399494755977059,89.1958388421213,76.2503141773092636],"hsluv":[296.399494755977059,73.8038640729286,76.2503141773092636]},"#ddaaff":{"lch":[76.8859510948180542,65.1444004641461447,289.080822119258073],"luv":[76.8859510948180542,21.295808093697417,-61.565261872824486],"rgb":[0.866666666666666696,0.66666666666666663,1],"xyz":[0.62240302977959594,0.513423956861582,1.01242305281765765],"hpluv":[289.080822119258073,113.514774922986319,76.8859510948180542],"hsluv":[289.080822119258073,99.9999999999968736,76.8859510948180542]},"#663300":{"lch":[27.2772702365161024,46.6784293424923,33.1138040531735385],"luv":[27.2772702365161024,39.0972512948193938,25.5006020923387098],"rgb":[0.4,0.2,0],"xyz":[0.0666314194074114075,0.0519284799764346272,0.00651436879857064926],"hpluv":[33.1138040531735385,217.147410386557254,27.2772702365161024],"hsluv":[33.1138040531735385,100.000000000002288,27.2772702365161024]},"#663311":{"lch":[27.3893959478715772,43.971204952951652,30.1269617465812196],"luv":[27.3893959478715772,38.0313691656755353,22.0699303215615963],"rgb":[0.4,0.2,0.0666666666666666657],"xyz":[0.0676430849070485257,0.0523331461762894801,0.0118424737633262799],"hpluv":[30.1269617465812196,203.716046393577358,27.3893959478715772],"hsluv":[30.1269617465812196,87.8713966090680572,27.3893959478715772]},"#663322":{"lch":[27.5957277293980781,39.608651287835805,23.9834802389854467],"luv":[27.5957277293980781,36.1889469500517436,16.0998563809655693],"rgb":[0.4,0.2,0.133333333333333331],"xyz":[0.0695184430455255548,0.0530832894316803,0.0217193599593054759],"hpluv":[23.9834802389854467,182.132533879714401,27.5957277293980781],"hsluv":[23.9834802389854467,66.9779468056010501,27.5957277293980781]},"#663333":{"lch":[27.9312558147072,34.2527069144242517,12.1770506300619683],"luv":[27.9312558147072,33.482036777055967,7.2250359324586606],"rgb":[0.4,0.2,0.2],"xyz":[0.0726061937779832883,0.0543183897246634143,0.0379815138169166192],"hpluv":[12.1770506300619683,155.612242967619039,27.9312558147072],"hsluv":[12.1770506300619683,36.4647718300342518,27.9312558147072]},"#663344":{"lch":[28.4068233476218452,30.4023991370198274,352.642674566889241],"luv":[28.4068233476218452,30.1520905841737843,-3.89323858637544307],"rgb":[0.4,0.2,0.266666666666666663],"xyz":[0.0770641890222021619,0.0561015878223509873,0.0614602887698032577],"hpluv":[352.642674566889241,135.807736934047625,28.4068233476218452],"hsluv":[352.642674566889241,42.3197568133242044,28.4068233476218452]},"#663355":{"lch":[29.027378781744666,31.164203729876963,328.257954430910445],"luv":[29.027378781744666,26.5028264215118483,-16.3953586660521324],"rgb":[0.4,0.2,0.333333333333333315],"xyz":[0.0830266030615641609,0.0584865534380958202,0.0928623360437771661],"hpluv":[328.257954430910445,136.234637721643935,29.027378781744666],"hsluv":[328.257954430910445,48.648881209958347,29.027378781744666]},"#663366":{"lch":[29.7928910898429251,37.2833882928919067,307.715012949244567],"luv":[29.7928910898429251,22.8075289246907325,-29.4935190668720466],"rgb":[0.4,0.2,0.4],"xyz":[0.0906115988350723323,0.0615205517474991317,0.132809980450921128],"hpluv":[307.715012949244567,158.796911496206434,29.7928910898429251],"hsluv":[307.715012949244567,54.9388950129523792,29.7928910898429251]},"#663377":{"lch":[30.6992208566667273,46.7654342463890345,294.320996437271049],"luv":[30.6992208566667273,19.2602655771695837,-42.6151148086008646],"rgb":[0.4,0.2,0.466666666666666674],"xyz":[0.0999256118552742517,0.0652461569555799481,0.181863782357319037],"hpluv":[294.320996437271049,193.302265796468333,30.6992208566667273],"hsluv":[294.320996437271049,60.8304716126584424,30.6992208566667273]},"#663388":{"lch":[31.7390466224972485,57.6768981875091811,286.074834637191429],"luv":[31.7390466224972485,15.9703082974272554,-55.4217812544619122],"rgb":[0.4,0.2,0.533333333333333326],"xyz":[0.11106602895721808,0.0697023237963575459,0.240536645760891205],"hpluv":[286.074834637191429,230.593651019326217,31.7390466224972485],"hsluv":[286.074834637191429,66.1275975958513,31.7390466224972485]},"#663399":{"lch":[32.9028065942714818,68.9918273860838696,280.844497617061506],"luv":[32.9028065942714818,12.9804074562249703,-67.7597319087197292],"rgb":[0.4,0.2,0.6],"xyz":[0.124122993066290793,0.0749251094399867,0.309303323402009112],"hpluv":[280.844497617061506,266.074975063872387,32.9028065942714818],"hsluv":[280.844497617061506,70.7618769362906761,32.9028065942714818]},"#6633aa":{"lch":[34.1795810026756612,80.2563017922262,277.366876751775067],"luv":[34.1795810026756612,10.2906460265496023,-79.5938225097975],"rgb":[0.4,0.2,0.66666666666666663],"xyz":[0.139180686031543321,0.0809481866260878,0.388607173019007712],"hpluv":[277.366876751775067,297.955725741163178,34.1795810026756612],"hsluv":[277.366876751775067,74.7463951454814293,34.1795810026756612]},"#6633bb":{"lch":[35.5578512622049701,91.2933310256451875,274.950579703742051],"luv":[35.5578512622049701,7.87828999249439477,-90.9527615663878208],"rgb":[0.4,0.2,0.733333333333333282],"xyz":[0.15631827813888,0.0878032234690225566,0.478865158117649459],"hpluv":[274.950579703742051,325.793841875348,35.5578512622049701],"hsluv":[274.950579703742051,78.1373397599298158,35.5578512622049701]},"#6633cc":{"lch":[37.0261004663704369,102.052471518039624,273.208108112313198],"luv":[37.0261004663704369,5.71114175070883,-101.892540467119574],"rgb":[0.4,0.2,0.8],"xyz":[0.175610653582601722,0.0955201736465113582,0.58047166878791967],"hpluv":[273.208108112313198,349.747708937339723,37.0261004663704369],"hsluv":[273.208108112313198,81.008127051099,37.0261004663704369]},"#6633dd":{"lch":[38.5732487885037258,112.538160698021628,271.912259810227567],"luv":[38.5732487885037258,3.75528971541350476,-112.475488051606391],"rgb":[0.4,0.2,0.866666666666666696],"xyz":[0.197128979133235266,0.104127503866764892,0.693801516687925668],"hpluv":[271.912259810227567,370.214070757058153,38.5732487885037258],"hsluv":[271.912259810227567,83.8924044294761,38.5732487885037258]},"#6633ee":{"lch":[40.1889386764538372,122.775879994578517,270.923585069715159],"luv":[40.1889386764538372,1.97901241536538453,-122.759929204537158],"rgb":[0.4,0.2,0.933333333333333348],"xyz":[0.22094115939941,0.113652375973234937,0.819212332756448891],"hpluv":[270.923585069715159,387.655406037674595,40.1889386764538372],"hsluv":[270.923585069715159,91.8481370725274502,40.1889386764538372]},"#6633ff":{"lch":[41.8636962738951581,132.796565847050772,270.152898062524457],"luv":[41.8636962738951581,0.354377123439640451,-132.796093005873018],"rgb":[0.4,0.2,1],"xyz":[0.247112207809241397,0.124120795337167633,0.957046521048230736],"hpluv":[270.152898062524457,402.521052726566381,41.8636962738951581],"hsluv":[270.152898062524457,99.9999999999993747,41.8636962738951581]},"#ddbb00":{"lch":[76.6269242453545871,86.8164471599593,69.4373142874166263],"luv":[76.6269242453545871,30.4927107526369845,81.2852390562642],"rgb":[0.866666666666666696,0.733333333333333282,0],"xyz":[0.475876739286364758,0.509140637318047595,0.0732090665375303],"hpluv":[69.4373142874166263,149.25100710879434,76.6269242453545871],"hsluv":[69.4373142874166263,100.000000000002373,76.6269242453545871]},"#ddbb11":{"lch":[76.6514577805917412,85.7837129406502754,69.2755127455160391],"luv":[76.6514577805917412,30.3566774947925779,80.2328956062352461],"rgb":[0.866666666666666696,0.733333333333333282,0.0666666666666666657],"xyz":[0.476888404786001863,0.509545303517902504,0.0785371715022859379],"hpluv":[69.2755127455160391,147.663405788509436,76.6514577805917412],"hsluv":[69.2755127455160391,98.710789014839,76.6514577805917412]},"#ddbb22":{"lch":[76.6969020797125722,83.8847347199512257,68.9672438614109353],"luv":[76.6969020797125722,30.1063672837106679,78.2959473281657523],"rgb":[0.866666666666666696,0.733333333333333282,0.133333333333333331],"xyz":[0.478763762924478919,0.510295446773293304,0.0884140576982651305],"hpluv":[68.9672438614109353,144.735860207932831,76.6969020797125722],"hsluv":[68.9672438614109353,96.3396664069398554,76.6969020797125722]},"#ddbb33":{"lch":[76.7716285455552452,80.8014056767331823,68.4347482297151828],"luv":[76.7716285455552452,29.6994133556607949,75.1452726767666093],"rgb":[0.866666666666666696,0.733333333333333282,0.2],"xyz":[0.481851513656936625,0.511530547066276431,0.104676211555876281],"hpluv":[68.4347482297151828,139.9591753538609,76.7716285455552452],"hsluv":[68.4347482297151828,92.4878111801133542,76.7716285455552452]},"#ddbb44":{"lch":[76.8793043130786771,76.4437058057830683,67.6060651816737277],"luv":[76.8793043130786771,29.122950030038453,70.6788082728408398],"rgb":[0.866666666666666696,0.733333333333333282,0.266666666666666663],"xyz":[0.486309508901155541,0.513313745163964,0.128154986508762919],"hpluv":[67.6060651816737277,133.157612926581692,76.8793043130786771],"hsluv":[67.6060651816737277,87.0382611213693167,76.8793043130786771]},"#ddbb55":{"lch":[77.0229278214451654,70.786451757311653,66.3713649049339551],"luv":[77.0229278214451654,28.3717024864450664,64.851894732620238],"rgb":[0.866666666666666696,0.733333333333333282,0.333333333333333315],"xyz":[0.492271922940517526,0.515698710779708747,0.159557033782736835],"hpluv":[66.3713649049339551,124.235507886155276,77.0229278214451654],"hsluv":[66.3713649049339551,79.9485715087726,77.0229278214451654]},"#ddbb66":{"lch":[77.2049977781888259,63.8693414267369732,64.5489675558404912],"luv":[77.2049977781888259,27.4471820183984,57.6710063509733359],"rgb":[0.866666666666666696,0.733333333333333282,0.4],"xyz":[0.499856918714025711,0.518732709089112065,0.199504678189880769],"hpluv":[64.5489675558404912,113.177180957201557,77.2049977781888259],"hsluv":[64.5489675558404912,71.2432689272834665,77.2049977781888259]},"#ddbb77":{"lch":[77.4276024714994264,55.80459657383539,61.8158033937064815],"luv":[77.4276024714994264,26.3569386858829375,49.1880552764299495],"rgb":[0.866666666666666696,0.733333333333333282,0.466666666666666674],"xyz":[0.509170931734227561,0.522458314297192916,0.248558480096278678],"hpluv":[61.8158033937064815,100.062778032150931,77.4276024714994264],"hsluv":[61.8158033937064815,61.00659046349368,77.4276024714994264]},"#ddbb88":{"lch":[77.6924726660212883,46.8021917196541537,57.5480835848938881],"luv":[77.6924726660212883,25.1136643841879952,39.4936578574539112],"rgb":[0.866666666666666696,0.733333333333333282,0.533333333333333326],"xyz":[0.520311348836171472,0.526914481137970458,0.307231343499850873],"hpluv":[57.5480835848938881,85.1204314231653285,77.6924726660212883],"hsluv":[57.5480835848938881,49.3735690170151145,77.6924726660212883]},"#ddbb99":{"lch":[78.001015952892,37.2494741955694195,50.4191367157405352],"luv":[78.001015952892,23.7341209657771088,28.7091419207933036],"rgb":[0.866666666666666696,0.733333333333333282,0.6],"xyz":[0.533368312945244116,0.532137266781599672,0.375998021140968752],"hpluv":[50.4191367157405352,68.8881727109007471,78.001015952892],"hsluv":[50.4191367157405352,37.2278198354843894,78.001015952892]},"#ddbbaa":{"lch":[78.3543411988951135,27.9779961680489,37.3601297670291643],"luv":[78.3543411988951135,22.2379488027189254,16.9776883770144309],"rgb":[0.866666666666666696,0.733333333333333282,0.66666666666666663],"xyz":[0.548426005910496728,0.538160343967700738,0.455301870757967353],"hpluv":[37.3601297670291643,52.7537881236722086,78.3543411988951135],"hsluv":[37.3601297670291643,37.9002282962103152,78.3543411988951135]},"#ddbbbb":{"lch":[78.7532777240269724,21.1216737069600953,12.1770506300632171],"luv":[78.7532777240269724,20.6464457718990104,4.45526398447083238],"rgb":[0.866666666666666696,0.733333333333333282,0.733333333333333282],"xyz":[0.565563598017833291,0.545015380810635497,0.545559855856609155],"hpluv":[12.1770506300632171,40.7192307977840144,78.7532777240269724],"hsluv":[12.1770506300632171,38.5653299871361952,78.7532777240269724]},"#ddbbcc":{"lch":[79.1983918483363425,20.8793784390591419,335.381067074864461],"luv":[79.1983918483363425,18.9814116783666442,-8.69795692664743747],"rgb":[0.866666666666666696,0.733333333333333282,0.8],"xyz":[0.584855973461555,0.552732330988124354,0.647166366526879311],"hpluv":[335.381067074864461,41.2776027841095186,79.1983918483363425],"hsluv":[335.381067074864461,39.1976988204569,79.1983918483363425]},"#ddbbdd":{"lch":[79.6900023594157858,28.2216267397768341,307.715012949250536],"luv":[79.6900023594157858,17.264138203128045,-22.325092338948604],"rgb":[0.866666666666666696,0.733333333333333282,0.866666666666666696],"xyz":[0.606374299012188644,0.56133966120837786,0.760496214426885309],"hpluv":[307.715012949250536,57.3946451248898555,79.6900023594157858],"hsluv":[307.715012949250536,39.7709084435557401,79.6900023594157858]},"#ddbbee":{"lch":[80.2281958041266,39.4567857635703447,293.154060026294076],"luv":[80.2281958041266,15.5145982189510505,-36.2785774927409221],"rgb":[0.866666666666666696,0.733333333333333282,0.933333333333333348],"xyz":[0.630186479278363354,0.570864533314847877,0.885907030495408532],"hpluv":[293.154060026294076,82.8233888781043674,80.2281958041266],"hsluv":[293.154060026294076,68.7191774169969278,80.2281958041266]},"#ddbbff":{"lch":[80.8128420975971409,52.2658591287574765,285.253756774661895],"luv":[80.8128420975971409,13.7508586713070624,-50.4245368473411],"rgb":[0.866666666666666696,0.733333333333333282,1],"xyz":[0.656357527688194775,0.581332952678780601,1.02374121878719038],"hpluv":[285.253756774661895,113.64059963508393,80.8128420975971409],"hsluv":[285.253756774661895,99.9999999999962768,80.8128420975971409]},"#664400":{"lch":[31.7142168878436834,41.7146560735594463,49.9018869072924431],"luv":[31.7142168878436834,26.8683448374877969,31.9093180282686859],"rgb":[0.4,0.266666666666666663,0],"xyz":[0.0754639898903774337,0.0695936209423669294,0.00945855895955924342],"hpluv":[49.9018869072924431,166.906788900061372,31.7142168878436834],"hsluv":[49.9018869072924431,100.000000000002103,31.7142168878436834]},"#664411":{"lch":[31.8065195391856221,38.988494662362406,47.7128576067384387],"luv":[31.8065195391856221,26.2332728657793552,28.8429906699465946],"rgb":[0.4,0.266666666666666663,0.0666666666666666657],"xyz":[0.0764756553900145519,0.0699982871422217823,0.0147866639243148749],"hpluv":[47.7128576067384387,155.546285842055198,31.8065195391856221],"hsluv":[47.7128576067384387,90.7993319288460157,31.8065195391856221]},"#664422":{"lch":[31.9766874661881033,34.3475437583520318,43.0092135947734064],"luv":[31.9766874661881033,25.116436032279772,23.4290077311931029],"rgb":[0.4,0.266666666666666663,0.133333333333333331],"xyz":[0.078351013528491581,0.0707484303976126,0.0246635501202940727],"hpluv":[43.0092135947734064,136.301783870263904,31.9766874661881033],"hsluv":[43.0092135947734064,74.6688439558526227,31.9766874661881033]},"#664433":{"lch":[32.2542649002247757,27.9288783689085562,32.9719795273007179],"luv":[32.2542649002247757,23.4305644913898661,15.1997004759998031],"rgb":[0.4,0.266666666666666663,0.2],"xyz":[0.0814387642609493145,0.0719835306905957095,0.0409257039779052159],"hpluv":[32.9719795273007179,109.876716511985933,32.2542649002247757],"hsluv":[32.9719795273007179,50.4508902462759465,32.2542649002247757]},"#664444":{"lch":[32.6494757012261942,21.7704999617243,12.1770506300622419],"luv":[32.6494757012261942,21.2806737346177428,4.59212303669972144],"rgb":[0.4,0.266666666666666663,0.266666666666666663],"xyz":[0.0858967595051681881,0.0737667287882832895,0.0644044789307918475],"hpluv":[12.1770506300622419,84.6119136876739,32.6494757012261942],"hsluv":[12.1770506300622419,19.8271939783404392,32.6494757012261942]},"#664455":{"lch":[33.1682230288457163,20.3425996427482829,337.72581918360828],"luv":[33.1682230288457163,18.8246474429619,-7.71064257201243208],"rgb":[0.4,0.266666666666666663,0.333333333333333315],"xyz":[0.0918591735445301871,0.0761516944040281224,0.0958065262047657629],"hpluv":[337.72581918360828,77.8257963773028649,33.1682230288457163],"hsluv":[337.72581918360828,26.9902218950403885,33.1682230288457163]},"#664466":{"lch":[33.8127168447387447,26.5268160416637819,307.715012949245931],"luv":[33.8127168447387447,16.2273642995468066,-20.9843898457416387],"rgb":[0.4,0.266666666666666663,0.4],"xyz":[0.0994441693180383585,0.0791856927134314409,0.135754170611909725],"hpluv":[307.715012949245931,99.5507152142919125,33.8127168447387447],"hsluv":[307.715012949245931,34.4415155187259359,33.8127168447387447]},"#664477":{"lch":[34.5819879544663067,37.1994974310500766,291.489286484323088],"luv":[34.5819879544663067,13.6271894146704895,-34.6136146303646512],"rgb":[0.4,0.266666666666666663,0.466666666666666674],"xyz":[0.108758182338240278,0.0829112979215122503,0.184807972518307634],"hpluv":[291.489286484323088,136.49804898345451,34.5819879544663067],"hsluv":[291.489286484323088,41.7425383187140824,34.5819879544663067]},"#664488":{"lch":[35.4724176022540263,49.4256461635840623,283.003444619748336],"luv":[35.4724176022540263,11.1212465051830698,-48.1582015326441066],"rgb":[0.4,0.266666666666666663,0.533333333333333326],"xyz":[0.119898599440184106,0.0873674647622898481,0.243480835921879801],"hpluv":[283.003444619748336,176.807585609029246,35.4724176022540263],"hsluv":[283.003444619748336,48.5905204317402166,35.4724176022540263]},"#664499":{"lch":[36.4782980897457563,61.9753280698008169,278.131406705371774],"luv":[36.4782980897457563,8.76603164871553453,-61.3522450974139844],"rgb":[0.4,0.266666666666666663,0.6],"xyz":[0.132955563549256806,0.092590250405919,0.312247513562997736],"hpluv":[278.131406705371774,215.5875082467536,36.4782980897457563],"hsluv":[278.131406705371774,54.8155424382278511,36.4782980897457563]},"#6644aa":{"lch":[37.5923984663849922,74.3597011725147468,275.081334091822],"luv":[37.5923984663849922,6.58602388672208239,-74.0674655150911576],"rgb":[0.4,0.266666666666666663,0.66666666666666663],"xyz":[0.148013256514509361,0.0986133275920201,0.391551363179996281],"hpluv":[275.081334091822,251.001852587777108,37.5923984663849922],"hsluv":[275.081334091822,60.3520360208115179,37.5923984663849922]},"#6644bb":{"lch":[38.8064988843830392,86.3901107279874765,273.04172423936518],"luv":[38.8064988843830392,4.58413310153298603,-86.2684006766171905],"rgb":[0.4,0.266666666666666663,0.733333333333333282],"xyz":[0.165150848621846,0.105468364434954859,0.481809348278638083],"hpluv":[273.04172423936518,282.487278503057098,38.8064988843830392],"hsluv":[273.04172423936518,65.2044789549227346,38.8064988843830392]},"#6644cc":{"lch":[40.1118623747323184,98.0126069922284415,271.608181870646],"luv":[40.1118623747323184,2.75066337520804938,-97.9740015535209],"rgb":[0.4,0.266666666666666663,0.8],"xyz":[0.184443224065567735,0.11318531461244366,0.583415858948908239],"hpluv":[271.608181870646,310.061926380003911,40.1118623747323184],"hsluv":[271.608181870646,73.249037078124374,40.1118623747323184]},"#6644dd":{"lch":[41.4996246628331491,109.23540368219534,270.561113733160255],"luv":[41.4996246628331491,1.06975602599714947,-109.230165429047204],"rgb":[0.4,0.266666666666666663,0.866666666666666696],"xyz":[0.205961549616201278,0.121792644832697194,0.696745706848914237],"hpluv":[270.561113733160255,334.009312605211903,41.4996246628331491],"hsluv":[270.561113733160255,82.0982912580276434,41.4996246628331491]},"#6644ee":{"lch":[42.9610953823040305,120.093362966476874,269.772657810053431],"luv":[42.9610953823040305,-0.476513570908160711,-120.092417593346411],"rgb":[0.4,0.266666666666666663,0.933333333333333348],"xyz":[0.229773729882376043,0.131317516939167239,0.82215652291743746],"hpluv":[269.772657810053431,354.717803858999673,42.9610953823040305],"hsluv":[269.772657810053431,90.971694410809846,42.9610953823040305]},"#6644ff":{"lch":[44.4879743720372502,130.630057251556309,269.16406595263021],"luv":[44.4879743720372502,-1.90579898569535566,-130.61615439053088],"rgb":[0.4,0.266666666666666663,1],"xyz":[0.255944778292207409,0.141785936303099935,0.959990711209219305],"hpluv":[269.16406595263021,372.597392941492103,44.4879743720372502],"hsluv":[269.16406595263021,99.9999999999993463,44.4879743720372502]},"#ddcc00":{"lch":[81.0484811072975475,89.5621409057231119,78.2088923998372394],"luv":[81.0484811072975475,18.3014975440108643,87.6723004789036224],"rgb":[0.866666666666666696,0.8,0],"xyz":[0.514100482595981623,0.585588123937282434,0.0859503143074022424],"hpluv":[78.2088923998372394,197.564965691755532,81.0484811072975475],"hsluv":[78.2088923998372394,100.000000000002245,81.0484811072975475]},"#ddcc11":{"lch":[81.070830830397739,88.588371741804238,78.1407504993947413],"luv":[81.070830830397739,18.2056357525625714,86.6974880530521261],"rgb":[0.866666666666666696,0.8,0.0666666666666666657],"xyz":[0.515112148095618783,0.585992790137137343,0.0912784192721578791],"hpluv":[78.1407504993947413,195.686226016320433,81.070830830397739],"hsluv":[78.1407504993947413,98.8754134531589699,81.070830830397739]},"#ddcc22":{"lch":[81.1122340585289265,86.7947856050049751,78.0111959233441894],"luv":[81.1122340585289265,18.0290607078827385,84.9016358983162149],"rgb":[0.866666666666666696,0.8,0.133333333333333331],"xyz":[0.516987506234095728,0.586742933392528143,0.101155305468137072],"hpluv":[78.0111959233441894,192.214732219338657,81.1122340585289265],"hsluv":[78.0111959233441894,96.8049917221618443,81.1122340585289265]},"#ddcc33":{"lch":[81.1803270736657367,83.8738846457710139,77.7882255314295747],"luv":[81.1803270736657367,17.7414783140301893,81.9760237679585089],"rgb":[0.866666666666666696,0.8,0.2],"xyz":[0.520075256966553545,0.58797803368551127,0.117417459325748208],"hpluv":[77.7882255314295747,186.530107062901806,81.1803270736657367],"hsluv":[77.7882255314295747,93.4358723678778631,81.1803270736657367]},"#ddcc44":{"lch":[81.2784695635313312,79.7261575767135469,77.443216014682],"luv":[81.2784695635313312,17.3330313363216426,77.8191893214074213],"rgb":[0.866666666666666696,0.8,0.266666666666666663],"xyz":[0.524533252210772405,0.589761231783198836,0.140896234278634847],"hpluv":[77.443216014682,178.389435414851135,81.2784695635313312],"hsluv":[77.443216014682,88.6570950843060643,81.2784695635313312]},"#ddcc55":{"lch":[81.4094229919429893,74.303525235023784,76.9333685993953509],"luv":[81.4094229919429893,16.7988406729037365,72.37964364652683],"rgb":[0.866666666666666696,0.8,0.333333333333333315],"xyz":[0.530495666250134335,0.592146197398943586,0.172298281552608762],"hpluv":[76.9333685993953509,167.620308244181615,81.4094229919429893],"hsluv":[76.9333685993953509,82.4185745103993668,81.4094229919429893]},"#ddcc66":{"lch":[81.5755062452221154,67.6049359495878406,76.1891492108976252],"luv":[81.5755062452221154,16.1384724175358123,65.6504156329288548],"rgb":[0.866666666666666696,0.8,0.4],"xyz":[0.538080662023642575,0.595180195708346904,0.212245925959752724],"hpluv":[76.1891492108976252,154.10859642349061,81.5755062452221154],"hsluv":[76.1891492108976252,74.724981631947216,81.5755062452221154]},"#ddcc77":{"lch":[81.7786782860545571,59.6741108071854,75.0887439649445554],"luv":[81.7786782860545571,15.3554995822328237,57.6646176889111857],"rgb":[0.866666666666666696,0.8,0.466666666666666674],"xyz":[0.547394675043844425,0.598905800916427755,0.261299727866150633],"hpluv":[75.0887439649445554,137.792143148878608,81.7786782860545571],"hsluv":[75.0887439649445554,65.6305091544174104,81.7786782860545571]},"#ddcc88":{"lch":[82.020587165389415,50.599662209211,73.3985048227604722],"luv":[82.020587165389415,14.4570002873895778,48.4904213054152891],"rgb":[0.866666666666666696,0.8,0.533333333333333326],"xyz":[0.558535092145788337,0.603361967757205298,0.319972591269722773],"hpluv":[73.3985048227604722,118.661765286999071,82.020587165389415],"hsluv":[73.3985048227604722,55.2326761810852389,82.020587165389415]},"#ddcc99":{"lch":[82.3026016456871901,40.5232855707982438,70.6109505258247765],"luv":[82.3026016456871901,13.4529549720920478,38.2250529884698622],"rgb":[0.866666666666666696,0.8,0.6],"xyz":[0.571592056254861,0.608584753400834511,0.388739268910840707],"hpluv":[70.6109505258247765,96.7842051030752231,82.3026016456871901],"hsluv":[70.6109505258247765,43.6647666281718685,82.3026016456871901]},"#ddccaa":{"lch":[82.6258332993788542,29.6818113573176419,65.4008685536862231],"luv":[82.6258332993788542,12.3555588351715961,26.9879619705157374],"rgb":[0.866666666666666696,0.8,0.66666666666666663],"xyz":[0.586649749220113592,0.614607830586935577,0.468043118527839308],"hpluv":[65.4008685536862231,72.4135107626852,82.6258332993788542],"hsluv":[65.4008685536862231,31.0871436920773085,82.6258332993788542]},"#ddccbb":{"lch":[82.9911533066729419,18.6379527757414252,53.1465475992889],"luv":[82.9911533066729419,11.1784915779275345,14.9135713265793797],"rgb":[0.866666666666666696,0.8,0.733333333333333282],"xyz":[0.603787341327450156,0.621462867429870336,0.55830110362648111],"hpluv":[53.1465475992889,46.5946179098545272,82.9911533066729419],"hsluv":[53.1465475992889,24.678645774572626,82.9911533066729419]},"#ddcccc":{"lch":[83.3992063850657,10.164901186858037,12.1770506300648638],"luv":[83.3992063850657,9.93619558955776228,2.14411598208697862],"rgb":[0.866666666666666696,0.8,0.8],"xyz":[0.62307971677117191,0.629179817607359193,0.659907614296751266],"hpluv":[12.1770506300648638,26.1289592314662436,83.3992063850657],"hsluv":[12.1770506300648638,25.0002112827592455,83.3992063850657]},"#ddccdd":{"lch":[83.8504233095379163,14.1290270468723165,307.715012949259346],"luv":[83.8504233095379163,8.64321103323171513,-11.1769543403501022],"rgb":[0.866666666666666696,0.8,0.866666666666666696],"xyz":[0.644598042321805509,0.637787147827612699,0.773237462196757264],"hpluv":[307.715012949259346,37.4791950150616557,83.8504233095379163],"hsluv":[307.715012949259346,25.214872966603707,83.8504233095379163]},"#ddccee":{"lch":[84.3450329093034,25.9620569722210597,286.361909425528779],"luv":[84.3450329093034,7.31360586969829818,-24.9106316943502399],"rgb":[0.866666666666666696,0.8,0.933333333333333348],"xyz":[0.668410222587980218,0.647312019934082716,0.898648278265280487],"hpluv":[286.361909425528779,71.3464154396222199,84.3450329093034],"hsluv":[286.361909425528779,60.879598082714125,84.3450329093034]},"#ddccff":{"lch":[84.8830740665913623,39.380529428060008,278.705583312848262],"luv":[84.8830740665913623,5.96052452183370107,-38.926831947371717],"rgb":[0.866666666666666696,0.8,1],"xyz":[0.694581270997811639,0.65778043929801544,1.03648246655706222],"hpluv":[278.705583312848262,112.590543218900592,84.8830740665913623],"hsluv":[278.705583312848262,99.9999999999947704,84.8830740665913623]},"#665500":{"lch":[36.5970311204425656,41.5054710368830655,69.2006364019199651],"luv":[36.5970311204425656,14.7384507745119784,38.800543743107859],"rgb":[0.4,0.333333333333333315,0],"xyz":[0.0872772466047234,0.0932201343710592,0.0133963111976744542],"hpluv":[69.2006364019199651,143.912599562803223,36.5970311204425656],"hsluv":[69.2006364019199651,100.000000000002359,36.5970311204425656]},"#665511":{"lch":[36.673028710438345,38.8606023214232366,68.2658014049057869],"luv":[36.673028710438345,14.3901304021596417,36.0980686435250391],"rgb":[0.4,0.333333333333333315,0.0666666666666666657],"xyz":[0.0882889121043605174,0.0936248005709140463,0.0187244161624300839],"hpluv":[68.2658014049057869,134.462776824764262,36.673028710438345],"hsluv":[68.2658014049057869,93.0449405246809107,36.673028710438345]},"#665522":{"lch":[36.8133307706753357,34.1687527519613923,66.2355675996872719],"luv":[36.8133307706753357,13.769229594380441,31.2715842419585037],"rgb":[0.4,0.333333333333333315,0.133333333333333331],"xyz":[0.0901642702428375464,0.0943749438263048607,0.0286013023584092835],"hpluv":[66.2355675996872719,117.777773408929676,36.8133307706753357],"hsluv":[66.2355675996872719,80.6853283069105629,36.8133307706753357]},"#665533":{"lch":[37.0427251812615097,27.0303271109949854,61.7081001991288645],"luv":[37.0427251812615097,12.8113945713483854,23.8014023297917383],"rgb":[0.4,0.333333333333333315,0.2],"xyz":[0.09325202097529528,0.0956100441192879735,0.0448634562160204267],"hpluv":[61.7081001991288645,92.5950345984193177,37.0427251812615097],"hsluv":[61.7081001991288645,61.7209513910547045,37.0427251812615097]},"#665544":{"lch":[37.3704580906404473,18.1024774089589755,50.3425610862832542],"luv":[37.3704580906404473,11.5529306171195891,13.9366237840407656],"rgb":[0.4,0.333333333333333315,0.266666666666666663],"xyz":[0.0977100162195141536,0.0973932422169755535,0.0683422311689070583],"hpluv":[50.3425610862832542,61.4679768710498351,37.3704580906404473],"hsluv":[50.3425610862832542,37.0117339514184067,37.3704580906404473]},"#665555":{"lch":[37.8025949068387348,10.2943047784276782,12.1770506300631105],"luv":[37.8025949068387348,10.0626876598879917,2.1714115065313786],"rgb":[0.4,0.333333333333333315,0.333333333333333315],"xyz":[0.103672430258876153,0.0997782078327203864,0.0997442784428809737],"hpluv":[12.1770506300631105,34.5553054430909654,37.8025949068387348],"hsluv":[12.1770506300631105,8.09737912949257321,37.8025949068387348]},"#665566":{"lch":[38.3424918197480693,13.7697499972876347,307.715012949250308],"luv":[38.3424918197480693,8.42342892447929,-10.8927434626015351],"rgb":[0.4,0.333333333333333315,0.4],"xyz":[0.111257426032384324,0.102812206142123705,0.139691922850024935],"hpluv":[307.715012949250308,45.570631638882567,38.3424918197480693],"hsluv":[307.715012949250308,15.7660506346962208,38.3424918197480693]},"#665577":{"lch":[38.9911218270375812,25.5692820710091411,285.225395910208761],"luv":[38.9911218270375812,6.71492531026355,-24.671805035392353],"rgb":[0.4,0.333333333333333315,0.466666666666666674],"xyz":[0.120571439052586243,0.106537811350204514,0.188745724756422845],"hpluv":[285.225395910208761,83.2131821356252885,38.9911218270375812],"hsluv":[285.225395910208761,23.5948697041559434,38.9911218270375812]},"#665588":{"lch":[39.7473800461840554,39.003702064123587,277.369365694294345],"luv":[39.7473800461840554,5.00282395952989312,-38.6815269493963],"rgb":[0.4,0.333333333333333315,0.533333333333333326],"xyz":[0.131711856154530071,0.110993978190982112,0.247418588159995],"hpluv":[277.369365694294345,124.519293959659265,39.7473800461840554],"hsluv":[277.369365694294345,31.2388068533835614,39.7473800461840554]},"#665599":{"lch":[40.6084045881889466,52.6763518020623636,273.629018089310307],"luv":[40.6084045881889466,3.33420095564239061,-52.5707251534733189],"rgb":[0.4,0.333333333333333315,0.6],"xyz":[0.144768820263602771,0.11621676383461127,0.316185265801112947],"hpluv":[273.629018089310307,164.603508765513965,40.6084045881889466],"hsluv":[273.629018089310307,39.2894117268144569,40.6084045881889466]},"#6655aa":{"lch":[41.5699140891343575,66.1399121177165,271.505962745252077],"luv":[41.5699140891343575,1.73822184255944534,-66.1170670838121168],"rgb":[0.4,0.333333333333333315,0.66666666666666663],"xyz":[0.159826513228855327,0.122239841020712364,0.395489115418111492],"hpluv":[271.505962745252077,201.894186201954597,41.5699140891343575],"hsluv":[271.505962745252077,49.6682832978127067,41.5699140891343575]},"#6655bb":{"lch":[42.6265484117568647,79.2031960637105499,270.166039680829499],"luv":[42.6265484117568647,0.229525718995523903,-79.2028634876978],"rgb":[0.4,0.333333333333333315,0.733333333333333282],"xyz":[0.176964105336191974,0.129094877863647123,0.485747100516753294],"hpluv":[270.166039680829499,235.777232293519603,42.6265484117568647],"hsluv":[270.166039680829499,59.8653820834470309,42.6265484117568647]},"#6655cc":{"lch":[43.7721949853351333,91.7929775852419,269.258674658723919],"luv":[43.7721949853351333,-1.18763654850412936,-91.7852943199147688],"rgb":[0.4,0.333333333333333315,0.8],"xyz":[0.1962564807799137,0.136811828041135924,0.58735361118702345],"hpluv":[269.258674658723919,266.103421792879146,43.7721949853351333],"hsluv":[269.258674658723919,69.9112236392489734,43.7721949853351333]},"#6655dd":{"lch":[45.0002850881211458,103.899953671233533,268.61259940679895],"luv":[45.0002850881211458,-2.51566121975990953,-103.869494181457682],"rgb":[0.4,0.333333333333333315,0.866666666666666696],"xyz":[0.217774806330547244,0.145419158261389458,0.700683459087029448],"hpluv":[268.61259940679895,292.98097185143456,45.0002850881211458],"hsluv":[268.61259940679895,79.8793625185682714,45.0002850881211458]},"#6655ee":{"lch":[46.3040490971424106,115.549020689755764,268.134901078425969],"luv":[46.3040490971424106,-3.7607010001107648,-115.487805894602445],"rgb":[0.4,0.333333333333333315,0.933333333333333348],"xyz":[0.241586986596722,0.154944030367859503,0.826094275155552671],"hpluv":[268.134901078425969,316.655201018988919,46.3040490971424106],"hsluv":[268.134901078425969,89.8701820385079344,46.3040490971424106]},"#6655ff":{"lch":[47.6767252326213651,126.781348408818275,267.771145841725911],"luv":[47.6767252326213651,-4.93065761335473951,-126.685432942615918],"rgb":[0.4,0.333333333333333315,1],"xyz":[0.267758035006553374,0.165412449731792199,0.963928463447334516],"hpluv":[267.771145841725911,337.433561350206048,47.6767252326213651],"hsluv":[267.771145841725911,99.9999999999992468,47.6767252326213651]},"#dddd00":{"lch":[85.547159878993142,94.3072427966830844,85.8743202181747449],"luv":[85.547159878993142,6.78488618903739749,94.0628585750738466],"rgb":[0.866666666666666696,0.866666666666666696,0],"xyz":[0.556734473143156827,0.670856105031634,0.100161644489793561],"hpluv":[85.8743202181747449,283.614606809988061,85.547159878993142],"hsluv":[85.8743202181747449,100.000000000002203,85.547159878993142]},"#dddd11":{"lch":[85.5675738163798627,93.4011806547303394,85.8743202181746881],"luv":[85.5675738163798627,6.71970001318247423,93.159144368282],"rgb":[0.866666666666666696,0.866666666666666696,0.0666666666666666657],"xyz":[0.557746138642794,0.671260771231488862,0.105489749454549198],"hpluv":[85.8743202181746881,281.335749103468061,85.5675738163798627],"hsluv":[85.8743202181746881,99.0156164862488,85.5675738163798627]},"#dddd22":{"lch":[85.6053941241358558,91.7307060091609401,85.8743202181746739],"luv":[85.6053941241358558,6.59951857201479086,91.4929985275198447],"rgb":[0.866666666666666696,0.866666666666666696,0.133333333333333331],"xyz":[0.559621496781270933,0.672010914486879662,0.11536663565052839],"hpluv":[85.8743202181746739,277.118842420723468,85.6053941241358558],"hsluv":[85.8743202181746739,97.2017654403352083,85.6053941241358558]},"#dddd33":{"lch":[85.667603455332241,89.0058006932873,85.8743202181745602],"luv":[85.667603455332241,6.4034766573555908,88.775154428206335],"rgb":[0.866666666666666696,0.866666666666666696,0.2],"xyz":[0.56270924751372875,0.673246014779862789,0.131628789508139526],"hpluv":[85.8743202181745602,270.196330508983522,85.667603455332241],"hsluv":[85.8743202181745602,94.2458512979473113,85.667603455332241]},"#dddd44":{"lch":[85.7572852094861418,85.1265937151141117,85.8743202181744607],"luv":[85.7572852094861418,6.12438910193468278,84.9059998802570419],"rgb":[0.866666666666666696,0.866666666666666696,0.266666666666666663],"xyz":[0.567167242757947609,0.675029212877550355,0.155107564461026165],"hpluv":[85.8743202181744607,260.24482525674506,85.7572852094861418],"hsluv":[85.8743202181744607,90.0440000232135844,85.7572852094861418]},"#dddd55":{"lch":[85.8769849033878074,80.0369945631262,85.874320218174276],"luv":[85.8769849033878074,5.75822050268421481,79.8295897229865545],"rgb":[0.866666666666666696,0.866666666666666696,0.333333333333333315],"xyz":[0.573129656797309539,0.677414178493295105,0.18650961173500008],"hpluv":[85.874320218174276,247.008869171162701,85.8769849033878074],"hsluv":[85.874320218174276,84.5423921226573327,85.8769849033878074]},"#dddd66":{"lch":[86.0288537292730098,73.7198014533942398,85.8743202181739775],"luv":[86.0288537292730098,5.30373328608645522,73.5287667485177252],"rgb":[0.866666666666666696,0.866666666666666696,0.4],"xyz":[0.58071465257081778,0.680448176802698423,0.226457256142144042],"hpluv":[85.8743202181739775,230.281095596483937,86.0288537292730098],"hsluv":[85.8743202181739775,77.7321300368988,86.0288537292730098]},"#dddd77":{"lch":[86.2147251389940834,66.1931358813644124,85.8743202181736365],"luv":[86.2147251389940834,4.76223119383214133,66.0216054929389315],"rgb":[0.866666666666666696,0.866666666666666696,0.466666666666666674],"xyz":[0.59002866559101963,0.684173782010779274,0.275511058048541924],"hpluv":[85.8743202181736365,209.886373280136951,86.2147251389940834],"hsluv":[85.8743202181736365,69.6453389130317362,86.2147251389940834]},"#dddd88":{"lch":[86.4361603707972,57.5066396271378224,85.8743202181730823],"luv":[86.4361603707972,4.13728567831694072,57.3576190965201391],"rgb":[0.866666666666666696,0.866666666666666696,0.533333333333333326],"xyz":[0.601169082692963541,0.688629948851556817,0.334183921452114119],"hpluv":[85.8743202181730823,185.665493576193455,86.4361603707972],"hsluv":[85.8743202181730823,60.3508056243124429,86.4361603707972]},"#dddd99":{"lch":[86.6944777431662,47.7369558995854888,85.8743202181722154],"luv":[86.6944777431662,3.43441079587341314,47.613252157820078],"rgb":[0.866666666666666696,0.866666666666666696,0.6],"xyz":[0.614226046802036185,0.693852734495186,0.402950599093232054],"hpluv":[85.8743202181722154,157.456397081560084,86.6944777431662],"hsluv":[85.8743202181722154,49.9486591868920939,86.6944777431662]},"#ddddaa":{"lch":[86.990772885999732,36.9824894935128,85.874320218170638],"luv":[86.990772885999732,2.66068622896724838,36.886654469181245],"rgb":[0.866666666666666696,0.866666666666666696,0.66666666666666663],"xyz":[0.629283739767288797,0.699875811681287097,0.482254448710230599],"hpluv":[85.874320218170638,125.071764704863014,86.990772885999732],"hsluv":[85.874320218170638,38.5641267001819443,86.990772885999732]},"#ddddbb":{"lch":[87.3259337660435477,25.3576808227713499,85.8743202181676821],"luv":[87.3259337660435477,1.82434533444747116,25.2919698878957568],"rgb":[0.866666666666666696,0.866666666666666696,0.733333333333333282],"xyz":[0.64642133187462536,0.706730848524221855,0.572512433808872401],"hpluv":[85.8743202181676821,88.2719508819342735,87.3259337660435477],"hsluv":[85.8743202181676821,26.340671416181145,87.3259337660435477]},"#ddddcc":{"lch":[87.7006527393466797,12.9871390430395461,85.8743202181585445],"luv":[87.7006527393466797,0.934353054076054512,12.9534846621895881],"rgb":[0.866666666666666696,0.866666666666666696,0.8],"xyz":[0.665713707318347114,0.714447798701710712,0.674118944479142557],"hpluv":[85.8743202181585445,46.7319159493201113,87.7006527393466797],"hsluv":[85.8743202181585445,13.4329442518860063,87.7006527393466797]},"#dddddd":{"lch":[88.1154369871094,4.67545248961294327e-12,0],"luv":[88.1154369871094,4.4193702762792188e-12,1.52611347670073729e-12],"rgb":[0.866666666666666696,0.866666666666666696,0.866666666666666696],"xyz":[0.687232032868980713,0.723055128921964219,0.787448792379148554],"hpluv":[0,1.74708563976297451e-11,88.1154369871094],"hsluv":[0,1.74437740136320375e-11,88.1154369871094]},"#ddddee":{"lch":[88.5706181797242209,13.4751686036456029,265.874320218195521],"luv":[88.5706181797242209,-0.969464090371862097,-13.4402495614536726],"rgb":[0.866666666666666696,0.866666666666666696,0.933333333333333348],"xyz":[0.711044213135155423,0.732580001028434236,0.912859608447671778],"hpluv":[265.874320218195521,52.5550848411252431,88.5706181797242209],"hsluv":[265.874320218195521,47.1269490590101725,88.5706181797242209]},"#ddddff":{"lch":[89.0663618949558753,27.3146757005029208,265.874320218186369],"luv":[89.0663618949558753,-1.9651403266809826,-27.2438934831293338],"rgb":[0.866666666666666696,0.866666666666666696,1],"xyz":[0.737215261544986844,0.743048420392367,1.05069379673945362],"hpluv":[265.874320218186369,111.815120511018762,89.0663618949558753],"hsluv":[265.874320218186369,99.9999999999922125,89.0663618949558753]},"#666600":{"lch":[41.7321583215394583,46.0055575524193685,85.8743202181747449],"luv":[41.7321583215394583,3.30984623025532709,45.8863404908370924],"rgb":[0.4,0.4,0],"xyz":[0.102305304310569861,0.123276249782752534,0.0184056637662898],"hpluv":[85.8743202181747449,139.887458074797365,41.7321583215394583],"hsluv":[85.8743202181747449,100.000000000002203,41.7321583215394583]},"#666611":{"lch":[41.7952597887023742,43.6298127640598423,85.8743202181746],"luv":[41.7952597887023742,3.13892449057558931,43.5167521176544625],"rgb":[0.4,0.4,0.0666666666666666657],"xyz":[0.103316969810206979,0.123680915982607387,0.0237337687310454348],"hpluv":[85.8743202181746,132.463323325332908,41.7952597887023742],"hsluv":[85.8743202181746,94.6927802880713756,41.7952597887023742]},"#666622":{"lch":[41.9118699845736913,39.3503176022612067,85.874320218174276],"luv":[41.9118699845736913,2.83103840719259514,39.248346677737],"rgb":[0.4,0.4,0.133333333333333331],"xyz":[0.105192327948684008,0.124431059237998201,0.0336106549270246274],"hpluv":[85.874320218174276,119.138061739500813,41.9118699845736913],"hsluv":[85.874320218174276,85.1670788640685288,41.9118699845736913]},"#666633":{"lch":[42.1028501842444953,32.6344620115447057,85.8743202181736507],"luv":[42.1028501842444953,2.34786962297492563,32.5498943011565842],"rgb":[0.4,0.4,0.2],"xyz":[0.108280078681141742,0.125666159530981314,0.0498728087846357776],"hpluv":[85.8743202181736507,98.3567766096709306,42.1028501842444953],"hsluv":[85.8743202181736507,70.3113616926845,42.1028501842444953]},"#666644":{"lch":[42.3763861696741557,23.5947988734222314,85.8743202181723575],"luv":[42.3763861696741557,1.69751569722617934,23.5336562041455402],"rgb":[0.4,0.4,0.266666666666666663],"xyz":[0.112738073925360616,0.127449357628668908,0.0733515837375224161],"hpluv":[85.8743202181723575,70.6531759312171346,42.3763861696741557],"hsluv":[85.8743202181723575,50.5071554688203506,42.3763861696741557]},"#666655":{"lch":[42.7382714661199543,12.562340839470254,85.87432021816781],"luv":[42.7382714661199543,0.903791165304248856,12.5297872646162745],"rgb":[0.4,0.4,0.333333333333333315],"xyz":[0.118700487964722615,0.129834323244413741,0.104753631011496318],"hpluv":[85.87432021816781,37.2986356199978459,42.7382714661199543],"hsluv":[85.87432021816781,26.6633164497530721,42.7382714661199543]},"#666666":{"lch":[43.1922895629847048,2.27708065554704512e-12,0],"luv":[43.1922895629847048,2.15069538500574498e-12,7.48067960001998255e-13],"rgb":[0.4,0.4,0.4],"xyz":[0.126285483738230786,0.132868321553817031,0.144701275418640279],"hpluv":[0,6.68977504875838914e-12,43.1922895629847048],"hsluv":[0,1.91542116883063395e-12,43.1922895629847048]},"#666677":{"lch":[43.7404449074606489,13.5883126365404472,265.874320218186085],"luv":[43.7404449074606489,-0.977604179760566572,-13.5531003971814314],"rgb":[0.4,0.4,0.466666666666666674],"xyz":[0.135599496758432692,0.136593926761897855,0.193755077325038189],"hpluv":[265.874320218186085,39.4204575510779804,43.7404449074606489],"hsluv":[265.874320218186085,10.3527957183817456,43.7404449074606489]},"#666688":{"lch":[44.3831523723879684,27.7327571842679852,265.874320218181708],"luv":[44.3831523723879684,-1.9952189844931838,-27.660891566352042],"rgb":[0.4,0.4,0.533333333333333326],"xyz":[0.146739913860376547,0.141050093602675453,0.252427940728610356],"hpluv":[265.874320218181708,79.2892354857961692,44.3831523723879684],"hsluv":[265.874320218181708,21.2254167484079588,44.3831523723879684]},"#666699":{"lch":[45.1194249231942308,42.0446421145154,265.87432021818023],"luv":[45.1194249231942308,-3.02488020162380478,-41.9356892193690598],"rgb":[0.4,0.4,0.6],"xyz":[0.159796877969449247,0.14627287924630461,0.321194618369728291],"hpluv":[265.87432021818023,118.245992523098394,45.1194249231942308],"hsluv":[265.87432021818023,32.3647541960069702,45.1194249231942308]},"#6666aa":{"lch":[45.9470714788517682,56.2348015337582652,265.874320218179548],"luv":[45.9470714788517682,-4.04578393932889835,-56.0890767962662125],"rgb":[0.4,0.4,0.66666666666666663],"xyz":[0.174854570934701803,0.152295956432405705,0.400498467986726892],"hpluv":[265.874320218179548,155.305436018888514,45.9470714788517682],"hsluv":[265.874320218179548,43.5990379455573205,45.9470714788517682]},"#6666bb":{"lch":[46.8629040956598786,70.1103551977131,265.874320218179093],"luv":[46.8629040956598786,-5.04405352741049562,-69.9286738753289541],"rgb":[0.4,0.4,0.733333333333333282],"xyz":[0.191992163042038422,0.159150993275340463,0.490756453085368638],"hpluv":[265.874320218179093,189.841997809706953,46.8629040956598786],"hsluv":[265.874320218179093,54.8353857399755285,46.8629040956598786]},"#6666cc":{"lch":[47.8629477245616854,83.5592716582008,265.874320218178866],"luv":[47.8629477245616854,-6.01162892081844,-83.3427393224351505],"rgb":[0.4,0.4,0.8],"xyz":[0.211284538485760176,0.166867943452829265,0.592362963755638794],"hpluv":[265.874320218178866,221.531011478982748,47.8629477245616854],"hsluv":[265.874320218178866,66.0482344892977693,47.8629477245616854]},"#6666dd":{"lch":[48.9426439028117102,96.5306872715973583,265.874320218178696],"luv":[48.9426439028117102,-6.94485076081307,-96.2805413000828736],"rgb":[0.4,0.4,0.866666666666666696],"xyz":[0.23280286403639372,0.175475273673082799,0.705692811655644792],"hpluv":[265.874320218178696,250.274901054084751,48.9426439028117102],"hsluv":[265.874320218178696,77.2646968282616911,48.9426439028117102]},"#6666ee":{"lch":[50.0970402589656203,109.016062738443594,265.874320218178525],"luv":[50.0970402589656203,-7.84310469187671711,-108.73356263723052],"rgb":[0.4,0.4,0.933333333333333348],"xyz":[0.256615044302568429,0.185000145779552844,0.831103627724168],"hpluv":[265.874320218178525,276.132643737939816,50.0970402589656203],"hsluv":[265.874320218178525,88.5507283896609181,50.0970402589656203]},"#6666ff":{"lch":[51.3209595583197142,121.033610519319112,265.874320218178411],"luv":[51.3209595583197142,-8.70770100014002502,-120.719968599376287],"rgb":[0.4,0.4,1],"xyz":[0.28278609271239985,0.19546856514348554,0.96893781601594986],"hpluv":[265.874320218178411,299.261292593223402,51.3209595583197142],"hsluv":[265.874320218178411,99.9999999999991616,51.3209595583197142]},"#ddee00":{"lch":[90.1008574130140261,100.518542770188731,92.3281002120423295],"luv":[90.1008574130140261,-4.08324753875312307,100.435574027231638],"rgb":[0.866666666666666696,0.933333333333333348,0],"xyz":[0.603913249483671644,0.765213657712664919,0.115887903269964759],"hpluv":[92.3281002120423295,458.324419080212692,90.1008574130140261],"hsluv":[92.3281002120423295,100.000000000002288,90.1008574130140261]},"#ddee11":{"lch":[90.1195571422023676,99.6821059706602739,92.3717344777628284],"luv":[90.1195571422023676,-4.12512016496088219,99.5967149778072667],"rgb":[0.866666666666666696,0.933333333333333348,0.0666666666666666657],"xyz":[0.604924914983308804,0.765618323912519827,0.121216008234720396],"hpluv":[92.3717344777628284,455.439701471196656,90.1195571422023676],"hsluv":[92.3717344777628284,99.1349582088955827,90.1195571422023676]},"#ddee22":{"lch":[90.1542040339558213,98.139145338163118,92.4541942657322409],"luv":[90.1542040339558213,-4.20238430415396635,98.0491295925940562],"rgb":[0.866666666666666696,0.933333333333333348,0.133333333333333331],"xyz":[0.606800273121785749,0.766368467167910628,0.131092894430699575],"hpluv":[92.4541942657322409,450.094002053356689,90.1542040339558213],"hsluv":[92.4541942657322409,97.539848527320828,90.1542040339558213]},"#ddee33":{"lch":[90.2112004280082402,95.6198982889531237,92.5945991605726562],"luv":[90.2112004280082402,-4.32860020636881337,95.5218727257959728],"rgb":[0.866666666666666696,0.933333333333333348,0.2],"xyz":[0.609888023854243566,0.767603567460893754,0.147355048288310725],"hpluv":[92.5945991605726562,441.296742170845221,90.2112004280082402],"hsluv":[92.5945991605726562,94.9371734060285348,90.2112004280082402]},"#ddee44":{"lch":[90.2933822328294582,92.028546743238266,92.808164678773025],"luv":[90.2933822328294582,-4.50867173729536486,91.9180357429253689],"rgb":[0.866666666666666696,0.933333333333333348,0.266666666666666663],"xyz":[0.614346019098462426,0.76938676555858132,0.170833823241197363],"hpluv":[92.808164678773025,428.602609406071736,90.2933822328294582],"hsluv":[92.808164678773025,91.2305485856041827,90.2933822328294582]},"#ddee55":{"lch":[90.4030992965535,87.3081168904988658,93.1158428735316477],"luv":[90.4030992965535,-4.74562541158387852,87.1790474507375137],"rgb":[0.866666666666666696,0.933333333333333348,0.333333333333333315],"xyz":[0.620308433137824355,0.77177173117432607,0.202235870515171279],"hpluv":[93.1158428735316477,411.63119840797242,90.4030992965535],"hsluv":[93.1158428735316477,86.365058197250562,90.4030992965535]},"#ddee66":{"lch":[90.5423480313319828,81.4363754503924,93.5488244177654451],"luv":[90.5423480313319828,-5.04083628618753,81.2802141731499717],"rgb":[0.866666666666666696,0.933333333333333348,0.4],"xyz":[0.627893428911332596,0.774805729483729388,0.242183514922315241],"hpluv":[93.5488244177654451,390.03815237863023,90.5423480313319828],"hsluv":[93.5488244177654451,80.3228278296054583,90.5423480313319828]},"#ddee77":{"lch":[90.7128424721769449,74.4235139877598613,94.1564113073248],"luv":[90.7128424721769449,-5.39417557361030209,74.2277731322134855],"rgb":[0.866666666666666696,0.933333333333333348,0.466666666666666674],"xyz":[0.637207441931534446,0.77853133469181024,0.291237316828713122],"hpluv":[94.1564113073248,363.492124647987794,90.7128424721769449],"hsluv":[94.1564113073248,73.1200108954656116,90.7128424721769449]},"#ddee88":{"lch":[90.9160566530372449,66.3104835404903099,95.0215233218939801],"luv":[90.9160566530372449,-5.80415396856009735,66.0559764448523197],"rgb":[0.866666666666666696,0.933333333333333348,0.533333333333333326],"xyz":[0.648347859033478358,0.782987501532587782,0.349910180232285317],"hpluv":[95.0215233218939801,331.65301907995223,90.9160566530372449],"hsluv":[95.0215233218939801,64.803658473982523,90.9160566530372449]},"#ddee99":{"lch":[91.1532518637430798,57.1683554138076389,96.2947128608995513],"luv":[91.1532518637430798,-6.26808654843775237,56.8236918172404799],"rgb":[0.866666666666666696,0.933333333333333348,0.6],"xyz":[0.661404823142551,0.788210287176217,0.418676857873403252],"hpluv":[96.2947128608995513,294.152965661212647,91.1532518637430798],"hsluv":[96.2947128608995513,55.4479539090275679,91.1532518637430798]},"#ddeeaa":{"lch":[91.4254953447680805,47.1012792006961263,98.2790075719046712],"luv":[91.4254953447680805,-6.78228473243696595,46.6104185365255219],"rgb":[0.866666666666666696,0.933333333333333348,0.66666666666666663],"xyz":[0.676462516107803613,0.794233364362318062,0.497980707490401797],"hpluv":[98.2790075719046712,250.593114601078071,91.4254953447680805],"hsluv":[98.2790075719046712,45.1497304611624699,91.4254953447680805]},"#ddeebb":{"lch":[91.7336739482950634,36.2629153409390739,101.681625346389353],"luv":[91.7336739482950634,-7.34227032126066,35.5118303605101318],"rgb":[0.866666666666666696,0.933333333333333348,0.733333333333333282],"xyz":[0.693600108215140176,0.80108840120525282,0.588238692589043599],"hpluv":[101.681625346389353,200.613962446551909,91.7336739482950634],"hsluv":[101.681625346389353,34.0234190840686495,91.7336739482950634]},"#ddeecc":{"lch":[92.0785048140775189,24.9340669502590622,108.575873850927678],"luv":[92.0785048140775189,-7.94300120518182506,23.6350677285782567],"rgb":[0.866666666666666696,0.933333333333333348,0.8],"xyz":[0.712892483658861931,0.808805351382741677,0.689845203259313755],"hpluv":[108.575873850927678,144.339382081965653,92.0785048140775189],"hsluv":[108.575873850927678,22.1956929245148693,92.0785048140775189]},"#ddeedd":{"lch":[92.4605443140240908,14.0242187757329084,127.71501294922345],"luv":[92.4605443140240908,-8.57909621466854766,11.0940443666446207],"rgb":[0.866666666666666696,0.933333333333333348,0.866666666666666696],"xyz":[0.73441080920949553,0.817412681602995184,0.803175051159319753],"hpluv":[127.71501294922345,85.5555802205660854,92.4605443140240908],"hsluv":[127.71501294922345,19.0167034911391681,92.4605443140240908]},"#ddeeee":{"lch":[92.8801960589335636,9.45784403502816851,192.177050630058346],"luv":[92.8801960589335636,-9.24504689815110403,-1.99497409554724747],"rgb":[0.866666666666666696,0.933333333333333348,0.933333333333333348],"xyz":[0.758222989475670239,0.826937553709465201,0.928585867227843],"hpluv":[192.177050630058346,61.3009405779386327,92.8801960589335636],"hsluv":[192.177050630058346,16.5065503962475049,92.8801960589335636]},"#ddeeff":{"lch":[93.3377184761608305,18.4254994321377019,237.36941304521946],"luv":[93.3377184761608305,-9.93540601395951306,-15.5173044263971267],"rgb":[0.866666666666666696,0.933333333333333348,1],"xyz":[0.78439403788550166,0.837405973073397925,1.06642005551962482],"hpluv":[237.36941304521946,128.083838047846456,93.3377184761608305],"hsluv":[237.36941304521946,99.9999999999860592,93.3377184761608305]},"#667700":{"lch":[46.9985837429297462,53.5023535392226,97.7743932102929705],"luv":[46.9985837429297462,-7.23741162388150272,53.0105810873873509],"rgb":[0.4,0.466666666666666674,0],"xyz":[0.12075904236398749,0.160183725889588319,0.0245569097840955056],"hpluv":[97.7743932102929705,144.453291553004675,46.9985837429297462],"hsluv":[97.7743932102929705,100.000000000002416,46.9985837429297462]},"#667711":{"lch":[47.0515894602548315,51.4525286527524344,98.1592061252685681],"luv":[47.0515894602548315,-7.3023584206057679,50.9317019768564],"rgb":[0.4,0.466666666666666674,0.0666666666666666657],"xyz":[0.121770707863624608,0.160588392089443172,0.0298850147488511353],"hpluv":[98.1592061252685681,138.762383385982389,47.0515894602548315],"hsluv":[98.1592061252685681,95.8888552433840573,47.0515894602548315]},"#667722":{"lch":[47.1496128779850068,47.7434140964333835,98.9413563019921],"luv":[47.1496128779850068,-7.4204465613794337,47.1632331632727],"rgb":[0.4,0.466666666666666674,0.133333333333333331],"xyz":[0.123646066002101637,0.161338535344834,0.0397619009448303348],"hpluv":[98.9413563019921,128.491579290861381,47.1496128779850068],"hsluv":[98.9413563019921,88.4562635009272071,47.1496128779850068]},"#667733":{"lch":[47.3103471969426579,41.884713336750373,100.466311561708949],"luv":[47.3103471969426579,-7.6086666810921777,41.1878307590699961],"rgb":[0.4,0.466666666666666674,0.2],"xyz":[0.126733816734559357,0.162573635637817099,0.0560240548024414781],"hpluv":[100.466311561708949,112.341117260385403,47.3103471969426579],"hsluv":[100.466311561708949,76.7252257071794,47.3103471969426579]},"#667744":{"lch":[47.5409803755201068,33.9506682862991624,103.399633201782777],"luv":[47.5409803755201068,-7.86778476785512915,33.0264415269496823],"rgb":[0.4,0.466666666666666674,0.266666666666666663],"xyz":[0.131191811978778244,0.164356833735504693,0.0795028297553281166],"hpluv":[103.399633201782777,90.6190532449782324,47.5409803755201068],"hsluv":[103.399633201782777,60.8161329795325543,47.5409803755201068]},"#667755":{"lch":[47.8468512336942808,24.3055974565694441,109.700167733355244],"luv":[47.8468512336942808,-8.19336864569332768,22.8829800934354815],"rgb":[0.4,0.466666666666666674,0.333333333333333315],"xyz":[0.137154226018140257,0.166741799351249526,0.110904877029302018],"hpluv":[109.700167733355244,64.4602914823941262,47.8468512336942808],"hsluv":[109.700167733355244,41.23982633361328,47.8468512336942808]},"#667766":{"lch":[48.2317738399223543,14.0211946941261125,127.715012949232488],"luv":[48.2317738399223543,-8.57724628010491408,11.0916521267580634],"rgb":[0.4,0.466666666666666674,0.4],"xyz":[0.144739221791648415,0.169775797660652816,0.15085252143644598],"hpluv":[127.715012949232488,36.8885098590324958,48.2317738399223543],"hsluv":[127.715012949232488,18.7828263722028552,48.2317738399223543]},"#667777":{"lch":[48.6982180758881356,9.21652694043341,192.177050630059739],"luv":[48.6982180758881356,-9.00915932709454736,-1.94407228846053126],"rgb":[0.4,0.466666666666666674,0.466666666666666674],"xyz":[0.154053234811850348,0.17350140286873364,0.199906323342843889],"hpluv":[192.177050630059739,24.0156061835451808,48.6982180758881356],"hsluv":[192.177050630059739,23.9216020554503501,48.6982180758881356]},"#667788":{"lch":[49.2474401880289605,18.4334880243097601,239.056580638027469],"luv":[49.2474401880289605,-9.47834019220879398,-15.8099509152663327],"rgb":[0.4,0.466666666666666674,0.533333333333333326],"xyz":[0.165193651913794148,0.177957569709511237,0.258579186746416056],"hpluv":[239.056580638027469,47.4966726259429564,49.2474401880289605],"hsluv":[239.056580638027469,29.274081353383373,49.2474401880289605]},"#667799":{"lch":[49.8796002039077422,31.7351192214463786,251.680675473596239],"luv":[49.8796002039077422,-9.97474964621831,-30.126768188683684],"rgb":[0.4,0.466666666666666674,0.6],"xyz":[0.178250616022866876,0.183180355353140395,0.327345864387534],"hpluv":[251.680675473596239,80.734004933806176,49.8796002039077422],"hsluv":[251.680675473596239,34.661761655835349,49.8796002039077422]},"#6677aa":{"lch":[50.5938810850088174,45.7960576637453798,256.758518919433186],"luv":[50.5938810850088174,-10.4898463625666416,-44.5784928057335676],"rgb":[0.4,0.466666666666666674,0.66666666666666663],"xyz":[0.193308308988119404,0.18920343253924149,0.406649714004532592],"hpluv":[256.758518919433186,114.860161977636537,50.5938810850088174],"hsluv":[256.758518919433186,39.9381656359214858,50.5938810850088174]},"#6677bb":{"lch":[51.388614147457119,59.9444468574027738,259.409682348511467],"luv":[51.388614147457119,-11.0169047239158306,-58.9233783768730106],"rgb":[0.4,0.466666666666666674,0.733333333333333282],"xyz":[0.210445901095456078,0.196058469382176248,0.496907699103174338],"hpluv":[259.409682348511467,148.020333314730891,51.388614147457119],"hsluv":[259.409682348511467,49.2101017344363356,51.388614147457119]},"#6677cc":{"lch":[52.2614099661724225,73.9004259234932306,261.00752312302825],"luv":[52.2614099661724225,-11.5509895931656974,-72.9921063615257566],"rgb":[0.4,0.466666666666666674,0.8],"xyz":[0.229738276539177805,0.20377541955966505,0.598514209773444494],"hpluv":[261.00752312302825,179.434168102703751,52.2614099661724225],"hsluv":[261.00752312302825,61.6581230008595327,52.2614099661724225]},"#6677dd":{"lch":[53.2092913421323,87.5170631601914266,262.060353074135],"luv":[53.2092913421323,-12.0887245225321198,-86.6781349799548],"rgb":[0.4,0.466666666666666674,0.866666666666666696],"xyz":[0.251256602089811376,0.212382749779918584,0.711844057673450492],"hpluv":[262.060353074135,208.710638687620559,53.2092913421323],"hsluv":[262.060353074135,74.2459971892304083,53.2092913421323]},"#6677ee":{"lch":[54.2288239257805884,100.719531231348427,262.797438231409785],"luv":[54.2288239257805884,-12.6279723106459851,-99.9247631309883531],"rgb":[0.4,0.466666666666666674,0.933333333333333348],"xyz":[0.275068782355986086,0.221907621886388629,0.837254873741973715],"hpluv":[262.797438231409785,235.68005803746027,54.2288239257805884],"hsluv":[262.797438231409785,87.0042080584200193,54.2288239257805884]},"#6677ff":{"lch":[55.3162401631211793,113.47857319487936,263.336661992011841],"luv":[55.3162401631211793,-13.1675101506557386,-112.712036849566218],"rgb":[0.4,0.466666666666666674,1],"xyz":[0.301239830765817507,0.232376041250321325,0.97508906203375556],"hpluv":[263.336661992011841,260.315806593762318,55.3162401631211793],"hsluv":[263.336661992011841,99.999999999999,55.3162401631211793]},"#ddff00":{"lch":[94.69236188875891,107.73563953931891,97.6513944636985],"luv":[94.69236188875891,-14.3445112693176284,106.77641604488548],"rgb":[0.866666666666666696,1,0],"xyz":[0.65576562191334542,0.868918402572014,0.13317202741318887],"hpluv":[97.6513944636985,949.977135711580445,94.69236188875891],"hsluv":[97.6513944636985,100.000000000002302,94.69236188875891]},"#ddff11":{"lch":[94.7095428290633237,106.965998536257018,97.7198690947758308],"luv":[94.7095428290633237,-14.3687245726656343,105.996531061225838],"rgb":[0.866666666666666696,1,0.0666666666666666657],"xyz":[0.65677728741298258,0.869323068771868934,0.138500132377944507],"hpluv":[97.7198690947758308,946.378692368412885,94.7095428290633237],"hsluv":[97.7198690947758308,99.9999999999867697,94.7095428290633237]},"#ddff22":{"lch":[94.7413776147606086,105.545731309599958,97.8489007917202827],"luv":[94.7413776147606086,-14.4134418215914106,104.556941866783148],"rgb":[0.866666666666666696,1,0.133333333333333331],"xyz":[0.658652645551459526,0.870073212027259735,0.148377018573923686],"hpluv":[97.8489007917202827,939.695870823628752,94.7413776147606086],"hsluv":[97.8489007917202827,99.9999999999872,94.7413776147606086]},"#ddff33":{"lch":[94.7937532988665197,103.225383790498825,98.0674915546983],"luv":[94.7937532988665197,-14.4865977424562669,102.203807876928138],"rgb":[0.866666666666666696,1,0.2],"xyz":[0.661740396283917343,0.871308312320242861,0.164639172431534836],"hpluv":[98.0674915546983,928.656435156239354,94.7937532988665197],"hsluv":[98.0674915546983,99.9999999999868834,94.7937532988665197]},"#ddff44":{"lch":[94.8692843830354491,99.9146373114600692,98.397314807396512],"luv":[94.8692843830354491,-14.5912004882884094,98.8434702820129729],"rgb":[0.866666666666666696,1,0.266666666666666663],"xyz":[0.666198391528136202,0.873091510417930428,0.188117947384421474],"hpluv":[98.397314807396512,912.633071017653265,94.8692843830354491],"hsluv":[98.397314807396512,99.9999999999866276,94.8692843830354491]},"#ddff55":{"lch":[94.9701440016210654,95.558111661139634,98.8668834316730738],"luv":[94.9701440016210654,-14.7292629682473848,94.4161083536863828],"rgb":[0.866666666666666696,1,0.333333333333333315],"xyz":[0.672160805567498132,0.875476476033675177,0.21951999465839539],"hpluv":[98.8668834316730738,891.031026100052486,94.9701440016210654],"hsluv":[98.8668834316730738,99.9999999999861586,94.9701440016210654]},"#ddff66":{"lch":[95.0981866754888,90.1320341607989235,99.5166683548804798],"luv":[95.0981866754888,-14.9019372161492765,88.8915960547979438],"rgb":[0.866666666666666696,1,0.4],"xyz":[0.679745801341006373,0.878510474343078496,0.259467639065539379],"hpluv":[99.5166683548804798,863.234823568518,95.0981866754888],"hsluv":[99.5166683548804798,99.9999999999856186,95.0981866754888]},"#ddff77":{"lch":[95.2550143462764396,83.6430269583913599,100.407261812829162],"luv":[95.2550143462764396,-15.1095945804084604,82.2669806810598487],"rgb":[0.866666666666666696,1,0.466666666666666674],"xyz":[0.689059814361208223,0.882236079551159347,0.308521440971937233],"hpluv":[100.407261812829162,828.556184265804632,95.2550143462764396],"hsluv":[100.407261812829162,99.9999999999855476,95.2550143462764396]},"#ddff88":{"lch":[95.4420158908659175,76.1281736437493,101.633961649281417],"luv":[95.4420158908659175,-15.3518949618923237,74.5641880758576434],"rgb":[0.866666666666666696,1,0.533333333333333326],"xyz":[0.700200231463152134,0.886692246391936889,0.367194304375509428],"hpluv":[101.633961649281417,786.17501332264635,95.4420158908659175],"hsluv":[101.633961649281417,99.9999999999848512,95.4420158908659175]},"#ddff99":{"lch":[95.6603925662724208,67.6570848719276086,103.355147801887099],"luv":[95.6603925662724208,-15.6278614338241617,65.8274341013866859],"rgb":[0.866666666666666696,1,0.6],"xyz":[0.713257195572224778,0.891915032035566102,0.435960982016627363],"hpluv":[103.355147801887099,735.074270676232231,95.6603925662724208],"hsluv":[103.355147801887099,99.9999999999844107,95.6603925662724208]},"#ddffaa":{"lch":[95.9111754000973775,58.338925144698,105.852499131344544],"luv":[95.9111754000973775,-15.935965587620279,56.1201852084333268],"rgb":[0.866666666666666696,1,0.66666666666666663],"xyz":[0.72831488853747739,0.897938109221667169,0.515264831633625908],"hpluv":[105.852499131344544,673.992295850936557,95.9111754000973775],"hsluv":[105.852499131344544,99.9999999999831886,95.9111754000973775]},"#ddffbb":{"lch":[96.1952377631310185,48.3433070572267596,109.672211431084662],"luv":[96.1952377631310185,-16.2742233848326485,45.5216980180866813],"rgb":[0.866666666666666696,1,0.733333333333333282],"xyz":[0.745452480644814,0.904793146064601927,0.60552281673226771],"hpluv":[109.672211431084662,601.502194015230771,96.1952377631310185],"hsluv":[109.672211431084662,99.9999999999821654,96.1952377631310185]},"#ddffcc":{"lch":[96.513305005727517,37.9644197829535202,115.996292551248089],"luv":[96.513305005727517,-16.6402982513575566,34.1232712904577653],"rgb":[0.866666666666666696,1,0.8],"xyz":[0.764744856088535707,0.912510096242090785,0.707129327402537866],"hpluv":[115.996292551248089,516.693096965009204,96.513305005727517],"hsluv":[115.996292551248089,99.9999999999804885,96.513305005727517]},"#ddffdd":{"lch":[96.8659623148576,27.841508205801528,127.715012949232161],"luv":[96.8659623148576,-17.0316066426751398,22.0243945284064],"rgb":[0.866666666666666696,1,0.866666666666666696],"xyz":[0.786263181639169306,0.921117426462344291,0.820459175302543864],"hpluv":[127.715012949232161,422.676993554754517,96.8659623148576],"hsluv":[127.715012949232161,99.9999999999786411,96.8659623148576]},"#ddffee":{"lch":[97.2536615310726802,19.7831433293950418,151.864226334417424],"luv":[97.2536615310726802,-17.4454209009420502,9.32898974060759478],"rgb":[0.866666666666666696,1,0.933333333333333348],"xyz":[0.810075361905344,0.930642298568814308,0.945869991371067087],"hpluv":[151.864226334417424,343.73229759561508,97.2536615310726802],"hsluv":[151.864226334417424,99.9999999999752,97.2536615310726802]},"#ddffff":{"lch":[97.6767274082888406,18.2904922799610645,192.177050630059568],"luv":[97.6767274082888406,-17.878964623675607,-3.85807359036494368],"rgb":[0.866666666666666696,1,1],"xyz":[0.836246410315175437,0.941110717932747,1.08370417966284882],"hpluv":[192.177050630059568,376.852754928906336,97.6767274082888406],"hsluv":[192.177050630059568,99.9999999999715072,97.6767274082888406]},"#668800":{"lch":[52.32310792684153,62.4331707825390509,105.73052795354684],"luv":[52.32310792684153,-16.9264656143939405,60.0948881001240167],"rgb":[0.4,0.533333333333333326,0],"xyz":[0.142831412088957943,0.204328465339529863,0.0319143663590854554],"hpluv":[105.73052795354684,151.412310196323318,52.32310792684153],"hsluv":[105.73052795354684,100.000000000002359,52.32310792684153]},"#668811":{"lch":[52.3681821172622222,60.6739112189649603,106.201766876928076],"luv":[52.3681821172622222,-16.9292783492562116,58.26425179456308],"rgb":[0.4,0.533333333333333326,0.0666666666666666657],"xyz":[0.143843077588595075,0.204733131539384716,0.0372424713238410851],"hpluv":[106.201766876928076,147.019120365759306,52.3681821172622222],"hsluv":[106.201766876928076,96.7617570127925859,52.3681821172622222]},"#668822":{"lch":[52.4515808002199,57.4815115963739842,107.134347730867304],"luv":[52.4515808002199,-16.9348150675510247,54.9302850350507796],"rgb":[0.4,0.533333333333333326,0.133333333333333331],"xyz":[0.145718435727072076,0.205483274794775544,0.0471193575198202846],"hpluv":[107.134347730867304,139.062145386582984,52.4515808002199],"hsluv":[107.134347730867304,90.8761910280814647,52.4515808002199]},"#668833":{"lch":[52.5884544541714121,52.4173031151438593,108.860637572968898],"luv":[52.5884544541714121,-16.9448041098426323,49.6028958786070291],"rgb":[0.4,0.533333333333333326,0.2],"xyz":[0.14880618645952981,0.206718375087758643,0.0633815113774314209],"hpluv":[108.860637572968898,126.480505252334424,52.5884544541714121],"hsluv":[108.860637572968898,81.504484256448066,52.5884544541714121]},"#668844":{"lch":[52.7851097594501937,45.5231929703366234,111.874794573011059],"luv":[52.7851097594501937,-16.9610118856818559,42.2455343678863215],"rgb":[0.4,0.533333333333333326,0.266666666666666663],"xyz":[0.153264181703748698,0.208501573185446237,0.0868602863303180595],"hpluv":[111.874794573011059,109.436101408621766,52.7851097594501937],"hsluv":[111.874794573011059,68.6312430201703734,52.7851097594501937]},"#668855":{"lch":[53.0463844713544859,37.0894540992544819,117.255878513522262],"luv":[53.0463844713544859,-16.9856764955971045,32.9714179156375593],"rgb":[0.4,0.533333333333333326,0.333333333333333315],"xyz":[0.15922659574311071,0.21088653880119107,0.118262333604291975],"hpluv":[117.255878513522262,88.7225425584692715,53.0463844713544859],"hsluv":[117.255878513522262,52.5261258187504225,53.0463844713544859]},"#668866":{"lch":[53.3759296841588906,27.8248149657310222,127.715012949236794],"luv":[53.3759296841588906,-17.0213948144824521,22.0111891193247189],"rgb":[0.4,0.533333333333333326,0.4],"xyz":[0.166811591516618868,0.213920537110594361,0.158209978011435937],"hpluv":[127.715012949236794,66.1494380276081415,53.3759296841588906],"hsluv":[127.715012949236794,33.681854155652033,53.3759296841588906]},"#668877":{"lch":[53.7763606180623839,19.6211535767711887,150.461713858693599],"luv":[53.7763606180623839,-17.0709226847205855,9.67332757511772101],"rgb":[0.4,0.533333333333333326,0.466666666666666674],"xyz":[0.176125604536820801,0.217646142318675184,0.207263779917833846],"hpluv":[150.461713858693599,46.2990901048939207,53.7763606180623839],"hsluv":[150.461713858693599,37.1484166060608132,53.7763606180623839]},"#668888":{"lch":[54.2493559855519436,17.5313913512660982,192.17705063006045],"luv":[54.2493559855519436,-17.1369431164247104,-3.69795393909545],"rgb":[0.4,0.533333333333333326,0.533333333333333326],"xyz":[0.187266021638764601,0.222102309159452782,0.265936643321406],"hpluv":[192.17705063006045,41.0072951616226788,54.2493559855519436],"hsluv":[192.17705063006045,40.8467805779917228,54.2493559855519436]},"#668899":{"lch":[54.7957384612029728,24.7393499057112685,225.882505108050964],"luv":[54.7957384612029728,-17.2218541013304964,-17.7607200042594577],"rgb":[0.4,0.533333333333333326,0.6],"xyz":[0.200322985747837329,0.22732509480308194,0.33470332096252392],"hpluv":[225.882505108050964,57.2902642666713859,54.7957384612029728],"hsluv":[225.882505108050964,44.6631352998217963,54.7957384612029728]},"#6688aa":{"lch":[55.4155508256813363,36.5699037808867828,241.717344836465486],"luv":[55.4155508256813363,-17.3276119763631087,-32.2042190673817643],"rgb":[0.4,0.533333333333333326,0.66666666666666663],"xyz":[0.215380678713089857,0.233348171989183034,0.414007170579522521],"hpluv":[241.717344836465486,83.7397171719788389,55.4155508256813363],"hsluv":[241.717344836465486,48.4952118884804193,55.4155508256813363]},"#6688bb":{"lch":[56.1081340603271457,49.918102431374308,249.531909378681803],"luv":[56.1081340603271457,-17.4556451944419777,-46.7666270025424495],"rgb":[0.4,0.533333333333333326,0.733333333333333282],"xyz":[0.232518270820426531,0.240203208832117793,0.504265155678164323],"hpluv":[249.531909378681803,112.8941838879785,56.1081340603271457],"hsluv":[249.531909378681803,52.2580147864780216,56.1081340603271457]},"#6688cc":{"lch":[56.8722093096567107,63.7230017864969795,253.960340799970709],"luv":[56.8722093096567107,-17.6068348542363715,-61.2423082770199372],"rgb":[0.4,0.533333333333333326,0.8],"xyz":[0.251810646264148286,0.247920159009606594,0.605871666348434479],"hpluv":[253.960340799970709,142.178999158492672,56.8722093096567107],"hsluv":[253.960340799970709,56.6402695601832349,56.8722093096567107]},"#6688dd":{"lch":[57.7059632125805564,77.5471512008463719,256.744147904563079],"luv":[57.7059632125805564,-17.7815469636593271,-75.4809727477468755],"rgb":[0.4,0.533333333333333326,0.866666666666666696],"xyz":[0.273328971814781774,0.256527489229860128,0.719201514248440477],"hpluv":[256.744147904563079,170.523595036459966,57.7059632125805564],"hsluv":[256.744147904563079,70.7529337108087475,57.7059632125805564]},"#6688ee":{"lch":[58.6071348177704721,91.1720868217648501,258.626369492504523],"luv":[58.6071348177704721,-17.979697586292076,-89.3816529839368599],"rgb":[0.4,0.533333333333333326,0.933333333333333348],"xyz":[0.297141152080956539,0.266052361336330145,0.8446123303169637],"hpluv":[258.626369492504523,197.40162879311913,58.6071348177704721],"hsluv":[258.626369492504523,85.1920367601911295,58.6071348177704721]},"#6688ff":{"lch":[59.57310174908622,104.481663139573541,259.967822360236937],"luv":[59.57310174908622,-18.2008336002305597,-102.884146439906075],"rgb":[0.4,0.533333333333333326,1],"xyz":[0.323312200490787904,0.276520780700262869,0.982446518608745434],"hpluv":[259.967822360236937,222.550815911907222,59.57310174908622],"hsluv":[259.967822360236937,99.9999999999987352,59.57310174908622]},"#669900":{"lch":[57.6618978033021961,71.9113437902946373,111.072092359847389],"luv":[57.6618978033021961,-25.8551729794803826,67.1025438856612624],"rgb":[0.4,0.6,0],"xyz":[0.168701012541425444,0.25606766624446553,0.0405375665099077104],"hpluv":[111.072092359847389,158.251486754186431,57.6618978033021961],"hsluv":[111.072092359847389,100.000000000002444,57.6618978033021961]},"#669911":{"lch":[57.7006802499588929,70.3894808316696867,111.521292839157113],"luv":[57.7006802499588929,-25.8221679479897865,65.4820177928093727],"rgb":[0.4,0.6,0.0666666666666666657],"xyz":[0.169712678041062576,0.256472332444320383,0.0458656714746633401],"hpluv":[111.521292839157113,154.798288730060023,57.7006802499588929],"hsluv":[111.521292839157113,97.4070268725327821,57.7006802499588929]},"#669922":{"lch":[57.7724648019637499,67.6202459496272326,112.394641072548438],"luv":[57.7724648019637499,-25.7622250908158499,62.5204400229094404],"rgb":[0.4,0.6,0.133333333333333331],"xyz":[0.171588036179539577,0.257222475699711184,0.0557425576706425396],"hpluv":[112.394641072548438,148.523500329687067,57.7724648019637499],"hsluv":[112.394641072548438,92.6757293451634183,57.7724648019637499]},"#669933":{"lch":[57.8903535973237524,63.206621217633213,113.958803391015238],"luv":[57.8903535973237524,-25.6669247559924365,57.7605915769530824],"rgb":[0.4,0.6,0.2],"xyz":[0.174675786911997311,0.258457575992694311,0.0720047115282536898],"hpluv":[113.958803391015238,138.546544821103367,57.8903535973237524],"hsluv":[113.958803391015238,85.092275495173979,57.8903535973237524]},"#669944":{"lch":[58.0598969225296457,57.1535921702901888,116.538768682419729],"luv":[58.0598969225296457,-25.5364113217858204,51.131446241744662],"rgb":[0.4,0.6,0.266666666666666663],"xyz":[0.179133782156216198,0.260240774090381877,0.0954834864811403283],"hpluv":[116.538768682419729,124.912700512594284,58.0598969225296457],"hsluv":[116.538768682419729,74.5746503624431796,58.0598969225296457]},"#669955":{"lch":[58.2854489010818355,49.6561447471622515,120.7300937454592],"luv":[58.2854489010818355,-25.3740154630121886,42.6836274282534163],"rgb":[0.4,0.6,0.333333333333333315],"xyz":[0.185096196195578211,0.262625739706126737,0.126885533755114244],"hpluv":[120.7300937454592,108.106592630407334,58.2854489010818355],"hsluv":[120.7300937454592,61.2495338993745833,58.2854489010818355]},"#669966":{"lch":[58.5704165792398754,41.1710358166226,127.715012949238272],"luv":[58.5704165792398754,-25.1857364161826034,32.5688942303571949],"rgb":[0.4,0.6,0.4],"xyz":[0.192681191969086368,0.265659738015530056,0.166833178162258178],"hpluv":[127.715012949238272,89.1975256314243552,58.5704165792398754],"hsluv":[127.715012949238272,45.4174387408809324,58.5704165792398754]},"#669977":{"lch":[58.9173908027988489,32.643461159974926,139.926834832055846],"luv":[58.9173908027988489,-24.9795271581232114,21.0147276798767138],"rgb":[0.4,0.6,0.466666666666666674],"xyz":[0.201995204989288302,0.269385343223610851,0.215886980068656087],"hpluv":[139.926834832055846,70.3059403526018514,58.9173908027988489],"hsluv":[139.926834832055846,47.7876005322921813,58.9173908027988489]},"#669988":{"lch":[59.328227692638464,26.116847909850911,161.480821243886396],"luv":[59.328227692638464,-24.7644493579715288,8.29528738156475498],"rgb":[0.4,0.6,0.533333333333333326],"xyz":[0.213135622091232102,0.273841510064388449,0.274559843472228282],"hpluv":[161.480821243886396,55.8597144892801083,59.328227692638464],"hsluv":[161.480821243886396,50.3655359274122105,59.328227692638464]},"#669999":{"lch":[59.8041090330486043,25.1148951486962346,192.17705063006062],"luv":[59.8041090330486043,-24.5498215694726056,-5.29756729424584893],"rgb":[0.4,0.6,0.6],"xyz":[0.226192586200304829,0.279064295708017607,0.343326521113346161],"hpluv":[192.17705063006062,53.2892577697712042,59.8041090330486043],"hsluv":[192.17705063006062,53.0806679813151447,59.8041090330486043]},"#6699aa":{"lch":[60.3455948386344119,31.1785657150768039,218.6653689057203],"luv":[60.3455948386344119,-24.3444790905776323,-19.4794583563761137],"rgb":[0.4,0.6,0.66666666666666663],"xyz":[0.241250279165557358,0.285087372894118729,0.422630370730344762],"hpluv":[218.6653689057203,65.5616517705923911,60.3455948386344119],"hsluv":[218.6653689057203,55.8649153078387357,60.3455948386344119]},"#6699bb":{"lch":[60.9526745558420231,41.7013653705125407,234.60099737489486],"luv":[60.9526745558420231,-24.1562241025528444,-33.9923625373734168],"rgb":[0.4,0.6,0.733333333333333282],"xyz":[0.258387871272894032,0.291942409737053488,0.512888355828986509],"hpluv":[234.60099737489486,86.8154127469588,60.9526745558420231],"hsluv":[234.60099737489486,58.6571249967150123,60.9526745558420231]},"#6699cc":{"lch":[61.6248198105828493,54.2138016672169485,243.734276496040906],"luv":[61.6248198105828493,-23.9914938552849968,-48.6162988492970101],"rgb":[0.4,0.6,0.8],"xyz":[0.277680246716615731,0.299659359914542289,0.614494866499256664],"hpluv":[243.734276496040906,111.633239234030881,61.6248198105828493],"hsluv":[243.734276496040906,61.4057918386087067,61.6248198105828493]},"#6699dd":{"lch":[62.361039595623,67.5283063616342361,249.312993820438976],"luv":[62.361039595623,-23.8552311607989473,-63.1743627299522288],"rgb":[0.4,0.6,0.866666666666666696],"xyz":[0.29919857226724933,0.308266690134795796,0.727824714399262662],"hpluv":[249.312993820438976,137.407942777337979,62.361039595623],"hsluv":[249.312993820438976,66.62550454031512,62.361039595623]},"#6699ee":{"lch":[63.1599376048740453,81.0888167917790526,252.968345076420633],"luv":[63.1599376048740453,-23.7509145884581336,-77.5325110189427278],"rgb":[0.4,0.6,0.933333333333333348],"xyz":[0.323010752533424039,0.317791562241265813,0.853235530467785885],"hpluv":[252.968345076420633,162.914071535813093,63.1599376048740453],"hsluv":[252.968345076420633,83.0301883133999183,63.1599376048740453]},"#6699ff":{"lch":[64.0197707514621186,94.6074384193794771,255.504450424431923],"luv":[64.0197707514621186,-23.6806962224400728,-91.5958079318982499],"rgb":[0.4,0.6,1],"xyz":[0.34918180094325546,0.328259981605198536,0.99106971875956773],"hpluv":[255.504450424431923,187.521252715437782,64.0197707514621186],"hsluv":[255.504450424431923,99.9999999999985079,64.0197707514621186]},"#550000":{"lch":[15.1243819173422267,50.8637728648741643,12.1770506300617765],"luv":[15.1243819173422267,49.7193613905117289,10.7288626130266547],"rgb":[0.333333333333333315,0,0],"xyz":[0.0374622858816120868,0.019316491157706641,0.00175604465070052949],"hpluv":[12.1770506300617765,426.746789183125202,15.1243819173422267],"hsluv":[12.1770506300617765,100.000000000002203,15.1243819173422267]},"#550011":{"lch":[15.3402258633588957,47.2707050856887108,7.4875089370669734],"luv":[15.3402258633588957,46.8676416739534929,6.15984766208174239],"rgb":[0.333333333333333315,0,0.0666666666666666657],"xyz":[0.0384739513812492051,0.0197211573575614939,0.00708414961545616138],"hpluv":[7.4875089370669734,391.020613457768548,15.3402258633588957],"hsluv":[7.4875089370669734,99.9999999999966889,15.3402258633588957]},"#550022":{"lch":[15.7326592199860933,42.4312907985821823,358.411234527054887],"luv":[15.7326592199860933,42.4149789665186745,-1.17643448760390168],"rgb":[0.333333333333333315,0,0.133333333333333331],"xyz":[0.0403493095197262272,0.0204713006129523117,0.0169610358114353557],"hpluv":[358.411234527054887,342.234221563623748,15.7326592199860933],"hsluv":[358.411234527054887,99.9999999999971578,15.7326592199860933]},"#550033":{"lch":[16.358416636328208,38.360101220613565,343.406058671947278],"luv":[16.358416636328208,36.7625096026365128,-10.9551473459637485],"rgb":[0.333333333333333315,0,0.2],"xyz":[0.0434370602521839677,0.0217064009059354281,0.0332231896690465],"hpluv":[343.406058671947278,297.562230749163234,16.358416636328208],"hsluv":[343.406058671947278,99.9999999999977547,16.358416636328208]},"#550044":{"lch":[17.2212923868602061,37.8614359764106112,324.728975934647224],"luv":[17.2212923868602061,30.9112016871952413,-21.8628896637516235],"rgb":[0.333333333333333315,0,0.266666666666666663],"xyz":[0.0478950554964028483,0.0234895990036230046,0.0567019646219331375],"hpluv":[324.728975934647224,278.978456842737614,17.2212923868602061],"hsluv":[324.728975934647224,99.9999999999983089,17.2212923868602061]},"#550055":{"lch":[18.3096014215038,41.7063030886972754,307.715012949243544],"luv":[18.3096014215038,25.5131777875110508,-32.9923245090298636],"rgb":[0.333333333333333315,0,0.333333333333333315],"xyz":[0.0538574695357648403,0.025874564619367834,0.0881040118959070528],"hpluv":[307.715012949243544,289.042783730483393,18.3096014215038],"hsluv":[307.715012949243544,99.9999999999988,18.3096014215038]},"#550066":{"lch":[19.6013792550641099,48.6148100748190828,295.355623011865077],"luv":[19.6013792550641099,20.818580180871372,-43.9316113733990079],"rgb":[0.333333333333333315,0,0.4],"xyz":[0.0614424653092730116,0.028908562928771149,0.128051656303051015],"hpluv":[295.355623011865077,314.717786655224245,19.6013792550641099],"hsluv":[295.355623011865077,99.9999999999992468,19.6013792550641099]},"#550077":{"lch":[21.069395574911745,57.1127554515679421,287.139622223683091],"luv":[21.069395574911745,16.83119884103942,-54.5763463493480572],"rgb":[0.333333333333333315,0,0.466666666666666674],"xyz":[0.0707564783294749311,0.0326341681368519654,0.177105458209448924],"hpluv":[287.139622223683091,343.969838941793114,21.069395574911745],"hsluv":[287.139622223683091,99.9999999999995737,21.069395574911745]},"#550088":{"lch":[22.6852054601189934,66.3294491167530822,281.703433904835379],"luv":[22.6852054601189934,13.454662288017035,-64.9505033302079084],"rgb":[0.333333333333333315,0,0.533333333333333326],"xyz":[0.0818968954314187592,0.0370903349776295563,0.235778321613021091],"hpluv":[281.703433904835379,371.024851449370942,22.6852054601189934],"hsluv":[281.703433904835379,99.9999999999998721,22.6852054601189934]},"#550099":{"lch":[24.4218644362266417,75.8503102235033424,278.01254475278904],"luv":[24.4218644362266417,10.5727682252252198,-75.1098271403773339],"rgb":[0.333333333333333315,0,0.6],"xyz":[0.0949538595404914726,0.0423131206212587208,0.304544999254138971],"hpluv":[278.01254475278904,394.110378481836165,24.4218644362266417],"hsluv":[278.01254475278904,100.000000000000071,24.4218644362266417]},"#5500aa":{"lch":[26.2553935553790794,85.4876195151354,275.424483319872081],"luv":[26.2553935553790794,8.0814629277942,-85.1047768771603614],"rgb":[0.333333333333333315,0,0.66666666666666663],"xyz":[0.110011552505744015,0.0483361978073598153,0.383848848871137571],"hpluv":[275.424483319872081,413.165469396605374,26.2553935553790794],"hsluv":[275.424483319872081,100.00000000000027,26.2553935553790794]},"#5500bb":{"lch":[28.1653177219846,95.1546470205467756,273.553022331801344],"luv":[28.1653177219846,5.89694295360029841,-94.9717479748942708],"rgb":[0.333333333333333315,0,0.733333333333333282],"xyz":[0.127149144613080661,0.0551912346502945739,0.474106833969779318],"hpluv":[273.553022331801344,428.701175528050442,28.1653177219846],"hsluv":[273.553022331801344,100.000000000000355,28.1653177219846]},"#5500cc":{"lch":[30.1346298593711452,104.80902699908826,272.162345307959299],"luv":[30.1346298593711452,3.95455850560158062,-104.734395532324456],"rgb":[0.333333333333333315,0,0.8],"xyz":[0.146441520056802388,0.0629081848277833755,0.575713344640049529],"hpluv":[272.162345307959299,441.338845171454864,30.1346298593711452],"hsluv":[272.162345307959299,100.000000000000441,30.1346298593711452]},"#5500dd":{"lch":[32.1494591091083208,114.428501102308275,271.104225820707256],"luv":[32.1494591091083208,2.20517261265448461,-114.407250986418532],"rgb":[0.333333333333333315,0,0.866666666666666696],"xyz":[0.167959845607435931,0.0715155150480369095,0.689043192540055527],"hpluv":[271.104225820707256,451.647764573950099,32.1494591091083208],"hsluv":[271.104225820707256,100.000000000000483,32.1494591091083208]},"#5500ee":{"lch":[34.1986254005705774,124.000502171291956,270.282536199645165],"luv":[34.1986254005705774,0.611467178704377612,-123.998994538754019],"rgb":[0.333333333333333315,0,0.933333333333333348],"xyz":[0.191772025873610696,0.0810403871545069404,0.81445400860857875],"hpluv":[270.282536199645165,460.101999214721616,34.1986254005705774],"hsluv":[270.282536199645165,100.000000000000597,34.1986254005705774]},"#5500ff":{"lch":[36.2731838611955055,133.517545782829444,269.6330586770423],"luv":[36.2731838611955055,-0.855085145745556,-133.514807647929],"rgb":[0.333333333333333315,0,1],"xyz":[0.217943074283442062,0.0915088065184396504,0.952288196900360595],"hpluv":[269.6330586770423,467.080772865482345,36.2731838611955055],"hsluv":[269.6330586770423,100.000000000000668,36.2731838611955055]},"#551100":{"lch":[17.1436512350983392,46.6418802884309827,16.9386517648024579],"luv":[17.1436512350983392,44.618427652544149,13.5889996193616174],"rgb":[0.333333333333333315,0.0666666666666666657,0],"xyz":[0.0394666861425404941,0.0233252916795635146,0.00242417807100998037],"hpluv":[16.9386517648024579,345.232802292268,17.1436512350983392],"hsluv":[16.9386517648024579,100.000000000002245,17.1436512350983392]},"#551111":{"lch":[17.3342210988239742,43.3325537190722372,12.1770506300618173],"luv":[17.3342210988239742,42.3575912084996133,9.14027783111198566],"rgb":[0.333333333333333315,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0404783516421776124,0.0237299578794183674,0.0077522830357656114],"hpluv":[12.1770506300618173,317.211759513802576,17.3342210988239742],"hsluv":[12.1770506300618173,74.3325474389658751,17.3342210988239742]},"#551122":{"lch":[17.681833534927847,38.7809423842287515,2.75476418742331486],"luv":[17.681833534927847,38.7361268795629599,1.86385798259144919],"rgb":[0.333333333333333315,0.0666666666666666657,0.133333333333333331],"xyz":[0.0423537097806546345,0.0244801011348091888,0.0176291692317448075],"hpluv":[2.75476418742331486,278.311009894887945,17.681833534927847],"hsluv":[2.75476418742331486,76.7057995287142234,17.681833534927847]},"#551133":{"lch":[18.2390179286851222,34.9181665436168771,346.660743506282301],"luv":[18.2390179286851222,33.9761101882180157,-8.05619582966011727],"rgb":[0.333333333333333315,0.0666666666666666657,0.2],"xyz":[0.045441460513112375,0.0257152014277923,0.0338913230893559542],"hpluv":[346.660743506282301,242.9345634355779,18.2390179286851222],"hsluv":[346.660743506282301,79.7834922439867285,18.2390179286851222]},"#551144":{"lch":[19.0128230091186055,34.7408929356053093,326.164658676814156],"luv":[19.0128230091186055,28.8572161490225767,-19.3440098762325228],"rgb":[0.333333333333333315,0.0666666666666666657,0.266666666666666663],"xyz":[0.0498994557573312555,0.0274983995254798746,0.0573700980422425927],"hpluv":[326.164658676814156,231.864199750183133,19.0128230091186055],"hsluv":[326.164658676814156,83.0221027238197706,19.0128230091186055]},"#551155":{"lch":[19.9971255718025702,39.1813209297373,307.715012949243771],"luv":[19.9971255718025702,23.9685594933690105,-30.9949038651824331],"rgb":[0.333333333333333315,0.0666666666666666657,0.333333333333333315],"xyz":[0.0558618697966932476,0.0298833651412247076,0.0887721453162165],"hpluv":[307.715012949243771,248.628452083429778,19.9971255718025702],"hsluv":[307.715012949243771,86.0178721207098391,19.9971255718025702]},"#551166":{"lch":[21.1763147828962417,46.7756191769153702,294.771362117319313],"luv":[21.1763147828962417,19.5989049109657927,-42.4716549674572263],"rgb":[0.333333333333333315,0.0666666666666666657,0.4],"xyz":[0.0634468655702014189,0.0329173634506280191,0.128719789723360456],"hpluv":[294.771362117319313,280.29057047770084,21.1763147828962417],"hsluv":[294.771362117319313,88.5810746573468464,21.1763147828962417]},"#551177":{"lch":[22.529041607596703,55.8726050260016436,286.442196236272423],"luv":[22.529041607596703,15.8146223861076685,-53.5877384405836494],"rgb":[0.333333333333333315,0.0666666666666666657,0.466666666666666674],"xyz":[0.0727608785904033384,0.0366429686587088355,0.177773591629758365],"hpluv":[286.442196236272423,314.699121073082495,22.529041607596703],"hsluv":[286.442196236272423,90.6792509168865166,22.529041607596703]},"#551188":{"lch":[24.0315326783493077,65.5523157673088548,281.05474383939486],"luv":[24.0315326783493077,12.5694476912001676,-64.3359548557037613],"rgb":[0.333333333333333315,0.0666666666666666657,0.533333333333333326],"xyz":[0.0839012956923471664,0.0410991354994864333,0.236446455033330533],"hpluv":[281.05474383939486,346.135302225987516,24.0315326783493077],"hsluv":[281.05474383939486,92.3586421581981654,24.0315326783493077]},"#551199":{"lch":[25.6600874124784752,75.409923320082811,277.450872837297311],"luv":[25.6600874124784752,9.77886091464338847,-74.7731931533810439],"rgb":[0.333333333333333315,0.0666666666666666657,0.6],"xyz":[0.0969582598014198799,0.0463219211431155908,0.30521313267444844],"hpluv":[277.450872837297311,372.914863977489176,25.6600874124784752],"hsluv":[277.450872837297311,93.6909530677945099,25.6600874124784752]},"#5511aa":{"lch":[27.3926712394503795,85.2829889480110097,274.948569823839534],"luv":[27.3926712394503795,7.3566383451248436,-84.9650991652784882],"rgb":[0.333333333333333315,0.0666666666666666657,0.66666666666666663],"xyz":[0.112015952766672422,0.0523449983292166923,0.38451698229144704],"hpluv":[274.948569823839534,395.063906765864772,27.3926712394503795],"hsluv":[274.948569823839534,94.7471527755802185,27.3926712394503795]},"#5511bb":{"lch":[29.2097366740877575,95.1102004757886732,273.151254165932869],"luv":[29.2097366740877575,5.22840137893499524,-94.9663838079847125],"rgb":[0.333333333333333315,0.0666666666666666657,0.733333333333333282],"xyz":[0.129153544874009069,0.0592000351721514509,0.474774967390088787],"hpluv":[273.151254165932869,413.179515249173164,29.2097366740877575],"hsluv":[273.151254165932869,95.5878244802283,29.2097366740877575]},"#5511cc":{"lch":[31.0944914716528729,104.870266468627406,271.822015936655589],"luv":[31.0944914716528729,3.33433100744475697,-104.81724584215],"rgb":[0.333333333333333315,0.0666666666666666657,0.8],"xyz":[0.148445920317730795,0.0669169853496402456,0.576381478060359],"hpluv":[271.822015936655589,427.964986778194486,31.0944914716528729],"hsluv":[271.822015936655589,96.2613872132177733,31.0944914716528729]},"#5511dd":{"lch":[33.0328257175950526,114.557035031638449,270.814150293263936],"luv":[33.0328257175950526,1.62775523553093748,-114.545469959022128],"rgb":[0.333333333333333315,0.0666666666666666657,0.866666666666666696],"xyz":[0.169964245868364339,0.0755243155698937796,0.689711325960365],"hpluv":[270.814150293263936,440.063516862193467,33.0328257175950526],"hsluv":[270.814150293263936,96.8053522828386832,33.0328257175950526]},"#5511ee":{"lch":[35.0130604571318926,124.169729525043778,270.033521846843314],"luv":[35.0130604571318926,0.0726475571782520396,-124.169708273213573],"rgb":[0.333333333333333315,0.0666666666666666657,0.933333333333333348],"xyz":[0.193776426134539104,0.0850491876763638244,0.815122142028888219],"hpluv":[270.033521846843314,450.012925469310176,35.0130604571318926],"hsluv":[270.033521846843314,97.2483877085506663,35.0130604571318926]},"#5511ff":{"lch":[37.0256255288684244,133.709282746677673,269.417732433602225],"luv":[37.0256255288684244,-1.35879534673770408,-133.702378317802101],"rgb":[0.333333333333333315,0.0666666666666666657,1],"xyz":[0.219947474544370469,0.0955176070402965205,0.952956330320670064],"hpluv":[269.417732433602225,458.245787382607887,37.0256255288684244],"hsluv":[269.417732433602225,99.999999999999531,37.0256255288684244]},"#552200":{"lch":[20.34436993371488,40.5799496107340403,26.5709502396200712],"luv":[20.34436993371488,36.2939416756913289,18.1516420207988389],"rgb":[0.333333333333333315,0.133333333333333331,0],"xyz":[0.0431823098773084293,0.0307565391490994891,0.0036627193159325909],"hpluv":[26.5709502396200712,253.10841584108,20.34436993371488],"hsluv":[26.5709502396200712,100.000000000002359,20.34436993371488]},"#552211":{"lch":[20.5030711832139332,37.4561676233306144,21.8926823519782197],"luv":[20.5030711832139332,34.7549742653004543,13.9662542166947503],"rgb":[0.333333333333333315,0.133333333333333331,0.0666666666666666657],"xyz":[0.0441939753769455546,0.031161205348954342,0.00899082428068822236],"hpluv":[21.8926823519782197,231.816181029165051,20.5030711832139332],"hsluv":[21.8926823519782197,79.998991439989,20.5030711832139332]},"#552222":{"lch":[20.7936643332181177,32.9512801850020054,12.1770506300619488],"luv":[20.7936643332181177,32.2098915499349658,6.95052171940595098],"rgb":[0.333333333333333315,0.133333333333333331,0.133333333333333331],"xyz":[0.0460693335154225697,0.0319113486043451633,0.0188677104766674167],"hpluv":[12.1770506300619488,201.08542320769223,20.7936643332181177],"hsluv":[12.1770506300619488,47.1205474310924046,20.7936643332181177]},"#552233":{"lch":[21.2623572347893699,28.8586800011052311,354.1745907436],"luv":[21.2623572347893699,28.7096478626609084,-2.92908364650122532],"rgb":[0.333333333333333315,0.133333333333333331,0.2],"xyz":[0.0491570842478803102,0.0331464488973282762,0.0351298643342785599],"hpluv":[354.1745907436,172.228245917758017,21.2623572347893699],"hsluv":[354.1745907436,52.8325366869496236,21.2623572347893699]},"#552244":{"lch":[21.9189283311679688,28.7014290952845421,329.54904741067952],"luv":[21.9189283311679688,24.7424491748557642,-14.5459011732283336],"rgb":[0.333333333333333315,0.133333333333333331,0.266666666666666663],"xyz":[0.0536150794920991908,0.0349296469950158492,0.0586086392871652],"hpluv":[329.54904741067952,166.158870546468904,21.9189283311679688],"hsluv":[329.54904741067952,59.1960886419386,21.9189283311679688]},"#552255":{"lch":[22.7630226511172538,33.9275210993755394,307.715012949244226],"luv":[22.7630226511172538,20.7546297224435,-26.8388157904337739],"rgb":[0.333333333333333315,0.133333333333333331,0.333333333333333315],"xyz":[0.0595774935314611828,0.0373146126107606821,0.0900106865611391138],"hpluv":[307.715012949244226,189.13048019699076,22.7630226511172538],"hsluv":[307.715012949244226,65.4333859354686211,22.7630226511172538]},"#552266":{"lch":[23.7863579144178132,42.6539605518829816,293.531429927677038],"luv":[23.7863579144178132,17.0296819355444384,-39.1069083914310625],"rgb":[0.333333333333333315,0.133333333333333331,0.4],"xyz":[0.0671624893049693611,0.0403486109201639936,0.129958330968283076],"hpluv":[293.531429927677038,227.546804006344104,23.7863579144178132],"hsluv":[293.531429927677038,71.0608597854246,23.7863579144178132]},"#552277":{"lch":[24.975052770659552,52.81712200152176,285.022920758889427],"luv":[24.975052770659552,13.6904851349353347,-51.0119495147337858],"rgb":[0.333333333333333315,0.133333333333333331,0.466666666666666674],"xyz":[0.0764765023251712805,0.04407421612824481,0.179012132874680985],"hpluv":[285.022920758889427,268.353735360872861,24.975052770659552],"hsluv":[285.022920758889427,75.8822745115455604,24.975052770659552]},"#552288":{"lch":[26.3119033569515395,63.3751525334233818,279.769698022236867],"luv":[26.3119033569515395,10.754023379801918,-62.4560720809542573],"rgb":[0.333333333333333315,0.133333333333333331,0.533333333333333326],"xyz":[0.0876169194271151086,0.0485303829690224,0.237684996278253152],"hpluv":[279.769698022236867,305.637106002952862,26.3119033569515395],"hsluv":[279.769698022236867,79.8897505498065357,26.3119033569515395]},"#552299":{"lch":[27.7783456471686065,73.9162973481211,276.357347681517297],"luv":[27.7783456471686065,8.18468635974612368,-73.4617582341209783],"rgb":[0.333333333333333315,0.133333333333333331,0.6],"xyz":[0.100673883536187808,0.0537531686126515654,0.306451673919371059],"hpluv":[276.357347681517297,337.654974874305083,27.7783456471686065],"hsluv":[276.357347681517297,83.1678045973750102,27.7783456471686065]},"#5522aa":{"lch":[29.3559430420228864,84.3037876124251824,274.032676149589577],"luv":[29.3559430420228864,5.92869585954675404,-84.0950603258353482],"rgb":[0.333333333333333315,0.133333333333333331,0.66666666666666663],"xyz":[0.115731576501440364,0.0597762457987526669,0.38575552353636966],"hpluv":[274.032676149589577,364.410076381253305,29.3559430420228864],"hsluv":[274.032676149589577,85.8312635149374898,29.3559430420228864]},"#5522bb":{"lch":[31.0273723986379082,94.5090555446981568,272.384235640696716],"luv":[31.0273723986379082,3.93164792491766635,-94.4272403734501324],"rgb":[0.333333333333333315,0.133333333333333331,0.733333333333333282],"xyz":[0.132869168608777,0.0666312826416874254,0.476013508635011406],"hpluv":[272.384235640696716,386.516244750379769,31.0273723986379082],"hsluv":[272.384235640696716,87.9935415010939437,31.0273723986379082]},"#5522cc":{"lch":[32.7769760620793207,104.54175742802569,271.176024316906762],"luv":[32.7769760620793207,2.1456208028374788,-104.519736688869415],"rgb":[0.333333333333333315,0.133333333333333331,0.8],"xyz":[0.152161544052498737,0.0743482328191762271,0.577620019305281507],"hpluv":[271.176024316906762,404.725193356887132,32.7769760620793207],"hsluv":[271.176024316906762,89.7538092894248507,32.7769760620793207]},"#5522dd":{"lch":[34.5909880118612847,114.421842397276407,270.265889656874094],"luv":[34.5909880118612847,0.530989812409553341,-114.420610326139567],"rgb":[0.333333333333333315,0.133333333333333331,0.866666666666666696],"xyz":[0.173679869603132281,0.0829555630394297611,0.690949867205287505],"hpluv":[270.265889656874094,419.744772471420788,34.5909880118612847],"hsluv":[270.265889656874094,91.1938440016712519,34.5909880118612847]},"#5522ee":{"lch":[36.4575428526747132,124.16924767107497,269.564389707514863],"luv":[36.4575428526747132,-0.94402906580191559,-124.165659005715739],"rgb":[0.333333333333333315,0.133333333333333331,0.933333333333333348],"xyz":[0.197492049869307018,0.092480435145899792,0.816360683273810728],"hpluv":[269.564389707514863,432.181309790662738,36.4575428526747132],"hsluv":[269.564389707514863,92.960018101107309,36.4575428526747132]},"#5522ff":{"lch":[38.3665568136218695,133.800754994484379,269.013084090219763],"luv":[38.3665568136218695,-2.30459494965050871,-133.780906258001124],"rgb":[0.333333333333333315,0.133333333333333331,1],"xyz":[0.223663098279138411,0.102948854509832488,0.954194871565592573],"hpluv":[269.013084090219763,442.532391911887146,38.3665568136218695],"hsluv":[269.013084090219763,99.9999999999994458,38.3665568136218695]},"#ccaa00":{"lch":[70.5858735612972623,80.4904122142546186,67.9906634155396],"luv":[70.5858735612972623,30.1643998932495876,74.6244962294604335],"rgb":[0.8,0.66666666666666663,0],"xyz":[0.392753797737474875,0.415879162748823417,0.059586129772359088],"hpluv":[67.9906634155396,144.699051457387782,70.5858735612972623],"hsluv":[67.9906634155396,100.000000000002373,70.5858735612972623]},"#ccaa11":{"lch":[70.6139482370970342,79.3332745728624786,67.7767588069511078],"luv":[70.6139482370970342,30.0051392857341135,73.4401802210267078],"rgb":[0.8,0.66666666666666663,0.0666666666666666657],"xyz":[0.393765463237112,0.416283828948678269,0.0649142347371147177],"hpluv":[67.7767588069511078,142.56214209062793,70.6139482370970342],"hsluv":[67.7767588069511078,98.4234445622979308,70.6139482370970342]},"#ccaa22":{"lch":[70.6659431154106,77.2098224605726529,67.3668792611096166],"luv":[70.6659431154106,29.7125737342128318,71.263733037795],"rgb":[0.8,0.66666666666666663,0.133333333333333331],"xyz":[0.395640821375589036,0.41703397220406907,0.0747911209330939103],"hpluv":[67.3668792611096166,138.644204697820271,70.6659431154106],"hsluv":[67.3668792611096166,95.5289103121581746,70.6659431154106]},"#ccaa33":{"lch":[70.7514162745237911,73.7740913884545,66.6515854645136159],"luv":[70.7514162745237911,29.2382542862800783,67.7328653349528622],"rgb":[0.8,0.66666666666666663,0.2],"xyz":[0.398728572108046742,0.418269072497052197,0.0910532747907050605],"hpluv":[66.6515854645136159,132.314688307412609,70.7514162745237911],"hsluv":[66.6515854645136159,90.8407422295077822,70.7514162745237911]},"#ccaa44":{"lch":[70.8745233475107597,68.9449101039795096,65.5199261400916271],"luv":[70.8745233475107597,28.5691680681362534,62.74713750555],"rgb":[0.8,0.66666666666666663,0.266666666666666663],"xyz":[0.403186567352265657,0.420052270594739763,0.114532049743591699],"hpluv":[65.5199261400916271,123.438713002021714,70.8745233475107597],"hsluv":[65.5199261400916271,84.237349466135143,70.8745233475107597]},"#ccaa55":{"lch":[71.0386313772099,62.7256766939065713,63.7915144306433959],"luv":[71.0386313772099,27.7020883768036121,56.2770363138665672],"rgb":[0.8,0.66666666666666663,0.333333333333333315],"xyz":[0.409148981391627642,0.422437236210484623,0.1459340970175656],"hpluv":[63.7915144306433959,112.044384698186093,71.0386313772099],"hsluv":[63.7915144306433959,75.6976413431368229,71.0386313772099]},"#ccaa66":{"lch":[71.2465086991263661,55.2096541299921952,61.1466680322388356],"luv":[71.2465086991263661,26.6424757380098143,48.3558103613508123],"rgb":[0.8,0.66666666666666663,0.4],"xyz":[0.416733977165135827,0.425471234519887942,0.185881741424709562],"hpluv":[61.1466680322388356,98.331070119416168,71.2465086991263661],"hsluv":[61.1466680322388356,65.2901205751262,71.2465086991263661]},"#ccaa77":{"lch":[71.5004247203994794,46.6032511345785068,56.9687004258729388],"luv":[71.5004247203994794,25.4032971934547263,39.0709035986321638],"rgb":[0.8,0.66666666666666663,0.466666666666666674],"xyz":[0.426047990185337733,0.429196839727968737,0.234935543331107471],"hpluv":[56.9687004258729388,82.707885898124573,71.5004247203994794],"hsluv":[56.9687004258729388,53.160756563752912,71.5004247203994794]},"#ccaa88":{"lch":[71.8022091544958556,37.3024926838847648,49.9478623796008847],"luv":[71.8022091544958556,24.003572993357885,28.5535364531929083],"rgb":[0.8,0.66666666666666663,0.533333333333333326],"xyz":[0.437188407287281533,0.433653006568746335,0.293608406734679639],"hpluv":[49.9478623796008847,65.9233659814751149,71.8022091544958556],"hsluv":[49.9478623796008847,39.5178130280575743,71.8022091544958556]},"#ccaa99":{"lch":[72.1532912119235874,28.1535194843350283,37.0598425499876214],"luv":[72.1532912119235874,22.4666918036374241,16.9666855559712388],"rgb":[0.8,0.66666666666666663,0.6],"xyz":[0.450245371396354233,0.438875792212375493,0.362375084375797574],"hpluv":[37.0598425499876214,49.5126161932360702,72.1532912119235874],"hsluv":[37.0598425499876214,26.6696495224772221,72.1532912119235874]},"#ccaaaa":{"lch":[72.5547286434336,21.297823518763618,12.177050630063027],"luv":[72.5547286434336,20.8186322940273918,4.49241984263274841],"rgb":[0.8,0.66666666666666663,0.66666666666666663],"xyz":[0.465303064361606789,0.444898869398476615,0.441678933992796174],"hpluv":[12.177050630063027,37.2485034287350203,72.5547286434336],"hsluv":[12.177050630063027,27.9047031904792959,72.5547286434336]},"#ccaabb":{"lch":[73.0072318845295,20.9674028584132515,335.544386587188285],"luv":[73.0072318845295,19.0862548050106788,-8.68025691700441193],"rgb":[0.8,0.66666666666666663,0.733333333333333282],"xyz":[0.482440656468943463,0.451753906241411374,0.531936919091437921],"hpluv":[335.544386587188285,36.4433325399841053,73.0072318845295],"hsluv":[335.544386587188285,29.1493731958161852,73.0072318845295]},"#ccaacc":{"lch":[73.5111862218870442,28.2733952257813925,307.715012949249683],"luv":[73.5111862218870442,17.2958067637387,-22.366044486780595],"rgb":[0.8,0.66666666666666663,0.8],"xyz":[0.501733031912665162,0.459470856418900175,0.633543429761708077],"hpluv":[307.715012949249683,48.8049486057506,73.5111862218870442],"hsluv":[307.715012949249683,30.3693282248248444,73.5111862218870442]},"#ccaadd":{"lch":[74.0666736076556,39.5441054640130645,293.032470315564865],"luv":[74.0666736076556,15.4717391639018693,-36.3917787995197202],"rgb":[0.8,0.66666666666666663,0.866666666666666696],"xyz":[0.523251357463298761,0.468078186639153682,0.746873277661714075],"hpluv":[293.032470315564865,67.7482749884916871,74.0666736076556],"hsluv":[293.032470315564865,52.1368854824616719,74.0666736076556]},"#ccaaee":{"lch":[74.6734949675833093,52.4074038625381462,285.081329657377239],"luv":[74.6734949675833093,13.6358764846886817,-50.6023601436286],"rgb":[0.8,0.66666666666666663,0.933333333333333348],"xyz":[0.54706353772947347,0.477603058745623699,0.872284093730237298],"hpluv":[285.081329657377239,89.0564736794959799,74.6734949675833093],"hsluv":[285.081329657377239,75.3315532053798194,74.6734949675833093]},"#ccaaff":{"lch":[75.3311933526529316,65.9300530396585458,280.316334998223624],"luv":[75.3311933526529316,11.8069327652914797,-64.8642292214135239],"rgb":[0.8,0.66666666666666663,1],"xyz":[0.573234586139304891,0.488071478109556423,1.01011828202201914],"hpluv":[280.316334998223624,111.057502918871393,75.3311933526529316],"hsluv":[280.316334998223624,99.9999999999973426,75.3311933526529316]},"#553300":{"lch":[24.6368918170402651,35.1311640480653367,43.6144672720514848],"luv":[24.6368918170402651,25.4348822629288698,24.2335604409056025],"rgb":[0.333333333333333315,0.2,0],"xyz":[0.049300031966319241,0.0429919833271212859,0.00570196001226947087],"hpluv":[43.6144672720514848,180.944734702515461,24.6368918170402651],"hsluv":[43.6144672720514848,100.000000000002245,24.6368918170402651]},"#553311":{"lch":[24.7639934196671305,31.9442274162558917,39.8156129865950632],"luv":[24.7639934196671305,24.536650698978292,20.4544967598277161],"rgb":[0.333333333333333315,0.2,0.0666666666666666657],"xyz":[0.0503116974659563593,0.0433966495269761388,0.0110300649770251023],"hpluv":[39.8156129865950632,163.685811409294416,24.7639934196671305],"hsluv":[39.8156129865950632,85.3309596574143256,24.7639934196671305]},"#553322":{"lch":[24.9975315322943885,26.9096454002331456,31.2519949010175395],"luv":[24.9975315322943885,23.0048892205904032,13.9608054035092266],"rgb":[0.333333333333333315,0.2,0.133333333333333331],"xyz":[0.0521870556044333814,0.0441467927823669601,0.0209069511730043],"hpluv":[31.2519949010175395,136.59983556614165,24.9975315322943885],"hsluv":[31.2519949010175395,60.4417762068684823,24.9975315322943885]},"#553333":{"lch":[25.3763514371309924,21.2787516643900716,12.1770506300621495],"luv":[25.3763514371309924,20.7999895475976082,4.48839695377019332],"rgb":[0.333333333333333315,0.2,0.2],"xyz":[0.0552748063368911219,0.0453818930753500729,0.0371691050306154416],"hpluv":[12.1770506300621495,106.403592780468983,25.3763514371309924],"hsluv":[12.1770506300621495,24.9336598370546909,25.3763514371309924]},"#553344":{"lch":[25.9113402150992655,19.4972565515274532,338.627269772390264],"luv":[25.9113402150992655,18.1564179844864455,-7.10545558065754257],"rgb":[0.333333333333333315,0.2,0.266666666666666663],"xyz":[0.05973280158111,0.047165091173037646,0.0606478799835020801],"hpluv":[338.627269772390264,95.4823185470749536,25.9113402150992655],"hsluv":[338.627269772390264,32.9723178491547841,25.9113402150992655]},"#553355":{"lch":[26.6061908173450519,25.0719265662328183,307.715012949245363],"luv":[26.6061908173450519,15.3373584467403763,-19.8334802195371829],"rgb":[0.333333333333333315,0.2,0.333333333333333315],"xyz":[0.065695215620472,0.0495500567887824789,0.0920499272574759886],"hpluv":[307.715012949245363,119.576085528419512,26.6061908173450519],"hsluv":[307.715012949245363,41.369683748934996,26.6061908173450519]},"#553366":{"lch":[27.4586282592714284,35.2024776289392847,290.893042573756475],"luv":[27.4586282592714284,12.5540679631371699,-32.8878367910220533],"rgb":[0.333333333333333315,0.2,0.4],"xyz":[0.0732802113939801658,0.0525840550981857904,0.13199757166461995],"hpluv":[290.893042573756475,162.679833835368925,27.4586282592714284],"hsluv":[290.893042573756475,49.429407074258,27.4586282592714284]},"#553377":{"lch":[28.461655060413058,46.8206771520520633,282.253113271302652],"luv":[28.461655060413058,9.93678843358592445,-45.7540822725452898],"rgb":[0.333333333333333315,0.2,0.466666666666666674],"xyz":[0.0825942244141820853,0.0563096603062666068,0.18105137357101786],"hpluv":[282.253113271302652,208.74537696470955,28.461655060413058],"hsluv":[282.253113271302652,56.732994513665389,28.461655060413058]},"#553388":{"lch":[29.6048600369324433,58.6666973974172876,277.388246485053742],"luv":[29.6048600369324433,7.54407762538358551,-58.1796207988872567],"rgb":[0.333333333333333315,0.2,0.533333333333333326],"xyz":[0.0937346415161259133,0.0607658271470442046,0.239724236974590027],"hpluv":[277.388246485053742,251.459446283522851,29.6048600369324433],"hsluv":[277.388246485053742,63.1061783000114715,29.6048600369324433]},"#553399":{"lch":[30.8756880539778678,70.2946203588512759,274.394660626066695],"luv":[30.8756880539778678,5.38640350826703,-70.0879469569565714],"rgb":[0.333333333333333315,0.2,0.6],"xyz":[0.106791605625198627,0.0659886127906733622,0.308490914615707934],"hpluv":[274.394660626066695,288.898157334443908,30.8756880539778678],"hsluv":[274.394660626066695,68.537799314251,30.8756880539778678]},"#5533aa":{"lch":[32.2605562861205,81.571224268378316,272.422737250332261],"luv":[32.2605562861205,3.44819039224039026,-81.498310483475251],"rgb":[0.333333333333333315,0.2,0.66666666666666663],"xyz":[0.121849298590451169,0.0720116899767744567,0.387794764232706535],"hpluv":[272.422737250332261,320.851781583216223,32.2605562861205],"hsluv":[272.422737250332261,73.1042224024611897,32.2605562861205]},"#5533bb":{"lch":[33.7457437232739395,92.4864953275551755,271.055064965734516],"luv":[33.7457437232739395,1.70298313903478205,-92.4708152143261231],"rgb":[0.333333333333333315,0.2,0.733333333333333282],"xyz":[0.138986890697787802,0.0788667268197092153,0.478052749331348281],"hpluv":[271.055064965734516,347.775228922495899,33.7457437232739395],"hsluv":[271.055064965734516,76.9172199670655772,33.7457437232739395]},"#5533cc":{"lch":[35.3180325241442,103.075547069605378,270.067872161558512],"luv":[35.3180325241442,0.12210251098248695,-103.075474748725966],"rgb":[0.333333333333333315,0.2,0.8],"xyz":[0.158279266141509556,0.0865836769971980169,0.579659260001618493],"hpluv":[270.067872161558512,370.338167129355497,35.3180325241442],"hsluv":[270.067872161558512,80.0940957669769205,35.3180325241442]},"#5533dd":{"lch":[36.9651203282397915,113.385246995104879,269.332372034398134],"luv":[36.9651203282397915,-1.32116971635525937,-113.377549570986602],"rgb":[0.333333333333333315,0.2,0.866666666666666696],"xyz":[0.179797591692143099,0.0951910072174515509,0.69298910790162449],"hpluv":[269.332372034398134,389.227711455139399,36.9651203282397915],"hsluv":[269.332372034398134,84.8119298710034855,36.9651203282397915]},"#5533ee":{"lch":[38.6758450270606247,123.460606758128,268.77009087446072],"luv":[38.6758450270606247,-2.64999738284680575,-123.432163292052948],"rgb":[0.333333333333333315,0.2,0.933333333333333348],"xyz":[0.203609771958317837,0.104715879323921596,0.818399923970147714],"hpluv":[268.77009087446072,405.067987408818738,38.6758450270606247],"hsluv":[268.77009087446072,92.2936685874649356,38.6758450270606247]},"#5533ff":{"lch":[40.4402700894382363,133.340096114557781,268.33094335317071],"luv":[40.4402700894382363,-3.88371885476632706,-133.283524712158766],"rgb":[0.333333333333333315,0.2,1],"xyz":[0.22978082036814923,0.115184298687854292,0.956234112261929559],"hpluv":[268.33094335317071,418.394573227645935,40.4402700894382363],"hsluv":[268.33094335317071,99.99999999999946,40.4402700894382363]},"#ccbb00":{"lch":[75.0632334950121418,83.0331806403360275,77.5616137481136292],"luv":[75.0632334950121418,17.8844849446013434,81.0842419062853423],"rgb":[0.8,0.733333333333333282,0],"xyz":[0.426708295646073654,0.483788158566022,0.0709042957418917],"hpluv":[77.5616137481136292,140.366584388758554,75.0632334950121418],"hsluv":[77.5616137481136292,100.000000000002373,75.0632334950121418]},"#ccbb11":{"lch":[75.0886164663743898,81.9438461169387438,77.472162284636525],"luv":[75.0886164663743898,17.7747618107910519,79.9928231718707394],"rgb":[0.8,0.733333333333333282,0.0666666666666666657],"xyz":[0.427719961145710759,0.484192824765876828,0.0762324007066473436],"hpluv":[77.472162284636525,138.478250548668058,75.0886164663743898],"hsluv":[77.472162284636525,98.6397508878022222,75.0886164663743898]},"#ccbb22":{"lch":[75.1356323460541802,79.9401497843360289,77.301186242421764],"luv":[75.1356323460541802,17.5729239259544805,77.9847414064744839],"rgb":[0.8,0.733333333333333282,0.133333333333333331],"xyz":[0.429595319284187815,0.484942968021267629,0.0861092869026265362],"hpluv":[77.301186242421764,135.007637737713509,75.1356323460541802],"hsluv":[77.301186242421764,96.1390577710114087,75.1356323460541802]},"#ccbb33":{"lch":[75.2129378077961235,76.6847204783522471,77.0041162235267223],"luv":[75.2129378077961235,17.2449407213965777,74.720535158405653],"rgb":[0.8,0.733333333333333282,0.2],"xyz":[0.432683070016645521,0.486178068314250755,0.102371440760237686],"hpluv":[77.0041162235267223,129.376563997369885,75.2129378077961235],"hsluv":[77.0041162235267223,92.0797058264172392,75.2129378077961235]},"#ccbb44":{"lch":[75.3243183189310628,72.0782997366288,76.5373230188340585],"luv":[75.3243183189310628,16.7806861485978907,70.0977165484408431],"rgb":[0.8,0.733333333333333282,0.266666666666666663],"xyz":[0.437141065260864436,0.487961266411938321,0.125850215713124325],"hpluv":[76.5373230188340585,121.425150369898518,75.3243183189310628],"hsluv":[76.5373230188340585,86.34290383100182,75.3243183189310628]},"#ccbb55":{"lch":[75.4728625341146397,66.0852327898053,75.831238609121371],"luv":[75.4728625341146397,16.1762634357197506,64.0748507149330351],"rgb":[0.8,0.733333333333333282,0.333333333333333315],"xyz":[0.443103479300226422,0.490346232027683182,0.157252262987098212],"hpluv":[75.831238609121371,111.10994393806304,75.4728625341146397],"hsluv":[75.831238609121371,78.8905565478608395,75.4728625341146397]},"#ccbb66":{"lch":[75.6611363515091284,58.7289677793131,74.7643785098968863],"luv":[75.6611363515091284,15.4333320312120961,56.6648384700597134],"rgb":[0.8,0.733333333333333282,0.4],"xyz":[0.450688475073734607,0.493380230337086501,0.197199907394242202],"hpluv":[74.7643785098968863,98.4960546107130739,75.6611363515091284],"hsluv":[74.7643785098968863,69.7569980114599701,75.6611363515091284]},"#ccbb77":{"lch":[75.8912747684230737,50.090867045562554,73.1036630558194389],"luv":[75.8912747684230737,14.5584607724557671,47.9285528814827799],"rgb":[0.8,0.733333333333333282,0.466666666666666674],"xyz":[0.460002488093936512,0.497105835545167296,0.246253709300640111],"hpluv":[73.1036630558194389,83.7540906733876795,75.8912747684230737],"hsluv":[73.1036630558194389,59.0406908273499624,75.8912747684230737]},"#ccbb88":{"lch":[76.1650362860674335,40.3168412407358332,70.3426656865815119],"luv":[76.1650362860674335,13.5623472284534756,37.9672283066009157],"rgb":[0.8,0.733333333333333282,0.533333333333333326],"xyz":[0.471142905195880313,0.501562002385944838,0.304926572704212251],"hpluv":[70.3426656865815119,67.6831847004182379,76.1650362860674335],"hsluv":[70.3426656865815119,46.8939441374685586,76.1650362860674335]},"#ccbb99":{"lch":[76.4838383644648871,29.6573629081618826,65.1594516064859732],"luv":[76.4838383644648871,12.4588924968264081,26.9134756658990248],"rgb":[0.8,0.733333333333333282,0.6],"xyz":[0.484199869304953068,0.506784788029574,0.373693250345330186],"hpluv":[65.1594516064859732,50.6096239917615662,76.4838383644648871],"hsluv":[65.1594516064859732,33.5105935092195324,76.4838383644648871]},"#ccbbaa":{"lch":[76.8487828748923,18.695758935396551,52.9508743401004551],"luv":[76.8487828748923,11.26418644921627,14.9214444946778713],"rgb":[0.8,0.733333333333333282,0.66666666666666663],"xyz":[0.499257562270205568,0.512807865215675118,0.452997099962328786],"hpluv":[52.9508743401004551,32.5142912020767696,76.8487828748923],"hsluv":[52.9508743401004551,19.1124274046376854,76.8487828748923]},"#ccbbbb":{"lch":[77.2606763328388126,10.2255548171674207,12.1770506300639045],"luv":[77.2606763328388126,9.99548454110707,2.15690985147396086],"rgb":[0.8,0.733333333333333282,0.733333333333333282],"xyz":[0.516395154377542243,0.519662902058609877,0.543255085060970533],"hpluv":[12.1770506300639045,18.1733155366010308,77.2606763328388126],"hsluv":[12.1770506300639045,17.1437484893634,77.2606763328388126]},"#ccbbcc":{"lch":[77.7200476270310361,14.1732404034447406,307.715012949257925],"luv":[77.7200476270310361,8.67025786172679247,-11.2119299027867267],"rgb":[0.8,0.733333333333333282,0.8],"xyz":[0.535687529821264,0.527379852236098734,0.644861595731240689],"hpluv":[307.715012949257925,25.815587331502627,77.7200476270310361],"hsluv":[307.715012949257925,18.1614974693692588,77.7200476270310361]},"#ccbbdd":{"lch":[78.2271648233418375,26.0669286991650679,286.275412631614586],"luv":[78.2271648233418375,7.3053819239814537,-25.022313377306272],"rgb":[0.8,0.733333333333333282,0.866666666666666696],"xyz":[0.557205855371897485,0.53598718245635224,0.758191443631246687],"hpluv":[286.275412631614586,48.8074477639820898,78.2271648233418375],"hsluv":[286.275412631614586,43.4510455050629929,78.2271648233418375]},"#ccbbee":{"lch":[78.7820519440635,39.5678846485468299,278.599571826643512],"luv":[78.7820519440635,5.9165048525659989,-39.1230426461218741],"rgb":[0.8,0.733333333333333282,0.933333333333333348],"xyz":[0.581018035638072305,0.545512054562822257,0.88360225969976991],"hpluv":[278.599571826643512,76.4037468789834,78.7820519440635],"hsluv":[278.599571826643512,70.6968150087455314,78.7820519440635]},"#ccbbff":{"lch":[79.3845061922316546,53.5695670840829834,274.837592460092935],"luv":[79.3845061922316546,4.51760925339512553,-53.3787385033564235],"rgb":[0.8,0.733333333333333282,1],"xyz":[0.607189084047903616,0.555980473926755,1.02143644799155164],"hpluv":[274.837592460092935,107.038572744282547,79.3845061922316546],"hsluv":[274.837592460092935,99.9999999999963762,79.3845061922316546]},"#554400":{"lch":[29.5776499109456879,34.0768703371065413,65.9474553070004674],"luv":[29.5776499109456879,13.8888553561515469,31.1180460322924546],"rgb":[0.333333333333333315,0.266666666666666663,0],"xyz":[0.0581326024492852811,0.0606571242930536,0.0086461501732580659],"hpluv":[65.9474553070004674,146.195957524823825,29.5776499109456879],"hsluv":[65.9474553070004674,100.000000000002217,29.5776499109456879]},"#554411":{"lch":[29.6787804923011507,30.8713815411758574,64.2244588846852906],"luv":[29.6787804923011507,13.4243191404277429,27.7998175151708296],"rgb":[0.333333333333333315,0.266666666666666663,0.0666666666666666657],"xyz":[0.0591442679489224,0.0610617904929084548,0.0139742551380136974],"hpluv":[64.2244588846852906,131.992525946838612,29.6787804923011507],"hsluv":[64.2244588846852906,89.4077694450363509,29.6787804923011507]},"#554422":{"lch":[29.8650740872788916,25.3442505658492152,60.1547603291711539],"luv":[29.8650740872788916,12.6127938179319639,21.9829131111162219],"rgb":[0.333333333333333315,0.266666666666666663,0.133333333333333331],"xyz":[0.0610196260873994215,0.0618119337482992762,0.0238511413339928952],"hpluv":[60.1547603291711539,107.684992873038837,29.8650740872788916],"hsluv":[60.1547603291711539,70.9921927199271892,29.8650740872788916]},"#554433":{"lch":[30.1685472793317686,17.4710669916127905,49.2680266756281497],"luv":[30.1685472793317686,11.400244593092479,13.2390560480378525],"rgb":[0.333333333333333315,0.266666666666666663,0.2],"xyz":[0.064107376819857162,0.0630470340412823821,0.0401132951916040384],"hpluv":[49.2680266756281497,73.4859575586117302,30.1685472793317686],"hsluv":[49.2680266756281497,43.7071568358896,30.1685472793317686]},"#554444":{"lch":[30.5997780424982437,10.1013456632853149,12.1770506300629258],"luv":[30.5997780424982437,9.87407003600776356,2.13071000682558],"rgb":[0.333333333333333315,0.266666666666666663,0.266666666666666663],"xyz":[0.0685653720640760356,0.0648302321389699621,0.06359207014449067],"hpluv":[12.1770506300629258,41.8890279889816597,30.5997780424982437],"hsluv":[12.1770506300629258,9.81589763549682282,30.5997780424982437]},"#554455":{"lch":[31.1643459369041338,13.3310860490153988,307.715012949249],"luv":[31.1643459369041338,8.15508312366709198,-10.5457325251654854],"rgb":[0.333333333333333315,0.266666666666666663,0.333333333333333315],"xyz":[0.0745277861034380346,0.0672151977547148,0.0949941174184645853],"hpluv":[307.715012949249,54.2808752323906702,31.1643459369041338],"hsluv":[307.715012949249,18.7795296363480162,31.1643459369041338]},"#554466":{"lch":[31.8635722620044533,24.8340912161126894,284.841165372516684],"luv":[31.8635722620044533,6.36101223964894835,-24.005616214070443],"rgb":[0.333333333333333315,0.266666666666666663,0.4],"xyz":[0.0821127818769462,0.0702491960641181135,0.134941761825608547],"hpluv":[284.841165372516684,98.8992811700442331,31.8635722620044533],"hsluv":[284.841165372516684,27.8963704264996828,31.8635722620044533]},"#554477":{"lch":[32.6951743277909443,37.9095930577936784,276.944338121378166],"luv":[32.6951743277909443,4.58346102749711282,-37.6314912117090259],"rgb":[0.333333333333333315,0.266666666666666663,0.466666666666666674],"xyz":[0.0914267948971481254,0.0739748012721989229,0.183995563732006456],"hpluv":[276.944338121378166,147.131204947893167,32.6951743277909443],"hsluv":[276.944338121378166,36.6308714978363952,32.6951743277909443]},"#554488":{"lch":[33.6539551717380903,51.1018638808679526,273.231940865766],"luv":[33.6539551717380903,2.88102600900669881,-51.0205858574182116],"rgb":[0.333333333333333315,0.266666666666666663,0.533333333333333326],"xyz":[0.102567211999091953,0.0784309681129765207,0.242668427135578624],"hpluv":[273.231940865766,192.681471981123309,33.6539551717380903],"hsluv":[273.231940865766,44.6505812495932801,33.6539551717380903]},"#554499":{"lch":[34.7325237210335871,63.9719124096453271,271.149517924849135],"luv":[34.7325237210335871,1.28337422751110575,-63.9590378909774913],"rgb":[0.333333333333333315,0.266666666666666663,0.6],"xyz":[0.115624176108164667,0.0836537537566056782,0.311435104776696559],"hpluv":[271.149517924849135,233.718085138698228,34.7325237210335871],"hsluv":[271.149517924849135,51.7999710200133876,34.7325237210335871]},"#5544aa":{"lch":[35.9219992682327671,76.3678985235758461,269.849629436139082],"luv":[35.9219992682327671,-0.200424374653859844,-76.367635520403681],"rgb":[0.333333333333333315,0.266666666666666663,0.66666666666666663],"xyz":[0.130681869073417223,0.0896768309427067867,0.390738954393695104],"hpluv":[269.849629436139082,269.767524553786757,35.9219992682327671],"hsluv":[269.849629436139082,58.0490239963672465,35.9219992682327671]},"#5544bb":{"lch":[37.2126506061998725,88.2627815084196925,268.978337620063314],"luv":[37.2126506061998725,-1.57376312233016602,-88.2487499584998574],"rgb":[0.333333333333333315,0.266666666666666663,0.733333333333333282],"xyz":[0.147819461180753842,0.0965318677856415452,0.480996939492336906],"hpluv":[268.978337620063314,300.972163983169935,37.2126506061998725],"hsluv":[268.978337620063314,66.0075029321504729,37.2126506061998725]},"#5544cc":{"lch":[38.5944341452357733,99.6871153018899605,268.363808876145868],"luv":[38.5944341452357733,-2.84637030136680202,-99.6464707519528758],"rgb":[0.333333333333333315,0.266666666666666663,0.8],"xyz":[0.167111836624475596,0.104248817963130347,0.582603450162607062],"hpluv":[268.363808876145868,327.758284181939189,38.5944341452357733],"hsluv":[268.363808876145868,74.5283681063652352,38.5944341452357733]},"#5544dd":{"lch":[40.0574145710935738,110.694467066426,267.913412719582],"luv":[40.0574145710935738,-4.03035995406870118,-110.621070496360275],"rgb":[0.333333333333333315,0.266666666666666663,0.866666666666666696],"xyz":[0.18863016217510914,0.112856148183383881,0.695933298062613059],"hpluv":[267.913412719582,350.65684831918054,40.0574145710935738],"hsluv":[267.913412719582,82.9425769408534,40.0574145710935738]},"#5544ee":{"lch":[41.5920687629554777,121.343449115737442,267.573227144435918],"luv":[41.5920687629554777,-5.13798666158471651,-121.23462268002875],"rgb":[0.333333333333333315,0.266666666666666663,0.933333333333333348],"xyz":[0.212442342441283877,0.122381020289853898,0.821344114131136283],"hpluv":[267.573227144435918,370.207437425804358,41.5920687629554777],"hsluv":[267.573227144435918,91.3878688389195872,41.5920687629554777]},"#5544ff":{"lch":[43.1894854939413833,131.689092168021887,267.309962581974105],"luv":[43.1894854939413833,-6.18053297470727,-131.543977468321657],"rgb":[0.333333333333333315,0.266666666666666663,1],"xyz":[0.23861339085111527,0.132849439653786594,0.959178302422918128],"hpluv":[267.309962581974105,386.911020330846497,43.1894854939413833],"hsluv":[267.309962581974105,99.9999999999994174,43.1894854939413833]},"#cccc00":{"lch":[79.627228346343,87.7811065558180132,85.8743202181747449],"luv":[79.627228346343,6.31536666608958797,87.5536339167982192],"rgb":[0.8,0.8,0],"xyz":[0.464932038955690574,0.560235645185256814,0.0836455435117636481],"hpluv":[85.8743202181747449,177.871840357077815,79.627228346343],"hsluv":[85.8743202181747449,100.000000000002245,79.627228346343]},"#cccc11":{"lch":[79.6502471087807891,86.7718911178833707,85.8743202181747],"luv":[79.6502471087807891,6.24275917928854351,86.5470337215737],"rgb":[0.8,0.8,0.0666666666666666657],"xyz":[0.465943704455327679,0.560640311385111723,0.0889736484765192848],"hpluv":[85.8743202181747,176.061859354342118,79.6502471087807891],"hsluv":[85.8743202181747,98.8217369524532927,79.6502471087807891]},"#cccc22":{"lch":[79.6928884771461838,84.9132131482774497,85.8743202181746597],"luv":[79.6928884771461838,6.10903754655005482,84.6931722597497298],"rgb":[0.8,0.8,0.133333333333333331],"xyz":[0.467819062593804735,0.561390454640502523,0.0988505346724984774],"hpluv":[85.8743202181746597,172.717957044242922,79.6928884771461838],"hsluv":[85.8743202181746597,96.653203912443459,79.6928884771461838]},"#cccc33":{"lch":[79.7630142061039891,81.8867831673476445,85.8743202181745602],"luv":[79.7630142061039891,5.89130259459140682,81.6745848549912665],"rgb":[0.8,0.8,0.2],"xyz":[0.470906813326262441,0.56262555493348565,0.115112688530109614],"hpluv":[85.8743202181745602,167.243641009868185,79.7630142061039891],"hsluv":[85.8743202181745602,93.1263971058523623,79.7630142061039891]},"#cccc44":{"lch":[79.8640786601047523,77.5899505798540901,85.8743202181744],"luv":[79.8640786601047523,5.58216917901353593,77.3888869169280156],"rgb":[0.8,0.8,0.266666666666666663],"xyz":[0.475364808570481356,0.564408753031173216,0.138591463482996252],"hpluv":[85.8743202181744,159.406599578518,79.8640786601047523],"hsluv":[85.8743202181744,88.1281264379617113,79.8640786601047523]},"#cccc55":{"lch":[79.9989166638852396,71.9729259129294832,85.8743202181741481],"luv":[79.9989166638852396,5.17805522174052,71.7864179952492236],"rgb":[0.8,0.8,0.333333333333333315],"xyz":[0.481327222609843342,0.566793718646918,0.169993510756970168],"hpluv":[85.8743202181741481,149.042041148428552,79.9989166638852396],"hsluv":[85.8743202181741481,81.6104176612222147,79.9989166638852396]},"#cccc66":{"lch":[80.1699032642976448,65.0330295388014,85.8743202181738],"luv":[80.1699032642976448,4.67876793832737103,64.8645054060685453],"rgb":[0.8,0.8,0.4],"xyz":[0.488912218383351527,0.569827716956321284,0.209941155164114129],"hpluv":[85.8743202181738,136.038559250079544,80.1699032642976448],"hsluv":[85.8743202181738,73.5839630734023,80.1699032642976448]},"#cccc77":{"lch":[80.3790384438565724,56.8098315426934803,85.8743202181733096],"luv":[80.3790384438565724,4.0871541782499472,56.6626166941875837],"rgb":[0.8,0.8,0.466666666666666674],"xyz":[0.498226231403553432,0.573553322164402135,0.258994957070512],"hpluv":[85.8743202181733096,120.326663009793734,80.3790384438565724],"hsluv":[85.8743202181733096,64.1122831116318252,80.3790384438565724]},"#cccc88":{"lch":[80.6279973255091704,47.3795499902223085,85.8743202181724854],"luv":[80.6279973255091704,3.40869741112766222,47.2567724166107865],"rgb":[0.8,0.8,0.533333333333333326],"xyz":[0.509366648505497288,0.578009489005179677,0.317667820474084206],"hpluv":[85.8743202181724854,101.866799769447482,80.6279973255091704],"hsluv":[85.8743202181724854,53.3047126681541172,80.6279973255091704]},"#cccc99":{"lch":[80.9181626169042119,36.8483625211582861,85.8743202181711496],"luv":[80.9181626169042119,2.65103653276840934,36.7528750683892724],"rgb":[0.8,0.8,0.6],"xyz":[0.522423612614569932,0.58323227464880889,0.386434498115202141],"hpluv":[85.8743202181711496,80.635831276566,80.9181626169042119],"hsluv":[85.8743202181711496,41.30786304104587,80.9181626169042119]},"#ccccaa":{"lch":[81.2506473976222452,25.3448572993520607,85.8743202181683216],"luv":[81.2506473976222452,1.82342275263520492,25.27917959487],"rgb":[0.8,0.8,0.66666666666666663],"xyz":[0.537481305579822544,0.58925535183491,0.465738347732200686],"hpluv":[85.8743202181683216,56.6117825452175509,81.2506473976222452],"hsluv":[85.8743202181683216,28.2959036617823898,81.2506473976222452]},"#ccccbb":{"lch":[81.6263125989092657,13.0121158497344798,85.8743202181599],"luv":[81.6263125989092657,0.936149997616518514,12.9783967449324749],"rgb":[0.8,0.8,0.733333333333333282],"xyz":[0.554618897687159107,0.596110388677844716,0.555996332830842488],"hpluv":[85.8743202181599,29.7570160502500514,81.6263125989092657],"hsluv":[85.8743202181599,14.4603328966824272,81.6263125989092657]},"#cccccc":{"lch":[82.0457816743453,4.34523248843710382e-12,0],"luv":[82.0457816743453,4.08534684758697557e-12,1.48019813318368677e-12],"rgb":[0.8,0.8,0.8],"xyz":[0.573911273130880861,0.603827338855333573,0.657602843501112644],"hpluv":[0,1.02065966511349575e-11,82.0457816743453],"hsluv":[0,1.01642596056880755e-11,82.0457816743453]},"#ccccdd":{"lch":[82.5094539517328087,13.5418343873660199,265.874320218194214],"luv":[82.5094539517328087,-0.974260325972223118,-13.5067425899839115],"rgb":[0.8,0.8,0.866666666666666696],"xyz":[0.59542959868151446,0.612434669075587079,0.770932691401118642],"hpluv":[265.874320218194214,32.7843842039110882,82.5094539517328087],"hsluv":[265.874320218194214,30.4637656032122131,82.5094539517328087]},"#ccccee":{"lch":[83.0175175610870895,27.4698052042972165,265.874320218185687],"luv":[83.0175175610870895,-1.97630103922669687,-27.3986209901955817],"rgb":[0.8,0.8,0.933333333333333348],"xyz":[0.61924177894768917,0.621959541182057096,0.896343507469641865],"hpluv":[265.874320218185687,68.7964750954906776,83.0175175610870895],"hsluv":[265.874320218185687,63.7216981471091941,83.0175175610870895]},"#ccccff":{"lch":[83.5699624582004219,41.6509292947620153,265.874320218182845],"luv":[83.5699624582004219,-2.99655473483939438,-41.5429966521238825],"rgb":[0.8,0.8,1],"xyz":[0.645412827357520591,0.63242796054598982,1.03417769576142371],"hpluv":[265.874320218182845,108.336501116640306,83.5699624582004219],"hsluv":[265.874320218182845,99.9999999999952536,83.5699624582004219]},"#555500":{"lch":[34.8595382729148753,38.4291768930055397,85.8743202181747307],"luv":[34.8595382729148753,2.76476741155027961,38.3295929776711901],"rgb":[0.333333333333333315,0.333333333333333315,0],"xyz":[0.0699458591636312466,0.084283637721745866,0.0125839024113732767],"hpluv":[85.8743202181747307,139.887458074797564,34.8595382729148753],"hsluv":[85.8743202181747307,100.000000000002331,34.8595382729148753]},"#555511":{"lch":[34.9408046802893,35.5443725161734108,85.8743202181745318],"luv":[34.9408046802893,2.55722164100294558,35.4522641737772517],"rgb":[0.333333333333333315,0.333333333333333315,0.0666666666666666657],"xyz":[0.0709575246632683648,0.0846883039216007188,0.0179120073761289064],"hpluv":[85.8743202181745318,129.085444875460666,34.9408046802893],"hsluv":[85.8743202181745318,92.2780688504912,34.9408046802893]},"#555522":{"lch":[35.0907688239250604,30.4130442263608813,85.8743202181740202],"luv":[35.0907688239250604,2.18805086034508589,30.3342330139914047],"rgb":[0.333333333333333315,0.333333333333333315,0.133333333333333331],"xyz":[0.0728328828017454,0.0854384471769915332,0.027788893572108106],"hpluv":[85.8743202181740202,109.978131404858061,35.0907688239250604],"hsluv":[85.8743202181740202,78.6190076783406653,35.0907688239250604]},"#555533":{"lch":[35.3357817552570097,22.5221214621125654,85.8743202181728549],"luv":[35.3357817552570097,1.62034247131604014,22.4637584885032275],"rgb":[0.333333333333333315,0.333333333333333315,0.2],"xyz":[0.0759206335342031274,0.0866735474699746461,0.0440510474297192492],"hpluv":[85.8743202181728549,80.8786547215116656,35.3357817552570097],"hsluv":[85.8743202181728549,57.8169450175211566,35.3357817552570097]},"#555544":{"lch":[35.6854507669058592,12.1926559388895619,85.8743202181691743],"luv":[35.6854507669058592,0.877194374836262392,12.1610603515028455],"rgb":[0.333333333333333315,0.333333333333333315,0.266666666666666663],"xyz":[0.080378628778422,0.0884567455676622261,0.0675298223826058808],"hpluv":[85.8743202181691743,43.355725530805,35.6854507669058592],"hsluv":[85.8743202181691743,30.9932899828832262,35.6854507669058592]},"#555555":{"lch":[36.1458508397197278,1.89718584003012571e-12,0],"luv":[36.1458508397197278,1.79982851973451413e-12,5.9994283991150471e-13],"rgb":[0.333333333333333315,0.333333333333333315,0.333333333333333315],"xyz":[0.086341042817784,0.090841711183407059,0.0989318696565798],"hpluv":[0,6.66025333978279224e-12,36.1458508397197278],"hsluv":[0,1.90696849203660445e-12,36.1458508397197278]},"#555566":{"lch":[36.7200402720523087,13.391014832031539,265.874320218184835],"luv":[36.7200402720523087,-0.963409690459316,-13.3563138627398903],"rgb":[0.333333333333333315,0.333333333333333315,0.4],"xyz":[0.0939260385912921714,0.0938757094928103775,0.138879514063723758],"hpluv":[265.874320218184835,46.2753453717946712,36.7200402720523087],"hsluv":[265.874320218184835,10.0205788523093844,36.7200402720523087]},"#555577":{"lch":[37.4084382237490445,27.3651172837118537,265.874320218181],"luv":[37.4084382237490445,-1.96876932050326592,-27.294204353927416],"rgb":[0.333333333333333315,0.333333333333333315,0.466666666666666674],"xyz":[0.103240051611494091,0.0976013147008911869,0.187933315970121667],"hpluv":[265.874320218181,92.8254499938530131,37.4084382237490445],"hsluv":[265.874320218181,20.457601163446,37.4084382237490445]},"#555588":{"lch":[38.2091925227490421,41.4380747403329508,265.874320218179832],"luv":[38.2091925227490421,-2.98124102314999906,-41.330693680935326],"rgb":[0.333333333333333315,0.333333333333333315,0.533333333333333326],"xyz":[0.114380468713437919,0.102057481541668785,0.246606179373693835],"hpluv":[265.874320218179832,137.616667264503377,38.2091925227490421],"hsluv":[265.874320218179832,30.9677616121988244,38.2091925227490421]},"#555599":{"lch":[39.1185695394092079,55.2798607696674651,265.874320218179207],"luv":[39.1185695394092079,-3.97708121608675258,-55.1366106295487626],"rgb":[0.333333333333333315,0.333333333333333315,0.6],"xyz":[0.127437432822510632,0.107280267185297942,0.315372857014811769],"hpluv":[265.874320218179207,179.317758559659353,39.1185695394092079],"hsluv":[265.874320218179207,41.3377460212352688,39.1185695394092079]},"#5555aa":{"lch":[40.1313601009005083,68.6985541131433166,265.874320218178866],"luv":[40.1313601009005083,-4.94248222285034178,-68.5205312786852829],"rgb":[0.333333333333333315,0.333333333333333315,0.66666666666666663],"xyz":[0.142495125787763188,0.113303344371399051,0.394676706631810315],"hpluv":[265.874320218178866,217.221618066114,40.1313601009005083],"hsluv":[265.874320218178866,51.4705865731736907,40.1313601009005083]},"#5555bb":{"lch":[41.2412811653463791,81.6070675548115787,265.874320218178639],"luv":[41.2412811653463791,-5.8711785983783864,-81.3955940869131],"rgb":[0.333333333333333315,0.333333333333333315,0.733333333333333282],"xyz":[0.159632717895099807,0.120158381214333809,0.484934691730452117],"hpluv":[265.874320218178639,251.093199488524249,41.2412811653463791],"hsluv":[265.874320218178639,61.3584924374872642,41.2412811653463791]},"#5555cc":{"lch":[42.4413509436270431,93.9883543596933,265.874320218178468],"luv":[42.4413509436270431,-6.76194392407029365,-93.7447964935174838],"rgb":[0.333333333333333315,0.333333333333333315,0.8],"xyz":[0.178925093338821561,0.127875331391822611,0.586541202400722272],"hpluv":[265.874320218178468,281.011551484187919,42.4413509436270431],"hsluv":[265.874320218178468,71.0546332315999791,42.4413509436270431]},"#5555dd":{"lch":[43.7242196004532389,105.866759380085014,265.874320218178411],"luv":[43.7242196004532389,-7.61652967783202328,-105.592420264465588],"rgb":[0.333333333333333315,0.333333333333333315,0.866666666666666696],"xyz":[0.200443418889455105,0.136482661612076145,0.69987105030072827],"hpluv":[265.874320218178411,307.239379297131052,43.7242196004532389],"hsluv":[265.874320218178411,80.6500300064864462,43.7242196004532389]},"#5555ee":{"lch":[45.0824447652298588,117.287521338877212,265.874320218178354],"luv":[45.0824447652298588,-8.43819053636753402,-116.983586892732674],"rgb":[0.333333333333333315,0.333333333333333315,0.933333333333333348],"xyz":[0.224255599155629842,0.146007533718546162,0.825281866369251493],"hpluv":[265.874320218178354,330.128999417958312,45.0824447652298588],"hsluv":[265.874320218178354,90.2572110855712708,45.0824447652298588]},"#5555ff":{"lch":[46.508708270344421,128.30356479361032,265.874320218178241],"luv":[46.508708270344421,-9.23073412981071,-127.971083789162734],"rgb":[0.333333333333333315,0.333333333333333315,1],"xyz":[0.250426647565461236,0.156475953082478858,0.963116054661033338],"hpluv":[265.874320218178241,350.061034522531031,46.508708270344421],"hsluv":[265.874320218178241,99.9999999999992468,46.508708270344421]},"#ccdd00":{"lch":[84.2515012159558552,94.1174138813685772,92.7819892835375555],"luv":[84.2515012159558552,-4.56806363508048818,94.0064912138661128],"rgb":[0.8,0.866666666666666696,0],"xyz":[0.507566029502865779,0.645503626279608334,0.0978568736941549666],"hpluv":[92.7819892835375555,256.902059824464118,84.2515012159558552],"hsluv":[92.7819892835375555,100.000000000002373,84.2515012159558552]},"#ccdd11":{"lch":[84.2724460606142287,93.1910749716768692,92.8373396690251695],"luv":[84.2724460606142287,-4.61302172096193619,93.0768310858219508],"rgb":[0.8,0.866666666666666696,0.0666666666666666657],"xyz":[0.508577695002502939,0.645908292479463242,0.103184978658910603],"hpluv":[92.8373396690251695,254.758074317949962,84.2724460606142287],"hsluv":[92.8373396690251695,98.9747327605244465,84.2724460606142287]},"#ccdd22":{"lch":[84.3112490917695396,91.4838404394451175,92.9423140418060711],"luv":[84.3112490917695396,-4.69591125178302349,91.3632392106652],"rgb":[0.8,0.866666666666666696,0.133333333333333331],"xyz":[0.510453053140979884,0.646658435734854,0.113061864854889796],"hpluv":[92.9423140418060711,250.792999873820406,84.3112490917695396],"hsluv":[92.9423140418060711,97.0860193213801637,84.3112490917695396]},"#ccdd33":{"lch":[84.3750724084435291,88.7007441607730271,93.1221866378423329],"luv":[84.3750724084435291,-4.83112791130122865,88.5690816130525],"rgb":[0.8,0.866666666666666696,0.2],"xyz":[0.513540803873437701,0.647893536027837169,0.129324018712500932],"hpluv":[93.1221866378423329,244.290353733928498,84.3750724084435291],"hsluv":[93.1221866378423329,94.0094146319777,84.3750724084435291]},"#ccdd44":{"lch":[84.4670755276021197,84.7426243382763857,93.3985511967960491],"luv":[84.4670755276021197,-5.02363867224446459,84.5935897939611152],"rgb":[0.8,0.866666666666666696,0.266666666666666663],"xyz":[0.517998799117656561,0.649676734125524735,0.152802793665387571],"hpluv":[93.3985511967960491,234.956854948695792,84.4670755276021197],"hsluv":[93.3985511967960491,89.638788485123,84.4670755276021197]},"#ccdd55":{"lch":[84.5898637292301601,79.5568981087007359,93.8026723407881633],"luv":[84.5898637292301601,-5.27624840258561711,79.3817437416967095],"rgb":[0.8,0.866666666666666696,0.333333333333333315],"xyz":[0.523961213157018491,0.652061699741269485,0.184204840939361486],"hpluv":[93.8026723407881633,222.570337020009788,84.5898637292301601],"hsluv":[93.8026723407881633,83.9211409492819485,84.5898637292301601]},"#ccdd66":{"lch":[84.7456349568684857,73.1331501088793772,94.3836122863904],"luv":[84.7456349568684857,-5.58984810871231,72.9192103836116],"rgb":[0.8,0.866666666666666696,0.4],"xyz":[0.531546208930526731,0.655095698050672803,0.224152485346505448],"hpluv":[94.3836122863904,206.963810787645969,84.7456349568684857],"hsluv":[94.3836122863904,76.851201462777,84.7456349568684857]},"#ccdd77":{"lch":[84.9362580835765186,65.5005774458529828,95.2238145131341156],"luv":[84.9362580835765186,-5.96359854749608687,65.2285300930849274],"rgb":[0.8,0.866666666666666696,0.466666666666666674],"xyz":[0.540860221950728581,0.658821303258753654,0.273206287252903357],"hpluv":[95.2238145131341156,188.015270942662227,84.9362580835765186],"hsluv":[95.2238145131341156,68.4671748287691,84.9362580835765186]},"#ccdd88":{"lch":[85.1633194008604733,56.7265968622164536,96.4730545580279],"luv":[85.1633194008604733,-6.39512608731957588,56.3649638862273221],"rgb":[0.8,0.866666666666666696,0.533333333333333326],"xyz":[0.552000639052672493,0.663277470099531197,0.331879150656475552],"hpluv":[96.4730545580279,165.642146962004915,85.1633194008604733],"hsluv":[96.4730545580279,58.8458897999489707,85.1633194008604733]},"#ccdd99":{"lch":[85.4281525463895548,46.9188240443766134,98.432972024211054],"luv":[85.4281525463895548,-6.88075351903593724,46.4115425375783843],"rgb":[0.8,0.866666666666666696,0.6],"xyz":[0.565057603161745137,0.66850025574316041,0.400645828297593432],"hpluv":[98.432972024211054,139.807612964747022,85.4281525463895548],"hsluv":[98.432972024211054,48.0968721297954644,85.4281525463895548]},"#ccddaa":{"lch":[85.7318592309590457,36.2402041704229134,101.807730551991185],"luv":[85.7318592309590457,-7.41576493035038453,35.4733537857886176],"rgb":[0.8,0.866666666666666696,0.66666666666666663],"xyz":[0.580115296126997748,0.674523332929261477,0.479949677914592032],"hpluv":[101.807730551991185,110.570541660882469,85.7318592309590457],"hsluv":[101.807730551991185,36.355428538792907,85.7318592309590457]},"#ccddbb":{"lch":[86.0753247228475828,24.9849555175277693,108.661729708420211],"luv":[86.0753247228475828,-7.99469198849898,23.671351930590518],"rgb":[0.8,0.866666666666666696,0.733333333333333282],"xyz":[0.597252888234334312,0.681378369772196235,0.570207663013233779],"hpluv":[108.661729708420211,78.3375416693066313,86.0753247228475828],"hsluv":[108.661729708420211,23.7751141135998658,86.0753247228475828]},"#ccddcc":{"lch":[86.4592303781436158,14.0773589090278701,127.715012949224516],"luv":[86.4592303781436158,-8.61160385902942771,11.1360815742673065],"rgb":[0.8,0.866666666666666696,0.8],"xyz":[0.616545263678056066,0.689095319949685092,0.671814173683503935],"hpluv":[127.715012949224516,45.5363150686036633,86.4592303781436158],"hsluv":[127.715012949224516,10.5200784033656536,86.4592303781436158]},"#ccdddd":{"lch":[86.8840646031333677,9.47353258269296106,192.177050630057835],"luv":[86.8840646031333677,-9.26038246071566817,-1.99828333241680145],"rgb":[0.8,0.866666666666666696,0.866666666666666696],"xyz":[0.638063589228689665,0.697702650169938599,0.785144021583509932],"hpluv":[192.177050630057835,31.7497104564534354,86.8840646031333677],"hsluv":[192.177050630057835,13.7818607651735867,86.8840646031333677]},"#ccddee":{"lch":[87.3501331068194276,18.4943223550678582,237.507437159903361],"luv":[87.3501331068194276,-9.9349674143158051,-15.5992429896340141],"rgb":[0.8,0.866666666666666696,0.933333333333333348],"xyz":[0.661875769494864374,0.707227522276408616,0.910554837652033155],"hpluv":[237.507437159903361,64.5162574350921432,87.3501331068194276],"hsluv":[237.507437159903361,51.9237885878372083,87.3501331068194276]},"#ccddff":{"lch":[87.8575689716950876,31.3946063828198874,250.2096672964189],"luv":[87.8575689716950876,-10.6295595905023852,-29.5403752996496962],"rgb":[0.8,0.866666666666666696,1],"xyz":[0.688046817904695795,0.717695941640341339,1.04838902594381489],"hpluv":[250.2096672964189,114.576774718516177,87.8575689716950876],"hsluv":[250.2096672964189,99.999999999992923,87.8575689716950876]},"#556600":{"lch":[40.3019892206732919,46.2375853800199934,99.381148915360626],"luv":[40.3019892206732919,-7.53678920078613679,45.6191967302971264],"rgb":[0.333333333333333315,0.4,0],"xyz":[0.0849739168694777086,0.114339753133439206,0.0175932549799886241],"hpluv":[99.381148915360626,145.582103533726,40.3019892206732919],"hsluv":[99.381148915360626,100.000000000002302,40.3019892206732919]},"#556611":{"lch":[40.3683315206726334,43.7939991819964618,99.9948312384981364],"luv":[40.3683315206726334,-7.60085740022420797,43.1293557931736729],"rgb":[0.333333333333333315,0.4,0.0666666666666666657],"xyz":[0.0859855823691148269,0.114744419333294059,0.0229213599447442573],"hpluv":[99.9948312384981364,137.661701347396985,40.3683315206726334],"hsluv":[99.9948312384981364,94.2576138599214204,40.3683315206726334]},"#556622":{"lch":[40.4909010608148421,39.4175015547736436,101.28961011017671],"luv":[40.4909010608148421,-7.7166980000465113,38.6547797923705758],"rgb":[0.333333333333333315,0.4,0.133333333333333331],"xyz":[0.0878609405075918559,0.115494562588684874,0.0327982461407234499],"hpluv":[101.28961011017671,123.529583899053776,40.4909010608148421],"hsluv":[101.28961011017671,83.977954812826539,40.4909010608148421]},"#556633":{"lch":[40.6915589391927455,32.6300466430477343,104.01044750968255],"luv":[40.6915589391927455,-7.89969574444685207,31.6593548745491518],"rgb":[0.333333333333333315,0.4,0.2],"xyz":[0.0909486912400495895,0.116729662881667987,0.0490603999983346],"hpluv":[104.01044750968255,101.754281640855311,40.6915589391927455],"hsluv":[104.01044750968255,68.015525760737134,40.6915589391927455]},"#556644":{"lch":[40.9787805135115306,23.7356999706126039,110.078417815454017],"luv":[40.9787805135115306,-8.1486066005911173,22.2931304119395044],"rgb":[0.333333333333333315,0.4,0.266666666666666663],"xyz":[0.0954066864842684631,0.118512860979355567,0.0725391749512212386],"hpluv":[110.078417815454017,73.4991539757345436,40.9787805135115306],"hsluv":[110.078417815454017,46.8659194429644117,40.9787805135115306]},"#556655":{"lch":[41.3584605937638372,13.8246485480389332,127.71501294923371],"luv":[41.3584605937638372,-8.45701225317865202,10.9361716896901875],"rgb":[0.333333333333333315,0.4,0.333333333333333315],"xyz":[0.101369100523630462,0.120897826595100399,0.10394122222519514],"hpluv":[127.71501294923371,42.4159365242361659,41.3584605937638372],"hsluv":[127.71501294923371,21.5972717302380097,41.3584605937638372]},"#556666":{"lch":[41.8343160733152146,9.01834401177998402,192.177050630060307],"luv":[41.8343160733152146,-8.8154354231024481,-1.90226891261946607],"rgb":[0.333333333333333315,0.4,0.4],"xyz":[0.108954096297138633,0.123931824904503718,0.143888866632339102],"hpluv":[192.177050630060307,27.3547941496945484,41.8343160733152146],"hsluv":[192.177050630060307,27.2477194602778816,41.8343160733152146]},"#556677":{"lch":[42.4081371223492525,18.1914318380534858,239.570903430569189],"luv":[42.4081371223492525,-9.21344558994119289,-15.6856817728697795],"rgb":[0.333333333333333315,0.4,0.466666666666666674],"xyz":[0.118268109317340553,0.127657430112584541,0.192942668538737],"hpluv":[239.570903430569189,54.4323412384199443,42.4081371223492525],"hsluv":[239.570903430569189,33.1626844996427934,42.4081371223492525]},"#556688":{"lch":[43.0800011190655425,31.444407039181371,252.144687081813345],"luv":[43.0800011190655425,-9.64130614192028546,-29.9298504828121246],"rgb":[0.333333333333333315,0.4,0.533333333333333326],"xyz":[0.129408526419284381,0.132113596953362111,0.251615531942309179],"hpluv":[252.144687081813345,92.6204805766441694,43.0800011190655425],"hsluv":[252.144687081813345,39.0862788716996903,43.0800011190655425]},"#556699":{"lch":[43.8484890486876964,45.3842681536749,257.153237313451427],"luv":[43.8484890486876964,-10.090933534038701,-44.2482186789059639],"rgb":[0.333333333333333315,0.4,0.6],"xyz":[0.142465490528357108,0.137336382596991269,0.320382209583427113],"hpluv":[257.153237313451427,131.337888607863903,43.8484890486876964],"hsluv":[257.153237313451427,44.8182326355090055,43.8484890486876964]},"#5566aa":{"lch":[44.7109144588579,59.3119903927914223,259.748012643434],"luv":[44.7109144588579,-10.5562103110165033,-58.3650462882037928],"rgb":[0.333333333333333315,0.4,0.66666666666666663],"xyz":[0.157523183493609636,0.143359459783092391,0.399686059200425714],"hpluv":[259.748012643434,168.332615885742257,44.7109144588579],"hsluv":[259.748012643434,50.2202557252039341,44.7109144588579]},"#5566bb":{"lch":[45.6635615252987463,72.9454914642558805,261.300749278862554],"luv":[45.6635615252987463,-11.0328519112314041,-72.1063166696695532],"rgb":[0.333333333333333315,0.4,0.733333333333333282],"xyz":[0.174660775600946283,0.15021449662602715,0.48994404429906746],"hpluv":[261.300749278862554,202.706651650989187,45.6635615252987463],"hsluv":[261.300749278862554,56.1551480082100767,45.6635615252987463]},"#5566cc":{"lch":[46.7019230239281953,86.153038102066219,262.316955218783903],"luv":[46.7019230239281953,-11.5180515282988498,-85.3796255742992],"rgb":[0.333333333333333315,0.4,0.8],"xyz":[0.193953151044668037,0.157931446803515951,0.591550554969337616],"hpluv":[262.316955218783903,234.085848684940913,46.7019230239281953],"hsluv":[262.316955218783903,67.0801136297732086,46.7019230239281953]},"#5566dd":{"lch":[47.8209277182799539,98.8836589551542,263.023825475898036],"luv":[47.8209277182799539,-12.010072956506761,-98.1515978267222664],"rgb":[0.333333333333333315,0.4,0.866666666666666696],"xyz":[0.215471476595301581,0.166538777023769485,0.704880402869343614],"hpluv":[263.023825475898036,262.38914084011509,47.8209277182799539],"hsluv":[263.023825475898036,77.9738615315733909,47.8209277182799539]},"#5566ee":{"lch":[49.0151480019121095,111.133834597019145,263.537783903780621],"luv":[49.0151480019121095,-12.5078880087352609,-110.427722650603215],"rgb":[0.333333333333333315,0.4,0.933333333333333348],"xyz":[0.23928365686147629,0.176063649130239502,0.830291218937866837],"hpluv":[263.537783903780621,287.710232398192659,49.0151480019121095],"hsluv":[263.537783903780621,88.9133133505171145,49.0151480019121095]},"#5566ff":{"lch":[50.2789812841098751,122.927042369796439,263.924295565134457],"luv":[50.2789812841098751,-13.0108962765956715,-122.236550687040406],"rgb":[0.333333333333333315,0.4,1],"xyz":[0.265454705271307712,0.186532068494172198,0.968125407229648682],"hpluv":[263.924295565134457,310.2417842032321,50.2789812841098751],"hsluv":[263.924295565134457,99.99999999999919,50.2789812841098751]},"#ccee00":{"lch":[88.9159222564839382,101.512339113439552,98.3897184755654],"luv":[88.9159222564839382,-14.8112090817394879,100.426007975120399],"rgb":[0.8,0.933333333333333348,0],"xyz":[0.554744805843380595,0.739861178960639299,0.113583132474326151],"hpluv":[98.3897184755654,409.405376777149172,88.9159222564839382],"hsluv":[98.3897184755654,100.000000000002402,88.9159222564839382]},"#ccee11":{"lch":[88.9350466502285855,100.665090554083037,98.4749110233884863],"luv":[88.9350466502285855,-14.8356507509631186,99.5658773027044],"rgb":[0.8,0.933333333333333348,0.0666666666666666657],"xyz":[0.555756471343017755,0.740265845160494207,0.118911237439081788],"hpluv":[98.4749110233884863,406.753799510206477,88.9350466502285855],"hsluv":[98.4749110233884863,99.103544824997428,88.9350466502285855]},"#ccee22":{"lch":[88.9704797513205108,99.1029038393990191,98.635890718104875],"luv":[88.9704797513205108,-14.8807650249594605,97.9793262973016823],"rgb":[0.8,0.933333333333333348,0.133333333333333331],"xyz":[0.557631829481494701,0.741015988415885,0.12878812363506098],"hpluv":[98.635890718104875,401.844579090604725,88.9704797513205108],"hsluv":[98.635890718104875,97.4508266239822376,88.9704797513205108]},"#ccee33":{"lch":[89.0287677898111696,96.5543294248683281,98.9099371535565837],"luv":[89.0287677898111696,-14.95450175665089,95.3892101230339335],"rgb":[0.8,0.933333333333333348,0.2],"xyz":[0.560719580213952518,0.742251088708868134,0.145050277492672131],"hpluv":[98.9099371535565837,393.778440936160052,89.0287677898111696],"hsluv":[98.9099371535565837,94.7550356083218333,89.0287677898111696]},"#ccee44":{"lch":[89.1128082270408157,92.9258219449750698,99.3266297509707101],"luv":[89.1128082270408157,-15.0597883526499068,91.6973890518296],"rgb":[0.8,0.933333333333333348,0.266666666666666663],"xyz":[0.565177575458171377,0.7440342868065557,0.168529052445558769],"hpluv":[99.3266297509707101,382.168331694223468,89.1128082270408157],"hsluv":[99.3266297509707101,90.9176847425828782,89.1128082270408157]},"#ccee55":{"lch":[89.224999764075946,88.1655281542066263,99.9265688821158591],"luv":[89.224999764075946,-15.1984931464969293,86.8456456063635187],"rgb":[0.8,0.933333333333333348,0.333333333333333315],"xyz":[0.571139989497533307,0.74641925242230045,0.199931099719532657],"hpluv":[99.9265688821158591,366.702481299920066,89.224999764075946],"hsluv":[99.9265688821158591,85.8839575374920372,89.224999764075946]},"#ccee66":{"lch":[89.3673776950467555,82.2600687786622444,100.76990980050725],"luv":[89.3673776950467555,-15.3715621348797811,80.8111006793235873],"rgb":[0.8,0.933333333333333348,0.4],"xyz":[0.578724985271041548,0.749453250731703768,0.239878744126676646],"hpluv":[100.76990980050725,347.124780760482849,89.3673776950467555],"hsluv":[100.76990980050725,79.6381055931254451,89.3673776950467555]},"#ccee77":{"lch":[89.5416863487684651,75.2338064272131817,101.95104715507324],"luv":[89.5416863487684651,-15.5791079616514043,73.6031047215169707],"rgb":[0.8,0.933333333333333348,0.466666666666666674],"xyz":[0.588038998291243398,0.753178855939784619,0.288932546033074555],"hpluv":[101.95104715507324,323.225079834159544,89.5416863487684651],"hsluv":[101.95104715507324,72.2002225208687349,89.5416863487684651]},"#ccee88":{"lch":[89.7494222523926481,67.150335761217363,103.626883623375818],"luv":[89.7494222523926481,-15.8204941270879562,65.2600916212887654],"rgb":[0.8,0.933333333333333348,0.533333333333333326],"xyz":[0.599179415393187309,0.757635022780562162,0.347605409436646695],"hpluv":[103.626883623375818,294.840431689210504,89.7494222523926481],"hsluv":[103.626883623375818,63.6228180815060256,89.7494222523926481]},"#ccee99":{"lch":[89.9918618926625697,58.1187887690418705,106.076645299715267],"luv":[89.9918618926625697,-16.094429395756972,55.8458857070554586],"rgb":[0.8,0.933333333333333348,0.6],"xyz":[0.61223637950226,0.762857808424191375,0.41637208707776463],"hpluv":[106.076645299715267,261.881276027636488,89.9918618926625697],"hsluv":[106.076645299715267,53.9866751643902418,89.9918618926625697]},"#cceeaa":{"lch":[90.2700807835134071,48.3136880988356481,109.842100564752428],"luv":[90.2700807835134071,-16.3990756203548145,45.4453823452884791],"rgb":[0.8,0.933333333333333348,0.66666666666666663],"xyz":[0.627294072467512565,0.768880885610292442,0.495675936694763231],"hpluv":[109.842100564752428,224.429228200920562,90.2700807835134071],"hsluv":[109.842100564752428,43.3959332818477037,90.2700807835134071]},"#cceebb":{"lch":[90.5849674500281736,38.0375276056681,116.096591597387416],"luv":[90.5849674500281736,-16.7321662581560417,34.1597441246474745],"rgb":[0.8,0.933333333333333348,0.733333333333333282],"xyz":[0.644431664574849128,0.7757359224532272,0.585933921793405],"hpluv":[116.096591597387416,183.067580850930824,90.5849674500281736],"hsluv":[116.096591597387416,31.9725829176952736,90.5849674500281736]},"#cceecc":{"lch":[90.9372344233822,27.9388105970907,127.715012949233042],"luv":[90.9372344233822,-17.0911298567764973,22.1013668762570106],"rgb":[0.8,0.933333333333333348,0.8],"xyz":[0.663724040018570882,0.783452872630716057,0.687540432463675133],"hpluv":[127.715012949233042,140.086760618050221,90.9372344233822],"hsluv":[127.715012949233042,30.3633811556705,90.9372344233822]},"#cceedd":{"lch":[91.327427526889025,19.8359452431300802,151.749458426713772],"luv":[91.327427526889025,-17.4732117028180483,9.38890816213244861],"rgb":[0.8,0.933333333333333348,0.866666666666666696],"xyz":[0.685242365569204481,0.792060202850969564,0.800870280363681131],"hpluv":[151.749458426713772,104.258293798779974,91.327427526889025],"hsluv":[151.749458426713772,29.0871711351253381,91.327427526889025]},"#cceeee":{"lch":[91.7559342603931,18.2870370266976643,192.177050630059739],"luv":[91.7559342603931,-17.87558711202,-3.8573447624494035],"rgb":[0.8,0.933333333333333348,0.933333333333333348],"xyz":[0.709054545835379191,0.801585074957439581,0.926281096432204354],"hpluv":[192.177050630059739,101.458793010104,91.7559342603931],"hsluv":[192.177050630059739,27.4217374065650326,91.7559342603931]},"#cceeff":{"lch":[92.2229917973594553,25.3309747642836847,223.758903531404655],"luv":[92.2229917973594553,-18.2954610486514362,-17.5195430170439934],"rgb":[0.8,0.933333333333333348,1],"xyz":[0.735225594245210612,0.812053494321372304,1.06411528472398609],"hpluv":[223.758903531404655,149.53216426558339,92.2229917973594553],"hsluv":[223.758903531404655,99.9999999999890861,92.2229917973594553]},"#557700":{"lch":[45.8045523271613533,55.5294361467329836,107.801769483020877],"luv":[45.8045523271613533,-16.9767207468495087,52.8706840456749276],"rgb":[0.333333333333333315,0.466666666666666674,0],"xyz":[0.103427654922895337,0.151247229240274977,0.023744500997794328],"hpluv":[107.801769483020877,153.83457187868342,45.8045523271613533],"hsluv":[107.801769483020877,100.000000000002288,45.8045523271613533]},"#557711":{"lch":[45.859623178970125,53.470483995502839,108.496139146384877],"luv":[45.859623178970125,-16.9630166203079504,50.7084679896019068],"rgb":[0.333333333333333315,0.466666666666666674,0.0666666666666666657],"xyz":[0.104439320422532456,0.15165189544012983,0.0290726059625499578],"hpluv":[108.496139146384877,147.952722071756682,45.859623178970125],"hsluv":[108.496139146384877,95.6324690191426,45.859623178970125]},"#557722":{"lch":[45.9614512879267494,49.76586948312967,109.899607245517743],"luv":[45.9614512879267494,-16.93896350220896,46.7943723206405409],"rgb":[0.333333333333333315,0.466666666666666674,0.133333333333333331],"xyz":[0.106314678561009485,0.152402038695520659,0.0389494921585291573],"hpluv":[109.899607245517743,137.396980684000368,45.9614512879267494],"hsluv":[109.899607245517743,87.7486210093461239,45.9614512879267494]},"#557733":{"lch":[46.1283843073061,43.9801463057798472,112.602269297118809],"luv":[46.1283843073061,-16.9029726498973396,40.6022509803905223],"rgb":[0.333333333333333315,0.466666666666666674,0.2],"xyz":[0.109402429293467218,0.153637138988503757,0.0552116460161403],"hpluv":[112.602269297118809,120.983948144693443,46.1283843073061],"hsluv":[112.602269297118809,75.3373974156097432,46.1283843073061]},"#557744":{"lch":[46.3678258482665413,36.3216896494577526,117.654446368962965],"luv":[46.3678258482665413,-16.8582748313623227,32.1724060135666861],"rgb":[0.333333333333333315,0.466666666666666674,0.266666666666666663],"xyz":[0.113860424537686092,0.155420337086191351,0.0786904209690269391],"hpluv":[117.654446368962965,99.4005156049610861,46.3678258482665413],"hsluv":[117.654446368962965,58.5682493514162346,46.3678258482665413]},"#557755":{"lch":[46.6852246722490349,27.4798560002662136,127.715012949237362],"luv":[46.6852246722490349,-16.8103715694690621,21.7383047520213317],"rgb":[0.333333333333333315,0.466666666666666674,0.333333333333333315],"xyz":[0.119822838577048091,0.157805302701936184,0.110092468243000841],"hpluv":[127.715012949237362,74.6920408293198506,46.6852246722490349],"hsluv":[127.715012949237362,38.0315615795731219,46.6852246722490349]},"#557766":{"lch":[47.0844103757355299,19.3533005907945039,150.034269154893224],"luv":[47.0844103757355299,-16.7662346577491,9.66662397939114371],"rgb":[0.333333333333333315,0.466666666666666674,0.4],"xyz":[0.127407834350556276,0.160839301011339475,0.150040112650144802],"hpluv":[150.034269154893224,52.1575559127659147,47.0844103757355299],"hsluv":[150.034269154893224,41.6155983808333403,47.0844103757355299]},"#557777":{"lch":[47.5677829408255519,17.1184872206298522,192.177050630060563],"luv":[47.5677829408255519,-16.733329138647683,-3.61085871511915846],"rgb":[0.333333333333333315,0.466666666666666674,0.466666666666666674],"xyz":[0.136721847370758182,0.164564906219420298,0.199093914556542712],"hpluv":[192.177050630060563,45.665876663612373,47.5677829408255519],"hsluv":[192.177050630060563,45.4871270252879683,47.5677829408255519]},"#557788":{"lch":[48.1364533988364371,24.3189053895014062,226.569261606948],"luv":[48.1364533988364371,-16.7186932071720697,-17.6605338760746164],"rgb":[0.333333333333333315,0.466666666666666674,0.533333333333333326],"xyz":[0.147862264472702,0.169021073060197896,0.257766777960114879],"hpluv":[226.569261606948,64.1075619232690173,48.1364533988364371],"hsluv":[226.569261606948,49.4930397679002567,48.1364533988364371]},"#557799":{"lch":[48.7903733600049776,36.1922931768580227,242.470518495943224],"luv":[48.7903733600049776,-16.7282575252316086,-32.0943528610435749],"rgb":[0.333333333333333315,0.466666666666666674,0.6],"xyz":[0.160919228581774709,0.174243858703827054,0.326533455601232814],"hpluv":[242.470518495943224,94.128532149155447,48.7903733600049776],"hsluv":[242.470518495943224,53.4981409183259657,48.7903733600049776]},"#5577aa":{"lch":[49.5284680294880957,49.5215284063763121,250.210257263218182],"luv":[49.5284680294880957,-16.7664778987851584,-46.5968560588918308],"rgb":[0.333333333333333315,0.466666666666666674,0.66666666666666663],"xyz":[0.175976921547027265,0.180266935889928148,0.405837305218231414],"hpluv":[250.210257263218182,126.875705911364861,49.5284680294880957],"hsluv":[250.210257263218182,57.3943781585142503,49.5284680294880957]},"#5577bb":{"lch":[50.3487764471929324,63.2168000831305,254.554261837862072],"luv":[50.3487764471929324,-16.8362555209572413,-60.9336057753316069],"rgb":[0.333333333333333315,0.466666666666666674,0.733333333333333282],"xyz":[0.193114513654363912,0.187121972732862907,0.496095290316873161],"hpluv":[254.554261837862072,159.324628464713726,50.3487764471929324],"hsluv":[254.554261837862072,61.1035457400689737,50.3487764471929324]},"#5577cc":{"lch":[51.2485971738404942,76.8367273058076279,257.264224247337211],"luv":[51.2485971738404942,-16.9390629845235594,-74.9463195111900546],"rgb":[0.333333333333333315,0.466666666666666674,0.8],"xyz":[0.212406889098085638,0.194838922910351708,0.597701800987143317],"hpluv":[257.264224247337211,190.250673687597981,51.2485971738404942],"hsluv":[257.264224247337211,64.5753193228694329,51.2485971738404942]},"#5577dd":{"lch":[52.2246350466270428,90.1721178795433502,259.084439545341468],"luv":[52.2246350466270428,-17.075183181685393,-88.5406627612090347],"rgb":[0.333333333333333315,0.466666666666666674,0.866666666666666696],"xyz":[0.233925214648719182,0.203446253130605242,0.711031648887149315],"hpluv":[259.084439545341468,219.096874823476185,52.2246350466270428],"hsluv":[259.084439545341468,74.9139940771913757,52.2246350466270428]},"#5577ee":{"lch":[53.2731438322457791,103.123503170291656,260.373961187264626],"luv":[53.2731438322457791,-17.2439851141504441,-101.671539200978515],"rgb":[0.333333333333333315,0.466666666666666674,0.933333333333333348],"xyz":[0.257737394914893947,0.212971125237075287,0.836442464955672538],"hpluv":[260.373961187264626,245.63410016831412,53.2731438322457791],"hsluv":[260.373961187264626,87.3510385353649,53.2731438322457791]},"#5577ff":{"lch":[54.3900599484937572,115.652149768064447,261.324783585170792],"luv":[54.3900599484937572,-17.4441870719707097,-114.32899931064253],"rgb":[0.333333333333333315,0.466666666666666674,1],"xyz":[0.283908443324725313,0.223439544601007983,0.974276653247454383],"hpluv":[261.324783585170792,269.819603010977914,54.3900599484937572],"hsluv":[261.324783585170792,99.9999999999989768,54.3900599484937572]},"#ccff00":{"lch":[93.605159534834371,109.568762044642341,102.903766821995461],"luv":[93.605159534834371,-24.4682604068618268,106.801768939739262],"rgb":[0.8,1,0],"xyz":[0.606597178273054372,0.843565923819988406,0.130867256617550276],"hpluv":[102.903766821995461,795.170643052662513,93.605159534834371],"hsluv":[102.903766821995461,100.000000000002359,93.605159534834371]},"#ccff11":{"lch":[93.6226829283917681,108.793716578542018,103.00230683973929],"luv":[93.6226829283917681,-24.4775292120886689,106.004355243751533],"rgb":[0.8,1,0.0666666666666666657],"xyz":[0.607608843772691531,0.843970590019843314,0.136195361582305913],"hpluv":[103.00230683973929,791.823376913543598,93.6226829283917681],"hsluv":[103.00230683973929,99.9999999999883755,93.6226829283917681]},"#ccff22":{"lch":[93.6551518183817535,107.364125357399203,103.187929529698394],"luv":[93.6551518183817535,-24.4946701604029187,104.532609971684906],"rgb":[0.8,1,0.133333333333333331],"xyz":[0.609484201911168477,0.844720733275234115,0.146072247778285091],"hpluv":[103.187929529698394,785.615721446726184,93.6551518183817535],"hsluv":[103.187929529698394,99.9999999999883613,93.6551518183817535]},"#ccff33":{"lch":[93.7085695338431464,105.030410790236445,103.502196488744218],"luv":[93.7085695338431464,-24.5227776356263192,102.127472150246831],"rgb":[0.8,1,0.2],"xyz":[0.612571952643626294,0.845955833568217241,0.162334401635896242],"hpluv":[103.502196488744218,775.386532390006209,93.7085695338431464],"hsluv":[103.502196488744218,99.9999999999882334,93.7085695338431464]},"#ccff44":{"lch":[93.7856006692118456,101.704796230104463,103.975902087852319],"luv":[93.7856006692118456,-24.5631097372148304,98.6940687997238],"rgb":[0.8,1,0.266666666666666663],"xyz":[0.617029947887845154,0.847739031665904808,0.18581317658878288],"hpluv":[103.975902087852319,760.597322717251814,93.7856006692118456],"hsluv":[103.975902087852319,99.9999999999883329,93.7856006692118456]},"#ccff55":{"lch":[93.8884584724407887,97.3367975087049473,104.649262803016768],"luv":[93.8884584724407887,-24.6166025777849207,94.1725810773922802],"rgb":[0.8,1,0.333333333333333315],"xyz":[0.622992361927207083,0.850123997281649557,0.217215223862756796],"hpluv":[104.649262803016768,740.773636872505676,93.8884584724407887],"hsluv":[104.649262803016768,99.999999999988,93.8884584724407887]},"#ccff66":{"lch":[94.0190298395239381,91.9106503723783561,105.578857731119598],"luv":[94.0190298395239381,-24.6839280463924027,88.5340123798424514],"rgb":[0.8,1,0.4],"xyz":[0.630577357700715324,0.853157995591052876,0.257162868269900757],"hpluv":[105.578857731119598,715.472563222964368,94.0190298395239381],"hsluv":[105.578857731119598,99.9999999999875371,94.0190298395239381]},"#ccff77":{"lch":[94.1789424927264349,85.4453105292158597,106.848417981185563],"luv":[94.1789424927264349,-24.7655268674123263,81.7775627566241781],"rgb":[0.8,1,0.466666666666666674],"xyz":[0.639891370720917174,0.856883600799133727,0.306216670176298666],"hpluv":[106.848417981185563,684.262206540111833,94.1789424927264349],"hsluv":[106.848417981185563,99.9999999999873381,94.1789424927264349]},"#ccff88":{"lch":[94.3696051468525781,77.9966506735583778,108.587502777405675],"luv":[94.3696051468525781,-24.8616333733667219,73.92818611532],"rgb":[0.8,1,0.533333333333333326],"xyz":[0.651031787822861086,0.861339767639911269,0.364889533579870862],"hpluv":[108.587502777405675,646.714804777793233,94.3696051468525781],"hsluv":[108.587502777405675,99.9999999999870397,94.3696051468525781]},"#ccff99":{"lch":[94.5922333645115572,69.6635615227201868,111.00626449694991],"luv":[94.5922333645115572,-24.9722983929036886,65.0338074927618],"rgb":[0.8,1,0.6],"xyz":[0.66408875193193373,0.866562553283540482,0.433656211220988741],"hpluv":[111.00626449694991,602.43247210261859,94.5922333645115572],"hsluv":[111.00626449694991,99.999999999986656,94.5922333645115572]},"#ccffaa":{"lch":[94.8478672375315881,60.6030718965076574,114.464397640121035],"luv":[94.8478672375315881,-25.0974127381864349,55.1620539605116],"rgb":[0.8,1,0.66666666666666663],"xyz":[0.679146444897186341,0.872585630469641549,0.512960060837987397],"hpluv":[114.464397640121035,551.164539659931279,94.8478672375315881],"hsluv":[114.464397640121035,99.9999999999858886,94.8478672375315881]},"#ccffbb":{"lch":[95.1373841969384,51.0680528276179899,119.615591899534252],"luv":[95.1373841969384,-25.2367319023901224,44.3965469658538439],"rgb":[0.8,1,0.733333333333333282],"xyz":[0.696284037004522904,0.879440667312576307,0.603218045936629088],"hpluv":[119.615591899534252,493.192076617112832,95.1373841969384],"hsluv":[119.615591899534252,99.999999999985036,95.1373841969384]},"#ccffcc":{"lch":[95.4615088709507802,41.5047839306073527,127.715012949235671],"luv":[95.4615088709507802,-25.3899015983654444,32.8329101048280876],"rgb":[0.8,1,0.8],"xyz":[0.715576412448244659,0.887157617490065165,0.704824556606899244],"hpluv":[127.715012949235671,430.524428546451247,95.4615088709507802],"hsluv":[127.715012949235671,99.9999999999844,95.4615088709507802]},"#ccffdd":{"lch":[95.8208211701733603,32.8093273722257,141.163585516297758],"luv":[95.8208211701733603,-25.5564832849791728,20.5746962243056899],"rgb":[0.8,1,0.866666666666666696],"xyz":[0.737094737998878258,0.895764947710318671,0.818154404506905242],"hpluv":[141.163585516297758,370.598640927928557,95.8208211701733603],"hsluv":[141.163585516297758,99.9999999999829612,95.8208211701733603]},"#ccffee":{"lch":[96.2157633520208293,26.8716381406037179,163.283084738459195],"luv":[96.2157633520208293,-25.7359786647352209,7.72944619800421506],"rgb":[0.8,1,0.933333333333333348],"xyz":[0.760906918265053,0.905289819816788688,0.943565220575428465],"hpluv":[163.283084738459195,336.210724351278486,96.2157633520208293],"hsluv":[163.283084738459195,99.9999999999813411,96.2157633520208293]},"#ccffff":{"lch":[96.6466465538527899,26.5246444827845806,192.177050630060279],"luv":[96.6466465538527899,-25.9278521925209873,-5.59493034995961125],"rgb":[0.8,1,1],"xyz":[0.787077966674884388,0.915758239180721412,1.08139940886721031],"hpluv":[192.177050630060279,375.729722461639881,96.6466465538527899],"hsluv":[192.177050630060279,99.9999999999789111,96.6466465538527899]},"#558800":{"lch":[51.3121649295003266,65.2833526322192,113.133039202335894],"luv":[51.3121649295003266,-25.6477049188799029,60.0342515843809466],"rgb":[0.333333333333333315,0.533333333333333326,0],"xyz":[0.125500024647865804,0.195391968690216522,0.0311019575727842744],"hpluv":[113.133039202335894,161.443824642532,51.3121649295003266],"hsluv":[113.133039202335894,100.000000000002416,51.3121649295003266]},"#558811":{"lch":[51.3586018009433758,63.5282336791645363,113.757082680238781],"luv":[51.3586018009433758,-25.5929736747770171,58.1449582756467862],"rgb":[0.333333333333333315,0.533333333333333326,0.0666666666666666657],"xyz":[0.126511690147502937,0.195796634890071375,0.0364300625375399076],"hpluv":[113.757082680238781,156.961418592175818,51.3586018009433758],"hsluv":[113.757082680238781,96.6047658949560315,51.3586018009433758]},"#558822":{"lch":[51.4445144263052754,60.3557257759597761,114.985955444381503],"luv":[51.4445144263052754,-25.4940226670596211,54.707115096615226],"rgb":[0.333333333333333315,0.533333333333333326,0.133333333333333331],"xyz":[0.128387048285979938,0.196546778145462203,0.0463069487335191],"hpluv":[114.985955444381503,148.873956641671725,51.4445144263052754],"hsluv":[114.985955444381503,90.4397474873449454,51.4445144263052754]},"#558833":{"lch":[51.5854933484676366,55.3603846502330512,117.238150003797628],"luv":[51.5854933484676366,-25.3378965271949284,49.2215723864945502],"rgb":[0.333333333333333315,0.533333333333333326,0.2],"xyz":[0.131474799018437671,0.197781878438445302,0.0625691025911302434],"hpluv":[117.238150003797628,136.179218375975154,51.5854933484676366],"hsluv":[117.238150003797628,80.6386945119108844,51.5854933484676366]},"#558844":{"lch":[51.788002513998137,48.6519311113283521,121.094634958525788],"luv":[51.788002513998137,-25.1264429677671792,41.6614001762900799],"rgb":[0.333333333333333315,0.533333333333333326,0.266666666666666663],"xyz":[0.135932794262656559,0.199565076536132896,0.0860478775440168819],"hpluv":[121.094634958525788,119.20933058927335,51.788002513998137],"hsluv":[121.094634958525788,67.2069053574962112,51.788002513998137]},"#558855":{"lch":[52.0569745246593669,40.6501953066927229,127.715012949238655],"luv":[52.0569745246593669,-24.8671203906742271,32.1568764333225801],"rgb":[0.333333333333333315,0.533333333333333326,0.333333333333333315],"xyz":[0.141895208302018572,0.201950042151877729,0.117449924817990797],"hpluv":[127.715012949238655,99.0884509425644495,52.0569745246593669],"hsluv":[127.715012949238655,50.4536826414745647,52.0569745246593669]},"#558866":{"lch":[52.3961000606252156,32.296627997442414,139.535908661945541],"luv":[52.3961000606252156,-24.57168930668605,20.9595864611130054],"rgb":[0.333333333333333315,0.533333333333333326,0.4],"xyz":[0.149480204075526729,0.20498404046128102,0.157397569225134759],"hpluv":[139.535908661945541,78.2163498792783258,52.3961000606252156],"hsluv":[139.535908661945541,52.7717106037122505,52.3961000606252156]},"#558877":{"lch":[52.8079833364028417,25.6675371494617757,160.900154113051656],"luv":[52.8079833364028417,-24.2545338981935465,8.39881233868101873],"rgb":[0.333333333333333315,0.533333333333333326,0.466666666666666674],"xyz":[0.158794217095728663,0.208709645669361843,0.206451371131532668],"hpluv":[160.900154113051656,61.6770996704155934,52.8079833364028417],"hsluv":[160.900154113051656,55.3375604028527732,52.8079833364028417]},"#558888":{"lch":[53.2942460543653311,24.4817100724115,192.177050630060762],"luv":[53.2942460543653311,-23.9308828659180151,-5.16400748714853908],"rgb":[0.333333333333333315,0.533333333333333326,0.533333333333333326],"xyz":[0.169934634197672463,0.213165812510139441,0.265124234535104808],"hpluv":[192.177050630060762,58.2908991249141764,53.2942460543653311],"hsluv":[192.177050630060762,58.0627314448554515,53.2942460543653311]},"#558899":{"lch":[53.8556132197311399,30.5464388010487,219.367537814697016],"luv":[53.8556132197311399,-23.6152401502492637,-19.3753801529742589],"rgb":[0.333333333333333315,0.533333333333333326,0.6],"xyz":[0.18299159830674519,0.218388598153768598,0.333890912176222743],"hpluv":[219.367537814697016,71.9728892793730921,53.8556132197311399],"hsluv":[219.367537814697016,60.861676067449,53.8556132197311399]},"#5588aa":{"lch":[54.491995562986105,41.1624410064978434,235.49057853568965],"luv":[54.491995562986105,-23.3202411533326384,-33.9192114024460452],"rgb":[0.333333333333333315,0.533333333333333326,0.66666666666666663],"xyz":[0.198049291271997718,0.224411675339869693,0.413194761793221343],"hpluv":[235.49057853568965,95.8534470006528494,54.491995562986105],"hsluv":[235.49057853568965,63.6587877222075207,54.491995562986105]},"#5588bb":{"lch":[55.2025746803936102,53.7318677649407164,244.589939769846183],"luv":[55.2025746803936102,-23.0560079965343867,-48.5338449823709865],"rgb":[0.333333333333333315,0.533333333333333326,0.733333333333333282],"xyz":[0.215186883379334393,0.231266712182804451,0.503452746891863],"hpluv":[244.589939769846183,123.512789385845494,55.2025746803936102],"hsluv":[244.589939769846183,66.3923972476147,55.2025746803936102]},"#5588cc":{"lch":[55.9858924676882,67.0258402153595227,250.085698604565607],"luv":[55.9858924676882,-22.8299557310329213,-63.0179052166444436],"rgb":[0.333333333333333315,0.533333333333333326,0.8],"xyz":[0.234479258823056119,0.238983662360293253,0.60505925756213319],"hpluv":[250.085698604565607,151.915814945370954,55.9858924676882],"hsluv":[250.085698604565607,69.0160689386852653,55.9858924676882]},"#5588dd":{"lch":[56.8399439373084761,80.4799585659197589,253.656315856923044],"luv":[56.8399439373084761,-22.6469326722406379,-77.2278458285038596],"rgb":[0.333333333333333315,0.533333333333333326,0.866666666666666696],"xyz":[0.255997584373689691,0.247590992580546787,0.718389105462139188],"hpluv":[253.656315856923044,179.669115472769334,56.8399439373084761],"hsluv":[253.656315856923044,71.4978966707909791,56.8399439373084761]},"#5588ee":{"lch":[57.7622712344346212,93.8110643698785083,256.11666422549024],"luv":[57.7622712344346212,-22.5095618551803298,-91.0704969970917517],"rgb":[0.333333333333333315,0.533333333333333326,0.933333333333333348],"xyz":[0.2798097646398644,0.257115864687016804,0.843799921530662411],"hpluv":[256.11666422549024,206.086302990026525,57.7622712344346212],"hsluv":[256.11666422549024,85.5354286092897098,57.7622712344346212]},"#5588ff":{"lch":[58.7500561820581169,106.871298098059711,257.890974112124525],"luv":[58.7500561820581169,-22.4186692043534066,-104.493433421771144],"rgb":[0.333333333333333315,0.533333333333333326,1],"xyz":[0.305980813049695821,0.267584284050949528,0.981634109822444256],"hpluv":[257.890974112124525,230.829932612430156,58.7500561820581169],"hsluv":[257.890974112124525,99.9999999999988489,58.7500561820581169]},"#559900":{"lch":[56.7948235068901113,75.0667586450735769,116.650835958582277],"luv":[56.7948235068901113,-33.6713638042581849,67.0914116190665766],"rgb":[0.333333333333333315,0.6,0],"xyz":[0.151369625100333277,0.247131169595152217,0.0397251577236065259],"hpluv":[116.650835958582277,167.717444253109818,56.7948235068901113],"hsluv":[116.650835958582277,100.000000000002373,56.7948235068901113]},"#559911":{"lch":[56.8345345919718,73.5501475520203343,117.179331557793219],"luv":[56.8345345919718,-33.596019870913949,65.4288289193465431],"rgb":[0.333333333333333315,0.6,0.0666666666666666657],"xyz":[0.152381290599970409,0.24753583579500707,0.0450532626883621556],"hpluv":[117.179331557793219,164.214146288467191,56.8345345919718],"hsluv":[117.179331557793219,97.3073310640873501,56.8345345919718]},"#559922":{"lch":[56.9080340332033785,70.7973668034807559,118.203267177206257],"luv":[56.9080340332033785,-33.458907670269852,62.3920559351826256],"rgb":[0.333333333333333315,0.6,0.133333333333333331],"xyz":[0.154256648738447411,0.248285979050397898,0.0549301488843413552],"hpluv":[118.203267177206257,157.863907732936383,56.9080340332033785],"hsluv":[118.203267177206257,92.3971004449738444,56.9080340332033785]},"#559933":{"lch":[57.0287279601738675,66.4302504595433163,120.024921583566851],"luv":[57.0287279601738675,-33.2401456716524066,57.5158316626386181],"rgb":[0.333333333333333315,0.6,0.2],"xyz":[0.157344399470905172,0.249521079343381,0.0711923027419525],"hpluv":[120.024921583566851,147.812625691912672,57.0287279601738675],"hsluv":[120.024921583566851,84.5348632876942645,57.0287279601738675]},"#559944":{"lch":[57.2022813646338335,60.4886548808755862,122.993651447985457],"luv":[57.2022813646338335,-32.9388613723515604,50.7337045837447178],"rgb":[0.333333333333333315,0.6,0.266666666666666663],"xyz":[0.161802394715124032,0.251304277441068591,0.0946710776948391369],"hpluv":[122.993651447985457,134.183743453609452,57.2022813646338335],"hsluv":[122.993651447985457,73.6468983233054075,57.2022813646338335]},"#559955":{"lch":[57.4331244004656583,53.227141365646645,127.715012949239252],"luv":[57.4331244004656583,-32.5608701853658573,42.1060365117673499],"rgb":[0.333333333333333315,0.6,0.333333333333333315],"xyz":[0.167764808754486017,0.253689243056813396,0.126073124968813038],"hpluv":[127.715012949239252,117.600732304920115,57.4331244004656583],"hsluv":[127.715012949239252,59.8797334066369444,57.4331244004656583]},"#559966":{"lch":[57.7247064038159152,45.1954856350919556,135.286653522876605],"luv":[57.7247064038159152,-32.1175213159608433,31.7977475037242847],"rgb":[0.333333333333333315,0.6,0.4],"xyz":[0.175349804527994202,0.256723241366216715,0.166020769375957],"hpluv":[135.286653522876605,99.3510934192793371,57.7247064038159152],"hsluv":[135.286653522876605,61.4133131906424055,57.7247064038159152]},"#559977":{"lch":[58.0796295741768631,37.4448814339638858,147.624029462041108],"luv":[58.0796295741768631,-31.624170974627738,20.0507096076703846],"rgb":[0.333333333333333315,0.6,0.466666666666666674],"xyz":[0.184663817548196107,0.260448846574297566,0.215074571282354909],"hpluv":[147.624029462041108,81.8102930750829671,58.0796295741768631],"hsluv":[147.624029462041108,63.1432913181764448,58.0796295741768631]},"#559988":{"lch":[58.4997327930321092,31.9103493306277741,167.047427400638497],"luv":[58.4997327930321092,-31.0984204046450543,7.15252701768072],"rgb":[0.333333333333333315,0.6,0.533333333333333326],"xyz":[0.195804234650139963,0.264905013415075108,0.273747434685927105],"hpluv":[167.047427400638497,69.2176742514874093,58.4997327930321092],"hsluv":[167.047427400638497,65.0191416919107752,58.4997327930321092]},"#559999":{"lch":[58.9861545428406373,31.2617491707160085,192.177050630060933],"luv":[58.9861545428406373,-30.5583742056962677,-6.59414339527129822],"rgb":[0.333333333333333315,0.6,0.6],"xyz":[0.208861198759212663,0.270127799058704321,0.342514112327045],"hpluv":[192.177050630060933,67.2515837667627494,58.9861545428406373],"hsluv":[192.177050630060933,66.9883413382070216,58.9861545428406373]},"#5599aa":{"lch":[59.5393884281606915,36.5784761777074152,214.841775998693208],"luv":[59.5393884281606915,-30.0211576326403424,-20.8977274812183715],"rgb":[0.333333333333333315,0.6,0.66666666666666663],"xyz":[0.223918891724465219,0.276150876244805388,0.421817961944043585],"hpluv":[214.841775998693208,77.957978019602777,59.5393884281606915],"hsluv":[214.841775998693208,69.0007957908225,59.5393884281606915]},"#5599bb":{"lch":[60.1593377819191488,46.1560476826162613,230.269588518041076],"luv":[60.1593377819191488,-29.5018430010724479,-35.4967885479802],"rgb":[0.333333333333333315,0.6,0.733333333333333282],"xyz":[0.241056483831801838,0.283005913087740146,0.512075947042685331],"hpluv":[230.269588518041076,97.3564866347465312,60.1593377819191488],"hsluv":[230.269588518041076,71.0120526680823758,60.1593377819191488]},"#5599cc":{"lch":[60.8453721774886276,57.9560381686168284,239.960256152221575],"luv":[60.8453721774886276,-29.0128279276179057,-50.1712883614184761],"rgb":[0.333333333333333315,0.6,0.8],"xyz":[0.260348859275523592,0.290722863265228948,0.613682457712955487],"hpluv":[239.960256152221575,120.867757439807349,60.8453721774886276],"hsluv":[239.960256152221575,72.9851794318318667,60.8453721774886276]},"#5599dd":{"lch":[61.596386585270082,70.7674616346471623,246.194917025964173],"luv":[61.596386585270082,-28.563620381934669,-64.7468394355121],"rgb":[0.333333333333333315,0.6,0.866666666666666696],"xyz":[0.281867184826157136,0.29933019348548251,0.727012305612961485],"hpluv":[246.194917025964173,145.7866339341696,61.596386585270082],"hsluv":[246.194917025964173,74.8914393241793164,61.596386585270082]},"#5599ee":{"lch":[62.4108626997728209,83.9573424358243,250.401946751580681],"luv":[62.4108626997728209,-28.1609349474859023,-79.0935970339554757],"rgb":[0.333333333333333315,0.6,0.933333333333333348],"xyz":[0.305679365092331845,0.308855065591952527,0.852423121681484708],"hpluv":[250.401946751580681,170.701691169737018,62.4108626997728209],"hsluv":[250.401946751580681,83.3865807682554845,62.4108626997728209]},"#5599ff":{"lch":[63.2869312953637,97.1853240423286309,253.372761171991215],"luv":[63.2869312953637,-27.8089904224615658,-93.1216798650875859],"rgb":[0.333333333333333315,0.6,1],"xyz":[0.331850413502163266,0.319323484955885251,0.990257309973266553],"hpluv":[253.372761171991215,194.861470594675211,63.2869312953637],"hsluv":[253.372761171991215,99.9999999999986215,63.2869312953637]},"#440000":{"lch":[10.7708306123528814,36.2226426723970221,12.1770506300617765],"luv":[10.7708306123528814,35.407649887332731,7.64056094984030221],"rgb":[0.266666666666666663,0,0],"xyz":[0.0238384275584062923,0.0122916892098035059,0.00111742629180027137],"hpluv":[12.1770506300617765,426.746789183125145,10.7708306123528814],"hsluv":[12.1770506300617765,100.000000000002203,10.7708306123528814]},"#440011":{"lch":[11.0614468716721248,32.5827232355020158,4.73042674181564848],"luv":[11.0614468716721248,32.4717377839629151,2.68702414036008763],"rgb":[0.266666666666666663,0,0.0666666666666666657],"xyz":[0.024850093058043414,0.0126963554096583605,0.00644553125655590239],"hpluv":[4.73042674181564848,373.778888471265759,11.0614468716721248],"hsluv":[4.73042674181564848,99.999999999996831,11.0614468716721248]},"#440022":{"lch":[11.5842423793746683,28.6540476811609395,350.304317532446703],"luv":[11.5842423793746683,28.2447579299318896,-4.82577434136679706],"rgb":[0.266666666666666663,0,0.133333333333333331],"xyz":[0.0267254511965204326,0.0134464986650491784,0.0163224174525351],"hpluv":[350.304317532446703,313.875682434467763,11.5842423793746683],"hsluv":[350.304317532446703,99.9999999999974847,11.5842423793746683]},"#440033":{"lch":[12.4041921203750505,27.3919603751935874,328.642516788172941],"luv":[12.4041921203750505,23.3910134404871357,-14.2541216293086901],"rgb":[0.266666666666666663,0,0.2],"xyz":[0.0298132019289781731,0.0146815989580322912,0.0325845713101462417],"hpluv":[328.642516788172941,280.216663156604227,12.4041921203750505],"hsluv":[328.642516788172941,99.9999999999981668,12.4041921203750505]},"#440044":{"lch":[13.5105146335658439,30.7747615701782742,307.715012949243601],"luv":[13.5105146335658439,18.8259784531467211,-24.3447835271332202],"rgb":[0.266666666666666663,0,0.266666666666666663],"xyz":[0.0342711971731970502,0.0164647970557198695,0.0560633462630328802],"hpluv":[307.715012949243601,289.042783730483222,13.5105146335658439],"hsluv":[307.715012949243601,99.9999999999987779,13.5105146335658439]},"#440055":{"lch":[14.871657786523194,37.5926423334987589,293.358518425732086],"luv":[14.871657786523194,14.9048564440935021,-34.5116214049025416],"rgb":[0.266666666666666663,0,0.333333333333333315],"xyz":[0.0402336112125590423,0.0188497626714647,0.0874653935370067886],"hpluv":[293.358518425732086,320.761913781574776,14.871657786523194],"hsluv":[293.358518425732086,99.999999999999261,14.871657786523194]},"#440066":{"lch":[16.4463097679727497,46.0898544445027,284.618444278650202],"luv":[16.4463097679727497,11.6321972733021664,-44.597832562922008],"rgb":[0.266666666666666663,0,0.4],"xyz":[0.0478186069860672205,0.0218837609808680139,0.127413037944150764],"hpluv":[284.618444278650202,355.611827609674208,16.4463097679727497],"hsluv":[284.618444278650202,99.9999999999996447,16.4463097679727497]},"#440077":{"lch":[18.1919811936642475,55.3198462112611651,279.251207899416613],"luv":[18.1919811936642475,8.8934050845755,-54.6002997321373],"rgb":[0.266666666666666663,0,0.466666666666666674],"xyz":[0.0571326200062691331,0.0256093661889488303,0.176466839850548673],"hpluv":[279.251207899416613,385.869357778503058,18.1919811936642475],"hsluv":[279.251207899416613,100.000000000000028,18.1919811936642475]},"#440088":{"lch":[20.0701231572475791,64.8751824688912,275.807883046004235],"luv":[20.0701231572475791,6.56492582220058196,-64.5421648949036353],"rgb":[0.266666666666666663,0,0.533333333333333326],"xyz":[0.0682730371082129611,0.0300655330297264212,0.235139703254120841],"hpluv":[275.807883046004235,410.173767132845569,20.0701231572475791],"hsluv":[275.807883046004235,100.000000000000284,20.0701231572475791]},"#440099":{"lch":[22.0482755473713041,74.5764302852581267,273.495279820248],"luv":[22.0482755473713041,4.54664979059262,-74.4377050275844283],"rgb":[0.266666666666666663,0,0.6],"xyz":[0.0813300012172856746,0.0352883186733555787,0.303906380895238748],"hpluv":[273.495279820248,429.20649964036636,22.0482755473713041],"hsluv":[273.495279820248,100.000000000000384,22.0482755473713041]},"#4400aa":{"lch":[24.1003299188330615,84.3353594354864811,271.878389761009714],"luv":[24.1003299188330615,2.7643624238057809,-84.290041828810061],"rgb":[0.266666666666666663,0,0.66666666666666663],"xyz":[0.0963876941825382166,0.0413113958594566871,0.383210230512237349],"hpluv":[271.878389761009714,444.044033459252,24.1003299188330615],"hsluv":[271.878389761009714,100.000000000000398,24.1003299188330615]},"#4400bb":{"lch":[26.2058661049044161,94.1030045511215434,270.708980538846049],"luv":[26.2058661049044161,1.16440507249082947,-94.0958002589677704],"rgb":[0.266666666666666663,0,0.733333333333333282],"xyz":[0.113525286289874863,0.0481664327023914457,0.473468215610879095],"hpluv":[270.708980538846049,455.663559843794246,26.2058661049044161],"hsluv":[270.708980538846049,100.000000000000597,26.2058661049044161]},"#4400cc":{"lch":[28.3491756730399374,103.84959146554381,269.838851579513857],"luv":[28.3491756730399374,-0.292083914573144032,-103.849180711969012],"rgb":[0.266666666666666663,0,0.8],"xyz":[0.132817661733596604,0.0558833828798802473,0.575074726281149196],"hpluv":[269.838851579513857,464.840204698682,28.3491756730399374],"hsluv":[269.838851579513857,100.00000000000054,28.3491756730399374]},"#4400dd":{"lch":[30.5182871942398464,113.556060117994207,269.175711116484081],"luv":[30.5182871942398464,-1.63362415099869285,-113.544308803456943],"rgb":[0.266666666666666663,0,0.866666666666666696],"xyz":[0.154335987284230147,0.0644907131001337813,0.688404574181155193],"hpluv":[269.175711116484081,472.160320460814546,30.5182871942398464],"hsluv":[269.175711116484081,100.000000000000583,30.5182871942398464]},"#4400ee":{"lch":[32.7041215904695406,123.209994802530275,268.6598990566049],"luv":[32.7041215904695406,-2.88151723804096926,-123.176295112519156],"rgb":[0.266666666666666663,0,0.933333333333333348],"xyz":[0.178148167550404884,0.0740155852066038122,0.813815390249678416],"hpluv":[268.6598990566049,478.060407115886846,32.7041215904695406],"hsluv":[268.6598990566049,100.000000000000682,32.7041215904695406]},"#4400ff":{"lch":[34.8998090420324161,132.803387625161918,268.251574356178935],"luv":[34.8998090420324161,-4.05197057625710322,-132.741558297197031],"rgb":[0.266666666666666663,0,1],"xyz":[0.204319215960236278,0.0844840045705365084,0.951649578541460262],"hpluv":[268.251574356178935,482.864668803745815,34.8998090420324161],"hsluv":[268.251574356178935,100.000000000000824,34.8998090420324161]},"#441100":{"lch":[13.412021407860891,32.8203905090178907,19.8063713084711637],"luv":[13.412021407860891,30.878837797926078,11.1209446277644677],"rgb":[0.266666666666666663,0.0666666666666666657,0],"xyz":[0.025842827819334703,0.0163004897316603795,0.00178555971210972225],"hpluv":[19.8063713084711637,310.519467471828818,13.412021407860891],"hsluv":[19.8063713084711637,100.00000000000226,13.412021407860891]},"#441111":{"lch":[13.6534230745514442,29.3615880370140658,12.1770506300618155],"luv":[13.6534230745514442,28.7009658227648572,6.19333616848069],"rgb":[0.266666666666666663,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0268544933189718248,0.0167051559315152323,0.00711366467686535414],"hpluv":[12.1770506300618155,272.883526996448495,13.6534230745514442],"hsluv":[12.1770506300618155,63.9450685777404857,13.6534230745514442]},"#441122":{"lch":[14.0908014406849,25.4444274015795777,356.558123350094036],"luv":[14.0908014406849,25.3985311285907684,-1.52758053936917793],"rgb":[0.266666666666666663,0.0666666666666666657,0.133333333333333331],"xyz":[0.0287298514574488434,0.0174552991869060536,0.0169905508728445502],"hpluv":[356.558123350094036,229.137575437366081,14.0908014406849],"hsluv":[356.558123350094036,68.4589860949294,14.0908014406849]},"#441133":{"lch":[14.7844111345271223,24.27011571268606,331.648240125609],"luv":[14.7844111345271223,21.358884082162259,-11.5254755854986932],"rgb":[0.266666666666666663,0.0666666666666666657,0.2],"xyz":[0.0318176021899065839,0.0186903994798891665,0.0332527047304557],"hpluv":[331.648240125609,208.308572243058649,14.7844111345271223],"hsluv":[331.648240125609,73.8494669394836762,14.7844111345271223]},"#441144":{"lch":[15.733846020816415,28.3218749128348932,307.715012949243942],"luv":[15.733846020816415,17.3254634530922189,-22.4043949865608347],"rgb":[0.266666666666666663,0.0666666666666666657,0.266666666666666663],"xyz":[0.0362755974341254644,0.0204735975775767395,0.0567314796833423354],"hpluv":[307.715012949243942,228.415952286272613,15.733846020816415],"hsluv":[307.715012949243942,79.0249627886423127,15.733846020816415]},"#441155":{"lch":[16.9210970319156715,36.0495621705848492,292.339268883647492],"luv":[16.9210970319156715,13.7020846665308547,-33.3440220801582683],"rgb":[0.266666666666666663,0.0666666666666666657,0.333333333333333315],"xyz":[0.0422380114734874565,0.0228585631933215724,0.0881335269573162439],"hpluv":[292.339268883647492,270.340308544513618,16.9210970319156715],"hsluv":[292.339268883647492,83.4150097743113292,16.9210970319156715]},"#441166":{"lch":[18.3175541838796221,45.305096001334384,283.521508601515677],"luv":[18.3175541838796221,10.592801308498224,-44.0493392019540195],"rgb":[0.266666666666666663,0.0666666666666666657,0.4],"xyz":[0.0498230072469956348,0.025892561502724884,0.128081171364460206],"hpluv":[283.521508601515677,313.84766122316239,18.3175541838796221],"hsluv":[283.521508601515677,86.9023417707839485,18.3175541838796221]},"#441177":{"lch":[19.8903241139664431,55.0653797371295326,278.304914930180701],"luv":[19.8903241139664431,7.95370312292975612,-54.4879312529533735],"rgb":[0.266666666666666663,0.0666666666666666657,0.466666666666666674],"xyz":[0.0591370202671975473,0.0296181667108057,0.177134973270858115],"hpluv":[278.304914930180701,351.298345972174616,19.8903241139664431],"hsluv":[278.304914930180701,89.590178354910762,19.8903241139664431]},"#441188":{"lch":[21.6068634066631873,64.9598488176177824,275.03199667533886],"luv":[21.6068634066631873,5.69776159856002,-64.7094851716016422],"rgb":[0.266666666666666663,0.0666666666666666657,0.533333333333333326],"xyz":[0.0702774373691413823,0.0340743335515832912,0.235807836674430282],"hpluv":[275.03199667533886,381.498298720028686,21.6068634066631873],"hsluv":[275.03199667533886,91.6417594317348545,21.6068634066631873]},"#441199":{"lch":[23.437698327746169,74.8628785955689153,272.864058339832695],"luv":[23.437698327746169,3.74063102269824954,-74.769367197849931],"rgb":[0.266666666666666663,0.0666666666666666657,0.6],"xyz":[0.0833344014782140818,0.0392971191952124557,0.304574514315548162],"hpluv":[272.864058339832695,405.313331644098525,23.437698327746169],"hsluv":[272.864058339832695,93.2101268622270283,23.437698327746169]},"#4411aa":{"lch":[25.3575925472355337,84.7316846097945273,271.361966301038933],"luv":[25.3575925472355337,2.01394993465393446,-84.7077468858332878],"rgb":[0.266666666666666663,0.0666666666666666657,0.66666666666666663],"xyz":[0.0983920944434666378,0.0453201963813135572,0.383878363932546762],"hpluv":[271.361966301038933,424.011024215555381,25.3575925472355337],"hsluv":[271.361966301038933,94.4180404350203872,25.3575925472355337]},"#4411bb":{"lch":[27.345710117802,94.5503656807627,270.282295464151048],"luv":[27.345710117802,0.465846378280231621,-94.5492180693092337],"rgb":[0.266666666666666663,0.0666666666666666657,0.733333333333333282],"xyz":[0.115529686550803284,0.0521752332242483158,0.474136349031188509],"hpluv":[270.282295464151048,438.746165283595928,27.345710117802],"hsluv":[270.282295464151048,95.3579307613671,27.345710117802]},"#4411cc":{"lch":[29.3852471201757481,104.311620276565549,269.482476007084244],"luv":[29.3852471201757481,-0.942181651797373232,-104.307365120864873],"rgb":[0.266666666666666663,0.0666666666666666657,0.8],"xyz":[0.134822061994525,0.0598921834017371174,0.575742859701458665],"hpluv":[269.482476007084244,450.445933463405538,29.3852471201757481],"hsluv":[269.482476007084244,96.097629526357963,29.3852471201757481]},"#4411dd":{"lch":[31.4628506304707116,114.011096091836691,268.874895171215144],"luv":[31.4628506304707116,-2.23866735310417164,-113.989115272223103],"rgb":[0.266666666666666663,0.0666666666666666657,0.866666666666666696],"xyz":[0.156340387545158555,0.0684995136219906514,0.689072707601464662],"hpluv":[268.874895171215144,459.820552568088715,31.4628506304707116],"hsluv":[268.874895171215144,96.6865382756064378,31.4628506304707116]},"#4411ee":{"lch":[33.5680052377948073,123.64577428881995,268.40345713539682],"luv":[33.5680052377948073,-3.44493495426529961,-123.597774747940718],"rgb":[0.266666666666666663,0.0666666666666666657,0.933333333333333348],"xyz":[0.180152567811333292,0.0780243857284606823,0.814483523669987886],"hpluv":[268.40345713539682,467.404695294247745,33.5680052377948073],"hsluv":[268.40345713539682,97.1606953094382817,33.5680052377948073]},"#4411ff":{"lch":[35.6924730299026081,133.21354134861582,268.030966648817412],"luv":[35.6924730299026081,-4.57713081064657,-133.134884505082312],"rgb":[0.266666666666666663,0.0666666666666666657,1],"xyz":[0.206323616221164685,0.0884928050923933784,0.952317711961769731],"hpluv":[268.030966648817412,473.599309181226886,35.6924730299026081],"hsluv":[268.030966648817412,99.999999999999531,35.6924730299026081]},"#99aa00":{"lch":[66.1528677227115907,74.3468963767982842,94.6234982733471384],"luv":[66.1528677227115907,-5.99293371363564553,74.1049643840839565],"rgb":[0.6,0.66666666666666663,0],"xyz":[0.275106719282890377,0.355217387920677,0.0540714229698005533],"hpluv":[94.6234982733471384,142.611154102436132,66.1528677227115907],"hsluv":[94.6234982733471384,100.000000000002217,66.1528677227115907]},"#99aa11":{"lch":[66.184052262829,73.0311244080130706,94.7508326892346275],"luv":[66.184052262829,-6.04863423256243316,72.7802112955118901],"rgb":[0.6,0.66666666666666663,0.0666666666666666657],"xyz":[0.276118384782527482,0.355622054120531828,0.059399527934556183],"hpluv":[94.7508326892346275,140.021252931940353,66.184052262829],"hsluv":[94.7508326892346275,98.1390759685954,66.184052262829]},"#99aa22":{"lch":[66.2417975711995695,70.6178785015108872,94.9968669170454376],"luv":[66.2417975711995695,-6.15090676716144458,70.3494926065273],"rgb":[0.6,0.66666666666666663,0.133333333333333331],"xyz":[0.277993742921004539,0.356372197375922628,0.0692764141305353826],"hpluv":[94.9968669170454376,135.276352185575888,66.2417975711995695],"hsluv":[94.9968669170454376,94.7283581868373403,66.2417975711995695]},"#99aa33":{"lch":[66.3366981156763273,66.7162457715457,95.432805623918],"luv":[66.3366981156763273,-6.31658226271684953,66.416550937003791],"rgb":[0.6,0.66666666666666663,0.2],"xyz":[0.281081493653462244,0.357607297668905755,0.0855385679881465189],"hpluv":[95.432805623918,127.619510800204154,66.3366981156763273],"hsluv":[95.432805623918,89.220332613511431,66.3366981156763273]},"#99aa44":{"lch":[66.4733277612737652,61.2361369282317085,96.1403021162386],"luv":[66.4733277612737652,-6.55002950525979344,60.8848222414533211],"rgb":[0.6,0.66666666666666663,0.266666666666666663],"xyz":[0.28553948889768116,0.359390495766593321,0.109017342941033157],"hpluv":[96.1403021162386,116.896010950353556,66.4733277612737652],"hsluv":[96.1403021162386,81.495914591183535,66.4733277612737652]},"#99aa55":{"lch":[66.6553605356915853,54.1785870660784568,97.2658616968833769],"luv":[66.6553605356915853,-6.85216039608048888,53.7435316515674231],"rgb":[0.6,0.66666666666666663,0.333333333333333315],"xyz":[0.291501902937043145,0.361775461382338182,0.140419390215007073],"hpluv":[97.2658616968833769,103.141138146130345,66.6553605356915853],"hsluv":[97.2658616968833769,71.5645731506566563,66.6553605356915853]},"#99aa66":{"lch":[66.8857782590742573,45.6318272725976186,99.1048787772859328],"luv":[66.8857782590742573,-7.22087825912546055,45.0568815765480224],"rgb":[0.6,0.66666666666666663,0.4],"xyz":[0.29908689871055133,0.3648094596917415,0.180367034622151035],"hpluv":[99.1048787772859328,86.5711928674077882,66.8857782590742573],"hsluv":[99.1048787772859328,59.5487850828384495,66.8857782590742573]},"#99aa77":{"lch":[67.16697930835997,35.7793898766585272,102.348317274789],"luv":[67.16697930835997,-7.65157453727816339,34.9516544250255947],"rgb":[0.6,0.66666666666666663,0.466666666666666674],"xyz":[0.308400911730753235,0.368535064899822296,0.229420836528548944],"hpluv":[102.348317274789,67.5952906506277742,67.16697930835997],"hsluv":[102.348317274789,45.6652750399669927,67.16697930835997]},"#99aa88":{"lch":[67.5008436530857523,24.9656779050761699,109.02352802026725],"luv":[67.5008436530857523,-8.13772239581267165,23.6021725158659379],"rgb":[0.6,0.66666666666666663,0.533333333333333326],"xyz":[0.319541328832697036,0.372991231740599893,0.288093699932121083],"hpluv":[109.02352802026725,46.9324783865521482,67.5008436530857523],"hsluv":[109.02352802026725,30.201776912068496,67.5008436530857523]},"#99aa99":{"lch":[67.8887769686822509,14.1753245834603039,127.715012949228395],"luv":[67.8887769686822509,-8.67153282620695443,11.213578621049983],"rgb":[0.6,0.66666666666666663,0.6],"xyz":[0.332598292941769791,0.378214017384229051,0.356860377573239],"hpluv":[127.715012949228395,26.4956363039349618,67.8887769686822509],"hsluv":[127.715012949228395,13.4910013502760879,67.8887769686822509]},"#99aaaa":{"lch":[68.3317447891119798,9.45739632834534838,192.177050630059227],"luv":[68.3317447891119798,-9.24460926466251642,-1.99487965930680966],"rgb":[0.6,0.66666666666666663,0.66666666666666663],"xyz":[0.347655985907022291,0.384237094570330173,0.436164227190237619],"hpluv":[192.177050630059227,17.5625836428344968,68.3317447891119798],"hsluv":[192.177050630059227,17.4938385380963979,68.3317447891119798]},"#99aabb":{"lch":[68.8303024285350205,18.6222464744475609,238.07162859052869],"luv":[68.8303024285350205,-9.84853629911531137,-15.8048852105949411],"rgb":[0.6,0.66666666666666663,0.733333333333333282],"xyz":[0.364793578014358966,0.391092131413264932,0.52642221228887931],"hpluv":[238.07162859052869,34.3314162301526622,68.8303024285350205],"hsluv":[238.07162859052869,21.6214176811966929,68.8303024285350205]},"#99aacc":{"lch":[69.3846237501618646,31.7868422871013969,250.758533684062627],"luv":[69.3846237501618646,-10.475354770609286,-30.0111693376804425],"rgb":[0.6,0.66666666666666663,0.8],"xyz":[0.38408595345808072,0.398809081590753733,0.628028722959149466],"hpluv":[250.758533684062627,58.1330991079694357,69.3846237501618646],"hsluv":[250.758533684062627,38.7837447081888556,69.3846237501618646]},"#99aadd":{"lch":[69.9945303682966,45.800012761152324,255.951164454091042],"luv":[69.9945303682966,-11.1178995355210173,-44.4300965432191859],"rgb":[0.6,0.66666666666666663,0.866666666666666696],"xyz":[0.405604279008714208,0.40741641181100724,0.741358570859155463],"hpluv":[255.951164454091042,83.0311057452140346,69.9945303682966],"hsluv":[255.951164454091042,58.1375555879370935,69.9945303682966]},"#99aaee":{"lch":[70.6595219654936,60.0690973767372896,258.700300270425373],"luv":[70.6595219654936,-11.7699993169592201,-58.9046990972259],"rgb":[0.6,0.66666666666666663,0.933333333333333348],"xyz":[0.429416459274889,0.416941283917477257,0.866769386927678687],"hpluv":[258.700300270425373,107.874733956899746,70.6595219654936],"hsluv":[258.700300270425373,78.5353046306170199,70.6595219654936]},"#99aaff":{"lch":[71.378807837336737,74.3523754541628676,260.378973553217],"luv":[71.378807837336737,-12.4265554124673407,-73.3065921746310636],"rgb":[0.6,0.66666666666666663,1],"xyz":[0.455587507684720339,0.42740970328141,1.00460357521946064],"hpluv":[260.378973553217,132.179737350703419,71.378807837336737],"hsluv":[260.378973553217,99.99999999999784,71.378807837336737]},"#442200":{"lch":[17.3350542344952459,28.221345162136295,35.6239292836567927],"luv":[17.3350542344952459,22.9399340369809366,16.4378754448194186],"rgb":[0.266666666666666663,0.133333333333333331,0],"xyz":[0.0295584515541026382,0.023731737201196354,0.00302410095703233277],"hpluv":[35.6239292836567927,206.581692971425213,17.3350542344952459],"hsluv":[35.6239292836567927,100.000000000002331,17.3350542344952459]},"#442211":{"lch":[17.5234603686317101,24.6335663377647,28.604455948929278],"luv":[17.5234603686317101,21.6269347365689519,11.7935696215031331],"rgb":[0.266666666666666663,0.133333333333333331,0.0666666666666666657],"xyz":[0.03057011705373976,0.0241364034010512069,0.00835220592178796337],"hpluv":[28.604455948929278,178.380241443971528,17.5234603686317101],"hsluv":[28.604455948929278,74.2089163354216765,17.5234603686317101]},"#442222":{"lch":[17.8672188947691239,19.9697171584766728,12.1770506300619807],"luv":[17.8672188947691239,19.520407715454283,4.21227800744330061],"rgb":[0.266666666666666663,0.133333333333333331,0.133333333333333331],"xyz":[0.0324454751922167786,0.0248865466564420282,0.0182290921177671594],"hpluv":[12.1770506300619807,141.825486578211439,17.8672188947691239],"hsluv":[12.1770506300619807,33.2341074785113406,17.8672188947691239]},"#442233":{"lch":[18.4184657925371695,17.8165085202964129,340.00784749027008],"luv":[18.4184657925371695,16.7428760354525643,-6.09131167444770583],"rgb":[0.266666666666666663,0.133333333333333331,0.2],"xyz":[0.0355332259246745191,0.026121646949425141,0.0344912459753783],"hpluv":[340.00784749027008,122.746318288975218,18.4184657925371695],"hsluv":[340.00784749027008,42.0888291674463915,18.4184657925371695]},"#442244":{"lch":[19.1844846541763658,22.4593922221866436,307.715012949244738],"luv":[19.1844846541763658,13.7391814744519145,-17.7668002578431441],"rgb":[0.266666666666666663,0.133333333333333331,0.266666666666666663],"xyz":[0.0399912211688934,0.0279048450471127141,0.0579700209282649412],"hpluv":[307.715012949244738,148.554970924606664,19.1844846541763658],"hsluv":[307.715012949244738,51.3954955066877517,19.1844846541763658]},"#442255":{"lch":[20.1595909359386596,31.6741463862469885,290.023039430837684],"luv":[20.1595909359386596,10.8451637140407797,-29.7596030436068872],"rgb":[0.266666666666666663,0.133333333333333331,0.333333333333333315],"xyz":[0.0459536352082553917,0.030289810662857547,0.0893720682022388496],"hpluv":[290.023039430837684,199.371249454156271,20.1595909359386596],"hsluv":[290.023039430837684,59.9942694866150177,20.1595909359386596]},"#442266":{"lch":[21.3287002071660226,42.3208084503031685,281.207510247893651],"luv":[21.3287002071660226,8.22559640374024781,-41.5137373852322256],"rgb":[0.266666666666666663,0.133333333333333331,0.4],"xyz":[0.0535386309817635631,0.0333238089722608585,0.129319712609382825],"hpluv":[281.207510247893651,251.784442505332123,21.3287002071660226],"hsluv":[281.207510247893651,67.3437899952651406,21.3287002071660226]},"#442277":{"lch":[22.6709734328231463,53.1747129073287113,276.391210783405313],"luv":[22.6709734328231463,5.91922219198187882,-52.8442324328661215],"rgb":[0.266666666666666663,0.133333333333333331,0.466666666666666674],"xyz":[0.0628526440019654825,0.0370494141803416749,0.178373514515780734],"hpluv":[276.391210783405313,297.628360698128461,22.6709734328231463],"hsluv":[276.391210783405313,73.3546851738733,22.6709734328231463]},"#442288":{"lch":[24.1630625686767715,63.8732961962266543,273.501787345358252],"luv":[24.1630625686767715,3.90136026108148481,-63.7540379512086801],"rgb":[0.266666666666666663,0.133333333333333331,0.533333333333333326],"xyz":[0.0739930611039093106,0.0415055810211192727,0.237046377919352902],"hpluv":[273.501787345358252,335.433687598002,24.1630625686767715],"hsluv":[273.501787345358252,78.1624380374364875,24.1630625686767715]},"#442299":{"lch":[25.7815797239733442,74.3421908873045112,271.638748742297366],"luv":[25.7815797239733442,2.1260128283266071,-74.3117851715204836],"rgb":[0.266666666666666663,0.133333333333333331,0.6],"xyz":[0.087050025212982024,0.0467283666647484303,0.305813055560470781],"hpluv":[271.638748742297366,365.902315457699217,25.7815797239733442],"hsluv":[271.638748742297366,81.974423252689391,25.7815797239733442]},"#4422aa":{"lch":[27.5046927955253,84.5952413694672885,270.370058715866037],"luv":[27.5046927955253,0.546375125789773097,-84.5934769150692176],"rgb":[0.266666666666666663,0.133333333333333331,0.66666666666666663],"xyz":[0.102107718178234566,0.0527514438508495317,0.385116905177469382],"hpluv":[270.370058715866037,390.281946032504152,27.5046927955253],"hsluv":[270.370058715866037,84.9950544768410765,27.5046927955253]},"#4422bb":{"lch":[29.3129652277151251,94.666070770970677,269.4687873747244],"luv":[29.3129652277151251,-0.87767531850734,-94.6620020982533],"rgb":[0.266666666666666663,0.133333333333333331,0.733333333333333282],"xyz":[0.119245310285571213,0.0596064806937842903,0.475374890276111128],"hpluv":[269.4687873747244,409.801860030343846,29.3129652277151251],"hsluv":[269.4687873747244,87.3984435941311517,29.3129652277151251]},"#4422cc":{"lch":[31.1896477872922873,104.586362634530047,268.806646243455475],"luv":[31.1896477872922873,-2.17816227055809408,-104.563678484665701],"rgb":[0.266666666666666663,0.133333333333333331,0.8],"xyz":[0.138537685729292953,0.0673234308712731,0.576981400946381284],"hpluv":[268.806646243455475,425.504262664631483,31.1896477872922873],"hsluv":[268.806646243455475,89.3235413687926325,31.1896477872922873]},"#4422dd":{"lch":[33.1206275871571,114.38069493574325,268.306702684458742],"luv":[33.1206275871571,-3.37987077956927,-114.330747603157818],"rgb":[0.266666666666666663,0.133333333333333331,0.866666666666666696],"xyz":[0.160056011279926497,0.0759307610915266329,0.690311248846387282],"hpluv":[268.306702684458742,438.22131720165,33.1206275871571],"hsluv":[268.306702684458742,90.877884626449017,33.1206275871571]},"#4422ee":{"lch":[35.0941942457284952,124.066768949832422,267.920557621455941],"luv":[35.0941942457284952,-4.50178121539094178,-123.985068147498538],"rgb":[0.266666666666666663,0.133333333333333331,0.933333333333333348],"xyz":[0.183868191546101234,0.0854556331979966499,0.815722064914910505],"hpluv":[267.920557621455941,448.600262181889605,35.0941942457284952],"hsluv":[267.920557621455941,93.3452679661598523,35.0941942457284952]},"#4422ff":{"lch":[37.1007304630435,133.656986375695226,267.616535799179189],"luv":[37.1007304630435,-5.55843332369103926,-133.54135623850334],"rgb":[0.266666666666666663,0.133333333333333331,1],"xyz":[0.210039239955932627,0.0959240525619293599,0.95355625320669235],"hpluv":[267.616535799179189,457.139270395610822,37.1007304630435],"hsluv":[267.616535799179189,99.999999999999531,37.1007304630435]},"#bbaa00":{"lch":[68.9787767407419,76.4078567958722346,76.7962953219783344],"luv":[68.9787767407419,17.4526104568015299,74.3879490803561652],"rgb":[0.733333333333333282,0.66666666666666663,0],"xyz":[0.348671553863065253,0.393149255751080451,0.0575197745907461769],"hpluv":[76.7962953219783344,140.560034871296551,68.9787767407419],"hsluv":[76.7962953219783344,100.000000000002245,68.9787767407419]},"#bbaa11":{"lch":[69.0079227935645747,75.1793224892161902,76.6760735029220797],"luv":[69.0079227935645747,17.325534429098667,73.1556996185784811],"rgb":[0.733333333333333282,0.66666666666666663,0.0666666666666666657],"xyz":[0.349683219362702358,0.393553921950935304,0.0628478795555018],"hpluv":[76.6760735029220797,138.241608756115426,69.0079227935645747],"hsluv":[76.6760735029220797,98.327691673723,69.0079227935645747]},"#bbaa22":{"lch":[69.0618990033698168,72.923722885125926,76.4446579961253718],"luv":[69.0618990033698168,17.0921879270318975,70.8923583420220496],"rgb":[0.733333333333333282,0.66666666666666663,0.133333333333333331],"xyz":[0.351558577501179415,0.394304065206326104,0.072724765751481],"hpluv":[76.4446579961253718,133.98915323660276,69.0618990033698168],"hsluv":[76.4446579961253718,95.2591470849694701,69.0618990033698168]},"#bbaa33":{"lch":[69.1506211183474448,69.2704933393546298,76.037430434814425],"luv":[69.1506211183474448,16.7141363744442764,67.2237970716773248],"rgb":[0.733333333333333282,0.66666666666666663,0.2],"xyz":[0.35464632823363712,0.395539165499309231,0.0889869196090921494],"hpluv":[76.037430434814425,127.113454601419591,69.1506211183474448],"hsluv":[76.037430434814425,90.2940538071316752,69.1506211183474448]},"#bbaa44":{"lch":[69.2783900215706439,64.125663575375043,75.3840533289293688],"luv":[69.2783900215706439,16.1813855024742246,62.0504914743025964],"rgb":[0.733333333333333282,0.66666666666666663,0.266666666666666663],"xyz":[0.359104323477856036,0.397322363596996797,0.112465694561978788],"hpluv":[75.3840533289293688,117.455514697890109,69.2783900215706439],"hsluv":[75.3840533289293688,83.3108908827552455,69.2783900215706439]},"#bbaa55":{"lch":[69.4486803199850158,57.4759826537307603,74.3632861967268752],"luv":[69.4486803199850158,15.4919003466967737,55.3487994961044762],"rgb":[0.733333333333333282,0.66666666666666663,0.333333333333333315],"xyz":[0.365066737517218,0.399707329212741658,0.143867741835952689],"hpluv":[74.3632861967268752,105.017514149864908,69.4486803199850158],"hsluv":[74.3632861967268752,74.2978448337225501,69.4486803199850158]},"#bbaa66":{"lch":[69.6643364030220766,49.3851711615203186,72.7428070953876],"luv":[69.6643364030220766,14.6506772614363818,47.1619845472377079],"rgb":[0.733333333333333282,0.66666666666666663,0.4],"xyz":[0.372651733290726206,0.402741327522145,0.183815386243096651],"hpluv":[72.7428070953876,89.9550160304510342,69.6643364030220766],"hsluv":[72.7428070953876,63.3404983901227254,69.6643364030220766]},"#bbaa77":{"lch":[69.927675331165787,39.998456174204172,70.017617272721],"luv":[69.927675331165787,13.6687200676018641,37.5904587366697314],"rgb":[0.733333333333333282,0.66666666666666663,0.466666666666666674],"xyz":[0.381965746310928111,0.406466932730225772,0.23286918814949456],"hpluv":[70.017617272721,72.5827577171275635,69.927675331165787],"hsluv":[70.017617272721,50.6076787731359303,69.927675331165787]},"#bbaa88":{"lch":[70.2405480333122,29.5797452752191568,64.8698942165899837],"luv":[70.2405480333122,12.5617839686329518,26.7798975739685403],"rgb":[0.733333333333333282,0.66666666666666663,0.533333333333333326],"xyz":[0.393106163412871912,0.41092309957100337,0.291542051553066728],"hpluv":[64.8698942165899837,53.4374671266607422,70.2405480333122],"hsluv":[64.8698942165899837,36.3337734813298923,70.2405480333122]},"#bbaa99":{"lch":[70.6043801086793,18.7359983934483161,52.7186742094296079],"luv":[70.6043801086793,11.3489394865138475,14.907689570511744],"rgb":[0.733333333333333282,0.66666666666666663,0.6],"xyz":[0.406163127521944611,0.416145885214632527,0.360308729194184663],"hpluv":[52.7186742094296079,33.6732102985619051,70.6043801086793],"hsluv":[52.7186742094296079,20.7983697782308,70.6043801086793]},"#bbaaaa":{"lch":[71.0202025015365876,10.2824341490213804,12.177050630064155],"luv":[71.0202025015365876,10.0510841141786607,2.16890759569567715],"rgb":[0.733333333333333282,0.66666666666666663,0.66666666666666663],"xyz":[0.421220820487197167,0.422168962400733649,0.439612578811183263],"hpluv":[12.177050630064155,18.3718697222702261,71.0202025015365876],"hsluv":[12.177050630064155,12.5020210815887047,71.0202025015365876]},"#bbaabb":{"lch":[71.4886774714552615,14.2047670368859897,307.715012949256788],"luv":[71.4886774714552615,8.68954378602241562,-11.236869464535129],"rgb":[0.733333333333333282,0.66666666666666663,0.733333333333333282],"xyz":[0.438358412594533842,0.429023999243668408,0.529870563909825],"hpluv":[307.715012949256788,25.2136766683934965,71.4886774714552615],"hsluv":[307.715012949256788,14.1682246563909,71.4886774714552615]},"#bbaacc":{"lch":[72.010122844957138,26.1519063744379174,286.174295641089373],"luv":[72.010122844957138,7.28488198445553525,-25.1167812724863673],"rgb":[0.733333333333333282,0.66666666666666663,0.8],"xyz":[0.45765078803825554,0.43674094942115721,0.631477074580095166],"hpluv":[286.174295641089373,46.0838895939184923,72.010122844957138],"hsluv":[286.174295641089373,33.6938059680335442,72.010122844957138]},"#bbaadd":{"lch":[72.5845361735228494,39.7272427931479,278.476565574149959],"luv":[72.5845361735228494,5.85598959517198825,-39.2932717625671799],"rgb":[0.733333333333333282,0.66666666666666663,0.866666666666666696],"xyz":[0.47916911358888914,0.445348279641410716,0.744806922480101163],"hpluv":[278.476565574149959,69.451822258827633,72.5845361735228494],"hsluv":[278.476565574149959,54.5084651382981775,72.5845361735228494]},"#bbaaee":{"lch":[73.2116196006959825,53.7916684525604,274.71268656160521],"luv":[73.2116196006959825,4.41947960396952144,-53.6098106221266093],"rgb":[0.733333333333333282,0.66666666666666663,0.933333333333333348],"xyz":[0.502981293855063849,0.454873151747880733,0.870217738548624387],"hpluv":[274.71268656160521,93.2340021292866084,73.2116196006959825],"hsluv":[274.71268656160521,76.5987468488048506,73.2116196006959825]},"#bbaaff":{"lch":[73.8908057188696574,67.9996555049746121,272.519622378571285],"luv":[73.8908057188696574,2.98936916429642707,-67.9339150998584671],"rgb":[0.733333333333333282,0.66666666666666663,1],"xyz":[0.52915234226489527,0.465341571111813457,1.00805192684040623],"hpluv":[272.519622378571285,116.776549017196231,73.8908057188696574],"hsluv":[272.519622378571285,99.9999999999974847,73.8908057188696574]},"#99bb00":{"lch":[71.0859361318702696,82.3913749493211327,101.26222245755217],"luv":[71.0859361318702696,-16.0909976916487061,80.8048170552163185],"rgb":[0.6,0.733333333333333282,0],"xyz":[0.309061217191489157,0.423126383737875533,0.0653895889393331653],"hpluv":[101.26222245755217,147.074503152999483,71.0859361318702696],"hsluv":[101.26222245755217,100.000000000002302,71.0859361318702696]},"#99bb11":{"lch":[71.1136894680978457,81.2167121813616291,101.442926834262664],"luv":[71.1136894680978457,-16.1127230849120338,79.6023523040561685],"rgb":[0.6,0.733333333333333282,0.0666666666666666657],"xyz":[0.310072882691126261,0.423531049937730386,0.0707176939040888],"hpluv":[101.442926834262664,144.921066000062638,71.1136894680978457],"hsluv":[101.442926834262664,98.4331733262411,71.1136894680978457]},"#99bb22":{"lch":[71.1650900316793837,79.0601549481488917,101.789083890819583],"luv":[71.1650900316793837,-16.1527448632600859,77.392486287802754],"rgb":[0.6,0.733333333333333282,0.133333333333333331],"xyz":[0.311948240829603318,0.424281193193121187,0.080594580100068],"hpluv":[101.789083890819583,140.971066242853169,71.1650900316793837],"hsluv":[101.789083890819583,95.5563304227746357,71.1650900316793837]},"#99bb33":{"lch":[71.2495884989653,75.5680342451554168,102.392870056849247],"luv":[71.2495884989653,-16.2179420391938294,73.807222923575253],"rgb":[0.6,0.733333333333333282,0.2],"xyz":[0.315035991562061,0.425516293486104313,0.0968567339576791309],"hpluv":[102.392870056849247,134.584514176993849,71.2495884989653],"hsluv":[102.392870056849247,90.8963478676004826,71.2495884989653]},"#99bb44":{"lch":[71.3712967033779648,70.652786516275043,103.347443045401377],"luv":[71.3712967033779648,-16.3105834167977157,68.7443169368786471],"rgb":[0.6,0.733333333333333282,0.266666666666666663],"xyz":[0.319493986806279939,0.427299491583791879,0.120335508910565769],"hpluv":[103.347443045401377,125.616021445862458,71.3712967033779648],"hsluv":[103.347443045401377,84.331672265085615,71.3712967033779648]},"#99bb55":{"lch":[71.5335490617920442,64.3081830776187502,104.804237401434776],"luv":[71.5335490617920442,-16.4318507493525949,62.1734404042074189],"rgb":[0.6,0.733333333333333282,0.333333333333333315],"xyz":[0.325456400845641924,0.42968445719953674,0.151737556184539685],"hpluv":[104.804237401434776,114.076396323867073,71.5335490617920442],"hsluv":[104.804237401434776,75.8403293762878263,71.5335490617920442]},"#99bb66":{"lch":[71.7390905918245494,56.6109161874071347,107.032342660002968],"luv":[71.7390905918245494,-16.5819871692753225,54.1279367156704367],"rgb":[0.6,0.733333333333333282,0.4],"xyz":[0.33304139661915011,0.432718455508940059,0.191685200591683647],"hpluv":[107.032342660002968,100.134479122606095,71.7390905918245494],"hsluv":[107.032342660002968,65.4891515707011,71.7390905918245494]},"#99bb77":{"lch":[71.9901757540345102,47.73532562127712,110.555323727161408],"luv":[71.9901757540345102,-16.7604289857032249,44.6961892378372099],"rgb":[0.6,0.733333333333333282,0.466666666666666674],"xyz":[0.342355409639352,0.436444060717020854,0.240739002498081556],"hpluv":[110.555323727161408,84.1406731320706,71.9901757540345102],"hsluv":[110.555323727161408,53.4218452589237,71.9901757540345102]},"#99bb88":{"lch":[72.2886271035685581,38.007890289968195,116.511646356383693],"luv":[72.2886271035685581,-16.9659512259030869,34.0111191126451473],"rgb":[0.6,0.733333333333333282,0.533333333333333326],"xyz":[0.353495826741295815,0.440900227557798452,0.299411865901653695],"hpluv":[116.511646356383693,66.7180145269523592,72.2886271035685581],"hsluv":[116.511646356383693,39.8440619041218724,72.2886271035685581]},"#99bb99":{"lch":[72.6358740128595315,28.1115962970155238,127.715012949234961],"luv":[72.6358740128595315,-17.1968288028560856,22.2380512970816788],"rgb":[0.6,0.733333333333333282,0.6],"xyz":[0.366552790850368515,0.44612301320142761,0.36817854354277163],"hpluv":[127.715012949234961,49.1104221429672094,72.6358740128595315],"hsluv":[127.715012949234961,25.0059581073328268,72.6358740128595315]},"#99bbaa":{"lch":[73.0329812495468929,19.8989345424194468,151.280397210880039],"luv":[73.0329812495468929,-17.4510036711552878,9.56190706882358654],"rgb":[0.6,0.733333333333333282,0.66666666666666663],"xyz":[0.381610483815621071,0.452146090387528732,0.447482393159770231],"hpluv":[151.280397210880039,34.5740392557976648,73.0329812495468929],"hsluv":[151.280397210880039,28.0327457551748473,73.0329812495468929]},"#99bbbb":{"lch":[73.4806726048520602,18.1342571597367979,192.177050630060279],"luv":[73.4806726048520602,-17.7262447217336288,-3.82511840348453136],"rgb":[0.6,0.733333333333333282,0.733333333333333282],"xyz":[0.398748075922957745,0.45900112723046349,0.537740378258412],"hpluv":[192.177050630060279,31.3159775944509384,73.4806726048520602],"hsluv":[192.177050630060279,31.1933976709334857,73.4806726048520602]},"#99bbcc":{"lch":[73.9793524714423,25.2831678504957686,224.541830016242],"luv":[73.9793524714423,-18.0202882726228886,-17.734367401402082],"rgb":[0.6,0.733333333333333282,0.8],"xyz":[0.418040451366679444,0.466718077407952292,0.639346888928682189],"hpluv":[224.541830016242,43.3670907410057183,73.9793524714423],"hsluv":[224.541830016242,34.4349286550277398,73.9793524714423]},"#99bbdd":{"lch":[74.5291269946933284,36.8692317824205347,240.185846709470951],"luv":[74.5291269946933284,-18.3309507682094441,-31.9893184697537762],"rgb":[0.6,0.733333333333333282,0.866666666666666696],"xyz":[0.439558776917313043,0.475325407628205798,0.752676736828688187],"hpluv":[240.185846709470951,62.7736499155611796,74.5291269946933284],"hsluv":[240.185846709470951,50.9371920612126914,74.5291269946933284]},"#99bbee":{"lch":[75.129825653719962,50.0395173115419851,248.109771752659725],"luv":[75.129825653719962,-18.6562099892881648,-46.4316607672792],"rgb":[0.6,0.733333333333333282,0.933333333333333348],"xyz":[0.463370957183487753,0.484850279734675815,0.87808755289721141],"hpluv":[248.109771752659725,84.5162185097210568,75.129825653719962],"hsluv":[248.109771752659725,74.708817528734329,75.129825653719962]},"#99bbff":{"lch":[75.7810236401202104,63.8171103470632701,252.684342225014],"luv":[75.7810236401202104,-18.9942553989637197,-60.9248868270445527],"rgb":[0.6,0.733333333333333282,1],"xyz":[0.489542005593319174,0.495318699098608539,1.01592174118899314],"hpluv":[252.684342225014,106.860202909060845,75.7810236401202104],"hsluv":[252.684342225014,99.9999999999971,75.7810236401202104]},"#443300":{"lch":[22.2907133772276609,26.4379209369795269,61.2454831359909],"luv":[22.2907133772276609,12.7181702882918319,23.1778300966244757],"rgb":[0.266666666666666663,0.2,0],"xyz":[0.0356761736431134499,0.0359671813792181508,0.00506334165336921362],"hpluv":[61.2454831359909,150.502134175174433,22.2907133772276609],"hsluv":[61.2454831359909,100.000000000002217,22.2907133772276609]},"#443311":{"lch":[22.433780901835803,22.5495741902090607,57.6291729330006959],"luv":[22.433780901835803,12.072970412625418,19.0453847841311372],"rgb":[0.266666666666666663,0.2,0.0666666666666666657],"xyz":[0.0366878391427505751,0.0363718475790730036,0.0103914466181248451],"hpluv":[57.6291729330006959,127.548453681164943,22.433780901835803],"hsluv":[57.6291729330006959,82.4396262904162853,22.433780901835803]},"#443322":{"lch":[22.6962080128251955,16.3034653251506185,47.6268315603120129],"luv":[22.6962080128251955,10.9878263584328284,12.044527949459761],"rgb":[0.266666666666666663,0.2,0.133333333333333331],"xyz":[0.0385631972812275903,0.037121990834463825,0.0202683328141040411],"hpluv":[47.6268315603120129,91.1519465603444,22.6962080128251955],"hsluv":[47.6268315603120129,53.1527363908354289,22.6962080128251955]},"#443333":{"lch":[23.1206934094119845,9.67437860897999613,12.1770506300626202],"luv":[23.1206934094119845,9.4567095438703852,2.04064844418642899],"rgb":[0.266666666666666663,0.2,0.2],"xyz":[0.0416509480136853308,0.0383570911274469378,0.0365304866717151844],"hpluv":[12.1770506300626202,53.0959690287213917,23.1206934094119845],"hsluv":[12.1770506300626202,12.4420312875371923,23.1206934094119845]},"#443344":{"lch":[23.7177668131648574,12.5269391023357528,307.715012949247694],"luv":[23.7177668131648574,7.66315882209806354,-9.90960141180911],"rgb":[0.266666666666666663,0.2,0.266666666666666663],"xyz":[0.0461089432579042113,0.0401402892251345109,0.0600092616246018229],"hpluv":[307.715012949247694,67.0209373905010608,23.7177668131648574],"hsluv":[307.715012949247694,23.1872031280306743,23.7177668131648574]},"#443355":{"lch":[24.4893027034144382,23.4497607107203301,284.299245815683662],"luv":[24.4893027034144382,5.79176863833153277,-22.7232632654309157],"rgb":[0.266666666666666663,0.2,0.333333333333333315],"xyz":[0.0520713572972662,0.0425252548408793438,0.0914113088985757383],"hpluv":[284.299245815683662,121.507006770462795,24.4893027034144382],"hsluv":[284.299245815683662,34.0172562824217479,24.4893027034144382]},"#443366":{"lch":[25.4301832846655458,35.8361728283181407,276.366541048647719],"luv":[25.4301832846655458,3.97382245046802396,-35.6151655634680964],"rgb":[0.266666666666666663,0.2,0.4],"xyz":[0.0596563530707743817,0.0455592531502826553,0.1313589533057197],"hpluv":[276.366541048647719,178.818092823782393,25.4301832846655458],"hsluv":[276.366541048647719,44.0521665839457555,25.4301832846655458]},"#443377":{"lch":[26.5300434901181958,48.2102429207408818,272.708376965990851],"luv":[26.5300434901181958,2.27805419202829862,-48.1563909733176416],"rgb":[0.266666666666666663,0.2,0.466666666666666674],"xyz":[0.0689703660909762872,0.0492848583583634717,0.180412755212117609],"hpluv":[272.708376965990851,230.590114205629249,26.5300434901181958],"hsluv":[272.708376965990851,52.8563285469964583,26.5300434901181958]},"#443388":{"lch":[27.7750487339787355,60.1896827108213373,270.691543734184165],"luv":[27.7750487339787355,0.726454682878815761,-60.1852986070773568],"rgb":[0.266666666666666663,0.2,0.533333333333333326],"xyz":[0.0801107831929201153,0.0537410251991410626,0.239085618615689777],"hpluv":[270.691543734184165,274.983446475144433,27.7750487339787355],"hsluv":[270.691543734184165,60.324174233719404,27.7750487339787355]},"#443399":{"lch":[29.1495234429961272,71.6961686956082218,269.452076389218803],"luv":[29.1495234429961272,-0.685625105343165342,-71.6928903298230438],"rgb":[0.266666666666666663,0.2,0.6],"xyz":[0.0931677473019928426,0.058963810842770227,0.307852296256807656],"hpluv":[269.452076389218803,312.107220431461315,29.1495234429961272],"hsluv":[269.452076389218803,66.5368599437509,29.1495234429961272]},"#4433aa":{"lch":[30.6372824460415245,82.7612763398458924,268.632918119842316],"luv":[30.6372824460415245,-1.97450330946598829,-82.7377193188284821],"rgb":[0.266666666666666663,0.2,0.66666666666666663],"xyz":[0.108225440267245371,0.0649868880288713285,0.387156145873806257],"hpluv":[268.632918119842316,342.78062465137026,30.6372824460415245],"hsluv":[268.632918119842316,71.6553387322885698,30.6372824460415245]},"#4433bb":{"lch":[32.2226022397772525,93.4505902198726375,268.062492493372758],"luv":[32.2226022397772525,-3.15951219941267691,-93.3971642776391633],"rgb":[0.266666666666666663,0.2,0.733333333333333282],"xyz":[0.125363032374582017,0.0718419248718060871,0.477414130972448],"hpluv":[268.062492493372758,368.010970109266054,32.2226022397772525],"hsluv":[268.062492493372758,75.8581190135042789,32.2226022397772525]},"#4433cc":{"lch":[33.8908458580626331,103.832026214070311,267.649236367220567],"luv":[33.8908458580626331,-4.25888397543315911,-103.744646006447894],"rgb":[0.266666666666666663,0.2,0.8],"xyz":[0.144655407818303772,0.0795588750492948887,0.579020641642718159],"hpluv":[267.649236367220567,388.765974213008576,33.8908458580626331],"hsluv":[267.649236367220567,79.3114034284002,33.8908458580626331]},"#4433dd":{"lch":[35.628800942302739,113.96424557581804,267.340372831489958],"luv":[35.628800942302739,-5.28823530427115518,-113.841485571087048],"rgb":[0.266666666666666663,0.2,0.866666666666666696],"xyz":[0.166173733368937315,0.0881662052695484227,0.692350489542724157],"hpluv":[267.340372831489958,405.888493424646128,35.628800942302739],"hsluv":[267.340372831489958,85.5677988674314,35.628800942302739]},"#4433ee":{"lch":[37.4248062251042484,123.894025620863303,267.103630337901393],"luv":[37.4248062251042484,-6.26032296204841732,-123.73575853791813],"rgb":[0.266666666666666663,0.2,0.933333333333333348],"xyz":[0.189985913635112053,0.0976910773760184536,0.81776130561124738],"hpluv":[267.103630337901393,420.078186698807599,37.4248062251042484],"hsluv":[267.103630337901393,92.6566888343209,37.4248062251042484]},"#4433ff":{"lch":[39.2687372084732473,133.657198385904053,266.918330051954797],"luv":[39.2687372084732473,-7.18532525912719411,-133.4639193988003],"rgb":[0.266666666666666663,0.2,1],"xyz":[0.216156962044943446,0.10815949673995115,0.955595493903029225],"hpluv":[266.918330051954797,431.901531941155895,39.2687372084732473],"hsluv":[266.918330051954797,99.99999999999946,39.2687372084732473]},"#bbbb00":{"lch":[73.6141498101152223,81.1522849996882485,85.8743202181747591],"luv":[73.6141498101152223,5.83845950082822274,80.9419900380996],"rgb":[0.733333333333333282,0.733333333333333282,0],"xyz":[0.382626051771664,0.461058251568279,0.0688379405602788],"hpluv":[85.8743202181747591,139.887458074797564,73.6141498101152223],"hsluv":[85.8743202181747591,100.000000000002331,73.6141498101152223]},"#bbbb11":{"lch":[73.6403599567658205,80.0195247391518478,85.8743202181747449],"luv":[73.6403599567658205,5.75696364516240155,79.8121651696532695],"rgb":[0.733333333333333282,0.733333333333333282,0.0666666666666666657],"xyz":[0.383637717271301082,0.461462917768133862,0.0741660455250344325],"hpluv":[85.8743202181747449,137.885751829634614,73.6403599567658205],"hsluv":[85.8743202181747449,98.5690595334933732,73.6403599567658205]},"#bbbb22":{"lch":[73.6889060807276763,77.9361940700347873,85.8743202181746597],"luv":[73.6889060807276763,5.60707948923862176,77.7342331648256817],"rgb":[0.733333333333333282,0.733333333333333282,0.133333333333333331],"xyz":[0.385513075409778139,0.462213061023524663,0.0840429317210136251],"hpluv":[85.8743202181746597,134.207383902194948,73.6889060807276763],"hsluv":[85.8743202181746597,95.9395400768792541,73.6889060807276763]},"#bbbb33":{"lch":[73.768722281637082,74.5519121144895536,85.8743202181745318],"luv":[73.768722281637082,5.36359906059884217,74.3587211095223],"rgb":[0.733333333333333282,0.733333333333333282,0.2],"xyz":[0.388600826142235845,0.46344816131650779,0.100305085578624775],"hpluv":[85.8743202181745318,128.24069174643796,73.768722281637082],"hsluv":[85.8743202181745318,91.6741883163470419,73.768722281637082]},"#bbbb44":{"lch":[73.8837085661944144,69.7637661309282464,85.8743202181743328],"luv":[73.8837085661944144,5.01911835485944824,69.5829829463408629],"rgb":[0.733333333333333282,0.733333333333333282,0.266666666666666663],"xyz":[0.39305882138645476,0.465231359414195356,0.123783860531511414],"hpluv":[85.8743202181743328,119.817583791868643,73.8837085661944144],"hsluv":[85.8743202181743328,85.652842249664161,73.8837085661944144]},"#bbbb55":{"lch":[74.0370403615741,63.5337415760462747,85.8743202181740628],"luv":[74.0370403615741,4.57090243520957262,63.3691026414263376],"rgb":[0.733333333333333282,0.733333333333333282,0.333333333333333315],"xyz":[0.399021235425816745,0.467616325029940216,0.155185907805485301],"hpluv":[85.8743202181740628,108.891682763750694,74.0370403615741],"hsluv":[85.8743202181740628,77.8423486010655239,74.0370403615741]},"#bbbb66":{"lch":[74.2313474843288361,55.8815023675101799,85.8743202181735512],"luv":[74.2313474843288361,4.02036601211528843,55.7366931561128212],"rgb":[0.733333333333333282,0.733333333333333282,0.4],"xyz":[0.40660623119932493,0.470650323339343535,0.195133552212629291],"hpluv":[85.8743202181735512,95.5256619678334857,74.2313474843288361],"hsluv":[85.8743202181735512,68.2875100330713138,74.2313474843288361]},"#bbbb77":{"lch":[74.468808451125966,46.8772880877030289,85.8743202181728549],"luv":[74.468808451125966,3.37256243628739805,46.7558120565865849],"rgb":[0.733333333333333282,0.733333333333333282,0.466666666666666674],"xyz":[0.415920244219526836,0.47437592854742433,0.2441873541190272],"hpluv":[85.8743202181728549,79.8780401793102328,74.468808451125966],"hsluv":[85.8743202181728549,57.1016453359253688,74.468808451125966]},"#bbbb88":{"lch":[74.7512063572608128,36.6333476151433146,85.874320218171647],"luv":[74.7512063572608128,2.63556739569020726,36.5384173438683746],"rgb":[0.733333333333333282,0.733333333333333282,0.533333333333333326],"xyz":[0.427060661321470636,0.478832095388201928,0.30286021752259934],"hpluv":[85.874320218171647,62.1867310089120195,74.7512063572608128],"hsluv":[85.874320218171647,44.4548295213588744,74.7512063572608128]},"#bbbb99":{"lch":[75.079965438194165,25.2938928616919938,85.8743202181691316],"luv":[75.079965438194165,1.81975614231989979,25.2283472245258693],"rgb":[0.733333333333333282,0.733333333333333282,0.6],"xyz":[0.440117625430543336,0.484054881031831086,0.371626895163717275],"hpluv":[85.8743202181691316,42.7494899193068392,75.079965438194165],"hsluv":[85.8743202181691316,30.559916169503893,75.079965438194165]},"#bbbbaa":{"lch":[75.4561775549407372,13.0242335847304886,85.8743202181613583],"luv":[75.4561775549407372,0.937021801842234714,12.9904830784884187],"rgb":[0.733333333333333282,0.733333333333333282,0.66666666666666663],"xyz":[0.455175318395795891,0.490077958217932208,0.450930744780715875],"hpluv":[85.8743202181613583,21.9026519543336242,75.4561775549407372],"hsluv":[85.8743202181613583,15.6573378741524305,75.4561775549407372]},"#bbbbbb":{"lch":[75.8806235332097856,3.97454725928322e-12,0],"luv":[75.8806235332097856,3.75098259432623098e-12,1.31421287976393485e-12],"rgb":[0.733333333333333282,0.733333333333333282,0.733333333333333282],"xyz":[0.472312910503132566,0.496932995060866967,0.541188729879357622],"hpluv":[0,6.64654731741433278e-12,75.8806235332097856],"hsluv":[0,6.51507609526145538e-12,75.8806235332097856]},"#bbbbcc":{"lch":[76.3537921403793,13.6026726964261613,265.874320218192793],"luv":[76.3537921403793,-0.97863730689855577,-13.5674232449512715],"rgb":[0.733333333333333282,0.733333333333333282,0.8],"xyz":[0.491605285946854265,0.504649945238355713,0.642795240549627778],"hpluv":[265.874320218192793,23.0577392955455913,76.3537921403793],"hsluv":[265.874320218192793,22.3559583930985184,76.3537921403793]},"#bbbbdd":{"lch":[76.875898300454,27.6153317552162676,265.874320218184891],"luv":[76.875898300454,-1.98677087225565296,-27.543770429115412],"rgb":[0.733333333333333282,0.733333333333333282,0.866666666666666696],"xyz":[0.513123611497487864,0.51325727545860933,0.756125088449633775],"hpluv":[265.874320218184891,48.094692651754464,76.875898300454],"hsluv":[265.874320218184891,46.4508399898830717,76.875898300454]},"#bbbbee":{"lch":[77.4469014383288794,41.8833893600305487,265.874320218182334],"luv":[77.4469014383288794,-3.01327895494808,-41.7748543291725554],"rgb":[0.733333333333333282,0.733333333333333282,0.933333333333333348],"xyz":[0.536935791763662573,0.522782147565079347,0.881535904518157],"hpluv":[265.874320218182334,75.1781465494946,77.4469014383288794],"hsluv":[265.874320218182334,72.306149300046286,77.4469014383288794]},"#bbbbff":{"lch":[78.0665243938900915,56.270213901735211,265.874320218181083],"luv":[78.0665243938900915,-4.04833166396953814,-56.1243973979724444],"rgb":[0.733333333333333282,0.733333333333333282,1],"xyz":[0.563106840173494,0.533250566929012,1.01937009280993873],"hpluv":[265.874320218181083,104.437018855576454,78.0665243938900915],"hsluv":[265.874320218181083,99.9999999999968,78.0665243938900915]},"#99cc00":{"lch":[76.0430979526319,91.0941172293808,106.263360497649074],"luv":[76.0430979526319,-25.5111694560196547,87.4489475453331124],"rgb":[0.6,0.8,0],"xyz":[0.347284960501106077,0.499573870357110428,0.0781308367092051204],"hpluv":[106.263360497649074,152.00919412554731,76.0430979526319],"hsluv":[106.263360497649074,100.000000000002444,76.0430979526319]},"#99cc11":{"lch":[76.0679435797449202,90.0431717383104342,106.457693210299354],"luv":[76.0679435797449202,-25.5098862277023812,86.3540299079582496],"rgb":[0.6,0.8,0.0666666666666666657],"xyz":[0.348296626000743181,0.499978536556965281,0.083458941673960757],"hpluv":[106.457693210299354,150.416675371578,76.0679435797449202],"hsluv":[106.457693210299354,98.6698238814781377,76.0679435797449202]},"#99cc22":{"lch":[76.1139653123302224,88.1120975577654235,106.827460928226145],"luv":[76.1139653123302224,-25.5076232207001254,84.3392132620406301],"rgb":[0.6,0.8,0.133333333333333331],"xyz":[0.350171984139220238,0.500728679812356137,0.0933358278699399496],"hpluv":[106.827460928226145,147.536178080277807,76.1139653123302224],"hsluv":[106.827460928226145,96.2239688839219554,76.1139653123302224]},"#99cc33":{"lch":[76.1896394090333615,84.9806694979027668,107.464683868975555],"luv":[76.1896394090333615,-25.5042190273125513,81.0632407452271195],"rgb":[0.6,0.8,0.2],"xyz":[0.353259734871677944,0.501963780105339263,0.109597981727551086],"hpluv":[107.464683868975555,142.843382477451314,76.1896394090333615],"hsluv":[107.464683868975555,92.2523981769505497,76.1896394090333615]},"#99cc44":{"lch":[76.2986765643697566,80.5641186971074461,108.452476349375274],"luv":[76.2986765643697566,-25.4999909675489818,76.4220366262018445],"rgb":[0.6,0.8,0.266666666666666663],"xyz":[0.357717730115896859,0.503746978203026829,0.133076756680437724],"hpluv":[108.452476349375274,136.177549938509202,76.2986765643697566],"hsluv":[108.452476349375274,86.6370393323296,76.2986765643697566]},"#99cc55":{"lch":[76.4441084930992645,74.8483308647658276,109.915235611542258],"luv":[76.4441084930992645,-25.4955548836031696,70.3722197633315858],"rgb":[0.6,0.8,0.333333333333333315],"xyz":[0.363680144155258844,0.506131943818771579,0.16447880395441164],"hpluv":[109.915235611542258,127.465568679298812,76.4441084930992645],"hsluv":[109.915235611542258,79.3378797119037245,76.4441084930992645]},"#99cc66":{"lch":[76.6284587708723279,67.8919791104198111,112.053749389120497],"luv":[76.6284587708723279,-25.4918238993559072,62.9244606001029396],"rgb":[0.6,0.8,0.4],"xyz":[0.37126513992876703,0.509165942128174898,0.204426448361555602],"hpluv":[112.053749389120497,116.726185086844026,76.6284587708723279],"hsluv":[112.053749389120497,70.3850130172815796,76.6284587708723279]},"#99cc77":{"lch":[76.8538330837355801,59.8379910057359723,115.212918879407354],"luv":[76.8538330837355801,-25.4899847789994141,54.1372869986012262],"rgb":[0.6,0.8,0.466666666666666674],"xyz":[0.380579152948968935,0.512891547336255749,0.253480250267953511],"hpluv":[115.212918879407354,104.093311342856381,76.8538330837355801],"hsluv":[115.212918879407354,59.8707914454029577,76.8538330837355801]},"#99cc88":{"lch":[77.1219726780439885,50.9458531819172649,120.024060615406185],"luv":[77.1219726780439885,-25.4914521322680621,44.1097021597488919],"rgb":[0.6,0.8,0.533333333333333326],"xyz":[0.391719570050912735,0.517347714177033291,0.31215311367152565],"hpluv":[120.024060615406185,89.8814395273866324,77.1219726780439885],"hsluv":[120.024060615406185,47.9401368886289845,77.1219726780439885]},"#99cc99":{"lch":[77.4342891130262103,41.681173098632776,127.715012949236964],"luv":[77.4342891130262103,-25.4978049096247332,32.9724450969124447],"rgb":[0.6,0.8,0.6],"xyz":[0.40477653415998549,0.522570499820662504,0.380919791312643585],"hpluv":[127.715012949236964,74.7648437658604337,77.4342891130262103],"hsluv":[127.715012949236964,34.7788947556027495,77.4342891130262103]},"#99ccaa":{"lch":[77.7918890721377352,32.9651751214879525,140.702563314804109],"luv":[77.7918890721377352,-25.5107121176450882,20.8783701002018844],"rgb":[0.6,0.8,0.66666666666666663],"xyz":[0.419834227125238,0.528593577006763571,0.460223640929642186],"hpluv":[140.702563314804109,60.2770963674260756,77.7918890721377352],"hsluv":[140.702563314804109,37.0803100068772622,77.7918890721377352]},"#99ccbb":{"lch":[78.1955939192693421,26.7536671513630395,162.617393192268167],"luv":[78.1955939192693421,-25.5318556358660231,7.9926875226808507],"rgb":[0.6,0.8,0.733333333333333282],"xyz":[0.436971819232574665,0.535448613849698329,0.550481626028283877],"hpluv":[162.617393192268167,50.006554278151107,78.1955939192693421],"hsluv":[162.617393192268167,39.5096284608221353,78.1955939192693421]},"#99cccc":{"lch":[78.6459566685868481,26.1512486118356264,192.177050630060364],"luv":[78.6459566685868481,-25.562857556775878,-5.51616873291790277],"rgb":[0.6,0.8,0.8],"xyz":[0.45626419467629642,0.543165564027187187,0.652088136698554],"hpluv":[192.177050630060364,50.1138147500145,78.6459566685868481],"hsluv":[192.177050630060364,42.0292910605185952,78.6459566685868481]},"#99ccdd":{"lch":[79.1432779300782,32.1756084020034763,217.269502822152816],"luv":[79.1432779300782,-25.6052179328205156,-19.4844191766612091],"rgb":[0.6,0.8,0.866666666666666696],"xyz":[0.477782520226929908,0.551772894247440693,0.76541798459856],"hpluv":[217.269502822152816,63.4104034428488532,79.1432779300782],"hsluv":[217.269502822152816,44.6030324020319142,79.1432779300782]},"#99ccee":{"lch":[79.6876217339600146,42.4043636674930298,232.761609201673764],"luv":[79.6876217339600146,-25.6602666815912279,-33.7591583407321],"rgb":[0.6,0.8,0.933333333333333348],"xyz":[0.501594700493104728,0.56129776635391071,0.890828800667083254],"hpluv":[232.761609201673764,86.2263034184575901,79.6876217339600146],"hsluv":[232.761609201673764,69.2463215394111842,79.6876217339600146]},"#99ccff":{"lch":[80.278831719152322,54.6396736698167231,241.908088190648726],"luv":[80.278831719152322,-25.7291311718118969,-48.2027566419988105],"rgb":[0.6,0.8,1],"xyz":[0.527765748902936,0.571766185717843434,1.02866298895886521],"hpluv":[241.908088190648726,115.039816302159181,80.278831719152322],"hsluv":[241.908088190648726,99.9999999999963762,80.278831719152322]},"#444400":{"lch":[27.7455139749470092,30.5866720374503593,85.8743202181747307],"luv":[27.7455139749470092,2.20054242411605072,30.5074108925390952],"rgb":[0.266666666666666663,0.266666666666666663,0],"xyz":[0.044508744126079483,0.0536323223451504599,0.00800753181435780864],"hpluv":[85.8743202181747307,139.887458074797593,27.7455139749470092],"hsluv":[85.8743202181747307,100.000000000002331,27.7455139749470092]},"#444411":{"lch":[27.8552611903384602,27.0161424908788135,85.8743202181744],"luv":[27.8552611903384602,1.9436625081132386,26.9461338811715763],"rgb":[0.266666666666666663,0.266666666666666663,0.0666666666666666657],"xyz":[0.0455204096257166,0.0540369885450053128,0.0133356367791134401],"hpluv":[85.8743202181744,123.070915058641674,27.8552611903384602],"hsluv":[85.8743202181744,87.9785198418851451,27.8552611903384602]},"#444422":{"lch":[28.0572627170229296,20.802612285424587,85.8743202181735086],"luv":[28.0572627170229296,1.49663326596887214,20.7487051828516122],"rgb":[0.266666666666666663,0.266666666666666663,0.133333333333333331],"xyz":[0.0473957677641936234,0.0547871318003961341,0.0232125229750926379],"hpluv":[85.8743202181735086,94.0831614915658463,28.0572627170229296],"hsluv":[85.8743202181735086,67.2563236092702539,28.0572627170229296]},"#444433":{"lch":[28.3858756417530103,11.5666907278610811,85.8743202181704],"luv":[28.3858756417530103,0.832159628943940688,11.5367172430437677],"rgb":[0.266666666666666663,0.266666666666666663,0.2],"xyz":[0.0504835184966513639,0.056022232093379247,0.0394746768327037811],"hpluv":[85.8743202181704,51.7066205750809758,28.3858756417530103],"hsluv":[85.8743202181704,36.9630139018145201,28.3858756417530103]},"#444444":{"lch":[28.8519023983998864,1.56211738287899238e-12,0],"luv":[28.8519023983998864,1.45745810878583046e-12,5.6216241338882039e-13],"rgb":[0.266666666666666663,0.266666666666666663,0.266666666666666663],"xyz":[0.0549415137408702445,0.05780543019106682,0.0629534517855904197],"hpluv":[0,6.87034486140541504e-12,28.8519023983998864],"hsluv":[0,1.96712204652458306e-12,28.8519023983998864]},"#444455":{"lch":[29.4604491554767947,12.996237632929807,265.874320218183527],"luv":[29.4604491554767947,-0.935007647451096213,-12.9625596743385874],"rgb":[0.266666666666666663,0.266666666666666663,0.333333333333333315],"xyz":[0.0609039277802322365,0.0601903958068116529,0.094355499059564335],"hpluv":[265.874320218183527,55.9780294653588157,29.4604491554767947],"hsluv":[265.874320218183527,10.903125265393685,29.4604491554767947]},"#444466":{"lch":[30.2117995944983235,26.5936989313503034,265.874320218180401],"luv":[30.2117995944983235,-1.9132700229980284,-26.52478502590359],"rgb":[0.266666666666666663,0.266666666666666663,0.4],"xyz":[0.0684889235537404079,0.0632243941162149714,0.134303143466708297],"hpluv":[265.874320218180401,111.69699235114156,30.2117995944983235],"hsluv":[265.874320218180401,21.7557908165695544,30.2117995944983235]},"#444477":{"lch":[31.1022350000615333,40.188693881548005,265.874320218179378],"luv":[31.1022350000615333,-2.89135495838767076,-40.084550420447286],"rgb":[0.266666666666666663,0.266666666666666663,0.466666666666666674],"xyz":[0.0778029365739423273,0.0669499993242957808,0.183356945373106206],"hpluv":[265.874320218179378,163.965176201048621,31.1022350000615333],"hsluv":[265.874320218179378,31.9363305989270607,31.1022350000615333]},"#444488":{"lch":[32.1249060438116132,53.4239352836437,265.874320218178923],"luv":[32.1249060438116132,-3.84355760936744639,-53.2854945186250859],"rgb":[0.266666666666666663,0.266666666666666663,0.533333333333333326],"xyz":[0.0889433536758861554,0.0714061661650733787,0.242029808776678373],"hpluv":[265.874320218178923,211.024721596932807,32.1249060438116132],"hsluv":[265.874320218178923,41.1023574005893479,32.1249060438116132]},"#444499":{"lch":[33.2707247827276404,66.1374776044503818,265.874320218178639],"luv":[33.2707247827276404,-4.75822688765494473,-65.9660914467787336],"rgb":[0.266666666666666663,0.266666666666666663,0.6],"xyz":[0.102000317784958869,0.0766289518087025362,0.31079648641779628],"hpluv":[265.874320218178639,252.246234683596128,33.2707247827276404],"hsluv":[265.874320218178639,50.2337582903708224,33.2707247827276404]},"#4444aa":{"lch":[34.5292085317775772,78.2936422443982707,265.874320218178468],"luv":[34.5292085317775772,-5.63279591471267516,-78.090755061511743],"rgb":[0.266666666666666663,0.266666666666666663,0.66666666666666663],"xyz":[0.117058010750211411,0.0826520289948036446,0.390100336034794881],"hpluv":[265.874320218178468,287.726060771882089,34.5292085317775772],"hsluv":[265.874320218178468,59.0260968416557645,34.5292085317775772]},"#4444bb":{"lch":[35.8892144652077647,89.9250819913669801,265.874320218178354],"luv":[35.8892144652077647,-6.46961387860876,-89.6920535355044],"rgb":[0.266666666666666663,0.266666666666666663,0.733333333333333282],"xyz":[0.134195602857548058,0.0895070658377384,0.480358321133436628],"hpluv":[265.874320218178354,317.948086985701252,35.8892144652077647],"hsluv":[265.874320218178354,67.4283717547759807,35.8892144652077647]},"#4444cc":{"lch":[37.3395287853000397,101.093816173965237,265.874320218178298],"luv":[37.3395287853000397,-7.27314272811459173,-100.831845482823283],"rgb":[0.266666666666666663,0.266666666666666663,0.8],"xyz":[0.153487978301269812,0.0972240160152272,0.581964831803706728],"hpluv":[265.874320218178298,343.55405942077391,37.3395287853000397],"hsluv":[265.874320218178298,75.5808548987534294,37.3395287853000397]},"#4444dd":{"lch":[38.8693012328948697,111.868746538356049,265.874320218178241],"luv":[38.8693012328948697,-8.04833956400084105,-111.578854100252741],"rgb":[0.266666666666666663,0.266666666666666663,0.866666666666666696],"xyz":[0.175006303851903355,0.105831346235480739,0.695294679703712726],"hpluv":[265.874320218178241,365.208910634554,38.8693012328948697],"hsluv":[265.874320218178241,83.6313726076760702,38.8693012328948697]},"#4444ee":{"lch":[40.4683363226646691,122.314460404417545,265.874320218178127],"luv":[40.4683363226646691,-8.799851087852959,-121.997499338533331],"rgb":[0.266666666666666663,0.266666666666666663,0.933333333333333348],"xyz":[0.198818484118078065,0.115356218341950756,0.820705495772236],"hpluv":[265.874320218178127,383.532154053589807,40.4683363226646691],"hsluv":[265.874320218178127,91.7249319236633625,40.4683363226646691]},"#4444ff":{"lch":[42.1272645151277203,132.4867415013303,265.874320218178127],"luv":[42.1272645151277203,-9.53169063144130568,-132.143420370999962],"rgb":[0.266666666666666663,0.266666666666666663,1],"xyz":[0.224989532527909486,0.12582463770588348,0.958539684064017794],"hpluv":[265.874320218178127,399.069452944254863,42.1272645151277203],"hsluv":[265.874320218178127,99.9999999999994458,42.1272645151277203]},"#bbcc00":{"lch":[78.3160688649495711,87.6272661942945916,93.3039767998847651],"luv":[78.3160688649495711,-5.05025027162958828,87.4816137990130471],"rgb":[0.733333333333333282,0.8,0],"xyz":[0.420849795081280953,0.537505738187513904,0.081579188330150737],"hpluv":[93.3039767998847651,164.876849582678972,78.3160688649495711],"hsluv":[93.3039767998847651,100.000000000002302,78.3160688649495711]},"#bbcc11":{"lch":[78.3397318378619332,86.5943586896397193,93.3754549086192],"luv":[78.3397318378619332,-5.09856582429126703,86.4441298377475249],"rgb":[0.733333333333333282,0.8,0.0666666666666666657],"xyz":[0.421861460580918057,0.537910404387368812,0.0869072932949063737],"hpluv":[93.3754549086192,163.146061131239662,78.3397318378619332],"hsluv":[93.3754549086192,98.7690619278293,78.3397318378619332]},"#bbcc22":{"lch":[78.3835653101130134,84.6929692802742125,93.5116381573829329],"luv":[78.3835653101130134,-5.18755307791811582,84.5339478468458481],"rgb":[0.733333333333333282,0.8,0.133333333333333331],"xyz":[0.423736818719395114,0.538660547642759613,0.0967841794908855663],"hpluv":[93.5116381573829329,159.95035726483485,78.3835653101130134],"hsluv":[93.5116381573829329,96.5043106774720343,78.3835653101130134]},"#bbcc33":{"lch":[78.4556479267243,81.5996211754986405,93.7468972468941644],"luv":[78.4556479267243,-5.33246113691784,81.4251990123951],"rgb":[0.733333333333333282,0.8,0.2],"xyz":[0.42682456945185282,0.53989564793574274,0.113046333348496703],"hpluv":[93.7468972468941644,154.72407311273281,78.4556479267243],"hsluv":[93.7468972468941644,92.8230308779070157,78.4556479267243]},"#bbcc44":{"lch":[78.5595248117047475,77.2136355312914873,94.1131309849175],"luv":[78.5595248117047475,-5.53822791342104281,77.0147618547127877],"rgb":[0.733333333333333282,0.8,0.266666666666666663],"xyz":[0.431282564696071735,0.541678846033430306,0.136525108301383341],"hpluv":[94.1131309849175,147.254264694427633,78.5595248117047475],"hsluv":[94.1131309849175,87.6101015600037556,78.5595248117047475]},"#bbcc55":{"lch":[78.6981007967589079,71.4912273296626921,94.6593076474989488],"luv":[78.6981007967589079,-5.80727962831129307,71.2549723768110823],"rgb":[0.733333333333333282,0.8,0.333333333333333315],"xyz":[0.43724497873543372,0.544063811649175,0.167927155575357256],"hpluv":[94.6593076474989488,137.398731222980217,78.6981007967589079],"hsluv":[94.6593076474989488,80.8199795518833639,78.6981007967589079]},"#bbcc66":{"lch":[78.8738041161037273,64.440755538040392,95.4673459440295176],"luv":[78.8738041161037273,-6.13981465986491681,64.1475927081912403],"rgb":[0.733333333333333282,0.8,0.4],"xyz":[0.444829974508941905,0.547097809958578374,0.207874799982501218],"hpluv":[95.4673459440295176,125.075317361724217,78.8738041161037273],"hsluv":[95.4673459440295176,72.4696955468646848,78.8738041161037273]},"#bbcc77":{"lch":[79.0886730863018244,56.1202023011108153,96.6860819525870454],"luv":[79.0886730863018244,-6.5340457953894715,55.7385266387743386],"rgb":[0.733333333333333282,0.8,0.466666666666666674],"xyz":[0.454143987529143811,0.550823415166659225,0.2569286018888991],"hpluv":[96.6860819525870454,110.256785788709905,79.0886730863018244],"hsluv":[96.6860819525870454,62.6323703341884,79.0886730863018244]},"#bbcc88":{"lch":[79.3444074564468451,46.6379090458556931,98.6154841820407],"luv":[79.3444074564468451,-6.9864776714612713,46.1116437563841473],"rgb":[0.733333333333333282,0.8,0.533333333333333326],"xyz":[0.465284404631087611,0.555279582007436767,0.315601465292471295],"hpluv":[98.6154841820407,92.9740665461038702,79.3444074564468451],"hsluv":[98.6154841820407,51.4293340198482483,79.3444074564468451]},"#bbcc99":{"lch":[79.6424016540563,36.1659853952486898,101.956116252097843],"luv":[79.6424016540563,-7.49223418159530397,35.3814206410296137],"rgb":[0.733333333333333282,0.8,0.6],"xyz":[0.478341368740160311,0.560502367651066,0.38436814293358923],"hpluv":[101.956116252097843,73.3480812445522616,79.6424016540563],"hsluv":[101.956116252097843,39.0205672484538439,79.6424016540563]},"#bbccaa":{"lch":[79.9837682606211899,25.01387761080953,108.762036830266098],"luv":[79.9837682606211899,-8.04542335958215382,23.6847046866463593],"rgb":[0.733333333333333282,0.8,0.66666666666666663],"xyz":[0.493399061705412867,0.566525444837167,0.463671992550587775],"hpluv":[108.762036830266098,51.7527419020047645,79.9837682606211899],"hsluv":[108.762036830266098,25.5939208298632828,79.9837682606211899]},"#bbccbb":{"lch":[80.3693561861161356,14.1229851396422195,127.715012949226079],"luv":[80.3693561861161356,-8.63951499109438892,11.1721748094634776],"rgb":[0.733333333333333282,0.8,0.733333333333333282],"xyz":[0.510536653812749486,0.573380481680101806,0.553929977649229577],"hpluv":[127.715012949226079,29.8960175179438359,80.3693561861161356],"hsluv":[127.715012949226079,11.3539027840963094,80.3693561861161356]},"#bbcccc":{"lch":[80.7997661027856537,9.48102181692548207,192.177050630058517],"luv":[80.7997661027856537,-9.26770319062559622,-1.99986306118322021],"rgb":[0.733333333333333282,0.8,0.8],"xyz":[0.52982902925647124,0.581097431857590663,0.655536488319499733],"hpluv":[192.177050630058517,20.5979746439306091,80.7997661027856537],"hsluv":[192.177050630058517,14.8313634310922779,80.7997661027856537]},"#bbccdd":{"lch":[81.2753646562375138,18.5534915910332536,237.666646406054781],"luv":[81.2753646562375138,-9.9232294288842251,-15.6767843616051454],"rgb":[0.733333333333333282,0.8,0.866666666666666696],"xyz":[0.551347354807104839,0.589704762077844169,0.76886633621950573],"hpluv":[237.666646406054781,41.5059211719903089,81.2753646562375138],"hsluv":[237.666646406054781,34.6395739712995834,81.2753646562375138]},"#bbccee":{"lch":[81.7962983545147466,31.5457627715974915,250.366116177600304],"luv":[81.7962983545147466,-10.5996485000078611,-29.7116576534899401],"rgb":[0.733333333333333282,0.8,0.933333333333333348],"xyz":[0.575159535073279549,0.599229634184314186,0.894277152288029],"hpluv":[250.366116177600304,72.9233806917818725,81.7962983545147466],"hsluv":[250.366116177600304,65.9765826509477478,81.7962983545147466]},"#bbccff":{"lch":[82.3625076456434329,45.3963265868234203,255.598148289110497],"luv":[82.3625076456434329,-11.2910283768039683,-43.9697526234994669],"rgb":[0.733333333333333282,0.8,1],"xyz":[0.601330583483111,0.60969805354824691,1.0321113405798108],"hpluv":[255.598148289110497,108.847942718229262,82.3625076456434329],"hsluv":[255.598148289110497,99.9999999999958789,82.3625076456434329]},"#99dd00":{"lch":[81.0072374435841738,100.100388992767378,110.059278565234735],"luv":[81.0072374435841738,-34.3336498242400623,94.028125400062109],"rgb":[0.6,0.866666666666666696,0],"xyz":[0.389918951048281226,0.584841851451462,0.0923421668915964389],"hpluv":[110.059278565234735,220.251619684458433,81.0072374435841738],"hsluv":[110.059278565234735,100.000000000002245,81.0072374435841738]},"#99dd11":{"lch":[81.0296061686003,99.1554895677318626,110.248463134872608],"luv":[81.0296061686003,-34.3169109383134483,93.0277417498051733],"rgb":[0.6,0.866666666666666696,0.0666666666666666657],"xyz":[0.39093061654791833,0.585246517651316855,0.0976702718563520755],"hpluv":[110.248463134872608,218.472914234601802,81.0296061686003],"hsluv":[110.248463134872608,98.8616036668283,81.0296061686003]},"#99dd22":{"lch":[81.0710445633976,97.4178442494470431,110.606606003803336],"luv":[81.0710445633976,-34.2861684396920552,91.184949591117217],"rgb":[0.6,0.866666666666666696,0.133333333333333331],"xyz":[0.392805974686395387,0.585996660906707656,0.107547158052331268],"hpluv":[110.606606003803336,215.192819254761019,81.0710445633976],"hsluv":[110.606606003803336,96.7659338960775131,81.0710445633976]},"#99dd33":{"lch":[81.1391953168863154,94.5961335984436857,111.218234049095599],"luv":[81.1391953168863154,-34.2363517117206513,88.1833358024404106],"rgb":[0.6,0.866666666666666696,0.2],"xyz":[0.395893725418853093,0.587231761199690783,0.123809311909942404],"hpluv":[111.218234049095599,209.840835623165077,81.1391953168863154],"hsluv":[111.218234049095599,93.3562182204636599,81.1391953168863154]},"#99dd44":{"lch":[81.2374208116197565,90.6080011845065343,112.152709421166279],"luv":[81.2374208116197565,-34.1661449288095653,83.9195115533635487],"rgb":[0.6,0.866666666666666696,0.266666666666666663],"xyz":[0.400351720663072,0.589014959297378349,0.147288086862829043],"hpluv":[112.152709421166279,202.22119953609328,81.2374208116197565],"hsluv":[112.152709421166279,88.5208972681928827,81.2374208116197565]},"#99dd55":{"lch":[81.3684846041416421,85.4315699411036604,113.506988965296216],"luv":[81.3684846041416421,-34.0753153837539244,78.3417259453695607],"rgb":[0.6,0.866666666666666696,0.333333333333333315],"xyz":[0.406314134702434,0.591399924913123098,0.178690134136802958],"hpluv":[113.506988965296216,192.231211336261111,81.3684846041416421],"hsluv":[113.506988965296216,82.2103932307851579,81.3684846041416421]},"#99dd66":{"lch":[81.5347071887187695,79.1067404569191837,115.426438711198742],"luv":[81.5347071887187695,-33.9646313013793,71.4442454385217758],"rgb":[0.6,0.866666666666666696,0.4],"xyz":[0.413899130475942179,0.594433923222526417,0.21863777854394692],"hpluv":[115.426438711198742,179.864586291563711,81.5347071887187695],"hsluv":[115.426438711198742,74.4308834765056,81.5347071887187695]},"#99dd77":{"lch":[81.7380487099571,71.7428264562351217,118.139890255285593],"luv":[81.7380487099571,-33.8357763954940651,63.2627329764024324],"rgb":[0.6,0.866666666666666696,0.466666666666666674],"xyz":[0.423213143496144084,0.598159528430607268,0.267691580450344802],"hpluv":[118.139890255285593,165.232292085670224,81.7380487099571],"hsluv":[118.139890255285593,65.2389156719347,81.7380487099571]},"#99dd88":{"lch":[81.9801580086414248,63.5371271244577898,122.023063704989269],"luv":[81.9801580086414248,-33.6912346765093815,53.8689820694792942],"rgb":[0.6,0.866666666666666696,0.533333333333333326],"xyz":[0.434353560598087884,0.60261569527138481,0.326364443853917],"hpluv":[122.023063704989269,148.614644251947254,81.9801580086414248],"hsluv":[122.023063704989269,54.7350081565161943,81.9801580086414248]},"#99dd99":{"lch":[82.2624042681600827,54.8181455895933,127.715012949238044],"luv":[82.2624042681600827,-33.5341421039979721,43.3646215160552],"rgb":[0.6,0.866666666666666696,0.6],"xyz":[0.447410524707160584,0.607838480915014,0.395131121495034932],"hpluv":[127.715012949238044,130.58293025992694,82.2624042681600827],"hsluv":[127.715012949238044,43.0558433261763724,82.2624042681600827]},"#99ddaa":{"lch":[82.5858991321833855,46.1452119261310898,136.311935434488049],"luv":[82.5858991321833855,-33.3681126370237138,31.8739649675161907],"rgb":[0.6,0.866666666666666696,0.66666666666666663],"xyz":[0.46246821767241314,0.61386155810111509,0.474434971112033477],"hpluv":[136.311935434488049,112.281381223378744,82.5858991321833855],"hsluv":[136.311935434488049,44.8180878493830122,82.5858991321833855]},"#99ddbb":{"lch":[82.9515135213076,38.5190468703316,149.523212457301526],"luv":[82.9515135213076,-33.1970516149390349,19.536446347119437],"rgb":[0.6,0.866666666666666696,0.733333333333333282],"xyz":[0.479605809779749814,0.620716594944049849,0.564692956210675279],"hpluv":[149.523212457301526,96.0401150933983416,82.9515135213076],"hsluv":[149.523212457301526,46.6955526922259807,82.9515135213076]},"#99ddcc":{"lch":[83.3598915829196585,33.6584009809739158,168.866706644517421],"luv":[83.3598915829196585,-33.0249710093605202,6.49917274942921],"rgb":[0.6,0.866666666666666696,0.8],"xyz":[0.498898185223471513,0.628433545121538706,0.666299466880945435],"hpluv":[168.866706644517421,86.2854242091523,83.3598915829196585],"hsluv":[168.866706644517421,48.6618587245334879,83.3598915829196585]},"#99dddd":{"lch":[83.811463234187741,33.6120761253887,192.17705063006062],"luv":[83.811463234187741,-32.85581988586,-7.08990557672323529],"rgb":[0.6,0.866666666666666696,0.866666666666666696],"xyz":[0.520416510774105112,0.637040875341792212,0.779629314780951432],"hpluv":[192.17705063006062,88.9162454401141,83.811463234187741],"hsluv":[192.17705063006062,50.6906605199231777,83.811463234187741]},"#99ddee":{"lch":[84.3064561843391402,38.9043785470910208,212.822778279485817],"luv":[84.3064561843391402,-32.6933403312743565,-21.0878203738277712],"rgb":[0.6,0.866666666666666696,0.933333333333333348],"xyz":[0.544228691040279822,0.646565747448262229,0.905040130849474656],"hpluv":[212.822778279485817,106.615167592423816,84.3064561843391402],"hsluv":[212.822778279485817,60.6575363344623781,84.3064561843391402]},"#99ddff":{"lch":[84.8449079615810575,48.055447414973429,227.378328123916845],"luv":[84.8449079615810575,-32.5409551013358396,-35.3611689193969099],"rgb":[0.6,0.866666666666666696,1],"xyz":[0.570399739450111243,0.657034166812195,1.04287431914125639],"hpluv":[227.378328123916845,137.001856984753886,84.8449079615810575],"hsluv":[227.378328123916845,99.999999999994813,84.8449079615810575]},"#445500":{"lch":[33.4053570608210535,38.7644311760376397,101.469350612776353],"luv":[33.4053570608210535,-7.7080633936099785,37.9903525006263791],"rgb":[0.266666666666666663,0.333333333333333315,0],"xyz":[0.0563220008404254485,0.0772588357738427239,0.0119452840524730177],"hpluv":[101.469350612776353,147.25044771073371,33.4053570608210535],"hsluv":[101.469350612776353,100.000000000002245,33.4053570608210535]},"#445511":{"lch":[33.4914653280992525,35.8039831739898275,102.524785035338],"luv":[33.4914653280992525,-7.76452054412734,34.9519303021045076],"rgb":[0.266666666666666663,0.333333333333333315,0.0666666666666666657],"xyz":[0.0573336663400625668,0.0776635019736975768,0.0172733890172286492],"hpluv":[102.524785035338,135.655223597469387,33.4914653280992525],"hsluv":[102.524785035338,91.5452633494882093,33.4914653280992525]},"#445522":{"lch":[33.6502992474903806,30.5965852313305291,104.897478349629381],"luv":[33.6502992474903806,-7.86608410210478493,29.5681543001366229],"rgb":[0.266666666666666663,0.333333333333333315,0.133333333333333331],"xyz":[0.0592090244785395889,0.0784136452290883912,0.0271502752132078452],"hpluv":[104.897478349629381,115.378092601865731,33.6502992474903806],"hsluv":[104.897478349629381,76.6558497494370243,33.6502992474903806]},"#445533":{"lch":[33.9096245159150911,22.79863905315759,110.61032755328398],"luv":[33.9096245159150911,-8.02535730567797501,21.3394372651287],"rgb":[0.266666666666666663,0.333333333333333315,0.2],"xyz":[0.0622967752109973294,0.0796487455220715,0.0434124290708189919],"hpluv":[110.61032755328398,85.3149751467856419,33.9096245159150911],"hsluv":[110.61032755328398,54.1403397653178331,33.9096245159150911]},"#445544":{"lch":[34.2793424585633204,13.4702363502677187,127.715012949235046],"luv":[34.2793424585633204,-8.24020614134090401,10.6558092175245633],"rgb":[0.266666666666666663,0.333333333333333315,0.266666666666666663],"xyz":[0.0667547704552162,0.081431943619759084,0.0668912040237056305],"hpluv":[127.715012949235046,49.8634197051089814,34.2793424585633204],"hsluv":[127.715012949235046,25.3893680776039865,34.2793424585633204]},"#445555":{"lch":[34.7654846399243738,8.70030094248716424,192.177050630060222],"luv":[34.7654846399243738,-8.50454817645784544,-1.83518304377262664],"rgb":[0.266666666666666663,0.333333333333333315,0.333333333333333315],"xyz":[0.0727171844945782,0.0838169092355039169,0.098293251297679532],"hpluv":[192.177050630060222,31.7559649298661668,34.7654846399243738],"hsluv":[192.177050630060222,31.6316627668381969,34.7654846399243738]},"#445566":{"lch":[35.3707740335649916,17.7582093223154978,240.254504050727519],"luv":[35.3707740335649916,-8.81070452432763318,-15.4183489427423961],"rgb":[0.266666666666666663,0.333333333333333315,0.4],"xyz":[0.0803021802680863733,0.0868509075449072354,0.138240895704823508],"hpluv":[240.254504050727519,63.7079944588343352,35.3707740335649916],"hsluv":[240.254504050727519,38.2083413049732812,35.3707740335649916]},"#445577":{"lch":[36.0950574442792913,30.8488081821149329,252.743594747999822],"luv":[36.0950574442792913,-9.15124765847803623,-29.4602042177260124],"rgb":[0.266666666666666663,0.333333333333333315,0.466666666666666674],"xyz":[0.0896161932882882928,0.0905765127529880448,0.187294697611221417],"hpluv":[252.743594747999822,108.450105614435046,36.0950574442792913],"hsluv":[252.743594747999822,44.7362415879762878,36.0950574442792913]},"#445588":{"lch":[36.935739068143242,44.5159055243500319,257.651563208142],"luv":[36.935739068143242,-9.5200062368872409,-43.4860359874579245],"rgb":[0.266666666666666663,0.333333333333333315,0.533333333333333326],"xyz":[0.100756610390232121,0.0950326795937656427,0.245967561014793584],"hpluv":[257.651563208142,152.935302017774575,36.935739068143242],"hsluv":[257.651563208142,50.9359550606187952,36.935739068143242]},"#445599":{"lch":[37.8882410462664865,58.0440865604997711,260.167284745959819],"luv":[37.8882410462664865,-9.91231220062277885,-57.1914508600732674],"rgb":[0.266666666666666663,0.333333333333333315,0.6],"xyz":[0.113813574499304834,0.1002554652373948,0.314734238655911491],"hpluv":[260.167284745959819,194.398479571090235,37.8882410462664865],"hsluv":[260.167284745959819,56.6374271499956805,37.8882410462664865]},"#4455aa":{"lch":[38.9464770503006932,71.1678309986128141,261.658277796723496],"luv":[38.9464770503006932,-10.3247958657557941,-70.4149043837850144],"rgb":[0.266666666666666663,0.333333333333333315,0.66666666666666663],"xyz":[0.128871267464557376,0.106278542423495909,0.394038088272910092],"hpluv":[261.658277796723496,231.875507383352442,38.9464770503006932],"hsluv":[261.658277796723496,61.7617646139185652,38.9464770503006932]},"#4455bb":{"lch":[40.1033117689144,83.7900384834958,262.625350778636744],"luv":[40.1033117689144,-10.7550224317659584,-83.0969316013408417],"rgb":[0.266666666666666663,0.333333333333333315,0.733333333333333282],"xyz":[0.146008859571894023,0.113133579266430667,0.484296073371551838],"hpluv":[262.625350778636744,265.125486140416797,40.1033117689144],"hsluv":[262.625350778636744,66.2950009745661,40.1033117689144]},"#4455cc":{"lch":[41.3509797710146,95.8983760986006075,263.292411358069444],"luv":[41.3509797710146,-11.2011488171863753,-95.24196975873555],"rgb":[0.266666666666666663,0.333333333333333315,0.8],"xyz":[0.165301235015615777,0.120850529443919469,0.585902584041821939],"hpluv":[263.292411358069444,294.28272942652967,41.3509797710146],"hsluv":[263.292411358069444,71.9850161095278906,41.3509797710146]},"#4455dd":{"lch":[42.6814446156526657,107.523441304607104,263.773623462042394],"luv":[42.6814446156526657,-11.661670844638417,-106.88917561239117],"rgb":[0.266666666666666663,0.333333333333333315,0.866666666666666696],"xyz":[0.186819560566249321,0.129457859664173,0.699232431941827937],"hpluv":[263.773623462042394,319.67109728436958,42.6814446156526657],"hsluv":[263.773623462042394,81.2732363837730247,42.6814446156526657]},"#4455ee":{"lch":[44.0866885883675,118.714724855013472,264.132858108854521],"luv":[44.0866885883675,-12.1352655753704255,-118.092850024109339],"rgb":[0.266666666666666663,0.333333333333333315,0.933333333333333348],"xyz":[0.21063174083242403,0.13898273177064302,0.82464324801035116],"hpluv":[264.132858108854521,341.693279595385377,44.0866885883675],"hsluv":[264.132858108854521,90.5684283810677186,44.0866885883675]},"#4455ff":{"lch":[45.5589321196955765,129.526958246416882,264.408404412275218],"luv":[45.5589321196955765,-12.6207071057408875,-128.910630534181024],"rgb":[0.266666666666666663,0.333333333333333315,1],"xyz":[0.236802789242255451,0.149451151134575744,0.962477436302133],"hpluv":[264.408404412275218,360.766296003954039,45.5589321196955765],"hsluv":[264.408404412275218,99.9999999999992752,45.5589321196955765]},"#bbdd00":{"lch":[83.0607051195576673,95.2176030862527796,99.223939245402],"luv":[83.0607051195576673,-15.2627740644400269,93.9863802119702427],"rgb":[0.733333333333333282,0.866666666666666696,0],"xyz":[0.463483785628456102,0.622773719281865423,0.0957905185125420555],"hpluv":[99.223939245402,239.164338292747971,83.0607051195576673],"hsluv":[99.223939245402,100.00000000000216,83.0607051195576673]},"#bbdd11":{"lch":[83.082156377860457,94.2793845093074765,99.3314951275217481],"luv":[83.082156377860457,-15.2870500651298524,93.0317604034238457],"rgb":[0.733333333333333282,0.866666666666666696,0.0666666666666666657],"xyz":[0.464495451128093206,0.623178385481720332,0.101118623477297692],"hpluv":[99.3314951275217481,237.15213625798873,83.082156377860457],"hsluv":[99.3314951275217481,98.93507934353417,83.082156377860457]},"#bbdd22":{"lch":[83.1218967422411765,92.5513012339483794,99.5354402549794486],"luv":[83.1218967422411765,-15.3318301742674485,91.2725497814347],"rgb":[0.733333333333333282,0.866666666666666696,0.133333333333333331],"xyz":[0.466370809266570263,0.623928528737111132,0.110995509673276885],"hpluv":[99.5354402549794486,233.433860498438293,83.1218967422411765],"hsluv":[99.5354402549794486,96.9737920722735538,83.1218967422411765]},"#bbdd33":{"lch":[83.1872593514570298,89.7372330308786,99.8847694763800718],"luv":[83.1872593514570298,-15.4049421957575614,88.4050832700449263],"rgb":[0.733333333333333282,0.866666666666666696,0.2],"xyz":[0.469458559999027969,0.625163629030094259,0.127257663530888021],"hpluv":[99.8847694763800718,227.34486653748678,83.1872593514570298],"hsluv":[99.8847694763800718,93.7802848880547373,83.1872593514570298]},"#bbdd44":{"lch":[83.2814760883348697,85.7419087717973,100.421139587323779],"luv":[83.2814760883348697,-15.5091702542505097,84.3275788686944452],"rgb":[0.733333333333333282,0.866666666666666696,0.266666666666666663],"xyz":[0.473916555243246884,0.626946827127781825,0.15073643848377466],"hpluv":[100.421139587323779,218.62539011377612,83.2814760883348697],"hsluv":[100.421139587323779,89.2463889616074511,83.2814760883348697]},"#bbdd55":{"lch":[83.4072088624658,80.5207963453540572,101.204557559233223],"luv":[83.4072088624658,-15.6461875861262687,78.9860459708531835],"rgb":[0.733333333333333282,0.866666666666666696,0.333333333333333315],"xyz":[0.479878969282608869,0.629331792743526575,0.182138485757748575],"hpluv":[101.204557559233223,207.093501481883948,83.4072088624658],"hsluv":[101.204557559233223,83.3201121340644448,83.4072088624658]},"#bbdd66":{"lch":[83.5666996797624364,74.0772937371066149,102.328486133362119],"luv":[83.5666996797624364,-15.816696660053216,72.3690372616455164],"rgb":[0.733333333333333282,0.866666666666666696,0.4],"xyz":[0.487463965056117055,0.632365791052929893,0.222086130164892537],"hpluv":[102.328486133362119,192.635686460640301,83.5666996797624364],"hsluv":[102.328486133362119,75.9999631534792854,83.5666996797624364]},"#bbdd77":{"lch":[83.7618505003220122,66.4632811318093388,103.948126608074304],"luv":[83.7618505003220122,-16.0205304866066705,64.5035684418593149],"rgb":[0.733333333333333282,0.866666666666666696,0.466666666666666674],"xyz":[0.49677797807631896,0.636091396261010744,0.271139932071290446],"hpluv":[103.948126608074304,175.207590447676779,83.7618505003220122],"hsluv":[103.948126608074304,67.3303268013154,83.7618505003220122]},"#bbdd88":{"lch":[83.9942706402616,57.7845188457632091,106.339844930601203],"luv":[83.9942706402616,-16.2567564016803381,55.4505950331715454],"rgb":[0.733333333333333282,0.866666666666666696,0.533333333333333326],"xyz":[0.50791839517826276,0.640547563101788286,0.329812795474862641],"hpluv":[106.339844930601203,154.850612540446264,83.9942706402616],"hsluv":[106.339844930601203,57.39610210967858,83.9942706402616]},"#bbdd99":{"lch":[84.2653073070245711,48.2191913160874819,110.040291826115165],"luv":[84.2653073070245711,-16.5237946272095257,45.2996095159246153],"rgb":[0.733333333333333282,0.866666666666666696,0.6],"xyz":[0.520975359287335515,0.6457703487454175,0.39857947311598052],"hpluv":[110.040291826115165,131.749772406416298,84.2653073070245711],"hsluv":[110.040291826115165,46.3161497548768466,84.2653073070245711]},"#bbddaa":{"lch":[84.5760668100806328,38.0784660246866622,116.212889721452115],"luv":[84.5760668100806328,-16.8195514991441222,34.1624393473425059],"rgb":[0.733333333333333282,0.866666666666666696,0.66666666666666663],"xyz":[0.536033052252588,0.651793425931518566,0.477883322732979121],"hpluv":[116.212889721452115,106.421399158629868,84.5760668100806328],"hsluv":[116.212889721452115,34.2356923349747433,84.5760668100806328]},"#bbddbb":{"lch":[84.9274305013996553,28.0212505683590543,127.715012949233824],"luv":[84.9274305013996553,-17.1415612181778,22.1665821095230058],"rgb":[0.733333333333333282,0.866666666666666696,0.733333333333333282],"xyz":[0.55317064435992469,0.658648462774453325,0.568141307831620868],"hpluv":[127.715012949233824,80.3800713533813109,84.9274305013996553],"hsluv":[127.715012949233824,21.3181094477761164,84.9274305013996553]},"#bbddcc":{"lch":[85.3200677868051,19.876471170849122,151.617083508593169],"luv":[85.3200677868051,-17.4871274790593141,9.44851727715650291],"rgb":[0.733333333333333282,0.866666666666666696,0.8],"xyz":[0.572463019803646445,0.666365412951942182,0.669747818501891],"hpluv":[151.617083508593169,58.7374284962306703,85.3200677868051],"hsluv":[151.617083508593169,24.0698773292010699,85.3200677868051]},"#bbdddd":{"lch":[85.7544476215988,18.2643967282432129,192.177050630059739],"luv":[85.7544476215988,-17.8534562098583329,-3.85256916996079246],"rgb":[0.733333333333333282,0.866666666666666696,0.866666666666666696],"xyz":[0.593981345354279933,0.674972743172195688,0.783077666401897],"hpluv":[192.177050630059739,55.8245506661868234,85.7544476215988],"hsluv":[192.177050630059739,26.9205986284609722,85.7544476215988]},"#bbddee":{"lch":[86.2308493598319359,25.3453434934362818,223.980933900351914],"luv":[86.2308493598319359,-18.2377721186398958,-17.6002870700688909],"rgb":[0.733333333333333282,0.866666666666666696,0.933333333333333348],"xyz":[0.617793525620454753,0.684497615278665705,0.908488482470420244],"hpluv":[223.980933900351914,80.4705047412629142,86.2308493598319359],"hsluv":[223.980933900351914,55.5800524236117397,86.2308493598319359]},"#bbddff":{"lch":[86.7493734858622076,36.743147173338194,239.520163688183],"luv":[86.7493734858622076,-18.6374141011141354,-31.6655279416778761],"rgb":[0.733333333333333282,0.866666666666666696,1],"xyz":[0.643964574030286063,0.694966034642598429,1.0463226707622022],"hpluv":[239.520163688183,121.752323062157373,86.7493734858622076],"hsluv":[239.520163688183,99.9999999999938325,86.7493734858622076]},"#99ee00":{"lch":[85.9664003491010646,109.204546268980621,112.979852313128234],"luv":[85.9664003491010646,-42.6342645949387915,100.538313136150634],"rgb":[0.6,0.933333333333333348,0],"xyz":[0.437097727388796042,0.679199404132492912,0.108068425671767623],"hpluv":[112.979852313128234,339.428934639809256,85.9664003491010646],"hsluv":[112.979852313128234,100.000000000002444,85.9664003491010646]},"#99ee11":{"lch":[85.9866468155118326,108.350123359521945,113.156064955940181],"luv":[85.9866468155118326,-42.6072764400583495,99.6211284135251702],"rgb":[0.6,0.933333333333333348,0.0666666666666666657],"xyz":[0.438109392888433147,0.67960407033234782,0.11339653063652326],"hpluv":[113.156064955940181,337.317445797395,85.9866468155118326],"hsluv":[113.156064955940181,99.0182391276988,85.9866468155118326]},"#99ee22":{"lch":[86.0241571186350455,106.77763062148405,113.488368653358094],"luv":[86.0241571186350455,-42.5576013317541353,97.9301433166804287],"rgb":[0.6,0.933333333333333348,0.133333333333333331],"xyz":[0.439984751026910204,0.680354213587738621,0.123273416832502453],"hpluv":[113.488368653358094,333.419677856626379,86.0241571186350455],"hsluv":[113.488368653358094,97.2091916908085238,86.0241571186350455]},"#99ee33":{"lch":[86.0858572784747906,104.220652596579697,114.05202992935186],"luv":[86.0858572784747906,-42.476800751453851,95.1717701084636],"rgb":[0.6,0.933333333333333348,0.2],"xyz":[0.443072501759367909,0.681589313880721748,0.139535570690113603],"hpluv":[114.05202992935186,327.048640581280779,86.0858572784747906],"hsluv":[114.05202992935186,94.2610252844147709,86.0858572784747906]},"#99ee44":{"lch":[86.1748066309051239,100.599171066032113,114.904029942881266],"luv":[86.1748066309051239,-42.3622716989010186,91.2448966007484756],"rgb":[0.6,0.933333333333333348,0.266666666666666663],"xyz":[0.447530497003586825,0.683372511978409314,0.163014345643000241],"hpluv":[114.904029942881266,317.953677409096201,86.1748066309051239],"hsluv":[114.904029942881266,90.0700159696272777,86.1748066309051239]},"#99ee55":{"lch":[86.2935317577421586,95.884762204841536,116.119599614249481],"luv":[86.2935317577421586,-42.2129155656731854,86.0927254913233355],"rgb":[0.6,0.933333333333333348,0.333333333333333315],"xyz":[0.45349291104294881,0.685757477594154063,0.194416392916974157],"hpluv":[116.119599614249481,305.984138616458665,86.2935317577421586],"hsluv":[116.119599614249481,84.5822993375075924,86.2935317577421586]},"#99ee66":{"lch":[86.4441689863048879,90.1009507230509143,117.805124209421223],"luv":[86.4441689863048879,-42.0290075887870955,79.6978283411745565],"rgb":[0.6,0.933333333333333348,0.4],"xyz":[0.461077906816457,0.688791475903557382,0.234364037324118091],"hpluv":[117.805124209421223,291.090686380889622,86.4441689863048879],"hsluv":[117.805124209421223,77.7887546135139587,86.4441689863048879]},"#99ee77":{"lch":[86.6285404402691199,83.3280712532883712,120.117619079442107],"luv":[86.6285404402691199,-41.8120893585486826,72.0785449510868261],"rgb":[0.6,0.933333333333333348,0.466666666666666674],"xyz":[0.470391919836658901,0.692517081111638233,0.283417839230516],"hpluv":[120.117619079442107,273.344218704658658,86.6285404402691199],"hsluv":[120.117619079442107,69.7211272565473,86.6285404402691199]},"#99ee88":{"lch":[86.8481992617441563,75.7142340291470646,123.296374810060541],"luv":[86.8481992617441563,-41.5648380664255939,63.2851441582641],"rgb":[0.6,0.933333333333333348,0.533333333333333326],"xyz":[0.481532336938602701,0.696973247952415775,0.342090702634088195],"hpluv":[123.296374810060541,252.981665625798911,86.8481992617441563],"hsluv":[123.296374810060541,60.4476982156994964,86.8481992617441563]},"#99ee99":{"lch":[87.1044587056640864,67.4980907628946483,127.715012949238613],"luv":[87.1044587056640864,-41.2908999939099388,53.3952604107227131],"rgb":[0.6,0.933333333333333348,0.6],"xyz":[0.4945893010476754,0.702196033596045,0.410857380275206074],"hpluv":[127.715012949238613,230.504268403717248,87.1044587056640864],"hsluv":[127.715012949238613,50.0680020008431583,87.1044587056640864]},"#99eeaa":{"lch":[87.3984122167822477,59.0554460818204134,133.961345837807],"luv":[87.3984122167822477,-40.9946911699179566,42.5085992218733182],"rgb":[0.6,0.933333333333333348,0.66666666666666663],"xyz":[0.509646994012928,0.708219110782146,0.490161229892204675],"hpluv":[133.961345837807,206.883546406693341,87.3984122167822477],"hsluv":[133.961345837807,51.4281429353489514,87.3984122167822477]},"#99eebb":{"lch":[87.7309483141988409,50.9899623050450046,142.923108379062683],"luv":[87.7309483141988409,-40.6811762109167603,30.7411476358032338],"rgb":[0.6,0.933333333333333348,0.733333333333333282],"xyz":[0.526784586120264575,0.715074147625080814,0.580419214990846477],"hpluv":[142.923108379062683,183.977628608542716,87.7309483141988409],"hsluv":[142.923108379062683,52.8887094272277523,87.7309483141988409]},"#99eecc":{"lch":[88.1027624984453581,44.2777406304916781,155.702396707036257],"luv":[88.1027624984453581,-40.3556400464907483,18.219237958245273],"rgb":[0.6,0.933333333333333348,0.8],"xyz":[0.546076961563986329,0.722791097802569671,0.682025725661116633],"hpluv":[155.702396707036257,165.259943503195302,88.1027624984453581],"hsluv":[155.702396707036257,54.4312604691531305,88.1027624984453581]},"#99eedd":{"lch":[88.514367527899708,40.3437945821223494,172.775068456479858],"luv":[88.514367527899708,-40.023467685182176,5.07383442158517628],"rgb":[0.6,0.933333333333333348,0.866666666666666696],"xyz":[0.567595287114619929,0.731398428022823177,0.795355573561122631],"hpluv":[172.775068456479858,156.503534311163719,88.514367527899708],"hsluv":[172.775068456479858,56.0368199873083199,88.514367527899708]},"#99eeee":{"lch":[88.9661029048661476,40.6035054290346196,192.177050630060762],"luv":[88.9661029048661476,-39.6899452486728,-8.56463071492281891],"rgb":[0.6,0.933333333333333348,0.933333333333333348],"xyz":[0.591407467380794638,0.740923300129293194,0.920766389629645854],"hpluv":[192.177050630060762,164.568757380081195,88.9661029048661476],"hsluv":[192.177050630060762,57.6866071933722324,88.9661029048661476]},"#99eeff":{"lch":[89.4581440962481338,45.3723498615675496,209.831659516829347],"luv":[89.4581440962481338,-39.3600920674606272,-22.5706287994267498],"rgb":[0.6,0.933333333333333348,1],"xyz":[0.617578515790626059,0.751391719493225918,1.05860057792142759],"hpluv":[209.831659516829347,193.255751503994162,89.4581440962481338],"hsluv":[209.831659516829347,99.9999999999917293,89.4581440962481338]},"#446600":{"lch":[39.1245088935371612,48.4489514943966242,110.29724752770484],"luv":[39.1245088935371612,-16.806485623906017,45.4405429311736668],"rgb":[0.266666666666666663,0.4,0],"xyz":[0.0713500585462719106,0.107314951185536064,0.0169546366210883669],"hpluv":[110.29724752770484,157.13568029472475,39.1245088935371612],"hsluv":[110.29724752770484,100.000000000002302,39.1245088935371612]},"#446611":{"lch":[39.1937103273453289,46.0071342898824156,111.370502443062165],"luv":[39.1937103273453289,-16.7648801632844737,42.843846683952],"rgb":[0.266666666666666663,0.4,0.0666666666666666657],"xyz":[0.0723617240459090288,0.107719617385390917,0.022282741585844],"hpluv":[111.370502443062165,148.9526145018813,39.1937103273453289],"hsluv":[111.370502443062165,93.861989786091,39.1937103273453289]},"#446622":{"lch":[39.3215343087732165,41.6757739733598,113.610346420587263],"luv":[39.3215343087732165,-16.6917518579939177,38.1871124358693947],"rgb":[0.266666666666666663,0.4,0.133333333333333331],"xyz":[0.0742370821843860579,0.108469760640781732,0.0321596277818231926],"hpluv":[113.610346420587263,134.490790122462073,39.3215343087732165],"hsluv":[113.610346420587263,82.9003633409612,39.3215343087732165]},"#446633":{"lch":[39.530716823468623,35.0960892868442684,118.194686061271412],"luv":[39.530716823468623,-16.5818151114938139,30.931842668007679],"rgb":[0.266666666666666663,0.4,0.2],"xyz":[0.0773248329168437915,0.109704860933764844,0.0484217816394343359],"hpluv":[118.194686061271412,112.658344014206364,39.530716823468623],"hsluv":[118.194686061271412,65.945418212904,39.530716823468623]},"#446644":{"lch":[39.8299759493166761,26.8801274380109838,127.715012949238059],"luv":[39.8299759493166761,-16.4434970133495142,21.2638815143349724],"rgb":[0.266666666666666663,0.4,0.266666666666666663],"xyz":[0.0817828281610626651,0.111488059031452424,0.0719005565923209744],"hpluv":[127.715012949238059,85.6368345314009,39.8299759493166761],"hsluv":[127.715012949238059,43.6044123282566858,39.8299759493166761]},"#446655":{"lch":[40.2252775564066809,18.9132283301115756,149.466153210293243],"luv":[40.2252775564066809,-16.2905155992652197,9.6088140463343148],"rgb":[0.266666666666666663,0.4,0.333333333333333315],"xyz":[0.087745242200424664,0.113873024647197257,0.10330260386629489],"hpluv":[149.466153210293243,59.6631175613842473,40.2252775564066809],"hsluv":[149.466153210293243,47.2452022491104273,40.2252775564066809]},"#446666":{"lch":[40.7202569602655728,16.510473073285187,192.177050630060847],"luv":[40.7202569602655728,-16.1389950297194247,-3.48260829470770128],"rgb":[0.266666666666666663,0.4,0.4],"xyz":[0.0953302379739328354,0.116907022956600576,0.143250248273438852],"hpluv":[192.177050630060847,51.4503500463259655,40.7202569602655728],"hsluv":[192.177050630060847,51.2489582821824214,40.7202569602655728]},"#446677":{"lch":[41.3164898648363632,23.6752994583974647,227.46784435344162],"luv":[41.3164898648363632,-16.0045942322577233,-17.4462823519963166],"rgb":[0.266666666666666663,0.4,0.466666666666666674],"xyz":[0.104644250994134755,0.120632628164681385,0.192304050179836761],"hpluv":[227.46784435344162,72.7128872034151783,41.3164898648363632],"hsluv":[227.46784435344162,55.4049423234493261,41.3164898648363632]},"#446688":{"lch":[42.0137303768536654,35.5424939627414,243.425378218088099],"luv":[42.0137303768536654,-15.9003964812462133,-31.7875175002811758],"rgb":[0.266666666666666663,0.4,0.533333333333333326],"xyz":[0.115784668096078583,0.125088795005458969,0.2509769135834089],"hpluv":[243.425378218088099,107.348500116853913,42.0137303768536654],"hsluv":[243.425378218088099,59.5313600522085409,42.0137303768536654]},"#446699":{"lch":[42.8101553746289696,48.7666560663799089,251.050944767945737],"luv":[42.8101553746289696,-15.8358652521886238,-46.1238779333558782],"rgb":[0.266666666666666663,0.4,0.6],"xyz":[0.128841632205151296,0.130311580649088155,0.319743591224526835],"hpluv":[251.050944767945737,144.549135771893674,42.8101553746289696],"hsluv":[251.050944767945737,63.4907652576423231,42.8101553746289696]},"#4466aa":{"lch":[43.7026231888915078,62.2363741998113298,255.27738032783347],"luv":[43.7026231888915078,-15.8167390859625119,-60.1929982491778404],"rgb":[0.266666666666666663,0.4,0.66666666666666663],"xyz":[0.143899325170403825,0.136334657835189249,0.399047440841525436],"hpluv":[255.27738032783347,180.707469421570693,43.7026231888915078],"hsluv":[255.27738032783347,67.1924648453768896,43.7026231888915078]},"#4466bb":{"lch":[44.6869405362706402,75.5191451090451409,257.888120209084718],"luv":[44.6869405362706402,-15.8455247037125186,-73.83807029483539],"rgb":[0.266666666666666663,0.4,0.733333333333333282],"xyz":[0.161036917277740499,0.143189694678124,0.489305425940167182],"hpluv":[257.888120209084718,214.444923406304468,44.6869405362706402],"hsluv":[257.888120209084718,70.5866413561882098,44.6869405362706402]},"#4466cc":{"lch":[45.7581261645645299,88.428992560325014,259.626929599743789],"luv":[45.7581261645645299,-15.9222446749778896,-86.983727499712],"rgb":[0.266666666666666663,0.4,0.8],"xyz":[0.180329292721462225,0.150906644855612809,0.590911936610437283],"hpluv":[259.626929599743789,245.225581131482073,45.7581261645645299],"hsluv":[259.626929599743789,73.6549291646736179,45.7581261645645299]},"#4466dd":{"lch":[46.9106590907269165,100.895184366494064,260.849495088158733],"luv":[46.9106590907269165,-16.0451985527389489,-99.6111933055317422],"rgb":[0.266666666666666663,0.4,0.866666666666666696],"xyz":[0.201847618272095769,0.159513975075866343,0.704241784510443281],"hpluv":[260.849495088158733,272.92180192815988,46.9106590907269165],"hsluv":[260.849495088158733,78.541907894368677,46.9106590907269165]},"#4466ee":{"lch":[48.1387014995781897,112.90717489320852,261.744736192665698],"luv":[48.1387014995781897,-16.2116120228509466,-111.737253313235385],"rgb":[0.266666666666666663,0.4,0.933333333333333348],"xyz":[0.225659798538270506,0.16903884718233636,0.829652600578966504],"hpluv":[261.744736192665698,297.623004098842955,48.1387014995781897],"hsluv":[261.744736192665698,89.2025828989012126,48.1387014995781897]},"#4466ff":{"lch":[49.4362898036433194,124.485902067172418,262.421323096893047],"luv":[49.4362898036433194,-16.4181334215125325,-123.398479360286501],"rgb":[0.266666666666666663,0.4,1],"xyz":[0.251830846948101872,0.179507266546269084,0.967486788870748349],"hpluv":[262.421323096893047,319.531462910383539,49.4362898036433194],"hsluv":[262.421323096893047,99.9999999999992,49.4362898036433194]},"#bbee00":{"lch":[87.830324097455545,103.474670767003104,103.901308289378321],"luv":[87.830324097455545,-24.8598111448325625,100.444000717728017],"rgb":[0.733333333333333282,0.933333333333333348,0],"xyz":[0.510662561968970863,0.717131271962896388,0.111516777292713254],"hpluv":[103.901308289378321,376.707439149390723,87.830324097455545],"hsluv":[103.901308289378321,100.000000000002331,87.830324097455545]},"#bbee11":{"lch":[87.8498503793181413,102.621932764236291,104.023160127863235],"luv":[87.8498503793181413,-24.8667401733108697,99.5635792718425705],"rgb":[0.733333333333333282,0.933333333333333348,0.0666666666666666657],"xyz":[0.511674227468608,0.717535938162751297,0.116844882257468891],"hpluv":[104.023160127863235,374.263941750279344,87.8498503793181413],"hsluv":[104.023160127863235,99.0733759990956315,87.8498503793181413]},"#bbee22":{"lch":[87.8860274909110757,101.050540606732312,104.253301125000391],"luv":[87.8860274909110757,-24.8795662288424886,97.9398741125263],"rgb":[0.733333333333333282,0.933333333333333348,0.133333333333333331],"xyz":[0.513549585607085,0.718286081418142097,0.126721768453448069],"hpluv":[104.253301125000391,369.744422226518111,87.8860274909110757],"hsluv":[104.253301125000391,97.3653524759520224,87.8860274909110757]},"#bbee33":{"lch":[87.9455377581158899,98.4895893313188111,104.644745385959411],"luv":[87.9455377581158899,-24.9006321902472507,95.2898615970127878],"rgb":[0.733333333333333282,0.933333333333333348,0.2],"xyz":[0.516637336339542785,0.719521181711125224,0.142983922311059219],"hpluv":[104.644745385959411,362.331462484484575,87.9455377581158899],"hsluv":[104.644745385959411,94.5802259429375454,87.9455377581158899]},"#bbee44":{"lch":[88.03133674845418,94.8494424101932339,105.239087045756335],"luv":[88.03133674845418,-24.9309340294718567,91.5142898892991781],"rgb":[0.733333333333333282,0.933333333333333348,0.266666666666666663],"xyz":[0.521095331583761645,0.72130437980881279,0.166462697263945858],"hpluv":[105.239087045756335,351.690778632920285,88.03133674845418],"hsluv":[105.239087045756335,90.61757843521751,88.03133674845418]},"#bbee55":{"lch":[88.145869167101,90.085489786575252,106.092871571181419],"luv":[88.145869167101,-24.9712578135623886,86.5553681367929499],"rgb":[0.733333333333333282,0.933333333333333348,0.333333333333333315],"xyz":[0.527057745623123575,0.72368934542455754,0.197864744537919773],"hpluv":[106.092871571181419,337.573290416608245,88.145869167101],"hsluv":[106.092871571181419,85.422816781051381,88.145869167101]},"#bbee66":{"lch":[88.2912067804751786,84.1961694748550116,107.288882190620882],"luv":[88.2912067804751786,-25.0222263001917433,80.3920589686599527],"rgb":[0.733333333333333282,0.933333333333333348,0.4],"xyz":[0.534642741396631815,0.726723343733960858,0.237812388945063735],"hpluv":[107.288882190620882,319.804166688067426,88.2912067804751786],"hsluv":[107.288882190620882,78.9823949944632631,88.2912067804751786]},"#bbee77":{"lch":[88.4691221578712828,77.2243366572971439,108.954917992899311],"luv":[88.4691221578712828,-25.0843250262429365,73.0368044901840534],"rgb":[0.733333333333333282,0.933333333333333348,0.466666666666666674],"xyz":[0.543956754416833665,0.730448948942041709,0.286866190851461644],"hpluv":[108.954917992899311,298.285685525501094,88.4691221578712828],"hsluv":[108.954917992899311,71.3203705839542,88.4691221578712828]},"#bbee88":{"lch":[88.6811325759484106,69.2626802552854599,111.298371855766348],"luv":[88.6811325759484106,-25.1579200624522237,64.5321465184381822],"rgb":[0.733333333333333282,0.933333333333333348,0.533333333333333326],"xyz":[0.555097171518777577,0.734905115782819252,0.34553905425503384],"hpluv":[111.298371855766348,273.019747479454225,88.6811325759484106],"hsluv":[111.298371855766348,62.4946759175697224,88.6811325759484106]},"#bbee99":{"lch":[88.9285282571087095,60.4678989000773228,114.674688063820184],"luv":[88.9285282571087095,-25.2432722518949362,54.9467378777547069],"rgb":[0.733333333333333282,0.933333333333333348,0.6],"xyz":[0.568154135627850221,0.740127901426448465,0.414305731896151719],"hpluv":[114.674688063820184,244.173567048365754,88.9285282571087095],"hsluv":[114.674688063820184,52.5925914284503548,88.9285282571087095]},"#bbeeaa":{"lch":[89.2123917942545148,51.0969811847688931,119.731125412935242],"luv":[89.2123917942545148,-25.3405499711494109,44.3706886734509212],"rgb":[0.733333333333333282,0.933333333333333348,0.66666666666666663],"xyz":[0.583211828593102832,0.746150978612549531,0.493609581513150319],"hpluv":[119.731125412935242,212.254877789093854,89.2123917942545148],"hsluv":[119.731125412935242,41.7253920748903084,89.2123917942545148]},"#bbeebb":{"lch":[89.5336124490095,41.6027669810227181,127.715012949236097],"luv":[89.5336124490095,-25.4498411950279184,32.9104208971130276],"rgb":[0.733333333333333282,0.933333333333333348,0.733333333333333282],"xyz":[0.600349420700439396,0.75300601545548429,0.583867566611792066],"hpluv":[127.715012949236097,178.587287563939924,89.5336124490095],"hsluv":[127.715012949236097,37.7465419844818,89.5336124490095]},"#bbeecc":{"lch":[89.8928974614309766,32.8889663829363883,141.03222670888556],"luv":[89.8928974614309766,-25.571165029146556,20.6833176446640721],"rgb":[0.733333333333333282,0.933333333333333348,0.8],"xyz":[0.61964179614416115,0.760722965632973147,0.685474077282062222],"hpluv":[141.03222670888556,146.627829178506289,89.8928974614309766],"hsluv":[141.03222670888556,37.1073685119788,89.8928974614309766]},"#bbeedd":{"lch":[90.290781675649967,26.8655052232995288,163.094148385079734],"luv":[90.290781675649967,-25.704482585445124,7.81248653872008436],"rgb":[0.733333333333333282,0.933333333333333348,0.866666666666666696],"xyz":[0.641160121694794749,0.769330295853226653,0.79880392518206822],"hpluv":[163.094148385079734,125.084011642469022,90.290781675649967],"hsluv":[163.094148385079734,36.2429238875219255,90.290781675649967]},"#bbeeee":{"lch":[90.7276363011350782,26.4447005646089579,192.177050630060336],"luv":[90.7276363011350782,-25.8497069757021904,-5.5780675168164624],"rgb":[0.733333333333333282,0.933333333333333348,0.933333333333333348],"xyz":[0.664972301960969459,0.77885516795969667,0.924214741250591443],"hpluv":[192.177050630060336,129.38009793870765,90.7276363011350782],"hsluv":[192.177050630060336,36.8413123479339077,90.7276363011350782]},"#bbeeff":{"lch":[91.2036773284388289,32.4261328799939648,216.675663960190036],"luv":[91.2036773284388289,-26.0067122100428421,-19.367627980086624],"rgb":[0.733333333333333282,0.933333333333333348,1],"xyz":[0.69114335037080088,0.789323587323629394,1.06204892954237318],"hpluv":[216.675663960190036,167.86892764061264,91.2036773284388289],"hsluv":[216.675663960190036,99.9999999999901235,91.2036773284388289]},"#99ff00":{"lch":[90.9122626200542214,118.290950299530564,115.261698016578393],"luv":[90.9122626200542214,-50.4810643573161286,106.978554225220847],"rgb":[0.6,1,0],"xyz":[0.48895009981846993,0.782904148991842,0.125352549814991721],"hpluv":[115.261698016578393,591.369219456757151,90.9122626200542214],"hsluv":[115.261698016578393,100.000000000002402,90.9122626200542214]},"#99ff11":{"lch":[90.9306796583728,117.513960007406183,115.422432906031332],"luv":[90.9306796583728,-50.4474247175277384,106.134764031356056],"rgb":[0.6,1,0.0666666666666666657],"xyz":[0.489961765318107034,0.783308815191696928,0.130680654779747357],"hpluv":[115.422432906031332,588.764777700997797,90.9306796583728],"hsluv":[115.422432906031332,99.9999999999905356,90.9306796583728]},"#99ff22":{"lch":[90.9648031673089577,116.082935310332914,115.724658723180369],"luv":[90.9648031673089577,-50.3854319755480944,104.577990585497247],"rgb":[0.6,1,0.133333333333333331],"xyz":[0.491837123456584091,0.784058958447087728,0.140557540975726536],"hpluv":[115.724658723180369,583.951350293788323,90.9648031673089577],"hsluv":[115.724658723180369,99.9999999999904219,90.9648031673089577]},"#99ff33":{"lch":[91.0209396556716399,113.753057852482627,116.234667099004312],"luv":[91.0209396556716399,-50.2843870930134642,102.035477092383132],"rgb":[0.6,1,0.2],"xyz":[0.494924874189041797,0.785294058740070855,0.156819694833337686],"hpluv":[116.234667099004312,576.067585056329449,91.0209396556716399],"hsluv":[116.234667099004312,99.9999999999905924,91.0209396556716399]},"#99ff44":{"lch":[91.1018839706868562,110.446777199697451,116.999375135233294],"luv":[91.1018839706868562,-50.1407143313292565,98.409345898362929],"rgb":[0.6,1,0.266666666666666663],"xyz":[0.499382869433260712,0.787077256837758421,0.180298469786224325],"hpluv":[116.999375135233294,564.777897061868,91.1018839706868562],"hsluv":[116.999375135233294,99.9999999999903793,91.1018839706868562]},"#99ff55":{"lch":[91.2099533036034558,106.130684884370282,118.07780645420398],"luv":[91.2099533036034558,-49.9525457622324112,93.6400846106921279],"rgb":[0.6,1,0.333333333333333315],"xyz":[0.505345283472622642,0.789462222453503171,0.21170051706019824],"hpluv":[118.07780645420398,549.854625367801646,91.2099533036034558],"hsluv":[118.07780645420398,99.9999999999901377,91.2099533036034558]},"#99ff66":{"lch":[91.3471179899501351,100.815112661229691,119.549522622156928],"luv":[91.3471179899501351,-49.7195590247369807,87.7020660605103899],"rgb":[0.6,1,0.4],"xyz":[0.512930279246130882,0.792496220762906489,0.251648161467342202],"hpluv":[119.549522622156928,531.176396965461777,91.3471179899501351],"hsluv":[119.549522622156928,99.9999999999902656,91.3471179899501351]},"#99ff77":{"lch":[91.5150716426202,94.5571579863012488,121.52621580287979],"luv":[91.5150716426202,-49.442863485124569,80.6006164792656534],"rgb":[0.6,1,0.466666666666666674],"xyz":[0.522244292266332732,0.79622182597098734,0.300701963373740111],"hpluv":[121.52621580287979,508.746904082031563,91.5150716426202],"hsluv":[121.52621580287979,99.9999999999900098,91.5150716426202]},"#99ff88":{"lch":[91.7152730008064481,87.4673964918121385,124.169042550433474],"luv":[91.7152730008064481,-49.1248751175299461,72.3691377159004077],"rgb":[0.6,1,0.533333333333333326],"xyz":[0.533384709368276644,0.800677992811764883,0.359374826777312251],"hpluv":[124.169042550433474,482.74240688111388,91.7152730008064481],"hsluv":[124.169042550433474,99.999999999989754,91.7152730008064481]},"#99ff99":{"lch":[91.9489728509177,79.7227767672504,127.715012949239039],"luv":[91.9489728509177,-48.7691602166467675,63.0657604984184559],"rgb":[0.6,1,0.6],"xyz":[0.546441673477349288,0.805900778455394096,0.428141504418430185],"hpluv":[127.715012949239039,453.611771943482722,91.9489728509177],"hsluv":[127.715012949239039,99.9999999999896119,91.9489728509177]},"#99ffaa":{"lch":[92.2172324754492365,71.5909188251234525,132.515331265000469],"luv":[92.2172324754492365,-48.380245540777544,52.769418223432119],"rgb":[0.6,1,0.66666666666666663],"xyz":[0.561499366442601899,0.811923855641495162,0.507445354035428786],"hpluv":[132.515331265000469,422.278899597361089,92.2172324754492365],"hsluv":[132.515331265000469,99.999999999989285,92.2172324754492365]},"#99ffbb":{"lch":[92.5209371039878334,63.4744472180726902,139.080731133451],"luv":[92.5209371039878334,-47.9634018094000325,41.5754439123617558],"rgb":[0.6,1,0.733333333333333282],"xyz":[0.578636958549938463,0.818778892484429921,0.597703339134070477],"hpluv":[139.080731133451,390.542311531215887,92.5209371039878334],"hsluv":[139.080731133451,99.9999999999889866,92.5209371039878334]},"#99ffcc":{"lch":[92.8608063839845,55.9838497302527216,148.091690615728766],"luv":[92.8608063839845,-47.524412431304512,29.5909049148346774],"rgb":[0.6,1,0.8],"xyz":[0.597929333993660217,0.826495842661918778,0.699309849804340633],"hpluv":[148.091690615728766,361.818313682118117,92.8608063839845],"hsluv":[148.091690615728766,99.999999999988475,92.8608063839845]},"#99ffdd":{"lch":[93.237403107538583,50.0214511206169306,160.217319691395858],"luv":[93.237403107538583,-47.0693412211659066,16.9299347080170577],"rgb":[0.6,1,0.866666666666666696],"xyz":[0.619447659544293816,0.835103172882172284,0.812639697704346631],"hpluv":[160.217319691395858,342.295010089686684,93.237403107538583],"hsluv":[160.217319691395858,99.999999999988,93.237403107538583]},"#99ffee":{"lch":[93.6511409780710267,46.7516947594382444,175.449324589633676],"luv":[93.6511409780710267,-46.6043124006013088,3.70931645277729727],"rgb":[0.6,1,0.933333333333333348],"xyz":[0.643259839810468526,0.844628044988642301,0.938050513772869854],"hpluv":[175.449324589633676,341.869484566500148,93.6511409780710267],"hsluv":[175.449324589633676,99.9999999999875,93.6511409780710267]},"#99ffff":{"lch":[94.102291921527609,47.1972299789563579,192.177050630060847],"luv":[94.102291921527609,-46.1353140316371437,-9.95546668362271703],"rgb":[0.6,1,1],"xyz":[0.6694308882203,0.855096464352575,1.07588470206465181],"hpluv":[192.177050630060847,372.830957625984183,94.102291921527609],"hsluv":[192.177050630060847,99.999999999986585,94.102291921527609]},"#447700":{"lch":[44.83248944102629,58.4741115144389809,115.479055163134589],"luv":[44.83248944102629,-25.1544589141716,52.7870714677211339],"rgb":[0.266666666666666663,0.466666666666666674,0],"xyz":[0.0898037965996895393,0.144222427292371835,0.0231058826388940708],"hpluv":[115.479055163134589,165.50461307776385,44.83248944102629],"hsluv":[115.479055163134589,100.00000000000216,44.83248944102629]},"#447711":{"lch":[44.8893318820142468,56.4264635629906337,116.3750363045054],"luv":[44.8893318820142468,-25.0671673404006405,50.5527735317644158],"rgb":[0.266666666666666663,0.466666666666666674,0.0666666666666666657],"xyz":[0.0908154620993266576,0.144627093492226688,0.0284339876036497],"hpluv":[116.3750363045054,159.506732057184706,44.8893318820142468],"hsluv":[116.3750363045054,95.4073228169634433,44.8893318820142468]},"#447722":{"lch":[44.9944227930058389,52.7636609180533824,118.171656995978211],"luv":[44.9944227930058389,-24.9105023189221484,46.5131248971114388],"rgb":[0.266666666666666663,0.466666666666666674,0.133333333333333331],"xyz":[0.0926908202378036866,0.145377236747617516,0.0383108737996289],"hpluv":[118.171656995978211,148.804327803607492,44.9944227930058389],"hsluv":[118.171656995978211,87.128369469673089,44.9944227930058389]},"#447733":{"lch":[45.1666686690004795,47.1090234718488,121.574089601592789],"luv":[45.1666686690004795,-24.6663168629185812,40.1351828809748881],"rgb":[0.266666666666666663,0.466666666666666674,0.2],"xyz":[0.0957785709702614202,0.146612337040600615,0.0545730276572400433],"hpluv":[121.574089601592789,132.350433634303585,45.1666686690004795],"hsluv":[121.574089601592789,74.1245535442141232,45.1666686690004795]},"#447744":{"lch":[45.4136534494367368,39.7908238780444137,127.715012949239082],"luv":[45.4136534494367368,-24.3414133770851677,31.4770592606648769],"rgb":[0.266666666666666663,0.466666666666666674,0.266666666666666663],"xyz":[0.100236566214480294,0.148395535138288209,0.0780518026101266749],"hpluv":[127.715012949239082,111.18234158710581,45.4136534494367368],"hsluv":[127.715012949239082,56.6116285441109,45.4136534494367368]},"#447755":{"lch":[45.7409133262359902,31.7219583115713704,139.030718806592802],"luv":[45.7409133262359902,-23.9520203549447466,20.798638417872084],"rgb":[0.266666666666666663,0.466666666666666674,0.333333333333333315],"xyz":[0.106198980253842293,0.150780500754033042,0.10945384988410059],"hpluv":[139.030718806592802,88.0023935360314766,45.7409133262359902],"hsluv":[139.030718806592802,58.7992252631310066,45.7409133262359902]},"#447766":{"lch":[46.1522822994750328,25.0075472636366349,160.141849635166039],"luv":[46.1522822994750328,-23.5205108300662609,8.49488024846472],"rgb":[0.266666666666666663,0.466666666666666674,0.4],"xyz":[0.113783976027350464,0.153814499063436333,0.149401494291244552],"hpluv":[160.141849635166039,68.7570511480334,46.1522822994750328],"hsluv":[160.141849635166039,61.2825519214888672,46.1522822994750328]},"#447777":{"lch":[46.650089933282672,23.6026970305602966,192.177050630060933],"luv":[46.650089933282672,-23.0716472128555,-4.97859438013953248],"rgb":[0.266666666666666663,0.466666666666666674,0.466666666666666674],"xyz":[0.123097989047552384,0.157540104271517156,0.198455296197642461],"hpluv":[192.177050630060933,64.2019875277067,46.650089933282672],"hsluv":[192.177050630060933,63.9506821134950414,46.650089933282672]},"#447788":{"lch":[47.2353114433284134,29.6592888392359697,220.273189901853613],"luv":[47.2353114433284134,-22.6291741496980734,-19.1727382434503575],"rgb":[0.266666666666666663,0.466666666666666674,0.533333333333333326],"xyz":[0.134238406149496226,0.161996271112294754,0.257128159601214601],"hpluv":[220.273189901853613,79.6770556088496,47.2353114433284134],"hsluv":[220.273189901853613,66.6958169909158585,47.2353114433284134]},"#447799":{"lch":[47.9077085122244526,40.3569508451274856,236.603980798736757],"luv":[47.9077085122244526,-22.2133832668581981,-33.6934576046404],"rgb":[0.266666666666666663,0.466666666666666674,0.6],"xyz":[0.147295370258568925,0.167219056755923912,0.325894837242332536],"hpluv":[236.603980798736757,106.893740352524901,47.9077085122244526],"hsluv":[236.603980798736757,69.4246608010291197,47.9077085122244526]},"#4477aa":{"lch":[48.6659751090485,52.9419227285019574,245.636459716194196],"luv":[48.6659751090485,-21.8398581964299439,-48.2272513849846476],"rgb":[0.266666666666666663,0.466666666666666674,0.66666666666666663],"xyz":[0.162353063223821481,0.173242133942025,0.405198686859331136],"hpluv":[245.636459716194196,138.042751347741245,48.6659751090485],"hsluv":[245.636459716194196,72.0643617009564,48.6659751090485]},"#4477bb":{"lch":[49.5078912458612,66.145388752002,251.014275727268966],"luv":[49.5078912458612,-21.5192486824625604,-62.5470573991759125],"rgb":[0.266666666666666663,0.466666666666666674,0.733333333333333282],"xyz":[0.1794906553311581,0.180097170784959765,0.495456671957972883],"hpluv":[251.014275727268966,169.536991245322184,49.5078912458612],"hsluv":[251.014275727268966,74.5637193650047578,49.5078912458612]},"#4477cc":{"lch":[50.4304819457797606,79.4031370336833,254.471410742848605],"luv":[50.4304819457797606,-21.2577420931439356,-76.5046833330565761],"rgb":[0.266666666666666663,0.466666666666666674,0.8],"xyz":[0.198783030774879854,0.187814120962448566,0.597063182628243094],"hpluv":[254.471410742848605,199.794656417231295,50.4304819457797606],"hsluv":[254.471410742848605,76.8911855438839638,50.4304819457797606]},"#4477dd":{"lch":[51.4301761714764183,92.4467030892661654,256.833353640671476],"luv":[51.4301761714764183,-21.0578873175855144,-90.0164334652001514],"rgb":[0.266666666666666663,0.466666666666666674,0.866666666666666696],"xyz":[0.220301356325513398,0.1964214511827021,0.710393030528249092],"hpluv":[256.833353640671476,228.093412194404408,51.4301761714764183],"hsluv":[256.833353640671476,79.0312420746427904,51.4301761714764183]},"#4477ee":{"lch":[52.5029598761355913,105.148975578657073,258.524369979875587],"luv":[52.5029598761355913,-20.9195063280493,-103.046985983248078],"rgb":[0.266666666666666663,0.466666666666666674,0.933333333333333348],"xyz":[0.244113536591688135,0.205946323289172145,0.835803846596772315],"hpluv":[258.524369979875587,254.132720010738154,52.5029598761355913],"hsluv":[258.524369979875587,87.6254974090696,52.5029598761355913]},"#4477ff":{"lch":[53.6445179522116,117.458222301342076,259.779939364455799],"luv":[53.6445179522116,-20.8405325230258285,-115.594576820663164],"rgb":[0.266666666666666663,0.466666666666666674,1],"xyz":[0.270284585001519528,0.216414742653104841,0.973638034888554],"hpluv":[259.779939364455799,277.841684308431127,53.6445179522116],"hsluv":[259.779939364455799,99.999999999999,53.6445179522116]},"#bbff00":{"lch":[92.6117448358007778,112.09772632761252,107.605046807390437],"luv":[92.6117448358007778,-33.9043888880720843,106.847520616749406],"rgb":[0.733333333333333282,1,0],"xyz":[0.56251493439864475,0.820836016822245496,0.128800901435937365],"hpluv":[107.605046807390437,698.685604225905081,92.6117448358007778],"hsluv":[107.605046807390437,100.000000000002302,92.6117448358007778]},"#bbff11":{"lch":[92.6295901709342,111.320425805292416,107.729052066712285],"luv":[92.6295901709342,-33.8988588935206678,106.033506813595423],"rgb":[0.733333333333333282,1,0.0666666666666666657],"xyz":[0.56352659989828191,0.821240683022100404,0.134129006400693],"hpluv":[107.729052066712285,695.618439183936061,92.6295901709342],"hsluv":[107.729052066712285,99.9999999999893703,92.6295901709342]},"#bbff22":{"lch":[92.6626551654141,109.887399193340656,107.962519071076329],"luv":[92.6626551654141,-33.888700280085942,104.531318248662245],"rgb":[0.733333333333333282,1,0.133333333333333331],"xyz":[0.565401958036758856,0.821990826277491204,0.14400589259667218],"hpluv":[107.962519071076329,689.937572971075,92.6626551654141],"hsluv":[107.962519071076329,99.9999999999891713,92.6626551654141]},"#bbff33":{"lch":[92.7170524122382318,107.550157892444602,108.357408717671873],"luv":[92.7170524122382318,-33.8722333827189388,102.076972272674624],"rgb":[0.733333333333333282,1,0.2],"xyz":[0.568489708769216673,0.823225926570474331,0.160268046454283331],"hpluv":[108.357408717671873,680.59767216104342,92.7170524122382318],"hsluv":[108.357408717671873,99.9999999999894271,92.7170524122382318]},"#bbff44":{"lch":[92.7954935084343475,104.224206838295117,108.951712424811362],"luv":[92.7954935084343475,-33.8490183743317,98.5744857768270464],"rgb":[0.733333333333333282,1,0.266666666666666663],"xyz":[0.572947704013435533,0.825009124668161897,0.183746821407169969],"hpluv":[108.951712424811362,667.142517523628385,92.7954935084343475],"hsluv":[108.951712424811362,99.9999999999890576,92.7954935084343475]},"#bbff55":{"lch":[92.9002292713318809,99.8647848732016,109.794505003516988],"luv":[92.9002292713318809,-33.8189779888925628,93.9640994505754605],"rgb":[0.733333333333333282,1,0.333333333333333315],"xyz":[0.578910118052797462,0.827394090283906647,0.215148868681143884],"hpluv":[109.794505003516988,649.201221057988732,92.9002292713318809],"hsluv":[109.794505003516988,99.9999999999888445,92.9002292713318809]},"#bbff66":{"lch":[93.0331768315467826,94.4651128464689691,110.953951756581517],"luv":[93.0331768315467826,-33.7823795150753,88.2179595059619146],"rgb":[0.733333333333333282,1,0.4],"xyz":[0.586495113826305703,0.83042808859331,0.255096513088287846],"hpluv":[110.953951756581517,626.470359589551208,93.0331768315467826],"hsluv":[110.953951756581517,99.9999999999888871,93.0331768315467826]},"#bbff77":{"lch":[93.1959878807374196,88.0576290523864742,112.529317332402641],"luv":[93.1959878807374196,-33.7398191848892566,81.3373876867131571],"rgb":[0.733333333333333282,1,0.466666666666666674],"xyz":[0.595809126846507553,0.834153693801390816,0.304150314994685755],"hpluv":[112.529317332402641,598.713569857690459,93.1959878807374196],"hsluv":[112.529317332402641,99.9999999999886455,93.1959878807374196]},"#bbff88":{"lch":[93.3900894470196334,80.7182094219550805,114.670873894576516],"luv":[93.3900894470196334,-33.6921989698203319,73.3502901212028888],"rgb":[0.733333333333333282,1,0.533333333333333326],"xyz":[0.606949543948451464,0.838609860642168359,0.362823178398257951],"hpluv":[114.670873894576516,565.785048639302204,93.3900894470196334],"hsluv":[114.670873894576516,99.9999999999880913,93.3900894470196334]},"#bbff99":{"lch":[93.6167101348934239,72.575742292483838,117.61482369288214],"luv":[93.6167101348934239,-33.6406927329059684,64.3081811417119411],"rgb":[0.733333333333333282,1,0.6],"xyz":[0.620006508057524108,0.843832646285797572,0.43158985603937583],"hpluv":[117.61482369288214,527.702623330867254,93.6167101348934239],"hsluv":[117.61482369288214,99.9999999999881,93.6167101348934239]},"#bbffaa":{"lch":[93.8768980816178384,63.8331941826517948,121.746607961207644],"luv":[93.8768980816178384,-33.5867019719833948,54.2826872050868303],"rgb":[0.733333333333333282,1,0.66666666666666663],"xyz":[0.63506420102277672,0.849855723471898639,0.510893705656374486],"hpluv":[121.746607961207644,484.836572610502856,93.8768980816178384],"hsluv":[121.746607961207644,99.9999999999878781,93.8768980816178384]},"#bbffbb":{"lch":[94.1715339943383,54.8143223318485937,127.715012949237362],"luv":[94.1715339943383,-33.5318032859449531,43.3615970772812602],"rgb":[0.733333333333333282,1,0.733333333333333282],"xyz":[0.652201793130113283,0.856710760314833397,0.601151690755016177],"hpluv":[127.715012949237362,438.38038704048256,94.1715339943383],"hsluv":[127.715012949237362,99.999999999986926,94.1715339943383]},"#bbffcc":{"lch":[94.5013412228876888,46.0666753200389323,136.612331153023604],"luv":[94.5013412228876888,-33.4776907719138919,31.6446329670924698],"rgb":[0.733333333333333282,1,0.8],"xyz":[0.671494168573835,0.864427710492322254,0.702758201425286333],"hpluv":[136.612331153023604,391.513584290668746,94.5013412228876888],"hsluv":[136.612331153023604,99.9999999999865707,94.5013412228876888]},"#bbffdd":{"lch":[94.8668940681869515,38.5674836948257322,150.076437256866],"luv":[94.8668940681869515,-33.4261169986321818,19.2391658068743077],"rgb":[0.733333333333333282,1,0.866666666666666696],"xyz":[0.693012494124468637,0.873035040712575761,0.816088049325292331],"hpluv":[150.076437256866,352.109825744613431,94.8668940681869515],"hsluv":[150.076437256866,99.9999999999853628,94.8668940681869515]},"#bbffee":{"lch":[95.2686250900245568,33.9600576278843675,169.384373669661102],"luv":[95.2686250900245568,-33.3788361105619771,6.25610214058809699],"rgb":[0.733333333333333282,1,0.933333333333333348],"xyz":[0.716824674390643346,0.882559912819045778,0.941498865393815554],"hpluv":[169.384373669661102,337.406400875084444,95.2686250900245568],"hsluv":[169.384373669661102,99.9999999999845,95.2686250900245568]},"#bbffff":{"lch":[95.7068319095003,34.1048965933827191,192.177050630060478],"luv":[95.7068319095003,-33.3375521201936849,-7.19385781613020914],"rgb":[0.733333333333333282,1,1],"xyz":[0.742995722800474767,0.893028332182978501,1.0793330536855974],"hpluv":[192.177050630060478,374.679972152143307,95.7068319095003],"hsluv":[192.177050630060478,99.9999999999829186,95.7068319095003]},"#448800":{"lch":[50.4956227619448157,68.4221216779621244,118.715311426014551],"luv":[50.4956227619448157,-32.873947818662586,60.0074186224478723],"rgb":[0.266666666666666663,0.533333333333333326,0],"xyz":[0.111876166324659992,0.18836716674231338,0.0304633392138840171],"hpluv":[118.715311426014551,171.942062028892252,50.4956227619448157],"hsluv":[118.715311426014551,100.000000000002373,50.4956227619448157]},"#448811":{"lch":[50.543205868460916,66.6756511812714763,119.435612575278299],"luv":[50.543205868460916,-32.7674265649617098,58.0683925794095899],"rgb":[0.266666666666666663,0.533333333333333326,0.0666666666666666657],"xyz":[0.112887831824297111,0.188771832942168233,0.0357914441786396503],"hpluv":[119.435612575278299,167.395510973175305,50.543205868460916],"hsluv":[119.435612575278299,96.4702491056824272,50.543205868460916]},"#448822":{"lch":[50.6312327062127565,63.5295563644356918,120.846986072134357],"luv":[50.6312327062127565,-32.5745953261955492,54.5426463530750425],"rgb":[0.266666666666666663,0.533333333333333326,0.133333333333333331],"xyz":[0.11476318996277414,0.189521976197559061,0.0456683303746188429],"hpluv":[120.846986072134357,159.219643782083125,50.6312327062127565],"hsluv":[120.846986072134357,90.0662104861249,50.6312327062127565]},"#448833":{"lch":[50.775662969350762,58.6076690216783831,123.408487274566809],"luv":[50.775662969350762,-32.2696404838739213,48.9237076599487182],"rgb":[0.266666666666666663,0.533333333333333326,0.2],"xyz":[0.117850940695231873,0.19075707649054216,0.0619304842322299931],"hpluv":[123.408487274566809,146.466455796741883,50.775662969350762],"hsluv":[123.408487274566809,79.8990388198805732,50.775662969350762]},"#448844":{"lch":[50.9830910358637652,52.0733509329185,127.715012949239537],"luv":[50.9830910358637652,-31.855056956676961,41.1933152789351382],"rgb":[0.266666666666666663,0.533333333333333326,0.266666666666666663],"xyz":[0.122308935939450747,0.192540274588229754,0.0854092591851166316],"hpluv":[127.715012949239537,129.607069016793787,50.9830910358637652],"hsluv":[127.715012949239537,65.9930987522981241,50.9830910358637652]},"#448855":{"lch":[51.2585265038955384,44.4350179761376651,134.860489600104756],"luv":[51.2585265038955384,-31.3437036744621551,31.4967151066136601],"rgb":[0.266666666666666663,0.533333333333333326,0.333333333333333315],"xyz":[0.128271349978812732,0.194925240203974587,0.116811306459090533],"hpluv":[134.860489600104756,110.001490313735033,51.2585265038955384],"hsluv":[134.860489600104756,67.3517725464548676,51.2585265038955384]},"#448866":{"lch":[51.6056896491522537,36.7437212642011914,146.829747927558799],"luv":[51.6056896491522537,-30.7562765884277063,20.1035445321824895],"rgb":[0.266666666666666663,0.533333333333333326,0.4],"xyz":[0.135856345752320917,0.197959238513377878,0.156758950866234509],"hpluv":[146.829747927558799,90.3493178961374781,51.6056896491522537],"hsluv":[146.829747927558799,68.9308752248562797,51.6056896491522537]},"#448877":{"lch":[52.0271709342862039,31.0045548915217921,166.266503182991642],"luv":[52.0271709342862039,-30.1181499011556575,7.36067052332227245],"rgb":[0.266666666666666663,0.533333333333333326,0.466666666666666674],"xyz":[0.145170358772522823,0.201684843721458701,0.205812752772632418],"hpluv":[166.266503182991642,75.6196418937204555,52.0271709342862039],"hsluv":[166.266503182991642,70.6726995402934506,52.0271709342862039]},"#448888":{"lch":[52.5245390493459041,30.1341009641634088,192.177050630061],"luv":[52.5245390493459041,-29.456097564679137,-6.35628485662009179],"rgb":[0.266666666666666663,0.533333333333333326,0.533333333333333326],"xyz":[0.156310775874466679,0.206141010562236299,0.264485616176204585],"hpluv":[192.177050630061,72.8006598676027181,52.5245390493459041],"hsluv":[192.177050630061,72.5156967272479847,52.5245390493459041]},"#448899":{"lch":[53.0984315279962118,35.4547108695225,215.690916113393854],"luv":[53.0984315279962118,-28.7954664423823949,-20.6847198484066084],"rgb":[0.266666666666666663,0.533333333333333326,0.6],"xyz":[0.169367739983539378,0.211363796205865456,0.333252293817322465],"hpluv":[215.690916113393854,84.7289026839812,53.0984315279962118],"hsluv":[215.690916113393854,74.4011420122721319,53.0984315279962118]},"#4488aa":{"lch":[53.7486427971268625,45.1587425535104146,231.425064236121358],"luv":[53.7486427971268625,-28.1581765792043193,-35.3048030832715654],"rgb":[0.266666666666666663,0.533333333333333326,0.66666666666666663],"xyz":[0.184425432948791934,0.217386873391966551,0.412556143434321065],"hpluv":[231.425064236121358,106.613859301848393,53.7486427971268625],"hsluv":[231.425064236121358,76.2778611087785,53.7486427971268625]},"#4488bb":{"lch":[54.4742155909258514,57.0545505189943469,241.113543257937238],"luv":[54.4742155909258514,-27.5616516575745152,-49.9557513488787208],"rgb":[0.266666666666666663,0.533333333333333326,0.733333333333333282],"xyz":[0.201563025056128553,0.224241910234901309,0.502814128532962812],"hpluv":[241.113543257937238,132.904176722924205,54.4742155909258514],"hsluv":[241.113543257937238,78.1047803623200707,54.4742155909258514]},"#4488cc":{"lch":[55.273536978614473,69.875332030770025,247.25266296501286],"luv":[55.273536978614473,-27.0185618464256976,-64.4403549195783398],"rgb":[0.266666666666666663,0.533333333333333326,0.8],"xyz":[0.220855400499850307,0.231958860412390111,0.604420639203233],"hpluv":[247.25266296501286,160.415361718249983,55.273536978614473],"hsluv":[247.25266296501286,79.8515774594708603,55.273536978614473]},"#4488dd":{"lch":[56.1444377207636194,82.97891177410213,251.348812353132246],"luv":[56.1444377207636194,-26.53714651812043,-78.6211145551246631],"rgb":[0.266666666666666663,0.533333333333333326,0.866666666666666696],"xyz":[0.242373726050483851,0.240566190632643645,0.717750487103239],"hpluv":[251.348812353132246,187.542769341675751,56.1444377207636194],"hsluv":[251.348812353132246,81.4979766670821,56.1444377207636194]},"#4488ee":{"lch":[57.0842924141545609,96.0325607902411775,254.216059778839536],"luv":[57.0842924141545609,-26.1218678035424112,-92.4115834426919776],"rgb":[0.266666666666666663,0.533333333333333326,0.933333333333333348],"xyz":[0.266185906316658616,0.25009106273911369,0.843161303171762189],"hpluv":[254.216059778839536,213.472145126724115,57.0842924141545609],"hsluv":[254.216059778839536,85.8050168900109469,57.0842924141545609]},"#4488ff":{"lch":[58.090117466996233,108.861046277687535,256.304473865935392],"luv":[58.090117466996233,-25.7741898685227575,-105.765866579412872],"rgb":[0.266666666666666663,0.533333333333333326,1],"xyz":[0.29235695472649,0.260559482103046358,0.980995491463544],"hpluv":[256.304473865935392,237.798754650411269,58.090117466996233],"hsluv":[256.304473865935392,99.9999999999988631,58.090117466996233]},"#449900":{"lch":[56.0984423000037538,78.159424491283,120.852962610827774],"luv":[56.0984423000037538,-40.0830169860907191,67.0987882610508279],"rgb":[0.266666666666666663,0.6,0],"xyz":[0.137745766777127493,0.240106367647249075,0.0390865393647062687],"hpluv":[120.852962610827774,176.794958777624345,56.0984423000037538],"hsluv":[120.852962610827774,100.000000000002416,56.0984423000037538]},"#449911":{"lch":[56.1389235634784143,76.6482268999804859,121.431666795625887],"luv":[56.1389235634784143,-39.9706170908808929,65.4010738159938256],"rgb":[0.266666666666666663,0.6,0.0666666666666666657],"xyz":[0.138757432276764625,0.240511033847103928,0.0444146443294619],"hpluv":[121.431666795625887,173.251641588156104,56.1389235634784143],"hsluv":[121.431666795625887,97.2234127009916,56.1389235634784143]},"#449922":{"lch":[56.21384509356389,73.9109075723002746,122.549403254372123],"luv":[56.21384509356389,-39.7660359546788555,62.3015621201611793],"rgb":[0.266666666666666663,0.6,0.133333333333333331],"xyz":[0.140632790415241626,0.241261177102494756,0.0542915305254411],"hpluv":[122.549403254372123,166.841685682494415,56.21384509356389],"hsluv":[122.549403254372123,92.1627352690631,56.21384509356389]},"#449933":{"lch":[56.3368647095541064,69.5846668696270143,124.526315047954697],"luv":[56.3368647095541064,-39.4395235157555177,57.3284383897480296],"rgb":[0.266666666666666663,0.6,0.2],"xyz":[0.143720541147699388,0.242496277395477855,0.0705536843830522342],"hpluv":[124.526315047954697,156.73291295139785,56.3368647095541064],"hsluv":[124.526315047954697,84.0665441712718859,56.3368647095541064]},"#449944":{"lch":[56.5137417426914368,63.7361451042890153,127.715012949239735],"luv":[56.5137417426914368,-38.9895886498958575,50.4193233757345922],"rgb":[0.266666666666666663,0.6,0.266666666666666663],"xyz":[0.148178536391918247,0.244279475493165449,0.0940324593359388727],"hpluv":[127.715012949239735,143.110354253444,56.5137417426914368],"hsluv":[127.715012949239735,72.8686777069245,56.5137417426914368]},"#449955":{"lch":[56.7489681974646629,56.6620380577650309,132.698160989074609],"luv":[56.7489681974646629,-38.4245724364924328,41.642992086692793],"rgb":[0.266666666666666663,0.6,0.333333333333333315],"xyz":[0.154140950431280233,0.246664441108910282,0.125434506609912788],"hpluv":[132.698160989074609,126.69910537289924,56.7489681974646629],"hsluv":[132.698160989074609,73.7405349232989664,56.7489681974646629]},"#449966":{"lch":[57.0460268500437166,48.9673458777373511,140.456743036678859],"luv":[57.0460268500437166,-37.7608817984154683,31.1755796757022061],"rgb":[0.266666666666666663,0.6,0.4],"xyz":[0.161725946204788418,0.249698439418313572,0.16538215101705675],"hpluv":[140.456743036678859,108.923224533285605,57.0460268500437166],"hsluv":[140.456743036678859,74.7718537787272766,57.0460268500437166]},"#449977":{"lch":[57.4075272841014481,41.7361359201695734,152.500832231763781],"luv":[57.4075272841014481,-37.0206846158697,19.2710651526888199],"rgb":[0.266666666666666663,0.6,0.466666666666666674],"xyz":[0.171039959224990323,0.253424044626394396,0.214435952923454659],"hpluv":[152.500832231763781,92.2534727828265915,57.4075272841014481],"hsluv":[152.500832231763781,75.9325502249844817,57.4075272841014481]},"#449988":{"lch":[57.8352917232380861,36.7607331244742284,170.245603374965924],"luv":[57.8352917232380861,-36.2292854489646174,6.22819200942437323],"rgb":[0.266666666666666663,0.6,0.533333333333333326],"xyz":[0.182180376326934179,0.257880211467172,0.273108816327026827],"hpluv":[170.245603374965924,80.6548633994409414,57.8352917232380861],"hsluv":[170.245603374965924,77.1878957355486222,57.8352917232380861]},"#449999":{"lch":[58.3304201548299517,36.2276744984656105,192.17705063006116],"luv":[58.3304201548299517,-35.4125684996312486,-7.64162232943372643],"rgb":[0.266666666666666663,0.6,0.6],"xyz":[0.195237340436006879,0.263102997110801151,0.341875493968144761],"hpluv":[192.17705063006116,78.8106081595615251,58.3304201548299517],"hsluv":[192.17705063006116,78.5021203184449803,58.3304201548299517]},"#4499aa":{"lch":[58.8933484328044585,41.0197173156303379,212.502133513081617],"luv":[58.8933484328044585,-34.5948579745346478,-22.041166266239177],"rgb":[0.266666666666666663,0.6,0.66666666666666663],"xyz":[0.210295033401259435,0.269126074296902273,0.421179343585143307],"hpluv":[212.502133513081617,88.3823902117899536,58.8933484328044585],"hsluv":[212.502133513081617,79.8414276244135692,58.8933484328044585]},"#4499bb":{"lch":[59.523905851944221,49.8962585520308082,227.36281958486083],"luv":[59.523905851944221,-33.7974051546762055,-36.7065664738854878],"rgb":[0.266666666666666663,0.6,0.733333333333333282],"xyz":[0.227432625508596054,0.275981111139837032,0.511437328683785108],"hpluv":[227.36281958486083,106.36919851968392,59.523905851944221],"hsluv":[227.36281958486083,81.1761313086710885,59.523905851944221]},"#4499cc":{"lch":[60.2213749252976385,61.1171242450200438,237.278146949597897],"luv":[60.2213749252976385,-33.0375484580145766,-51.4181219791773],"rgb":[0.266666666666666663,0.6,0.8],"xyz":[0.246725000952317808,0.283698061317325834,0.613043839354055264],"hpluv":[237.278146949597897,128.780934100622716,60.2213749252976385],"hsluv":[237.278146949597897,82.4818489079811741,60.2213749252976385]},"#4499dd":{"lch":[60.9845539619455508,73.4958381074912,243.904542785491344],"luv":[60.9845539619455508,-32.3284648877968195,-66.0038527445257728],"rgb":[0.266666666666666663,0.6,0.866666666666666696],"xyz":[0.268243326502951351,0.29230539153757934,0.726373687254061262],"hpluv":[243.904542785491344,152.926314240713424,60.9845539619455508],"hsluv":[243.904542785491344,83.7398679369964469,60.9845539619455508]},"#4499ee":{"lch":[61.8118218103912653,86.3580647779335351,248.479300934605874],"luv":[61.8118218103912653,-31.6793620640961606,-80.3376211460214193],"rgb":[0.266666666666666663,0.6,0.933333333333333348],"xyz":[0.292055506769126061,0.301830263644049357,0.851784503322584485],"hpluv":[248.479300934605874,177.284466220706,61.8118218103912653],"hsluv":[248.479300934605874,84.9368954206658344,61.8118218103912653]},"#4499ff":{"lch":[62.7012034705467585,99.3269113509348,251.755860244601337],"luv":[62.7012034705467585,-31.0959452870692914,-94.3338619225358173],"rgb":[0.266666666666666663,0.6,1],"xyz":[0.318226555178957482,0.312298683007982081,0.98961869161436633],"hpluv":[251.755860244601337,201.015886170810859,62.7012034705467585],"hsluv":[251.755860244601337,99.9999999999986073,62.7012034705467585]},"#330000":{"lch":[6.35863201887414942,21.3842798011123882,12.1770506300617836],"luv":[6.35863201887414942,20.9031433498234946,4.51065635013277699],"rgb":[0.2,0,0],"xyz":[0.0136521011456799905,0.00703936465324139522,0.000639942241203736136],"hpluv":[12.1770506300617836,426.746789183125031,6.35863201887414942],"hsluv":[12.1770506300617836,100.000000000002217,6.35863201887414942]},"#330011":{"lch":[6.72416549840036915,18.2596394021459751,358.956333183931122],"luv":[6.72416549840036915,18.2566101970553,-0.332588648601129133],"rgb":[0.2,0,0.0666666666666666657],"xyz":[0.0146637666453171122,0.00744403085309625,0.00596804720595936738],"hpluv":[358.956333183931122,344.582429927088697,6.72416549840036915],"hsluv":[358.956333183931122,99.9999999999970868,6.72416549840036915]},"#330022":{"lch":[7.4017671226143058,16.6083885778583671,334.642609555635659],"luv":[7.4017671226143058,15.0082373074967617,-7.11276205668364714],"rgb":[0.2,0,0.133333333333333331],"xyz":[0.0165391247837941326,0.00819417410848706854,0.0158449334019385643],"hpluv":[334.642609555635659,284.728805881674077,7.4017671226143058],"hsluv":[334.642609555635659,99.999999999998,7.4017671226143058]},"#330033":{"lch":[8.50665746950019,19.3767863388894384,307.715012949243601],"luv":[8.50665746950019,11.8534455994177517,-15.3282639670843448],"rgb":[0.2,0,0.2],"xyz":[0.0196268755162518696,0.00942927440147018139,0.0321070872595497075],"hpluv":[307.715012949243601,289.042783730483279,8.50665746950019],"hsluv":[307.715012949243601,99.9999999999987921,8.50665746950019]},"#330044":{"lch":[9.96321399083228343,25.9151774110163871,290.632214162589],"luv":[9.96321399083228343,9.13167627644372,-24.2530185467023678],"rgb":[0.2,0,0.266666666666666663],"xyz":[0.0240848707604707502,0.0112124724991577579,0.0555858622124363461],"hpluv":[290.632214162589,330.060881015257678,9.96321399083228343],"hsluv":[290.632214162589,99.9999999999994,9.96321399083228343]},"#330055":{"lch":[11.6870713271151807,34.2775786608295405,281.502617436257196],"luv":[11.6870713271151807,6.83538450996046,-33.589133919325],"rgb":[0.2,0,0.333333333333333315],"xyz":[0.0300472847998327422,0.0135974381149025891,0.0869879094864102614],"hpluv":[281.502617436257196,372.172061509357604,11.6870713271151807],"hsluv":[281.502617436257196,99.9999999999999289,11.6870713271151807]},"#330066":{"lch":[13.6097387714237676,43.4818398400869768,276.434806151814087],"luv":[13.6097387714237676,4.87312317733106592,-43.2079051375733059],"rgb":[0.2,0,0.4],"xyz":[0.0376322805733409205,0.0166314364243059024,0.126935553893554209],"hpluv":[276.434806151814087,405.412793254212261,13.6097387714237676],"hsluv":[276.434806151814087,100.00000000000027,13.6097387714237676]},"#330077":{"lch":[15.6735112457106673,53.108485659557914,273.408523183706109],"luv":[15.6735112457106673,3.15755804167271537,-53.0145364618510655],"rgb":[0.2,0,0.466666666666666674],"xyz":[0.046946293593542833,0.0203570416323867187,0.175989355799952119],"hpluv":[273.408523183706109,429.968801903614121,15.6735112457106673],"hsluv":[273.408523183706109,100.000000000000313,15.6735112457106673]},"#330088":{"lch":[17.8339183845063687,62.9511834901283365,271.47985970994057],"luv":[17.8339183845063687,1.62574911173865799,-62.9301870538574448],"rgb":[0.2,0,0.533333333333333326],"xyz":[0.058086710695486661,0.0248132084731643096,0.234662219203524286],"hpluv":[271.47985970994057,447.91587095992594,17.8339183845063687],"hsluv":[271.47985970994057,100.000000000000441,17.8339183845063687]},"#330099":{"lch":[20.0583065104412341,72.8932825114363,270.184356583024851],"luv":[20.0583065104412341,0.234543162084408924,-72.8929051746271313],"rgb":[0.2,0,0.6],"xyz":[0.0711436748045593814,0.0300359941167934706,0.303428896844642193],"hpluv":[270.184356583024851,461.139761646516433,20.0583065104412341],"hsluv":[270.184356583024851,100.000000000000625,20.0583065104412341]},"#3300aa":{"lch":[22.3232943619689834,82.8637729479105474,269.276671227287579],"luv":[22.3232943619689834,-1.04608331699459467,-82.8571697371855578],"rgb":[0.2,0,0.66666666666666663],"xyz":[0.0862013677698119235,0.0360590713028945756,0.382732746461640794],"hpluv":[269.276671227287579,471.026936966419044,22.3232943619689834],"hsluv":[269.276671227287579,100.000000000000554,22.3232943619689834]},"#3300bb":{"lch":[24.6123405885396807,92.8181896970849,268.61855571411644],"luv":[24.6123405885396807,-2.23769945956788,-92.7912120826788538],"rgb":[0.2,0,0.733333333333333282],"xyz":[0.10333895987714857,0.0429141081458293341,0.47299073156028254],"hpluv":[268.61855571411644,478.541387025058441,24.6123405885396807],"hsluv":[268.61855571411644,100.000000000000625,24.6123405885396807]},"#3300cc":{"lch":[26.9138017967000778,102.728605647013808,268.127719933063759],"luv":[26.9138017967000778,-3.35631165306985224,-102.673762910819349],"rgb":[0.2,0,0.8],"xyz":[0.122631335320870311,0.0506310583233181358,0.574597242230552752],"hpluv":[268.127719933063759,484.345947247320225,26.9138017967000778],"hsluv":[268.127719933063759,100.000000000000881,26.9138017967000778]},"#3300dd":{"lch":[29.2194977691074271,112.577730384171886,267.752877980499],"luv":[29.2194977691074271,-4.41413050162269105,-112.49115889867052],"rgb":[0.2,0,0.866666666666666696],"xyz":[0.144149660871503854,0.0592383885435716698,0.687927090130558749],"hpluv":[267.752877980499,488.89890937186334,29.2194977691074271],"hsluv":[267.752877980499,100.000000000000753,29.2194977691074271]},"#3300ee":{"lch":[31.5236887929336334,122.355215968494591,267.460804758990776],"luv":[31.5236887929336334,-5.42068013199621,-122.235081304851008],"rgb":[0.2,0,0.933333333333333348],"xyz":[0.167961841137678591,0.0687632606500417,0.813337906199082],"hpluv":[267.460804758990776,492.52103452607281,31.5236887929336334],"hsluv":[267.460804758990776,100.000000000000824,31.5236887929336334]},"#3300ff":{"lch":[33.8223579343154,132.055276159319874,267.229255072945307],"luv":[33.8223579343154,-6.38352242786170443,-131.900896899631505],"rgb":[0.2,0,1],"xyz":[0.194132889547509985,0.0792316800139744,0.951172094490863818],"hpluv":[267.229255072945307,495.440155164142311,33.8223579343154],"hsluv":[267.229255072945307,100.000000000000881,33.8223579343154]},"#331100":{"lch":[9.83576796362177319,19.9321083570360571,25.9770166386959609],"luv":[9.83576796362177319,17.918363864654,8.73047421223431108],"rgb":[0.2,0.0666666666666666657,0],"xyz":[0.0156565014066084,0.0110481651750982679,0.00130807566151318702],"hpluv":[25.9770166386959609,257.148675223584291,9.83576796362177319],"hsluv":[25.9770166386959609,100.000000000002302,9.83576796362177319]},"#331111":{"lch":[10.1474261289244687,16.4836545456174051,12.1770506300618813],"luv":[10.1474261289244687,16.1127799065782149,3.4769513746129066],"rgb":[0.2,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0166681669062455212,0.0114528313749531225,0.00663618062626881826],"hpluv":[12.1770506300618813,206.127972902374523,10.1474261289244687],"hsluv":[12.1770506300618813,48.3021731216650707,10.1474261289244687]},"#331122":{"lch":[10.7062693823806221,14.2435433110065777,342.375847990242676],"luv":[10.7062693823806221,13.5749958919169824,-4.31254131423193],"rgb":[0.2,0.0666666666666666657,0.133333333333333331],"xyz":[0.0185435250447225398,0.0122029746303439404,0.0165130668222480161],"hpluv":[342.375847990242676,168.818174775843545,10.7062693823806221],"hsluv":[342.375847990242676,57.1044970617697913,10.7062693823806221]},"#331133":{"lch":[11.5784810016780177,17.5377888786733784,307.715012949244169],"luv":[11.5784810016780177,10.7284677021084427,-13.8735006223280077],"rgb":[0.2,0.0666666666666666657,0.2],"xyz":[0.0216312757771802804,0.0134380749233270532,0.0327752206798591628],"hpluv":[307.715012949244169,192.204068690519591,11.5784810016780177],"hsluv":[307.715012949244169,66.4967539441281,11.5784810016780177]},"#331144":{"lch":[12.7480449023252049,25.2894553184220108,288.641508688419037],"luv":[12.7480449023252049,8.08366941467993172,-23.9626968243691536],"rgb":[0.2,0.0666666666666666657,0.266666666666666663],"xyz":[0.0260892710213991574,0.0152212730210146297,0.0562539956327458],"hpluv":[288.641508688419037,251.73014018207067,12.7480449023252049],"hsluv":[288.641508688419037,74.5439781366083309,12.7480449023252049]},"#331155":{"lch":[14.1772863520069095,34.570642435857458,279.659572498507771],"luv":[14.1772863520069095,5.80074057604611415,-34.0805036230000695],"rgb":[0.2,0.0666666666666666657,0.333333333333333315],"xyz":[0.0320516850607611564,0.0176062386367594609,0.0876560429067197],"hpluv":[279.659572498507771,309.423764447612427,14.1772863520069095],"hsluv":[279.659572498507771,80.733364837348816,14.1772863520069095]},"#331166":{"lch":[15.8197098676790517,44.2946391552180785,274.993838621827194],"luv":[15.8197098676790517,3.85578699555013271,-44.1264995726595686],"rgb":[0.2,0.0666666666666666657,0.4],"xyz":[0.0396366808342693278,0.0206402369461627724,0.127603687313863678],"hpluv":[274.993838621827194,355.297359803625511,15.8197098676790517],"hsluv":[274.993838621827194,85.2848648605675095,15.8197098676790517]},"#331177":{"lch":[17.6293493428787755,54.1580116435351115,272.303494486185969],"luv":[17.6293493428787755,2.17675853502087469,-54.1142490242773135],"rgb":[0.2,0.0666666666666666657,0.466666666666666674],"xyz":[0.0489506938544712472,0.0243658421542435888,0.176657489220261588],"hpluv":[272.303494486185969,389.821469213037517,17.6293493428787755],"hsluv":[272.303494486185969,88.5936990192462588,17.6293493428787755]},"#331188":{"lch":[19.5658128626021437,64.0679547566568,270.623065923527406],"luv":[19.5658128626021437,0.696696562564985133,-64.064166587888522],"rgb":[0.2,0.0666666666666666657,0.533333333333333326],"xyz":[0.0600911109564150753,0.0288220089950211832,0.235330352623833755],"hpluv":[270.623065923527406,415.51077593183,19.5658128626021437],"hsluv":[270.623065923527406,91.0112456871911348,19.5658128626021437]},"#331199":{"lch":[21.5959931816331263,73.9854871429769645,269.508319412823],"luv":[21.5959931816331263,-0.634894604710849,-73.9827629696574576],"rgb":[0.2,0.0666666666666666657,0.6],"xyz":[0.0731480750654877887,0.0340447946386503442,0.304097030264951662],"hpluv":[269.508319412823,434.723064450461493,21.5959931816331263],"hsluv":[269.508319412823,92.7998436287799,21.5959931816331263]},"#3311aa":{"lch":[23.6938673935249824,83.8866252842298792,268.733700318675346],"luv":[23.6938673935249824,-1.85383566080119344,-83.8661385478044821],"rgb":[0.2,0.0666666666666666657,0.66666666666666663],"xyz":[0.0882057680307403308,0.0400678718247514457,0.383400879881950263],"hpluv":[268.733700318675346,449.258286440651602,23.6938673935249824],"hsluv":[268.733700318675346,94.1436997610677,23.6938673935249824]},"#3311bb":{"lch":[25.8394818705352094,93.7535423490500079,268.175268957576],"luv":[25.8394818705352094,-2.98531729009247,-93.7060007879569525],"rgb":[0.2,0.0666666666666666657,0.733333333333333282],"xyz":[0.105343360138076977,0.0469229086676862042,0.473658864980592],"hpluv":[268.175268957576,460.408371224539451,25.8394818705352094],"hsluv":[268.175268957576,95.1697562295976525,25.8394818705352094]},"#3311cc":{"lch":[28.017750605254669,103.572636018550753,267.760492630427507],"luv":[28.017750605254669,-4.04728980779695124,-103.493528189171812],"rgb":[0.2,0.0666666666666666657,0.8],"xyz":[0.124635735581798718,0.0546398588451750059,0.57526537565086211],"hpluv":[267.760492630427507,469.084508820223505,28.017750605254669],"hsluv":[267.760492630427507,95.9655004656031423,28.017750605254669]},"#3311dd":{"lch":[30.2173526676312889,113.33386550323506,267.444704079349265],"luv":[30.2173526676312889,-5.05282540459801588,-113.221173043455181],"rgb":[0.2,0.0666666666666666657,0.866666666666666696],"xyz":[0.146154061132432261,0.0632471890654285329,0.688595223550868107],"hpluv":[267.444704079349265,475.929488946899937,30.2173526676312889],"hsluv":[267.444704079349265,96.591763702558211,30.2173526676312889]},"#3311ee":{"lch":[32.429822932533412,123.030197380053124,267.199217974228532],"luv":[32.429822932533412,-6.01167404447580456,-122.883234180085807],"rgb":[0.2,0.0666666666666666657,0.933333333333333348],"xyz":[0.169966241398607,0.0727720611718985777,0.814006039619391331],"hpluv":[267.199217974228532,481.400425551936735,32.429822932533412],"hsluv":[267.199217974228532,97.0913881744298095,32.429822932533412]},"#3311ff":{"lch":[34.6488414224811834,132.657034918193688,267.004954598207064],"luv":[34.6488414224811834,-6.93127707868383425,-132.475832933200962],"rgb":[0.2,0.0666666666666666657,1],"xyz":[0.196137289808438392,0.0832404805358312738,0.951840227911173176],"hpluv":[267.004954598207064,485.826158631145177,34.6488414224811834],"hsluv":[267.004954598207064,99.999999999999531,34.6488414224811834]},"#88aa00":{"lch":[64.9493872277699467,75.8454165204624502,102.522158340464031],"luv":[64.9493872277699467,-16.4445883060260414,74.0412231301438624],"rgb":[0.533333333333333326,0.66666666666666663,0],"xyz":[0.245272120749672057,0.339833923051985953,0.0526729261635559762],"hpluv":[102.522158340464031,148.181371186867864,64.9493872277699467],"hsluv":[102.522158340464031,100.000000000002217,64.9493872277699467]},"#88aa11":{"lch":[64.9815053546997206,74.514883993558044,102.764001416735823],"luv":[64.9815053546997206,-16.4630035423646639,72.6734989589568414],"rgb":[0.533333333333333326,0.66666666666666663,0.0666666666666666657],"xyz":[0.246283786249309189,0.340238589251840806,0.0580010311283116059],"hpluv":[102.764001416735823,145.509915409181133,64.9815053546997206],"hsluv":[102.764001416735823,98.0498740713468635,64.9815053546997206]},"#88aa22":{"lch":[65.040976504183746,72.0784265262596762,103.230826782560158],"luv":[65.040976504183746,-16.4969246852166869,70.1651697527462801],"rgb":[0.533333333333333326,0.66666666666666663,0.133333333333333331],"xyz":[0.24815914438778619,0.340988732507231607,0.0678779173242908],"hpluv":[103.230826782560158,140.623392494363173,65.040976504183746],"hsluv":[103.230826782560158,94.4776072436414296,65.040976504183746]},"#88aa33":{"lch":[65.138705174337673,68.1506383708936596,104.056367163177015],"luv":[65.138705174337673,-16.5521781693680836,66.1100212389152],"rgb":[0.533333333333333326,0.66666666666666663,0.2],"xyz":[0.251246895120243952,0.342223832800214733,0.0841400711819019487],"hpluv":[104.056367163177015,132.760883332008575,65.138705174337673],"hsluv":[104.056367163177015,88.7139905695652544,65.138705174337673]},"#88aa44":{"lch":[65.2793887406011,62.6606585185119442,105.391240881396499],"luv":[65.2793887406011,-16.6306856640551395,60.4133960336360687],"rgb":[0.533333333333333326,0.66666666666666663,0.266666666666666663],"xyz":[0.255704890364462811,0.344007030897902299,0.107618846134788587],"hpluv":[105.391240881396499,121.803060858356815,65.2793887406011],"hsluv":[105.391240881396499,80.6421361820775,65.2793887406011]},"#88aa55":{"lch":[65.4667902277309821,55.6467221212728731,107.50018297907917],"luv":[65.4667902277309821,-16.7334615527701551,53.0711687011330397],"rgb":[0.533333333333333326,0.66666666666666663,0.333333333333333315],"xyz":[0.261667304403824796,0.34639199651364716,0.139020893408762503],"hpluv":[107.50018297907917,107.859366541167589,65.4667902277309821],"hsluv":[107.50018297907917,70.2829236383929157,65.4667902277309821]},"#88aa66":{"lch":[65.7039511656785606,47.2674293485405386,110.898270106627507],"luv":[65.7039511656785606,-16.8607549547505542,44.1579530727492582],"rgb":[0.533333333333333326,0.66666666666666663,0.4],"xyz":[0.269252300177333,0.349425994823050479,0.178968537815906464],"hpluv":[110.898270106627507,91.2871867148882075,65.7039511656785606],"hsluv":[110.898270106627507,57.7776943224234358,65.7039511656785606]},"#88aa77":{"lch":[65.993303036365262,37.8517489546572605,116.707912668539493],"luv":[65.993303036365262,-17.0121797895697142,33.8133204186420073],"rgb":[0.533333333333333326,0.66666666666666663,0.466666666666666674],"xyz":[0.278566313197534887,0.353151600031131274,0.228022339722304374],"hpluv":[116.707912668539493,72.782239014817236,65.993303036365262],"hsluv":[116.707912668539493,43.3670204896631262,65.993303036365262]},"#88aa88":{"lch":[66.3367341259492,28.0952907790087707,127.715012949235486],"luv":[66.3367341259492,-17.1868541575625393,22.2251526006848934],"rgb":[0.533333333333333326,0.66666666666666663,0.533333333333333326],"xyz":[0.289706730299478743,0.357607766871908872,0.286695203125876541],"hpluv":[127.715012949235486,53.7426121206727316,66.3367341259492],"hsluv":[127.715012949235486,27.3645684281827677,66.3367341259492]},"#88aa99":{"lch":[66.7356352778598705,19.8636867466165334,151.061783220075199],"luv":[66.7356352778598705,-17.3835461247401071,9.6113669837720046],"rgb":[0.533333333333333326,0.66666666666666663,0.6],"xyz":[0.302763694408551443,0.36283055251553803,0.35546188076699442],"hpluv":[151.061783220075199,37.7695130125235536,66.7356352778598705],"hsluv":[151.061783220075199,30.5390729913306274,66.7356352778598705]},"#88aaaa":{"lch":[67.1909358184889811,18.0059400546344968,192.177050630060364],"luv":[67.1909358184889811,-17.6008146924254447,-3.79805205519771905],"rgb":[0.533333333333333326,0.66666666666666663,0.66666666666666663],"xyz":[0.317821387373804,0.368853629701639152,0.434765730383993],"hpluv":[192.177050630060364,34.0051297749840913,67.1909358184889811],"hsluv":[192.177050630060364,33.872023720911649,67.1909358184889811]},"#88aabb":{"lch":[67.7031355134684674,25.1829477340388976,224.903065382651],"luv":[67.7031355134684674,-17.8371340556046292,-17.7768812016541453],"rgb":[0.533333333333333326,0.66666666666666663,0.733333333333333282],"xyz":[0.334958979481140617,0.37570866654457391,0.525023715482634823],"hpluv":[224.903065382651,47.1994684953027459,67.7031355134684674],"hsluv":[224.903065382651,37.296330310174362,67.7031355134684674]},"#88aacc":{"lch":[68.2723356589922901,36.8600300209604939,240.606662797769701],"luv":[68.2723356589922901,-18.0909926283411373,-32.1150712106857341],"rgb":[0.533333333333333326,0.66666666666666663,0.8],"xyz":[0.354251354924862372,0.383425616722062712,0.626630226152905],"hpluv":[240.606662797769701,68.5094136262693,68.2723356589922901],"hsluv":[240.606662797769701,40.7502319604911136,68.2723356589922901]},"#88aadd":{"lch":[68.8982708583434,50.1120766914241216,248.506358436024811],"luv":[68.8982708583434,-18.3609632112572676,-46.6271944285953168],"rgb":[0.533333333333333326,0.66666666666666663,0.866666666666666696],"xyz":[0.375769680475495915,0.392032946942316218,0.739960074052911],"hpluv":[248.506358436024811,92.2939864083951278,68.8982708583434],"hsluv":[248.506358436024811,59.5109742880650217,68.8982708583434]},"#88aaee":{"lch":[69.5803420919898,63.9362726255054454,253.044423586561948],"luv":[69.5803420919898,-18.6457452648911577,-61.1570367231747554],"rgb":[0.533333333333333326,0.66666666666666663,0.933333333333333348],"xyz":[0.39958186074167068,0.401557819048786235,0.8653708901214342],"hpluv":[253.044423586561948,116.600410917186778,69.5803420919898],"hsluv":[253.044423586561948,79.2673662112875093,69.5803420919898]},"#88aaff":{"lch":[70.3176511000829549,77.916964899147743,255.928474825822],"luv":[70.3176511000829549,-18.9441834980668631,-75.578907974954177],"rgb":[0.533333333333333326,0.66666666666666663,1],"xyz":[0.425752909151502046,0.412026238412718959,1.00320507841321604],"hpluv":[255.928474825822,140.607018245256825,70.3176511000829549],"hsluv":[255.928474825822,99.9999999999979394,70.3176511000829549]},"#332200":{"lch":[14.6681357538016819,18.4720509904151484,54.0318728094203635],"luv":[14.6681357538016819,10.8492842291989344,14.9502407842332925],"rgb":[0.2,0.133333333333333331,0],"xyz":[0.0193721251413763347,0.0184794126446342424,0.00254661690643579732],"hpluv":[54.0318728094203635,159.801011716648361,14.6681357538016819],"hsluv":[54.0318728094203635,100.000000000002359,14.6681357538016819]},"#332211":{"lch":[14.8903804788128475,14.003495227987683,44.8263438888978243],"luv":[14.8903804788128475,9.93193249146711,9.87190941941900668],"rgb":[0.2,0.133333333333333331,0.0666666666666666657],"xyz":[0.0203837906410134564,0.0188840788444890953,0.00787472187119143],"hpluv":[44.8263438888978243,119.33558852926538,14.8903804788128475],"hsluv":[44.8263438888978243,67.0844803779226595,14.8903804788128475]},"#332222":{"lch":[15.2941064614028619,8.70381909014442101,12.1770506300622809],"luv":[15.2941064614028619,8.50798716741232397,1.83592513820952408],"rgb":[0.2,0.133333333333333331,0.133333333333333331],"xyz":[0.0222591487794904751,0.0196342220998799166,0.0177516080671706253],"hpluv":[12.1770506300622809,72.2146104972558476,15.2941064614028619],"hsluv":[12.1770506300622809,16.9221215783466867,15.2941064614028619]},"#332233":{"lch":[15.9369990430381634,10.9638268591401484,307.7150129492465],"luv":[15.9369990430381634,6.70694938589646661,-8.67308072902737],"rgb":[0.2,0.133333333333333331,0.2],"xyz":[0.0253468995119482156,0.0208693223928630295,0.0340137619247817685],"hpluv":[307.7150129492465,87.2961214462547,15.9369990430381634],"hsluv":[307.7150129492465,30.2017993044426838,15.9369990430381634]},"#332244":{"lch":[16.8218835175385664,20.7382675483863608,283.478697838556343],"luv":[16.8218835175385664,4.83375477674434428,-20.1670661145035197],"rgb":[0.2,0.133333333333333331,0.266666666666666663],"xyz":[0.0298048947561670927,0.0226525204905506025,0.057492536877668407],"hpluv":[283.478697838556343,156.436171283708973,16.8218835175385664],"hsluv":[283.478697838556343,43.2894908809756558,16.8218835175385664]},"#332255":{"lch":[17.9355503164319856,31.8518286021958055,275.537546938931484],"luv":[17.9355503164319856,3.0736387963894658,-31.7031816992078603],"rgb":[0.2,0.133333333333333331,0.333333333333333315],"xyz":[0.0357673087955290847,0.0250374861062954354,0.0888945841516423224],"hpluv":[275.537546938931484,225.350740722061715,17.9355503164319856],"hsluv":[275.537546938931484,54.6600619512456092,17.9355503164319856]},"#332266":{"lch":[19.2543827660255502,42.9346801988288,271.988815040461645],"luv":[19.2543827660255502,1.49002234071320738,-42.9088172430781114],"rgb":[0.2,0.133333333333333331,0.4],"xyz":[0.043352304569037263,0.028071484415698747,0.12884222855878627],"hpluv":[271.988815040461645,282.955381276792764,19.2543827660255502],"hsluv":[271.988815040461645,63.8744485302889515,19.2543827660255502]},"#332277":{"lch":[20.7496984269819,53.7295137018198687,270.083996688769219],"luv":[20.7496984269819,0.0787684479011579453,-53.7294559637975908],"rgb":[0.2,0.133333333333333331,0.466666666666666674],"xyz":[0.0526663175892391755,0.0317970896237795633,0.17789603046518418],"hpluv":[270.083996688769219,328.579487011522247,20.7496984269819],"hsluv":[270.083996688769219,71.0892762838988546,20.7496984269819]},"#332288":{"lch":[22.3919640579388926,64.2366699579867,268.940142222195846],"luv":[22.3919640579388926,-1.18818265954209568,-64.2256801385464087],"rgb":[0.2,0.133333333333333331,0.533333333333333326],"xyz":[0.063806734691183,0.0362532564645571542,0.236568893868756347],"hpluv":[268.940142222195846,364.024117005976393,22.3919640579388926],"hsluv":[268.940142222195846,76.6637840765232426,22.3919640579388926]},"#332299":{"lch":[24.1535324867621668,74.5121507797046689,268.199285594367666],"luv":[24.1535324867621668,-2.34141182983712737,-74.4753543426316469],"rgb":[0.2,0.133333333333333331,0.6],"xyz":[0.076863698800255717,0.0414760421081863187,0.305335571509874282],"hpluv":[268.199285594367666,391.458538227207669,24.1535324867621668],"hsluv":[268.199285594367666,80.9654036049547301,24.1535324867621668]},"#3322aa":{"lch":[26.0100477302332607,84.6098540849434926,267.692459882235937],"luv":[26.0100477302332607,-3.40667075751279169,-84.541244387726735],"rgb":[0.2,0.133333333333333331,0.66666666666666663],"xyz":[0.0919213917655082591,0.0474991192942874202,0.384639421126872882],"hpluv":[267.692459882235937,412.780453116303818,26.0100477302332607],"hsluv":[267.692459882235937,84.3023702715129,26.0100477302332607]},"#3322bb":{"lch":[27.9408960039881222,94.5690254119923281,267.330995248517297],"luv":[27.9408960039881222,-4.40370835341661504,-94.4664380619492761],"rgb":[0.2,0.133333333333333331,0.733333333333333282],"xyz":[0.109058983872844906,0.0543541561372221788,0.474897406225514629],"hpluv":[267.330995248517297,429.484911570580266,27.9408960039881222],"hsluv":[267.330995248517297,86.9134730370406743,27.9408960039881222]},"#3322cc":{"lch":[29.9290875828623939,104.415306333233346,267.064581258752071],"luv":[29.9290875828623939,-5.34714045276937444,-104.278302084572317],"rgb":[0.2,0.133333333333333331,0.8],"xyz":[0.12835135931656666,0.0620711063147109804,0.576503916895784729],"hpluv":[267.064581258752071,442.700503900749,29.9290875828623939],"hsluv":[267.064581258752071,88.9774620844202389,29.9290875828623939]},"#3322dd":{"lch":[31.9608605817263296,114.164622106097937,266.862904678446171],"luv":[31.9608605817263296,-6.2476920173399213,-113.993540541052639],"rgb":[0.2,0.133333333333333331,0.866666666666666696],"xyz":[0.149869684867200204,0.0706784365349645144,0.689833764795790727],"hpluv":[266.862904678446171,453.265229710644405,31.9608605817263296],"hsluv":[266.862904678446171,90.6264253960307826,31.9608605817263296]},"#3322ee":{"lch":[34.0251904593745635,123.826689560879501,266.706806867468629],"luv":[34.0251904593745635,-7.11327635006579229,-123.622208147136817],"rgb":[0.2,0.133333333333333331,0.933333333333333348],"xyz":[0.173681865133374941,0.0802033086414345453,0.815244580864314],"hpluv":[266.706806867468629,461.799038215803307,34.0251904593745635],"hsluv":[266.706806867468629,93.6430785136650741,34.0251904593745635]},"#3322ff":{"lch":[36.1133053940478774,133.407509730883817,266.583697157343806],"luv":[36.1133053940478774,-7.94980801741223875,-133.170432923686747],"rgb":[0.2,0.133333333333333331,1],"xyz":[0.199852913543206334,0.0906717280053672414,0.953078769156095795],"hpluv":[266.583697157343806,468.761962088723578,36.1133053940478774],"hsluv":[266.583697157343806,99.999999999999531,36.1133053940478774]},"#aaaa00":{"lch":[67.4983691984715506,74.4102446110960472,85.8743202181747449],"luv":[67.4983691984715506,5.35340686476390193,74.217420717938225],"rgb":[0.66666666666666663,0.66666666666666663,0],"xyz":[0.309512896760441802,0.372958073182539818,0.0556842125390607443],"hpluv":[85.8743202181747449,139.887458074797593,67.4983691984715506],"hsluv":[85.8743202181747449,100.000000000002373,67.4983691984715506]},"#aaaa11":{"lch":[67.528557359020084,73.1276023311446863,85.8743202181746881],"luv":[67.528557359020084,5.26112782412359792,72.9381022286724345],"rgb":[0.66666666666666663,0.66666666666666663,0.0666666666666666657],"xyz":[0.310524562260078907,0.373362739382394671,0.061012317503816374],"hpluv":[85.8743202181746881,137.414698385368666,67.528557359020084],"hsluv":[85.8743202181746881,98.2323220941626118,67.528557359020084]},"#aaaa22":{"lch":[67.5844605157977,70.7729399531690575,85.8743202181746],"luv":[67.5844605157977,5.09172284764045369,70.589541633712912],"rgb":[0.66666666666666663,0.66666666666666663,0.133333333333333331],"xyz":[0.312399920398555964,0.374112882637785471,0.0708892036997955666],"hpluv":[85.8743202181746,132.880028295953878,67.5844605157977],"hsluv":[85.8743202181746,94.9906661574379854,67.5844605157977]},"#aaaa33":{"lch":[67.6763416895574181,66.9597491826677924,85.8743202181744607],"luv":[67.6763416895574181,4.81738479440415723,66.7862322215321882],"rgb":[0.66666666666666663,0.66666666666666663,0.2],"xyz":[0.315487671131013669,0.375347982930768598,0.0871513575574067167],"hpluv":[85.8743202181744607,125.549870841925909,67.6763416895574181],"hsluv":[85.8743202181744607,89.7506270896691376,67.6763416895574181]},"#aaaa44":{"lch":[67.8086418759902898,61.5895608625658824,85.8743202181741623],"luv":[67.8086418759902898,4.43102935143870269,61.429960004304057],"rgb":[0.66666666666666663,0.66666666666666663,0.266666666666666663],"xyz":[0.319945666375232585,0.377131181028456164,0.110630132510293355],"hpluv":[85.8743202181741623,115.255428047766188,67.8086418759902898],"hsluv":[85.8743202181741623,82.3915379076671854,67.8086418759902898]},"#aaaa55":{"lch":[67.9849384953625844,54.6449851984581514,85.8743202181737786],"luv":[67.9849384953625844,3.93140541890911,54.5033802508787772],"rgb":[0.66666666666666663,0.66666666666666663,0.333333333333333315],"xyz":[0.32590808041459457,0.379516146644201,0.142032179784267271],"hpluv":[85.8743202181737786,101.994541545207838,67.9849384953625844],"hsluv":[85.8743202181737786,72.9118556794948631,67.9849384953625844]},"#aaaa66":{"lch":[68.2081473948541515,46.1798212544818156,85.8743202181731675],"luv":[68.2081473948541515,3.32238354287766668,46.0601526125338268],"rgb":[0.66666666666666663,0.66666666666666663,0.4],"xyz":[0.333493076188102755,0.382550144953604343,0.181979824191411232],"hpluv":[85.8743202181731675,85.9122949373369806,68.2081473948541515],"hsluv":[85.8743202181731675,61.415294923296095,68.2081473948541515]},"#aaaa77":{"lch":[68.4806287458147551,36.3079853189649668,85.874320218171988],"luv":[68.4806287458147551,2.61215937225179973,36.2138981792368284],"rgb":[0.66666666666666663,0.66666666666666663,0.466666666666666674],"xyz":[0.342807089208304661,0.386275750161685139,0.231033626097809142],"hpluv":[85.874320218171988,67.2781031791916604,68.4806287458147551],"hsluv":[85.874320218171988,48.0944497134402909,68.4806287458147551]},"#aaaa88":{"lch":[68.804250183835336,25.1900382005990835,85.8743202181696574],"luv":[68.804250183835336,1.81228437202058101,25.1247616884732103],"rgb":[0.66666666666666663,0.66666666666666663,0.533333333333333326],"xyz":[0.353947506310248461,0.390731917002462736,0.289706489501381281],"hpluv":[85.8743202181696574,46.4571845078746506,68.804250183835336],"hsluv":[85.8743202181696574,33.210400093935057,68.804250183835336]},"#aaaa99":{"lch":[69.1804292601881485,13.0180161266067085,85.8743202181625236],"luv":[69.1804292601881485,0.936574490007753058,12.9842817320504498],"rgb":[0.66666666666666663,0.66666666666666663,0.6],"xyz":[0.36700447041932116,0.395954702646091894,0.358473167142499216],"hpluv":[85.8743202181625236,23.8781611725121081,69.1804292601881485],"hsluv":[85.8743202181625236,17.0695511242654057,69.1804292601881485]},"#aaaaaa":{"lch":[69.6101658300367916,3.6866289517569387e-12,0],"luv":[69.6101658300367916,3.46613397703382525e-12,1.25584564385283521e-12],"rgb":[0.66666666666666663,0.66666666666666663,0.66666666666666663],"xyz":[0.382062163384573716,0.401977779832193,0.437777016759497817],"hpluv":[0,6.72041492281092149e-12,69.6101658300367916],"hsluv":[0,4.48262290109626775e-12,69.6101658300367916]},"#aaaabb":{"lch":[70.0940699613229441,13.6540669730780309,265.874320218191428],"luv":[70.0940699613229441,-0.982334841759501587,-13.618684340418703],"rgb":[0.66666666666666663,0.66666666666666663,0.733333333333333282],"xyz":[0.399199755491910391,0.408832816675127775,0.528035001858139563],"hpluv":[265.874320218191428,24.7183841606301087,70.0940699613229441],"hsluv":[265.874320218191428,17.6184615311656536,70.0940699613229441]},"#aaaacc":{"lch":[70.6323884029978188,27.7441307883788433,265.87432021818438],"luv":[70.6323884029978188,-1.99603725260327192,-27.6722356973355303],"rgb":[0.66666666666666663,0.66666666666666663,0.8],"xyz":[0.41849213093563209,0.416549766852616576,0.629641512528409719],"hpluv":[265.87432021818438,49.8432735452352063,70.6323884029978188],"hsluv":[265.87432021818438,36.467826786828347,70.6323884029978188]},"#aaaadd":{"lch":[71.2250312240615813,42.0886841218373817,265.874320218182],"luv":[71.2250312240615813,-3.02804878123905441,-41.979617097899343],"rgb":[0.66666666666666663,0.66666666666666663,0.866666666666666696],"xyz":[0.440010456486265689,0.425157097072870083,0.742971360428415717],"hpluv":[265.874320218182,74.9845908684596,71.2250312240615813],"hsluv":[265.874320218182,56.4865697219014891,71.2250312240615813]},"#aaaaee":{"lch":[71.8715993709786432,56.5301989351418541,265.874320218180742],"luv":[71.8715993709786432,-4.0670361537863835,-56.3837087159979902],"rgb":[0.66666666666666663,0.66666666666666663,0.933333333333333348],"xyz":[0.463822636752440398,0.4346819691793401,0.86838217649693894],"hpluv":[265.874320218180742,99.8073514218055,71.8715993709786432],"hsluv":[265.874320218180742,77.6546881169827259,71.8715993709786432]},"#aaaaff":{"lch":[72.5714133442747595,70.9376272522327,265.87432021818006],"luv":[72.5714133442747595,-5.10357119085512778,-70.7538021683399],"rgb":[0.66666666666666663,0.66666666666666663,1],"xyz":[0.489993685162271819,0.445150388543272824,1.00621636478872079],"hpluv":[265.87432021818006,124.036757123492009,72.5714133442747595],"hsluv":[265.87432021818006,99.999999999997641,72.5714133442747595]},"#88bb00":{"lch":[70.0174964893220135,84.793654921948729,107.670265811619984],"luv":[70.0174964893220135,-25.7381496181260658,80.7930168347331659],"rgb":[0.533333333333333326,0.733333333333333282,0],"xyz":[0.279226618658270809,0.407742918869184512,0.0639910921330886],"hpluv":[107.670265811619984,153.672481251000221,70.0174964893220135],"hsluv":[107.670265811619984,100.000000000002288,70.0174964893220135]},"#88bb11":{"lch":[70.045943224524,83.6147085810298,107.921872667069366],"luv":[70.045943224524,-25.7299069713944561,79.5574721715938296],"rgb":[0.533333333333333326,0.733333333333333282,0.0666666666666666657],"xyz":[0.280238284157907913,0.408147585069039365,0.0693191970978442318],"hpluv":[107.921872667069366,151.474322676164348,70.045943224524],"hsluv":[107.921872667069366,98.3704135852689,70.045943224524]},"#88bb22":{"lch":[70.0986261940145567,81.4532385975490172,108.403169751544382],"luv":[70.0986261940145567,-25.7149121100318041,77.2876016784231],"rgb":[0.533333333333333326,0.733333333333333282,0.133333333333333331],"xyz":[0.28211364229638497,0.408897728324430165,0.0791960832938234244],"hpluv":[108.403169751544382,147.447759071005407,70.0986261940145567],"hsluv":[108.403169751544382,95.3794817356858431,70.0986261940145567]},"#88bb33":{"lch":[70.185227758130182,77.9617926087192643,109.240455548552404],"luv":[70.185227758130182,-25.6910124331637526,73.6071530961765887],"rgb":[0.533333333333333326,0.733333333333333282,0.2],"xyz":[0.285201393028842676,0.410132828617413292,0.0954582371514345607],"hpluv":[109.240455548552404,140.95335886915251,70.185227758130182],"hsluv":[109.240455548552404,90.5378353052476399,70.185227758130182]},"#88bb44":{"lch":[70.3099541281250708,73.067556170236557,110.558097475340105],"luv":[70.3099541281250708,-25.6581823155790048,68.4143657790612281],"rgb":[0.533333333333333326,0.733333333333333282,0.266666666666666663],"xyz":[0.289659388273061591,0.411916026715100858,0.118937012104321199],"hpluv":[110.558097475340105,131.870330314080604,70.3099541281250708],"hsluv":[110.558097475340105,83.7238240635208655,70.3099541281250708]},"#88bb55":{"lch":[70.4762099132372,66.7907607981454845,112.553407091589676],"luv":[70.4762099132372,-25.6172250438111178,61.682765089203194],"rgb":[0.533333333333333326,0.733333333333333282,0.333333333333333315],"xyz":[0.295621802312423576,0.414300992330845719,0.150339059378295115],"hpluv":[112.553407091589676,120.257778383662554,70.4762099132372],"hsluv":[112.553407091589676,74.9213657205140606,70.4762099132372]},"#88bb66":{"lch":[70.6867901559138687,59.2534136994931373,115.564788197424377],"luv":[70.6867901559138687,-25.56971066242372,53.4523800375924836],"rgb":[0.533333333333333326,0.733333333333333282,0.4],"xyz":[0.303206798085931761,0.417334990640249037,0.190286703785439076],"hpluv":[115.564788197424377,106.368844477737383,70.6867901559138687],"hsluv":[115.564788197424377,64.2082802413586791,70.6867901559138687]},"#88bb77":{"lch":[70.9439811929011483,50.7088031944788611,120.213509646437856],"luv":[70.9439811929011483,-25.5178724843925657,43.8203252530908287],"rgb":[0.533333333333333326,0.733333333333333282,0.466666666666666674],"xyz":[0.312520811106133667,0.421060595848329833,0.239340505691836986],"hpluv":[120.213509646437856,90.6999673798200519,70.9439811929011483],"hsluv":[120.213509646437856,51.7430673824667338,70.9439811929011483]},"#88bb88":{"lch":[71.2496205680497781,41.6266624709187667,127.715012949237462],"luv":[71.2496205680497781,-25.4644588867656232,32.9293237414924747],"rgb":[0.533333333333333326,0.733333333333333282,0.533333333333333326],"xyz":[0.323661228208077467,0.425516762689107431,0.298013369095409153],"hpluv":[127.715012949237462,74.1358655131278397,71.2496205680497781],"hsluv":[127.715012949237462,37.7483692132655,71.2496205680497781]},"#88bb99":{"lch":[71.605136773449729,32.9376822973712677,140.491872589160209],"luv":[71.605136773449729,-25.4125532319559895,20.9545473192710077],"rgb":[0.533333333333333326,0.733333333333333282,0.6],"xyz":[0.336718192317150167,0.430739548332736588,0.366780046736527088],"hpluv":[140.491872589160209,58.3697971606621948,71.605136773449729],"hsluv":[140.491872589160209,40.0947707109065163,71.605136773449729]},"#88bbaa":{"lch":[72.0115788449514298,26.624214972975043,162.310745910586235],"luv":[72.0115788449514298,-25.3653817896029707,8.0898843993512255],"rgb":[0.533333333333333326,0.733333333333333282,0.66666666666666663],"xyz":[0.351775885282402723,0.43676262551883771,0.446083896353525633],"hpluv":[162.310745910586235,46.9152251525928463,72.0115788449514298],"hsluv":[162.310745910586235,42.5902472855224445,72.0115788449514298]},"#88bbbb":{"lch":[72.4696411221425478,25.9090725846495289,192.177050630060563],"luv":[72.4696411221425478,-25.3261303787159093,-5.46508574835939687],"rgb":[0.533333333333333326,0.733333333333333282,0.733333333333333282],"xyz":[0.368913477389739397,0.443617662361772469,0.536341881452167435],"hpluv":[192.177050630060563,45.3664800039612786,72.4696411221425478],"hsluv":[192.177050630060563,45.1889022919971595,72.4696411221425478]},"#88bbcc":{"lch":[72.9796861172365539,31.9509756483125074,217.648879320727843],"luv":[72.9796861172365539,-25.297786835453639,-19.5163220435359541],"rgb":[0.533333333333333326,0.733333333333333282,0.8],"xyz":[0.388205852833461096,0.451334612539261271,0.637948392122437591],"hpluv":[217.648879320727843,55.5547835161394303,72.9796861172365539],"hsluv":[217.648879320727843,47.846459663484211,72.9796861172365539]},"#88bbdd":{"lch":[73.5417671198988501,42.2771793498237827,233.271065498294831],"luv":[73.5417671198988501,-25.2830202693059967,-33.8840490472881442],"rgb":[0.533333333333333326,0.733333333333333282,0.866666666666666696],"xyz":[0.409724178384094695,0.459941942759514777,0.751278240022443589],"hpluv":[233.271065498294831,72.9476439375157781,73.5417671198988501],"hsluv":[233.271065498294831,52.600286903313318,73.5417671198988501]},"#88bbee":{"lch":[74.1556513704433655,54.6140049995012049,242.42172167609948],"luv":[74.1556513704433655,-25.2841013367454792,-48.4087157615106349],"rgb":[0.533333333333333326,0.733333333333333282,0.933333333333333348],"xyz":[0.433536358650269404,0.469466814865984794,0.876689056090966812],"hpluv":[242.42172167609948,93.4542589851821646,74.1556513704433655],"hsluv":[242.42172167609948,75.5983078602269387,74.1556513704433655]},"#88bbff":{"lch":[74.8208441285393206,67.8489412305869877,248.103607922481928],"luv":[74.8208441285393206,-25.3028619495915343,-62.9543009116260492],"rgb":[0.533333333333333326,0.733333333333333282,1],"xyz":[0.459707407060100826,0.479935234229917518,1.01452324438274855],"hpluv":[248.103607922481928,115.069386567942303,74.8208441285393206],"hsluv":[248.103607922481928,99.9999999999973568,74.8208441285393206]},"#333300":{"lch":[20.3279441284931792,22.4095383785379596,85.8743202181747449],"luv":[20.3279441284931792,1.61224273913978733,22.3514671484727536],"rgb":[0.2,0.2,0],"xyz":[0.0254898472303871464,0.0307148568226560392,0.00458585760277267773],"hpluv":[85.8743202181747449,139.887458074797735,20.3279441284931792],"hsluv":[85.8743202181747449,100.000000000002458,20.3279441284931792]},"#333311":{"lch":[20.4867879892499971,17.9332091798965507,85.8743202181741],"luv":[20.4867879892499971,1.2901955319819518,17.8867377399899183],"rgb":[0.2,0.2,0.0666666666666666657],"xyz":[0.0265015127300242681,0.0311195230225108921,0.00991396256752831],"hpluv":[85.8743202181741,111.076827622251201,20.4867879892499971],"hsluv":[85.8743202181741,79.4044220625277717,20.4867879892499971]},"#333322":{"lch":[20.7776374982028358,10.4602453251552614,85.8743202181717749],"luv":[20.7776374982028358,0.752556982220839221,10.4331390411008691],"rgb":[0.2,0.2,0.133333333333333331],"xyz":[0.0283768708685012867,0.0318696662779017134,0.019790848763507507],"hpluv":[85.8743202181717749,63.8829601302186703,20.7776374982028358],"hsluv":[85.8743202181717749,45.6673964981637113,20.7776374982028358]},"#333333":{"lch":[21.246731294981295,1.12524964979295229e-12,0],"luv":[21.246731294981295,1.05794917113478783e-12,3.83314917077821647e-13],"rgb":[0.2,0.2,0.2],"xyz":[0.0314646216009590307,0.0331047665708848263,0.0360530026211186502],"hpluv":[0,6.72041492281092149e-12,21.246731294981295],"hsluv":[0,1.92419399944792236e-12,21.246731294981295]},"#333344":{"lch":[21.9038391599933462,12.2084714240410825,265.874320218182163],"luv":[21.9038391599933462,-0.878332211796974,-12.176834853004598],"rgb":[0.2,0.2,0.266666666666666663],"xyz":[0.0359226168451779043,0.0348879646685724,0.0595317775740052887],"hpluv":[265.874320218182163,70.7262082967351517,21.9038391599933462],"hsluv":[265.874320218182163,13.7757030029577514,21.9038391599933462]},"#333355":{"lch":[22.7485838486986935,25.0264321710322868,265.874320218179776],"luv":[22.7485838486986935,-1.80051382017376982,-24.9615796213830023],"rgb":[0.2,0.2,0.333333333333333315],"xyz":[0.0418850308845399,0.0372729302843172322,0.0909338248479792],"hpluv":[265.874320218179776,139.599512106194084,22.7485838486986935],"hsluv":[265.874320218179776,27.1905063829271256,22.7485838486986935]},"#333366":{"lch":[23.7726526978294,37.7235732610660364,265.874320218179],"luv":[23.7726526978294,-2.71400312032964841,-37.625817820292724],"rgb":[0.2,0.2,0.4],"xyz":[0.0494700266580480746,0.0403069285937205438,0.130881469255123173],"hpluv":[265.874320218179,201.360603518100845,23.7726526978294],"hsluv":[265.874320218179,39.2200280117306193,23.7726526978294]},"#333377":{"lch":[24.9621315786770737,49.9646270765614062,265.874320218178639],"luv":[24.9621315786770737,-3.59467945556105306,-49.8351506319748268],"rgb":[0.2,0.2,0.466666666666666674],"xyz":[0.0587840396782499941,0.0440325338018013601,0.179935271161521082],"hpluv":[265.874320218178639,253.992158426909725,24.9621315786770737],"hsluv":[265.874320218178639,49.4713434217918646,24.9621315786770737]},"#333388":{"lch":[26.2997861111378413,61.6680265106551175,265.874320218178468],"luv":[26.2997861111378413,-4.43667452222106906,-61.5082223194812912],"rgb":[0.2,0.2,0.533333333333333326],"xyz":[0.0699244567801938222,0.048488700642578958,0.238608134565093222],"hpluv":[265.874320218178468,297.541234413863208,26.2997861111378413],"hsluv":[265.874320218178468,57.953618257344317,26.2997861111378413]},"#333399":{"lch":[27.7670269025285634,72.8744236647892336,265.874320218178354],"luv":[27.7670269025285634,-5.24291301488723782,-72.6855796399362788],"rgb":[0.2,0.2,0.6],"xyz":[0.0829814208892665356,0.0537114862862081155,0.307374812206211157],"hpluv":[265.874320218178354,333.031319879373427,27.7670269025285634],"hsluv":[265.874320218178354,64.8662025552495862,27.7670269025285634]},"#3333aa":{"lch":[29.34539826905295,83.6653121043175361,265.874320218178241],"luv":[29.34539826905295,-6.01925794630032573,-83.4485049793509575],"rgb":[0.2,0.2,0.66666666666666663],"xyz":[0.0980391138545190777,0.059734563472309217,0.386678661823209757],"hpluv":[265.874320218178241,361.780166220798492,29.34539826905295],"hsluv":[265.874320218178241,70.4657614516561353,29.34539826905295]},"#3333bb":{"lch":[31.0175640968910713,94.1237197643615247,265.874320218178184],"luv":[31.0175640968910713,-6.77168271864664284,-93.8798111173964855],"rgb":[0.2,0.2,0.733333333333333282],"xyz":[0.115176705961855724,0.0665896003152439686,0.476936646921851504],"hpluv":[265.874320218178184,385.062051502536349,31.0175640968910713],"hsluv":[265.874320218178184,75.0004925607309758,31.0175640968910713]},"#3333cc":{"lch":[32.7678589751368321,104.319620441623087,265.874320218178127],"luv":[32.7678589751368321,-7.50522156082274261,-104.049290523324899],"rgb":[0.2,0.2,0.8],"xyz":[0.134469081405577451,0.0743065504927327702,0.578543157592121604],"hpluv":[265.874320218178127,403.977575952485893,32.7678589751368321],"hsluv":[265.874320218178127,79.524052836351089,32.7678589751368321]},"#3333dd":{"lch":[34.5825131799139243,114.307143948468337,265.874320218178127],"luv":[34.5825131799139243,-8.22376881440244745,-114.010932739554079],"rgb":[0.2,0.2,0.866666666666666696],"xyz":[0.155987406956211,0.0829138807129863,0.691873005492127602],"hpluv":[265.874320218178127,419.426773039758132,34.5825131799139243],"hsluv":[265.874320218178127,86.1542613798901584,34.5825131799139243]},"#3333ee":{"lch":[36.4496605331747929,124.126383834434506,265.87432021817807],"luv":[36.4496605331747929,-8.93020898923314732,-123.80472741871364],"rgb":[0.2,0.2,0.933333333333333348],"xyz":[0.179799587222385732,0.092438752819456349,0.817283821560650825],"hpluv":[265.87432021817807,432.12554656995303,36.4496605331747929],"hsluv":[265.87432021817807,92.9362870993519,36.4496605331747929]},"#3333ff":{"lch":[38.3592184432327414,133.806417871427385,265.87432021817807],"luv":[38.3592184432327414,-9.62663407069321231,-133.45967698167118],"rgb":[0.2,0.2,1],"xyz":[0.205970635632217125,0.102907172183389045,0.95511800985243267],"hpluv":[265.87432021817807,442.635784237250618,38.3592184432327414],"hsluv":[265.87432021817807,99.99999999999946,38.3592184432327414]},"#aabb00":{"lch":[72.2864137555308162,81.0402066187271686,93.9104624709461291],"luv":[72.2864137555308162,-5.52673715975233737,80.8515322376329664],"rgb":[0.66666666666666663,0.733333333333333282,0],"xyz":[0.343467394669040582,0.440867068999738376,0.0670023785085933632],"hpluv":[93.9104624709461291,142.260125307220505,72.2864137555308162],"hsluv":[93.9104624709461291,100.00000000000226,72.2864137555308162]},"#aabb11":{"lch":[72.3134178153803759,79.8795424406406198,94.0047051989067199],"luv":[72.3134178153803759,-5.5786590117117969,79.6845020324350912],"rgb":[0.66666666666666663,0.733333333333333282,0.0666666666666666657],"xyz":[0.344479060168677687,0.441271735199593229,0.072330483473349],"hpluv":[94.0047051989067199,140.170301198642704,72.3134178153803759],"hsluv":[94.0047051989067199,98.4998030851846522,72.3134178153803759]},"#aabb22":{"lch":[72.3634325080893319,77.7463008610920667,94.1853407287125179],"luv":[72.3634325080893319,-5.67416055225396132,77.5389656857163],"rgb":[0.66666666666666663,0.733333333333333282,0.133333333333333331],"xyz":[0.346354418307154743,0.44202187845498403,0.0822073696693281925],"hpluv":[94.1853407287125179,136.332658010127801,72.3634325080893319],"hsluv":[94.1853407287125179,95.7441801677588131,72.3634325080893319]},"#aabb33":{"lch":[72.4456578556837343,74.284969405898,94.5007685828256427],"luv":[72.4456578556837343,-5.82932493434540167,74.0558954469191377],"rgb":[0.66666666666666663,0.733333333333333282,0.2],"xyz":[0.349442169039612449,0.443256978747967156,0.0984695235269393288],"hpluv":[94.5007685828256427,130.115164427369336,72.4456578556837343],"hsluv":[94.5007685828256427,91.2774770665997721,72.4456578556837343]},"#aabb44":{"lch":[72.5641031469497193,69.3968632274838768,95.0004815565242922],"luv":[72.5641031469497193,-6.04891620231322502,69.1327363742496317],"rgb":[0.66666666666666663,0.733333333333333282,0.266666666666666663],"xyz":[0.353900164283831364,0.445040176845654722,0.121948298479825967],"hpluv":[95.0004815565242922,121.354905136961719,72.5641031469497193],"hsluv":[95.0004815565242922,84.978619462346515,72.5641031469497193]},"#aabb55":{"lch":[72.7220260779140659,63.0543258899363366,95.7659530899235705],"luv":[72.7220260779140659,-6.33475857174489843,62.7353078200147181],"rgb":[0.66666666666666663,0.733333333333333282,0.333333333333333315],"xyz":[0.359862578323193349,0.447425142461399583,0.153350345753799883],"hpluv":[95.7659530899235705,110.024206089370551,72.7220260779140659],"hsluv":[95.7659530899235705,76.8198788639563475,72.7220260779140659]},"#aabb66":{"lch":[72.922116394456026,55.2958006214329245,96.9449007941817342],"luv":[72.922116394456026,-6.68608027099689206,54.8900892418207675],"rgb":[0.66666666666666663,0.733333333333333282,0.4],"xyz":[0.367447574096701535,0.450459140770802902,0.193297990160943844],"hpluv":[96.9449007941817342,96.2215198645611167,72.922116394456026],"hsluv":[96.9449007941817342,66.8569788454327778,72.922116394456026]},"#aabb77":{"lch":[73.1665925415562555,46.2248747385797927,98.8352478745929801],"luv":[73.1665925415562555,-7.09985217623529596,45.6763740206356488],"rgb":[0.66666666666666663,0.733333333333333282,0.466666666666666674],"xyz":[0.37676158711690344,0.454184745978883697,0.242351792067341754],"hpluv":[98.8352478745929801,80.1682197570307267,73.1665925415562555],"hsluv":[98.8352478745929801,55.2184354086421223,73.1665925415562555]},"#aabb88":{"lch":[73.4572589636137,36.0214199172978056,102.133241078873],"luv":[73.4572589636137,-7.57119112276486117,35.2167539367396216],"rgb":[0.66666666666666663,0.733333333333333282,0.533333333333333326],"xyz":[0.387902004218847241,0.458640912819661295,0.301024655470913949],"hpluv":[102.133241078873,62.2250760292602862,73.4572589636137],"hsluv":[102.133241078873,42.0922357464751116,73.4572589636137]},"#aabb99":{"lch":[73.7955437608147236,25.0118273668521454,108.880774444702425],"luv":[73.7955437608147236,-8.09382587885112592,23.6660408786948082],"rgb":[0.66666666666666663,0.733333333333333282,0.6],"xyz":[0.40095896832792,0.463863698463290453,0.369791333112031828],"hpluv":[108.880774444702425,43.0085312761643337,73.7955437608147236],"hsluv":[108.880774444702425,27.7101400322224,73.7955437608147236]},"#aabbaa":{"lch":[74.1825262226786464,14.1574418893213867,127.715012949227386],"luv":[74.1825262226786464,-8.66059336811296632,11.1994322785447302],"rgb":[0.66666666666666663,0.733333333333333282,0.66666666666666663],"xyz":[0.416016661293172496,0.469886775649391575,0.449095182729030429],"hpluv":[127.715012949227386,24.2171200924073027,74.1825262226786464],"hsluv":[127.715012949227386,12.3308304853939106,74.1825262226786464]},"#aabbbb":{"lch":[74.6189593067414734,9.47715438031144153,192.177050630059],"luv":[74.6189593067414734,-9.26392276955498417,-1.99904729008021675],"rgb":[0.66666666666666663,0.733333333333333282,0.733333333333333282],"xyz":[0.43315425340050917,0.476741812492326333,0.539353167827672175],"hpluv":[192.177050630059,16.1164020856357908,74.6189593067414734],"hsluv":[192.177050630059,16.0533177597809029,74.6189593067414734]},"#aabbcc":{"lch":[75.1052899078477623,18.5983929047544514,237.852316168687679],"luv":[75.1052899078477623,-9.89626817417043547,-15.7468757175676597],"rgb":[0.66666666666666663,0.733333333333333282,0.8],"xyz":[0.452446628844230925,0.484458762669815135,0.640959678497942331],"hpluv":[237.852316168687679,31.4227520087917149,75.1052899078477623],"hsluv":[237.852316168687679,25.8004515395991127,75.1052899078477623]},"#aabbdd":{"lch":[75.6416785331857682,31.6798915222297,250.547006926215033],"luv":[75.6416785331857682,-10.5504613433008458,-29.8714461033234144],"rgb":[0.66666666666666663,0.733333333333333282,0.866666666666666696],"xyz":[0.473964954394864413,0.493066092890068641,0.754289526397948329],"hpluv":[250.547006926215033,53.1449318902714438,75.6416785331857682],"hsluv":[250.547006926215033,48.9122949421499484,75.6416785331857682]},"#aabbee":{"lch":[76.2280192594463699,45.6175545861468166,255.761586302643195],"luv":[76.2280192594463699,-11.2199701465387403,-44.2162137267639],"rgb":[0.66666666666666663,0.733333333333333282,0.933333333333333348],"xyz":[0.497777134661039178,0.502590964996538658,0.879700342466471552],"hpluv":[255.761586302643195,76.8288153841444483,76.2280192594463699],"hsluv":[255.761586302643195,73.6249760737912311,76.2280192594463699]},"#aabbff":{"lch":[76.863960378353255,59.8395450787859247,258.530312903596609],"luv":[76.863960378353255,-11.8990616804050067,-58.6445520603744583],"rgb":[0.66666666666666663,0.733333333333333282,1],"xyz":[0.523948183070870543,0.513059384360471382,1.01753453075825329],"hpluv":[258.530312903596609,104.151140840900069,76.863960378353255],"hsluv":[258.530312903596609,99.9999999999969305,76.863960378353255]},"#88cc00":{"lch":[75.0884647575288,93.9986167747887,111.475410134903882],"luv":[75.0884647575288,-34.413070492851,87.4727416674912348],"rgb":[0.533333333333333326,0.8,0],"xyz":[0.317450361967887784,0.484190405488419406,0.0767323399029605363],"hpluv":[111.475410134903882,158.85012628624969,75.0884647575288],"hsluv":[111.475410134903882,100.000000000002288,75.0884647575288]},"#88cc11":{"lch":[75.1138336746799,92.9472917959209752,111.713770271434171],"luv":[75.1138336746799,-34.3877142984514421,86.3520941119794685],"rgb":[0.533333333333333326,0.8,0.0666666666666666657],"xyz":[0.318462027467524889,0.484595071688274259,0.082060444867716173],"hpluv":[111.713770271434171,157.020421425354783,75.1138336746799],"hsluv":[111.713770271434171,98.6248626695712289,75.1138336746799]},"#88cc22":{"lch":[75.1608235532889495,91.0175657840787551,112.166724150973],"luv":[75.1608235532889495,-34.3412008388942667,84.2904455214339805],"rgb":[0.533333333333333326,0.8,0.133333333333333331],"xyz":[0.320337385606001945,0.48534521494366506,0.0919373310636953656],"hpluv":[112.166724150973,153.664310911800271,75.1608235532889495],"hsluv":[112.166724150973,96.0970283406349,75.1608235532889495]},"#88cc33":{"lch":[75.2380863503033908,87.8942550668024865,112.94545296029041],"luv":[75.2380863503033908,-34.2659803117460342,80.9397471396048331],"rgb":[0.533333333333333326,0.8,0.2],"xyz":[0.323425136338459651,0.486580315236648187,0.108199484921306516],"hpluv":[112.94545296029041,148.2388630129999,75.2380863503033908],"hsluv":[112.94545296029041,91.9942509365254324,75.2380863503033908]},"#88cc44":{"lch":[75.3494055810326415,83.5027286146262,114.147802574759467],"luv":[75.3494055810326415,-34.1602904869016655,76.1956707427555244],"rgb":[0.533333333333333326,0.8,0.266666666666666663],"xyz":[0.327883131582678566,0.488363513334335753,0.131678259874193154],"hpluv":[114.147802574759467,140.624231819797672,75.3494055810326415],"hsluv":[114.147802574759467,86.1974134191241177,75.3494055810326415]},"#88cc55":{"lch":[75.4978684165763241,77.8461227965530469,115.917002828128631],"luv":[75.4978684165763241,-34.0241050685150555,70.0169915716368365],"rgb":[0.533333333333333326,0.8,0.333333333333333315],"xyz":[0.333845545622040552,0.490748478950080613,0.16308030714816707],"hpluv":[115.917002828128631,130.840327774204638,75.4978684165763241],"hsluv":[115.917002828128631,78.6694108520956092,75.4978684165763241]},"#88cc66":{"lch":[75.6860396561484663,71.0106875190110287,118.477611184333398],"luv":[75.6860396561484663,-33.8589835890750237,62.4186428259808963],"rgb":[0.533333333333333326,0.8,0.4],"xyz":[0.341430541395548737,0.493782477259483932,0.203027951555311],"hpluv":[118.477611184333398,119.054896833398359,75.6860396561484663],"hsluv":[118.477611184333398,69.4467240035668141,75.6860396561484663]},"#88cc77":{"lch":[75.9160535408259705,63.1826013081171638,122.199343200922883],"luv":[75.9160535408259705,-33.6678964132470924,53.4650713940171656],"rgb":[0.533333333333333326,0.8,0.466666666666666674],"xyz":[0.350744554415750642,0.497508082467564727,0.252081753461708913],"hpluv":[122.199343200922883,105.609553255175555,75.9160535408259705],"hsluv":[122.199343200922883,58.6308874961384063,75.9160535408259705]},"#88cc88":{"lch":[76.1896681333118124,54.6887581458639929,127.715012949238314],"luv":[76.1896681333118124,-33.4549913615237,43.2622678616965288],"rgb":[0.533333333333333326,0.8,0.533333333333333326],"xyz":[0.361884971517694443,0.50196424930834227,0.310754616865281108],"hpluv":[127.715012949238314,91.92606633748386,76.1896681333118124],"hsluv":[127.715012949238314,46.3779062484352878,76.1896681333118124]},"#88cc99":{"lch":[76.5083007543168492,46.0935908553499587,136.122445502284393],"luv":[76.5083007543168492,-33.2253063874269188,31.9483666781575764],"rgb":[0.533333333333333326,0.8,0.6],"xyz":[0.374941935626767142,0.507187034951971483,0.379521294506399],"hpluv":[136.122445502284393,78.7570782006024643,76.5083007543168492],"hsluv":[136.122445502284393,48.1280089891728622,76.5083007543168492]},"#88ccaa":{"lch":[76.8730534179438223,38.4110576559043437,149.173477570542047],"luv":[76.8730534179438223,-32.9844501501569098,19.6833787378341469],"rgb":[0.533333333333333326,0.8,0.66666666666666663],"xyz":[0.389999628592019698,0.513210112138072549,0.458825144123397588],"hpluv":[149.173477570542047,66.8865090410736229,76.8730534179438223],"hsluv":[149.173477570542047,50.0095890879800891,76.8730534179438223]},"#88ccbb":{"lch":[77.2847330465352087,33.404634806871222,168.536638924911273],"luv":[77.2847330465352087,-32.73827895277973,6.638879257104497],"rgb":[0.533333333333333326,0.8,0.733333333333333282],"xyz":[0.407137220699356372,0.520065148981007308,0.54908312922203939],"hpluv":[168.536638924911273,59.444025112992847,77.2847330465352087],"hsluv":[168.536638924911273,51.9915664660802292,77.2847330465352087]},"#88cccc":{"lch":[77.7438691793350074,33.2404934388306,192.177050630060876],"luv":[77.7438691793350074,-32.4925976386916417,-7.01152642061846443],"rgb":[0.533333333333333326,0.8,0.8],"xyz":[0.426429596143078071,0.527782099158496165,0.650689639892309546],"hpluv":[192.177050630060876,60.6231146417445359,77.7438691793350074],"hsluv":[192.177050630060876,54.0427382519684585,77.7438691793350074]},"#88ccdd":{"lch":[78.2507307533704,38.5418325774740964,213.193277164244591],"luv":[78.2507307533704,-32.2529061156020589,-21.1003058159876602],"rgb":[0.533333333333333326,0.8,0.866666666666666696],"xyz":[0.44794792169371167,0.536389429378749671,0.764019487792315544],"hpluv":[213.193277164244591,72.2588367593471759,78.2507307533704],"hsluv":[213.193277164244591,56.1332045791076126,78.2507307533704]},"#88ccee":{"lch":[78.8053428571366368,47.78945312574524,227.924421751618695],"luv":[78.8053428571366368,-32.0242046898233,-35.4722728908382834],"rgb":[0.533333333333333326,0.8,0.933333333333333348],"xyz":[0.47176010195988638,0.545914301485219688,0.889430303860838767],"hpluv":[227.924421751618695,92.3999074491721473,78.8053428571366368],"hsluv":[227.924421751618695,70.4270935368067796,78.8053428571366368]},"#88ccff":{"lch":[79.4075039272108114,59.2521837878726885,237.529017152572294],"luv":[79.4075039272108114,-31.8108626015509195,-49.9889018100727327],"rgb":[0.533333333333333326,0.8,1],"xyz":[0.497931150369717801,0.556382720849152412,1.02726449215262061],"hpluv":[237.529017152572294,118.549697277888072,79.4075039272108114],"hsluv":[237.529017152572294,99.999999999996561,79.4075039272108114]},"#334400":{"lch":[26.2681529832905483,31.0251081485104194,104.276907196552472],"luv":[26.2681529832905483,-7.65105337509169647,30.0669040288198879],"rgb":[0.2,0.266666666666666663,0],"xyz":[0.034322417713353183,0.0483799977885883553,0.00753004776376127276],"hpluv":[104.276907196552472,149.872894059772364,26.2681529832905483],"hsluv":[104.276907196552472,100.000000000002302,26.2681529832905483]},"#334411":{"lch":[26.3856741683463127,27.3886432490873446,106.295788944443402],"luv":[26.3856741683463127,-7.68514827558869662,26.2883296351821087],"rgb":[0.2,0.266666666666666663,0.0666666666666666657],"xyz":[0.0353340832129903082,0.0487846639884432082,0.0128581527285169042],"hpluv":[106.295788944443402,131.716945387015755,26.3856741683463127],"hsluv":[106.295788944443402,86.6296124974134614,26.3856741683463127]},"#334422":{"lch":[26.6018195362025054,21.2226436820006832,111.412237748000109],"luv":[26.6018195362025054,-7.74787020962619799,19.7578114189793403],"rgb":[0.2,0.266666666666666663,0.133333333333333331],"xyz":[0.0372094413514673233,0.0495348072438340295,0.0227350389244961],"hpluv":[111.412237748000109,101.234249163259577,26.6018195362025054],"hsluv":[111.412237748000109,63.7673799144094,26.6018195362025054]},"#334433":{"lch":[26.9529945323855813,12.8320575385027151,127.715012949236225],"luv":[26.9529945323855813,-7.8498102472204323,10.150969399721264],"rgb":[0.2,0.266666666666666663,0.2],"xyz":[0.0402971920839250639,0.0507699075368171424,0.038997192782107247],"hpluv":[127.715012949236225,60.4127494816677171,26.9529945323855813],"hsluv":[127.715012949236225,30.7608572023581708,26.9529945323855813]},"#334444":{"lch":[27.4501004194092673,8.17817622085537721,192.177050630060421],"luv":[27.4501004194092673,-7.99417102070306651,-1.72504956193021397],"rgb":[0.2,0.266666666666666663,0.266666666666666663],"xyz":[0.0447551873281439444,0.0525531056345047154,0.0624759677349938855],"hpluv":[192.177050630060421,37.8052272806132379,27.4501004194092673],"hsluv":[192.177050630060421,37.6572465300637518,27.4501004194092673]},"#334455":{"lch":[28.0976851129048839,16.9879579660521678,241.20654356816641],"luv":[28.0976851129048839,-8.1823109542023289,-14.8875956186718064],"rgb":[0.2,0.266666666666666663,0.333333333333333315],"xyz":[0.0507176013675059364,0.0549380712502495483,0.0938780150089678],"hpluv":[241.20654356816641,76.720241835207986,28.0976851129048839],"hsluv":[241.20654356816641,44.9859363973003568,28.0976851129048839]},"#334466":{"lch":[28.8949601880565652,29.7043747380071501,253.545194757545516],"luv":[28.8949601880565652,-8.41402976058801855,-28.487786536758108],"rgb":[0.2,0.266666666666666663,0.4],"xyz":[0.0583025971410141147,0.0579720695596528598,0.133825659416111742],"hpluv":[253.545194757545516,130.448064952476017,28.8949601880565652],"hsluv":[253.545194757545516,52.1427730716471629,28.8949601880565652]},"#334477":{"lch":[29.8367962202096138,42.8398018741040758,258.299336276781332],"luv":[29.8367962202096138,-8.68785350705267589,-41.9496105590085691],"rgb":[0.2,0.266666666666666663,0.466666666666666674],"xyz":[0.0676166101612160342,0.0616976747677336762,0.182879461322509651],"hpluv":[258.299336276781332,182.19421868795277,29.8367962202096138],"hsluv":[258.299336276781332,58.7347196438674857,29.8367962202096138]},"#334488":{"lch":[30.9147794404111025,55.6960507233291082,260.699324576281469],"luv":[30.9147794404111025,-9.00134255207500189,-54.9638599302837605],"rgb":[0.2,0.266666666666666663,0.533333333333333326],"xyz":[0.0787570272631598622,0.066153841608511274,0.241552324726081818],"hpluv":[260.699324576281469,228.611238042833349,30.9147794404111025],"hsluv":[260.699324576281469,64.5716173949788583,30.9147794404111025]},"#334499":{"lch":[32.1182691124294664,68.0605660836803281,262.102678541403236],"luv":[32.1182691124294664,-9.35140200670356769,-67.4150720250304],"rgb":[0.2,0.266666666666666663,0.6],"xyz":[0.0918139913722325618,0.0713766272521404316,0.310319002367199726],"hpluv":[262.102678541403236,268.895014901030436,32.1182691124294664],"hsluv":[262.102678541403236,69.6097770986353623,32.1182691124294664]},"#3344aa":{"lch":[33.435366318838156,79.8975403264742852,263.001802037450773],"luv":[33.435366318838156,-9.73456660877536528,-79.3023023824649158],"rgb":[0.2,0.266666666666666663,0.66666666666666663],"xyz":[0.106871684337485118,0.07739970443824154,0.389622851984198326],"hpluv":[263.001802037450773,303.226149032408784,33.435366318838156],"hsluv":[263.001802037450773,73.891501645941716,33.435366318838156]},"#3344bb":{"lch":[34.8537252521307721,91.2457354427413492,263.615054402289786],"luv":[34.8537252521307721,-10.1472390443123768,-90.6797539490724773],"rgb":[0.2,0.266666666666666663,0.733333333333333282],"xyz":[0.124009276444821764,0.0842547412811763,0.479880837082840073],"hpluv":[263.615054402289786,332.202349056841342,34.8537252521307721],"hsluv":[263.615054402289786,77.4995146205371412,34.8537252521307721]},"#3344cc":{"lch":[36.3611746115969083,102.170263494902102,264.052905077601281],"luv":[36.3611746115969083,-10.5858721727669973,-101.620382074461631],"rgb":[0.2,0.266666666666666663,0.8],"xyz":[0.143301651888543491,0.0919716914586651,0.581487347753110284],"hpluv":[264.052905077601281,356.55451128807033,36.3611746115969083],"hsluv":[264.052905077601281,80.5286468598271767,36.3611746115969083]},"#3344dd":{"lch":[37.9461503215655611,112.73940211649635,264.376684246138268],"luv":[37.9461503215655611,-11.0470957042534899,-112.196855865421313],"rgb":[0.2,0.266666666666666663,0.866666666666666696],"xyz":[0.164819977439177034,0.100579021678918634,0.694817195653116282],"hpluv":[264.376684246138268,377.005191833442723,37.9461503215655611],"hsluv":[264.376684246138268,84.1625325255073,37.9461503215655611]},"#3344ee":{"lch":[39.5979632159824462,123.014623823289881,264.622878978329823],"luv":[39.5979632159824462,-11.5277944422180187,-122.473293536523641],"rgb":[0.2,0.266666666666666663,0.933333333333333348],"xyz":[0.188632157705351772,0.110103893785388651,0.820228011721639505],"hpluv":[264.622878978329823,394.205992168221826,39.5979632159824462],"hsluv":[264.622878978329823,91.9832832027675664,39.5979632159824462]},"#3344ff":{"lch":[41.3069357297154482,133.047388274610427,264.814390787746049],"luv":[41.3069357297154482,-12.0251481753234213,-132.502842754623401],"rgb":[0.2,0.266666666666666663,1],"xyz":[0.214803206115183165,0.120572313149321361,0.95806220001342135],"hpluv":[264.814390787746049,408.716999433792864,41.3069357297154482],"hsluv":[264.814390787746049,99.9999999999994458,41.3069357297154482]},"#aacc00":{"lch":[77.1199831352121,88.8460909387721,100.173289143969555],"luv":[77.1199831352121,-15.692520471132994,87.4492577233428108],"rgb":[0.66666666666666663,0.8,0],"xyz":[0.381691137978657502,0.517314555618973326,0.0797436262784653],"hpluv":[100.173289143969555,156.730643533439519,77.1199831352121],"hsluv":[100.173289143969555,100.000000000002373,77.1199831352121]},"#aacc11":{"lch":[77.1442576556984676,87.800209961997254,100.311366942902],"luv":[77.1442576556984676,-15.7160097521192821,86.3821967007212237],"rgb":[0.66666666666666663,0.8,0.0666666666666666657],"xyz":[0.382702803478294606,0.517719221818828235,0.085071731243220941],"hpluv":[100.311366942902,155.08420894585916,77.1442576556984676],"hsluv":[100.311366942902,98.7181568051142,77.1442576556984676]},"#aacc22":{"lch":[77.1892227090432641,85.8765024717939411,100.574350259733862],"luv":[77.1892227090432641,-15.7593085348968636,84.4181134075499102],"rgb":[0.66666666666666663,0.8,0.133333333333333331],"xyz":[0.384578161616771663,0.518469365074219,0.0949486174392001336],"hpluv":[100.574350259733862,152.047171814071362,77.1892227090432641],"hsluv":[100.574350259733862,96.3604791744028404,77.1892227090432641]},"#aacc33":{"lch":[77.2631626362465482,82.7513779572315116,101.028364552392574],"luv":[77.2631626362465482,-15.8299191574657527,81.2231753460099668],"rgb":[0.66666666666666663,0.8,0.2],"xyz":[0.387665912349229369,0.519704465367202162,0.111210771296811284],"hpluv":[101.028364552392574,147.088857703341773,77.2631626362465482],"hsluv":[101.028364552392574,92.5301726329619,77.2631626362465482]},"#aacc44":{"lch":[77.3697083481362569,78.3307208035327278,101.734312614214147],"luv":[77.3697083481362569,-15.9304072801298968,76.6937021240348],"rgb":[0.66666666666666663,0.8,0.266666666666666663],"xyz":[0.392123907593448284,0.521487663464889728,0.134689546249697922],"hpluv":[101.734312614214147,140.021584702469511,77.3697083481362569],"hsluv":[101.734312614214147,87.1104907412273377,77.3697083481362569]},"#aacc55":{"lch":[77.5118305539362495,72.5836718124644875,102.784946304826448],"luv":[77.5118305539362495,-16.0622064150904862,70.7841432727597493],"rgb":[0.66666666666666663,0.8,0.333333333333333315],"xyz":[0.398086321632810269,0.523872629080634478,0.16609159352367181],"hpluv":[102.784946304826448,130.736122666873541,77.5118305539362495],"hsluv":[102.784946304826448,80.0585735006639,77.5118305539362495]},"#aacc66":{"lch":[77.6920071630818114,65.5409770618580865,104.333567867024144],"luv":[77.6920071630818114,-16.225762577214013,63.5007425390513731],"rgb":[0.66666666666666663,0.8,0.4],"xyz":[0.405671317406318455,0.526906627390037796,0.2060392379308158],"hpluv":[104.333567867024144,119.198186871977654,77.6920071630818114],"hsluv":[104.333567867024144,71.3979720959128,77.6920071630818114]},"#aacc77":{"lch":[77.912311817127474,57.2990991241466574,106.653185897117098],"luv":[77.912311817127474,-16.4206512214041886,54.8958010589496865],"rgb":[0.66666666666666663,0.8,0.466666666666666674],"xyz":[0.41498533042652036,0.530632232598118647,0.255093039837213709],"hpluv":[106.653185897117098,105.457526508453554,77.912311817127474],"hsluv":[106.653185897117098,61.2114900666368769,77.912311817127474]},"#aacc88":{"lch":[78.1744663257663,48.0371110011961946,110.274462486898784],"luv":[78.1744663257663,-16.6457037997795574,45.0608985524173633],"rgb":[0.66666666666666663,0.8,0.533333333333333326],"xyz":[0.42612574752846416,0.53508839943889619,0.313765903240785848],"hpluv":[110.274462486898784,89.6844859178180513,78.1744663257663],"hsluv":[110.274462486898784,49.6324036967210418,78.1744663257663]},"#aacc99":{"lch":[78.4798746855988583,38.0746183254558517,116.349336294343573],"luv":[78.4798746855988583,-16.8991518201031816,34.1188397866961779],"rgb":[0.66666666666666663,0.8,0.6],"xyz":[0.43918271163753686,0.540311185082525403,0.382532580881903783],"hpluv":[116.349336294343573,72.2917022308792383,78.4798746855988583],"hsluv":[116.349336294343573,36.8338589582570535,78.4798746855988583]},"#aaccaa":{"lch":[78.8296472340984593,28.0820980315160789,127.715012949234293],"luv":[78.8296472340984593,-17.1787837008838338,22.2147163027108476],"rgb":[0.66666666666666663,0.8,0.66666666666666663],"xyz":[0.454240404602789416,0.546334262268626469,0.461836430498902384],"hpluv":[127.715012949234293,54.3703242245777503,78.8296472340984593],"hsluv":[127.715012949234293,23.0170216670413055,78.8296472340984593]},"#aaccbb":{"lch":[79.2246195207133,19.8998018903229301,151.462718702096396],"luv":[79.2246195207133,-17.4821042808439238,9.50674209115818236],"rgb":[0.66666666666666663,0.8,0.733333333333333282],"xyz":[0.47137799671012609,0.553189299111561228,0.55209441559754413],"hpluv":[151.462718702096396,39.3999249764932173,79.2246195207133],"hsluv":[151.462718702096396,25.9022649263565761,79.2246195207133]},"#aacccc":{"lch":[79.665368512397464,18.216345023755192,192.177050630059796],"luv":[79.665368512397464,-17.80648564660072,-3.84243346616347603],"rgb":[0.66666666666666663,0.8,0.8],"xyz":[0.490670372153847789,0.560906249289050085,0.653700926267814286],"hpluv":[192.177050630059796,36.9937893704297878,79.665368512397464],"hsluv":[192.177050630059796,28.9019874878943099,79.665368512397464]},"#aaccdd":{"lch":[80.1522276755556504,25.332665849504842,224.238778454296437],"luv":[80.1522276755556504,-18.1492995031005968,-17.6733382978265112],"rgb":[0.66666666666666663,0.8,0.866666666666666696],"xyz":[0.512188697704481388,0.569513579509303591,0.767030774167820284],"hpluv":[224.238778454296437,52.9363308364733882,80.1522276755556504],"hsluv":[224.238778454296437,37.9969627853472787,80.1522276755556504]},"#aaccee":{"lch":[80.6853018377357216,36.8247992939862954,239.828051209207672],"luv":[80.6853018377357216,-18.5080244281037345,-31.8358112007702587],"rgb":[0.66666666666666663,0.8,0.933333333333333348],"xyz":[0.536000877970656098,0.579038451615773608,0.892441590236343507],"hpluv":[239.828051209207672,79.4490805971393854,80.6853018377357216],"hsluv":[239.828051209207672,67.7857500876551313,80.6853018377357216]},"#aaccff":{"lch":[81.2644823279674284,49.9029399741520834,247.769045833277914],"luv":[81.2644823279674284,-18.8803249793402337,-46.1934708236816434],"rgb":[0.66666666666666663,0.8,1],"xyz":[0.562171926380487519,0.589506870979706332,1.03027577852812535],"hpluv":[247.769045833277914,111.562078640814406,81.2644823279674284],"hsluv":[247.769045833277914,99.9999999999962625,81.2644823279674284]},"#88dd00":{"lch":[80.1491214608994085,103.252993693735874,114.339076779275487],"luv":[80.1491214608994085,-42.5542610136121837,94.0761158653142218],"rgb":[0.533333333333333326,0.866666666666666696,0],"xyz":[0.360084352515062933,0.569458386582770926,0.0909436700853518548],"hpluv":[114.339076779275487,215.722602995807392,80.1491214608994085],"hsluv":[114.339076779275487,100.000000000002288,80.1491214608994085]},"#88dd11":{"lch":[80.1718911006532551,102.308936337717924,114.55620444532569],"luv":[80.1718911006532551,-42.518128048011647,93.0555062414261727],"rgb":[0.533333333333333326,0.866666666666666696,0.0666666666666666657],"xyz":[0.361096018014700038,0.569863052782625834,0.0962717750501074915],"hpluv":[114.55620444532569,214.038948901986089,80.1718911006532551],"hsluv":[114.55620444532569,98.8288322371321186,80.1718911006532551]},"#88dd22":{"lch":[80.2140714473537315,100.574216022873557,114.966813202702411],"luv":[80.2140714473537315,-42.4516967311958453,91.1757992740300125],"rgb":[0.533333333333333326,0.866666666666666696,0.133333333333333331],"xyz":[0.362971376153177094,0.570613196038016635,0.106148661246086684],"hpluv":[114.966813202702411,210.937294411552,80.2140714473537315],"hsluv":[114.966813202702411,96.6732644510524,80.2140714473537315]},"#88dd33":{"lch":[80.283440325316,97.7612202004146695,115.666709499512805],"luv":[80.283440325316,-42.3438510501166832,88.1150069699792908],"rgb":[0.533333333333333326,0.866666666666666696,0.2],"xyz":[0.3660591268856348,0.571848296330999761,0.122410815103697834],"hpluv":[115.666709499512805,205.88559104418357,80.283440325316],"hsluv":[115.666709499512805,93.1672856447162303,80.283440325316]},"#88dd44":{"lch":[80.3834168948860821,93.7943752395521,116.732715571790365],"luv":[80.3834168948860821,-42.1914333437924896,83.7691338081886698],"rgb":[0.533333333333333326,0.866666666666666696,0.266666666666666663],"xyz":[0.370517122129853715,0.573631494428687327,0.145889590056584473],"hpluv":[116.732715571790365,198.714220363605108,80.3834168948860821],"hsluv":[116.732715571790365,88.1979852499996184,80.3834168948860821]},"#88dd55":{"lch":[80.5168087418625475,88.6629430887769,118.270203219525229],"luv":[80.5168087418625475,-41.9934519908601374,78.0875628192801088],"rgb":[0.533333333333333326,0.866666666666666696,0.333333333333333315],"xyz":[0.376479536169215701,0.576016460044432077,0.17729163733055836],"hpluv":[118.270203219525229,189.352414361266369,80.5168087418625475],"hsluv":[118.270203219525229,81.7170886524359474,80.5168087418625475]},"#88dd66":{"lch":[80.6859701106092757,82.4238546620344437,120.433562333743893],"luv":[80.6859701106092757,-41.7508898851674672,71.0672569552589266],"rgb":[0.533333333333333326,0.866666666666666696,0.4],"xyz":[0.384064531942723886,0.579050458353835396,0.21723928173770235],"hpluv":[120.433562333743893,177.835721711884361,80.6859701106092757],"hsluv":[120.433562333743893,73.7344666622195604,80.6859701106092757]},"#88dd77":{"lch":[80.8928858528116734,75.2114908165065827,123.458458278308711],"luv":[80.8928858528116734,-41.4665196955592208,62.7478772165182832],"rgb":[0.533333333333333326,0.866666666666666696,0.466666666666666674],"xyz":[0.393378544962925791,0.582776063561916247,0.266293083644100259],"hpluv":[123.458458278308711,164.332036041008877,80.8928858528116734],"hsluv":[123.458458278308711,64.312379996729149,80.8928858528116734]},"#88dd88":{"lch":[81.1392211885512,67.2590471315356524,127.71501294923884],"luv":[81.1392211885512,-41.1446687958856145,53.2061617739807531],"rgb":[0.533333333333333326,0.866666666666666696,0.533333333333333326],"xyz":[0.404518962064869592,0.587232230402693789,0.324965947047672399],"hpluv":[127.71501294923884,149.199726190229825,81.1392211885512],"hsluv":[127.71501294923884,53.5585775308776633,81.1392211885512]},"#88dd99":{"lch":[81.4263538436063072,58.943488890057,133.791370377408185],"luv":[81.4263538436063072,-40.7909253788266,42.5492102073736831],"rgb":[0.533333333333333326,0.866666666666666696,0.6],"xyz":[0.417575926173942347,0.592455016046323,0.393732624688790334],"hpluv":[133.791370377408185,133.11083868071384,81.4263538436063072],"hsluv":[133.791370377408185,54.8771054313611515,81.4263538436063072]},"#88ddaa":{"lch":[81.7553965772464437,50.8758256364689956,142.591286230634154],"luv":[81.7553965772464437,-40.4117997418374131,30.906893661738728],"rgb":[0.533333333333333326,0.866666666666666696,0.66666666666666663],"xyz":[0.432633619139194847,0.598478093232424069,0.473036474305788934],"hpluv":[142.591286230634154,117.302359569381537,81.7553965772464437],"hsluv":[142.591286230634154,56.3076629138628,81.7553965772464437]},"#88ddbb":{"lch":[82.1272144034785327,44.0521153731503716,155.27715859232552],"luv":[82.1272144034785327,-40.0143654100278567,18.4238820470094566],"rgb":[0.533333333333333326,0.866666666666666696,0.733333333333333282],"xyz":[0.449771211246531522,0.605333130075358827,0.563294459404430681],"hpluv":[155.27715859232552,104.020343594656595,82.1272144034785327],"hsluv":[155.27715859232552,57.829298146967858,82.1272144034785327]},"#88ddcc":{"lch":[82.542438979776648,39.9525966793572422,172.446474622419316],"luv":[82.542438979776648,-39.6059077008678173,5.25186220437346396],"rgb":[0.533333333333333326,0.866666666666666696,0.8],"xyz":[0.469063586690253276,0.613050080252847684,0.664900970074700837],"hpluv":[172.446474622419316,96.9346789585341355,82.542438979776648],"hsluv":[172.446474622419316,59.4202271347422908,82.542438979776648]},"#88dddd":{"lch":[83.0014816422074375,40.0957403917498354,192.177050630060734],"luv":[83.0014816422074375,-39.1936046909777,-8.4575261684472629],"rgb":[0.533333333333333326,0.866666666666666696,0.866666666666666696],"xyz":[0.490581912240886764,0.621657410473101191,0.778230817974706834],"hpluv":[192.177050630060734,100.308679558078737,83.0014816422074375],"hsluv":[192.177050630060734,61.0588228331018783,83.0014816422074375]},"#88ddee":{"lch":[83.5045459788204,44.8677054153188,210.184175125347622],"luv":[83.5045459788204,-38.7842593009493157,-22.5586395802706683],"rgb":[0.533333333333333326,0.866666666666666696,0.933333333333333348],"xyz":[0.514394092507061584,0.631182282579571208,0.903641634043230058],"hpluv":[210.184175125347622,116.175045715242419,83.5045459788204],"hsluv":[210.184175125347622,62.7244468832174746,83.5045459788204]},"#88ddff":{"lch":[84.0516404633952732,53.2556266987753659,223.883407592331508],"luv":[84.0516404633952732,-38.3840933399078779,-36.9164347351224436],"rgb":[0.533333333333333326,0.866666666666666696,1],"xyz":[0.540565140916892894,0.641650701943503932,1.04147582233501179],"hpluv":[223.883407592331508,143.298172182841085,84.0516404633952732],"hsluv":[223.883407592331508,99.9999999999952,84.0516404633952732]},"#335500":{"lch":[32.2593993637483862,41.1235506245754365,113.326494368716226],"luv":[32.2593993637483862,-16.2836990313566261,37.7622504868051223],"rgb":[0.2,0.333333333333333315,0],"xyz":[0.0461356744276991415,0.0720065112172806193,0.0114678000018764836],"hpluv":[113.326494368716226,161.760937136611716,32.2593993637483862],"hsluv":[113.326494368716226,100.000000000002288,32.2593993637483862]},"#335511":{"lch":[32.3496341583576381,38.1897920123001313,115.090818108356473],"luv":[32.3496341583576381,-16.1945453684027605,34.5860797757347456],"rgb":[0.2,0.333333333333333315,0.0666666666666666657],"xyz":[0.0471473399273362598,0.0724111774171354722,0.016795904966632115],"hpluv":[115.090818108356473,149.801873896373706,32.3496341583576381],"hsluv":[115.090818108356473,90.8995446090399923,32.3496341583576381]},"#335522":{"lch":[32.5160201858231659,33.1206139518783189,118.966642902489184],"luv":[32.5160201858231659,-16.0403246718637718,28.9772851207727022],"rgb":[0.2,0.333333333333333315,0.133333333333333331],"xyz":[0.0490226980658132819,0.0731613206725262866,0.0266727911626113111],"hpluv":[118.966642902489184,129.252907346834121,32.5160201858231659],"hsluv":[118.966642902489184,74.935129302234273,32.5160201858231659]},"#335533":{"lch":[32.7875119073456176,25.8516304293262671,127.715012949238741],"luv":[32.7875119073456176,-15.8143300747053051,20.4502753072602665],"rgb":[0.2,0.333333333333333315,0.2],"xyz":[0.0521104487982710224,0.0743964209655094,0.0429349450202224578],"hpluv":[127.715012949238741,100.050394151032577,32.7875119073456176],"hsluv":[127.715012949238741,50.9434831873252207,32.7875119073456176]},"#335544":{"lch":[33.1742322541989836,18.1915220066791647,148.674883917516439],"luv":[33.1742322541989836,-15.539762262897943,9.45765624941535421],"rgb":[0.2,0.333333333333333315,0.266666666666666663],"xyz":[0.0565684440424899,0.0761796190631969794,0.0664137199731090894],"hpluv":[148.674883917516439,69.5836942134034899,33.1742322541989836],"hsluv":[148.674883917516439,54.5088767633859703,33.1742322541989836]},"#335555":{"lch":[33.6821363315134121,15.5994691341387064,192.177050630060819],"luv":[33.6821363315134121,-15.2484882598238034,-3.29044724269541522],"rgb":[0.2,0.333333333333333315,0.333333333333333315],"xyz":[0.0625308580818519,0.0785645846789418123,0.097815767247083],"hpluv":[192.177050630060819,58.7691644617976934,33.6821363315134121],"hsluv":[192.177050630060819,58.539124710901028,33.6821363315134121]},"#335566":{"lch":[34.3136156967701496,22.6822476529859181,228.692277460856218],"luv":[34.3136156967701496,-14.9726179113300351,-17.0383412183435361],"rgb":[0.2,0.333333333333333315,0.4],"xyz":[0.0701158538553600663,0.0815985829883451308,0.137763411654226953],"hpluv":[228.692277460856218,83.8800984368335,34.3136156967701496],"hsluv":[228.692277460856218,62.7386213411417089,34.3136156967701496]},"#335577":{"lch":[35.0679836745485218,34.4527831327976131,244.673076132176305],"luv":[35.0679836745485218,-14.7383029974912176,-31.1412377780608658],"rgb":[0.2,0.333333333333333315,0.466666666666666674],"xyz":[0.0794298668755619858,0.0853241881964259402,0.186817213560624862],"hpluv":[244.673076132176305,124.667382519216758,35.0679836745485218],"hsluv":[244.673076132176305,66.8604241763398335,35.0679836745485218]},"#335588":{"lch":[35.9419713942028523,47.4274747217606318,252.117898483801355],"luv":[35.9419713942028523,-14.5630489263951493,-45.1362710516793229],"rgb":[0.2,0.333333333333333315,0.533333333333333326],"xyz":[0.0905702839775058138,0.089780355037203538,0.245490076964197029],"hpluv":[252.117898483801355,167.443168522882189,35.9419713942028523],"hsluv":[252.117898483801355,70.7327730687023433,35.9419713942028523]},"#335599":{"lch":[36.9302538454711851,60.4953772811161272,256.174865065393647],"luv":[36.9302538454711851,-14.4559426241851021,-58.7427986669927833],"rgb":[0.2,0.333333333333333315,0.6],"xyz":[0.103627248086578527,0.0950031406808327,0.314256754605314936],"hpluv":[256.174865065393647,207.863972679723531,36.9302538454711851],"hsluv":[256.174865065393647,74.2581677802949258,36.9302538454711851]},"#3355aa":{"lch":[38.0259842211890557,73.2582460718320903,258.648348715518409],"luv":[38.0259842211890557,-14.4194259870406505,-71.8251402485603165],"rgb":[0.2,0.333333333333333315,0.66666666666666663],"xyz":[0.118684941051831069,0.101026217866933804,0.393560604222313537],"hpluv":[258.648348715518409,244.464262316607687,38.0259842211890557],"hsluv":[258.648348715518409,77.3978910060545,38.0259842211890557]},"#3355bb":{"lch":[39.2213032744107579,85.5750988898230815,260.277622363739169],"luv":[39.2213032744107579,-14.4514388960387397,-84.3460340729607623],"rgb":[0.2,0.333333333333333315,0.733333333333333282],"xyz":[0.135822533159167702,0.107881254709868563,0.483818589320955283],"hpluv":[260.277622363739169,276.862869377010384,39.2213032744107579],"hsluv":[260.277622363739169,80.1529964351826578,39.2213032744107579]},"#3355cc":{"lch":[40.5077939091134667,97.4185991778777,261.412040351160215],"luv":[40.5077939091134667,-14.5472816309580448,-96.326320717286734],"rgb":[0.2,0.333333333333333315,0.8],"xyz":[0.155114908602889456,0.115598204887357364,0.585425099991225495],"hpluv":[261.412040351160215,305.17054630009352,40.5077939091134667],"hsluv":[261.412040351160215,82.5478264076183734,40.5077939091134667]},"#3355dd":{"lch":[41.8768615158020552,108.813506268261335,262.235450095721887],"luv":[41.8768615158020552,-14.7009821832840935,-107.815862790406285],"rgb":[0.2,0.333333333333333315,0.866666666666666696],"xyz":[0.176633234153523,0.124205535107610898,0.698754947891231493],"hpluv":[262.235450095721887,329.72206067647727,41.8768615158020552],"hsluv":[262.235450095721887,84.6180359154754456,41.8768615158020552]},"#3355ee":{"lch":[43.3200322197542533,119.805986402952101,262.852770803428143],"luv":[43.3200322197542533,-14.9061911990543372,-118.875059797762361],"rgb":[0.2,0.333333333333333315,0.933333333333333348],"xyz":[0.200445414419697737,0.133730407214080915,0.824165763959754716],"hpluv":[262.852770803428143,350.936931775297865,43.3200322197542533],"hsluv":[262.852770803428143,90.8055999978327577,43.3200322197542533]},"#3355ff":{"lch":[44.8291710285026497,130.447860525532377,263.327743444412704],"luv":[44.8291710285026497,-15.1567128937849134,-129.564340657235334],"rgb":[0.2,0.333333333333333315,1],"xyz":[0.226616462829529131,0.144198826578013639,0.961999952251536561],"hpluv":[263.327743444412704,369.245812735261836,44.8291710285026497],"hsluv":[263.327743444412704,99.9999999999993,44.8291710285026497]},"#aadd00":{"lch":[81.9783608763648175,97.3184216433040916,105.014728605041086],"luv":[81.9783608763648175,-25.2120246284188454,93.9958988747909245],"rgb":[0.66666666666666663,0.866666666666666696,0],"xyz":[0.424325128525832707,0.602582536713324846,0.0939549564608566229],"hpluv":[105.014728605041086,227.603505169437568,81.9783608763648175],"hsluv":[105.014728605041086,100.000000000002203,81.9783608763648175]},"#aadd11":{"lch":[82.0002885274849262,96.374791846509865,105.167446282879951],"luv":[82.0002885274849262,-25.2155818179290208,93.017605521973266],"rgb":[0.66666666666666663,0.866666666666666696,0.0666666666666666657],"xyz":[0.425336794025469811,0.602987202913179754,0.0992830614256122596],"hpluv":[105.167446282879951,225.71449396257529,82.0002885274849262],"hsluv":[105.167446282879951,98.8971907906987298,82.0002885274849262]},"#aadd22":{"lch":[82.0409106120811,94.6380623122949345,105.456830413527484],"luv":[82.0409106120811,-25.2222030700150874,91.2151484706391216],"rgb":[0.66666666666666663,0.866666666666666696,0.133333333333333331],"xyz":[0.427212152163946868,0.603737346168570554,0.109159947621591452],"hpluv":[105.456830413527484,222.227322886837186,82.0409106120811],"hsluv":[105.456830413527484,96.86659260915998,82.0409106120811]},"#aadd33":{"lch":[82.1077210543303693,91.8137349028061891,105.951891130476156],"luv":[82.1077210543303693,-25.2331804702422886,88.2782448860360773],"rgb":[0.66666666666666663,0.866666666666666696,0.2],"xyz":[0.430299902896404574,0.604972446461553681,0.125422101479202602],"hpluv":[105.951891130476156,216.526835376233663,82.1077210543303693],"hsluv":[105.951891130476156,93.5615293661406469,82.1077210543303693]},"#aadd44":{"lch":[82.204019596801416,87.812555976334508,106.710442618715334],"luv":[82.204019596801416,-25.2491908313752447,84.1042409718896238],"rgb":[0.66666666666666663,0.866666666666666696,0.266666666666666663],"xyz":[0.434757898140623489,0.606755644559241247,0.148900876432089241],"hpluv":[106.710442618715334,208.386709262610594,82.204019596801416],"hsluv":[106.710442618715334,88.8720213109455415,82.204019596801416]},"#aadd55":{"lch":[82.332521082647844,82.6008871447080537,107.814707884186447],"luv":[82.332521082647844,-25.2708912490316564,78.6402480449573],"rgb":[0.66666666666666663,0.866666666666666696,0.333333333333333315],"xyz":[0.440720312179985474,0.609140610174986,0.180302923706063156],"hpluv":[107.814707884186447,197.666387369374576,82.332521082647844],"hsluv":[107.814707884186447,82.7472331150865,82.332521082647844]},"#aadd66":{"lch":[82.495508489392364,76.2000100439918526,109.390646830849064],"luv":[82.495508489392364,-25.2989483474785786,71.8777068583581666],"rgb":[0.66666666666666663,0.866666666666666696,0.4],"xyz":[0.448305307953493659,0.612174608484389315,0.22025056811320709],"hpluv":[109.390646830849064,184.308617744019813,82.495508489392364],"hsluv":[109.390646830849064,75.1895211365387723,82.495508489392364]},"#aadd77":{"lch":[82.694914273715753,68.6905071379487,111.642517734809914],"luv":[82.694914273715753,-25.3340491820501299,63.8480361711309499],"rgb":[0.66666666666666663,0.866666666666666696,0.466666666666666674],"xyz":[0.457619320973695565,0.615900213692470166,0.269304370019605],"hpluv":[111.642517734809914,168.351618208890358,82.694914273715753],"hsluv":[111.642517734809914,66.2494286969421182,82.694914273715753]},"#aadd88":{"lch":[82.9323686283524921,60.2252781448786436,114.920875432447886],"luv":[82.9323686283524921,-25.3769003534370228,54.6177357282387277],"rgb":[0.66666666666666663,0.866666666666666696,0.533333333333333326],"xyz":[0.468759738075639365,0.620356380533247709,0.327977233423177195],"hpluv":[114.920875432447886,149.967217229555729,82.9323686283524921],"hsluv":[114.920875432447886,56.0198042099318698,82.9323686283524921]},"#aadd99":{"lch":[83.2092305924335,51.0640475908324305,119.865599423026282],"luv":[83.2092305924335,-25.4282188712646082,44.2825320120006438],"rgb":[0.66666666666666663,0.866666666666666696,0.6],"xyz":[0.481816702184712065,0.625579166176876922,0.396743911064295074],"hpluv":[119.865599423026282,129.562195810811914,83.2092305924335],"hsluv":[119.865599423026282,44.6286172342680487,83.2092305924335]},"#aaddaa":{"lch":[83.526609727912188,41.6663179647472717,127.715012949236481],"luv":[83.526609727912188,-25.4887175141036408,32.9606937461220255],"rgb":[0.66666666666666663,0.866666666666666696,0.66666666666666663],"xyz":[0.496874395149964621,0.631602243362978,0.476047760681293675],"hpluv":[127.715012949236481,108.050849780995421,83.526609727912188],"hsluv":[127.715012949236481,32.2306770176982198,83.526609727912188]},"#aaddbb":{"lch":[83.8853825066367449,32.9442078204095523,140.880295511025736],"luv":[83.8853825066367449,-25.5590871805440472,20.7859060762739638],"rgb":[0.66666666666666663,0.866666666666666696,0.733333333333333282],"xyz":[0.514011987257301239,0.638457280205912747,0.566305745779935421],"hpluv":[140.880295511025736,87.605014056209555,83.8853825066367449],"hsluv":[140.880295511025736,34.4766875289621382,83.8853825066367449]},"#aaddcc":{"lch":[84.2862057978904602,26.8294893367150316,162.87488866986746],"luv":[84.2862057978904602,-25.639978502468459,7.90018990036700242],"rgb":[0.66666666666666663,0.866666666666666696,0.8],"xyz":[0.533304362701023,0.646174230383401604,0.667912256450205577],"hpluv":[162.87488866986746,73.4171355960865526,84.2862057978904602],"hsluv":[162.87488866986746,36.8333761539634708,84.2862057978904602]},"#aadddd":{"lch":[84.729528894444158,26.3242685722419552,192.177050630060421],"luv":[84.729528894444158,-25.7319846477226655,-5.55266440124834],"rgb":[0.66666666666666663,0.866666666666666696,0.866666666666666696],"xyz":[0.554822688251656593,0.654781560603655111,0.781242104350211575],"hpluv":[192.177050630060421,74.4077864529294146,84.729528894444158],"hsluv":[192.177050630060421,39.269697519551606,84.729528894444158]},"#aaddee":{"lch":[85.2156049558348769,32.3281965376105802,216.94937298104162],"luv":[85.2156049558348769,-25.8356267715816657,-19.4327733659894548],"rgb":[0.66666666666666663,0.866666666666666696,0.933333333333333348],"xyz":[0.578634868517831302,0.664306432710125128,0.906652920418734798],"hpluv":[216.94937298104162,94.7745998726022094,85.2156049558348769],"hsluv":[216.94937298104162,58.4216362813771397,85.2156049558348769]},"#aaddff":{"lch":[85.744502396509489,42.4619511969095527,232.326067904807843],"luv":[85.744502396509489,-25.9513430438233641,-33.608705623253762],"rgb":[0.66666666666666663,0.866666666666666696,1],"xyz":[0.604805916927662723,0.674774852074057852,1.04448710871051675],"hpluv":[232.326067904807843,129.682154580054771,85.744502396509489],"hsluv":[232.326067904807843,99.9999999999945572,85.744502396509489]},"#88ee00":{"lch":[85.1906878331824515,112.448241602139106,116.535675589642423],"luv":[85.1906878331824515,-50.2368100475369914,100.602534538950536],"rgb":[0.533333333333333326,0.933333333333333348,0],"xyz":[0.40726312885557775,0.663815939263801891,0.106669928865523039],"hpluv":[116.535675589642423,329.03324103323672,85.1906878331824515],"hsluv":[116.535675589642423,100.000000000002416,85.1906878331824515]},"#88ee11":{"lch":[85.2112458075113182,111.594873497969587,116.730132104203335],"luv":[85.2112458075113182,-50.1941202672300193,99.669283541253],"rgb":[0.533333333333333326,0.933333333333333348,0.0666666666666666657],"xyz":[0.408274794355214854,0.664220605463656799,0.111998033830278676],"hpluv":[116.730132104203335,327.047318494663614,85.2112458075113182],"hsluv":[116.730132104203335,98.9939616796445,85.2112458075113182]},"#88ee22":{"lch":[85.2493327369145,110.025246585506409,117.096539077460619],"luv":[85.2493327369145,-50.115524286233132,97.9489107224652429],"rgb":[0.533333333333333326,0.933333333333333348,0.133333333333333331],"xyz":[0.410150152493691911,0.6649707487190476,0.121874920026257869],"hpluv":[117.096539077460619,323.384561507736407,85.2493327369145],"hsluv":[117.096539077460619,97.140453749143191,85.2493327369145]},"#88ee33":{"lch":[85.3119799721786,107.475578977757436,117.717135468026783],"luv":[85.3119799721786,-49.9876247553973769,95.1432469906181097],"rgb":[0.533333333333333326,0.933333333333333348,0.2],"xyz":[0.413237903226149617,0.666205849012030726,0.138137073883869],"hpluv":[117.717135468026783,317.406918528502,85.3119799721786],"hsluv":[117.717135468026783,94.120593299189423,85.3119799721786]},"#88ee44":{"lch":[85.4022915890189864,103.870397610997969,118.652974854946393],"luv":[85.4022915890189864,-49.8062112723248518,91.1504296126099],"rgb":[0.533333333333333326,0.933333333333333348,0.266666666666666663],"xyz":[0.417695898470368532,0.667989047109718292,0.161615848836755643],"hpluv":[118.652974854946393,308.894438519259097,85.4022915890189864],"hsluv":[118.652974854946393,89.8292917088674869,85.4022915890189864]},"#88ee55":{"lch":[85.5228293578601466,99.1885702075232,119.98340282305692],"luv":[85.5228293578601466,-49.5693999595221584,85.9141842041562],"rgb":[0.533333333333333326,0.933333333333333348,0.333333333333333315],"xyz":[0.423658312509730517,0.670374012725463,0.193017896110729559],"hpluv":[119.98340282305692,297.731707367046795,85.5228293578601466],"hsluv":[119.98340282305692,84.2131356884780473,85.5228293578601466]},"#88ee66":{"lch":[85.6757572108422,93.4644574192068234,121.818598205465591],"luv":[85.6757572108422,-49.2774194314266083,79.4187681524083189],"rgb":[0.533333333333333326,0.933333333333333348,0.4],"xyz":[0.431243308283238702,0.673408011034866361,0.232965540517873521],"hpluv":[121.818598205465591,283.912655540997662,85.6757572108422],"hsluv":[121.818598205465591,77.2651144072775082,85.6757572108422]},"#88ee77":{"lch":[85.8629182835971676,86.7937408847250822,124.317503927832064],"luv":[85.8629182835971676,-48.9324360738715,71.6852157466327071],"rgb":[0.533333333333333326,0.933333333333333348,0.466666666666666674],"xyz":[0.440557321303440608,0.677133616242947212,0.282019342424271402],"hpluv":[124.317503927832064,267.563092583833793,85.8629182835971676],"hsluv":[124.317503927832064,69.0205357789205749,85.8629182835971676]},"#88ee88":{"lch":[86.0858807036169793,79.3454652904755164,127.71501294923921],"luv":[86.0858807036169793,-48.5383458294846,62.7672832477191918],"rgb":[0.533333333333333326,0.933333333333333348,0.533333333333333326],"xyz":[0.451697738405384408,0.681589783083724754,0.340692205827843597],"hpluv":[127.71501294923921,248.989760930573482,86.0858807036169793],"hsluv":[127.71501294923921,59.5524101967812,86.0858807036169793]},"#88ee99":{"lch":[86.3459670558122525,71.3853284581525429,132.362204285947513],"luv":[86.3459670558122525,-48.1005130697284287,52.7466184841000825],"rgb":[0.533333333333333326,0.933333333333333348,0.6],"xyz":[0.464754702514457163,0.686812568727354,0.409458883468961532],"hpluv":[132.362204285947513,228.778132650246619,86.3459670558122525],"hsluv":[132.362204285947513,60.5562348819982645,86.3459670558122525]},"#88eeaa":{"lch":[86.6442747471204768,63.319361027400987,138.776693085718904],"luv":[86.6442747471204768,-47.625461320552418,41.7271723811105204],"rgb":[0.533333333333333326,0.933333333333333348,0.66666666666666663],"xyz":[0.479812395479709664,0.692835645913455,0.488762733085960077],"hpluv":[138.776693085718904,207.981038552319745,86.6442747471204768],"hsluv":[138.776693085718904,61.6537348625427342,86.6442747471204768]},"#88eebb":{"lch":[86.9816911545789679,55.7684583245382299,147.664608842749317],"luv":[86.9816911545789679,-47.1205330954276,29.8291184029711189],"rgb":[0.533333333333333326,0.933333333333333348,0.733333333333333282],"xyz":[0.496949987587046338,0.699690682756389792,0.579020718184601879],"hpluv":[147.664608842749317,188.458500832318975,86.9816911545789679],"hsluv":[147.664608842749317,62.830800627143077,86.9816911545789679]},"#88eecc":{"lch":[87.3589058048410294,49.6608679924305463,159.75715297219557],"luv":[87.3589058048410294,-46.5935415809549696,17.182656741768227],"rgb":[0.533333333333333326,0.933333333333333348,0.8],"xyz":[0.516242363030768092,0.70740763293387865,0.680627228854872],"hpluv":[159.75715297219557,173.371642714007834,87.3589058048410294],"hsluv":[159.75715297219557,64.0722902507549179,87.3589058048410294]},"#88eedd":{"lch":[87.7764209496729,46.2191498548509543,175.132102674355139],"luv":[87.7764209496729,-46.0524373199716166,3.92209512827700335],"rgb":[0.533333333333333326,0.933333333333333348,0.866666666666666696],"xyz":[0.53776068858140158,0.716014963154132156,0.793957076754878],"hpluv":[175.132102674355139,167.447502067072264,87.7764209496729],"hsluv":[175.132102674355139,65.3626972838926434,87.7764209496729]},"#88eeee":{"lch":[88.2345613859691866,46.5524177333431339,192.177050630060933],"luv":[88.2345613859691866,-45.5050097647113958,-9.8194543195231],"rgb":[0.533333333333333326,0.933333333333333348,0.933333333333333348],"xyz":[0.56157286884757629,0.725539835260602173,0.919367892823401256],"hpluv":[192.177050630060933,175.887543813927181,88.2345613859691866],"hsluv":[192.177050630060933,66.6867488369664443,88.2345613859691866]},"#88eeff":{"lch":[88.7334840469836763,50.9233073192915242,208.009521596121829],"luv":[88.7334840469836763,-44.9586380478967271,-23.9145163700465169],"rgb":[0.533333333333333326,0.933333333333333348,1],"xyz":[0.587743917257407711,0.736008254624534897,1.05720208111518299],"hpluv":[208.009521596121829,201.749007974481685,88.7334840469836763],"hsluv":[208.009521596121829,99.9999999999925109,88.7334840469836763]},"#336600":{"lch":[38.2101034680229574,51.4017776291135888,118.130952889189317],"luv":[38.2101034680229574,-24.2353400261634,45.3298029694491902],"rgb":[0.2,0.4,0],"xyz":[0.0611637321335456105,0.10206262662897396,0.0164771525704918292],"hpluv":[118.130952889189317,170.702252266418213,38.2101034680229574],"hsluv":[118.130952889189317,100.000000000002288,38.2101034680229574]},"#336611":{"lch":[38.2816545292110959,48.9828222693822468,119.470954908934345],"luv":[38.2816545292110959,-24.0986808399199681,42.6447002480913682],"rgb":[0.2,0.4,0.0666666666666666657],"xyz":[0.0621753976331827357,0.102467292828828813,0.021805257535247459],"hpluv":[119.470954908934345,162.365005406289157,38.2816545292110959],"hsluv":[119.470954908934345,93.5286374368429,38.2816545292110959]},"#336622":{"lch":[38.4137944304132617,44.7307250918699282,122.230818066602779],"luv":[38.4137944304132617,-23.8562978467226365,37.8380076152656173],"rgb":[0.2,0.4,0.133333333333333331],"xyz":[0.0640507557716597509,0.103217436084219627,0.0316821437312266585],"hpluv":[122.230818066602779,147.760399550800031,38.4137944304132617],"hsluv":[122.230818066602779,81.994947572555219,38.4137944304132617]},"#336633":{"lch":[38.6299730126545171,38.3921679396875817,127.715012949239437],"luv":[38.6299730126545171,-23.4858075099586969,30.3706339201924216],"rgb":[0.2,0.4,0.2],"xyz":[0.0671385065041174844,0.10445253637720274,0.0479442975888378],"hpluv":[127.715012949239437,126.112332565807833,38.6299730126545171],"hsluv":[127.715012949239437,64.2136550115152,38.6299730126545171]},"#336644":{"lch":[38.9390987599147635,30.7877900918170191,138.353415806708398],"luv":[38.9390987599147635,-23.0064236741332095,20.4595329483365589],"rgb":[0.2,0.4,0.266666666666666663],"xyz":[0.0715965017483363719,0.10623573447489032,0.0714230725417244472],"hpluv":[138.353415806708398,100.330262339301328,38.9390987599147635],"hsluv":[138.353415806708398,66.1490613915476899,38.9390987599147635]},"#336655":{"lch":[39.3471830293532108,24.0314899024670439,159.111050143656939],"luv":[39.3471830293532108,-22.4519783641565418,8.56861566811244479],"rgb":[0.2,0.4,0.333333333333333315],"xyz":[0.077558915787698357,0.108620700090635153,0.102825119815698349],"hpluv":[159.111050143656939,77.5008343503898089,39.3471830293532108],"hsluv":[159.111050143656939,68.4324421599544337,39.3471830293532108]},"#336666":{"lch":[39.8577781510875653,22.3660784387423632,192.177050630061],"luv":[39.8577781510875653,-21.8628519700770774,-4.71775036033837925],"rgb":[0.2,0.4,0.4],"xyz":[0.0851439115612065422,0.111654698400038471,0.142772764222842297],"hpluv":[192.177050630061,71.205917149352544,39.8577781510875653],"hsluv":[192.177050630061,70.9271962998489727,39.8577781510875653]},"#336677":{"lch":[40.4722660639059,28.403364995264031,221.483563289625266],"luv":[40.4722660639059,-21.2782609928981294,-18.8145356618838697],"rgb":[0.2,0.4,0.466666666666666674],"xyz":[0.0944579245814084478,0.115380303608119281,0.191826566129240206],"hpluv":[221.483563289625266,89.0536244466218534,40.4722660639059],"hsluv":[221.483563289625266,73.4989606489913,40.4722660639059]},"#336688":{"lch":[41.1901179582142731,39.1584560294521253,238.034471274574031],"luv":[41.1901179582142731,-20.7308371309926542,-33.2207325394668516],"rgb":[0.2,0.4,0.533333333333333326],"xyz":[0.105598341683352276,0.119836470448896878,0.250499429532812401],"hpluv":[238.034471274574031,120.634589470818128,41.1901179582142731],"hsluv":[238.034471274574031,76.0346320246428746,41.1901179582142731]},"#336699":{"lch":[42.0091634944821948,51.6886413393569626,246.942440261812],"luv":[42.0091634944821948,-20.2441498032976277,-47.5593318103852951],"rgb":[0.2,0.4,0.6],"xyz":[0.118655305792425,0.12505925609252605,0.31926610717393028],"hpluv":[246.942440261812,156.131455895945,42.0091634944821948],"hsluv":[246.942440261812,78.4511744564818514,42.0091634944821948]},"#3366aa":{"lch":[42.9258754740709847,64.6951641030825,252.148217293940775],"luv":[42.9258754740709847,-19.832670948043944,-61.5802681172418218],"rgb":[0.2,0.4,0.66666666666666663],"xyz":[0.133712998757677531,0.131082333278627144,0.398569956790928881],"hpluv":[252.148217293940775,191.245834212653307,42.9258754740709847],"hsluv":[252.148217293940775,80.6959595489171,42.9258754740709847]},"#3366bb":{"lch":[43.9356615222631106,77.6311657782158164,255.449757662516049],"luv":[43.9356615222631106,-19.5031901130623,-75.1413566253536374],"rgb":[0.2,0.4,0.733333333333333282],"xyz":[0.150850590865014178,0.137937370121561903,0.488827941889570627],"hpluv":[255.449757662516049,224.211696450950683,43.9356615222631106],"hsluv":[255.449757662516049,82.7420790911240402,43.9356615222631106]},"#3366cc":{"lch":[45.0331492258045287,90.2591849706621332,257.681278432902445],"luv":[45.0331492258045287,-19.2567634880452658,-88.1810497302775786],"rgb":[0.2,0.4,0.8],"xyz":[0.170142966308735932,0.145654320299050705,0.590434452559840839],"hpluv":[257.681278432902445,254.330482568364204,45.0331492258045287],"hsluv":[257.681278432902445,84.5818015821218694,45.0331492258045287]},"#3366dd":{"lch":[46.2124513047425367,102.485732700579547,259.264483160570819],"luv":[46.2124513047425367,-19.0906003056708045,-100.691977769551045],"rgb":[0.2,0.4,0.866666666666666696],"xyz":[0.191661291859369476,0.154261650519304239,0.703764300459846837],"hpluv":[259.264483160570819,281.412724566330553,46.2124513047425367],"hsluv":[259.264483160570819,86.2202337385041488,46.2124513047425367]},"#3366ee":{"lch":[47.467400384741687,114.289765210034219,260.43068521754094],"luv":[47.467400384741687,-18.99960653492559,-112.699447129445844],"rgb":[0.2,0.4,0.933333333333333348],"xyz":[0.215473472125544213,0.163786522625774256,0.82917511652837006],"hpluv":[260.43068521754094,305.528142270574733,47.467400384741687],"hsluv":[260.43068521754094,89.4216395109538524,47.467400384741687]},"#3366ff":{"lch":[48.7917470574018068,125.686826272807437,261.315666926990161],"luv":[48.7917470574018068,-18.9775194272026404,-124.245853270525785],"rgb":[0.2,0.4,1],"xyz":[0.241644520535375606,0.17425494198970698,0.967009304820151905],"hpluv":[261.315666926990161,326.875761207371056,48.7917470574018068],"hsluv":[261.315666926990161,99.9999999999992184,48.7917470574018068]},"#aaee00":{"lch":[86.8465682321076713,106.130019137569278,108.773889799394041],"luv":[86.8465682321076713,-34.1562767274136,100.483479847491182],"rgb":[0.66666666666666663,0.933333333333333348,0],"xyz":[0.471503904866347523,0.696940089394355811,0.109681215241027807],"hpluv":[108.773889799394041,354.560190530248747,86.8465682321076713],"hsluv":[108.773889799394041,100.000000000002302,86.8465682321076713]},"#aaee11":{"lch":[86.8664697406872364,105.275413073012288,108.926122010215039],"luv":[86.8664697406872364,-34.1459453835818323,99.5839696515197801],"rgb":[0.66666666666666663,0.933333333333333348,0.0666666666666666657],"xyz":[0.472515570365984627,0.697344755594210719,0.115009320205783444],"hpluv":[108.926122010215039,352.296735211520456,86.8664697406872364],"hsluv":[108.926122010215039,99.0448212343627,86.8664697406872364]},"#aaee22":{"lch":[86.9033414770782286,103.701584155213482,109.21343759479339],"luv":[86.9033414770782286,-34.1269596340241961,97.9253245204656224],"rgb":[0.66666666666666663,0.933333333333333348,0.133333333333333331],"xyz":[0.474390928504461684,0.69809489884960152,0.124886206401762637],"hpluv":[109.21343759479339,348.114419217609168,86.9033414770782286],"hsluv":[109.21343759479339,97.2844700630890742,86.9033414770782286]},"#aaee33":{"lch":[86.9639927659971,101.139559122436452,109.701502859778287],"luv":[86.9639927659971,-34.0961634116812462,95.2190215245081504],"rgb":[0.66666666666666663,0.933333333333333348,0.2],"xyz":[0.47747867923691939,0.699329999142584646,0.141148360259373773],"hpluv":[109.701502859778287,341.266668172598315,86.9639927659971],"hsluv":[109.701502859778287,94.4148698146506,86.9639927659971]},"#aaee44":{"lch":[87.0514332975086091,97.5044422856038864,110.440992284795044],"luv":[87.0514332975086091,-34.052698770047833,91.3648180204122298],"rgb":[0.66666666666666663,0.933333333333333348,0.266666666666666663],"xyz":[0.481936674481138305,0.701113197240272212,0.164627135212260411],"hpluv":[110.440992284795044,331.464832239423686,87.0514332975086091],"hsluv":[110.440992284795044,90.3338544995677353,87.0514332975086091]},"#aaee55":{"lch":[87.1681505263978,92.7597711807761556,111.499860176168639],"luv":[87.1681505263978,-33.9963593100021271,86.3054036730909644],"rgb":[0.66666666666666663,0.933333333333333348,0.333333333333333315],"xyz":[0.48789908852050029,0.703498162856017,0.196029182486234327],"hpluv":[111.499860176168639,318.513853400728863,87.1681505263978],"hsluv":[111.499860176168639,84.9871568734489813,87.1681505263978]},"#aaee66":{"lch":[87.3162499846890086,86.9168013961255923,112.975973936880195],"luv":[87.3162499846890086,-33.9275471197994563,80.0215715377255492],"rgb":[0.66666666666666663,0.933333333333333348,0.4],"xyz":[0.495484084294008476,0.70653216116542028,0.235976826893378289],"hpluv":[112.975973936880195,302.308385752370668,87.3162499846890086],"hsluv":[112.975973936880195,78.3634586897027106,87.3162499846890086]},"#aaee77":{"lch":[87.4975302296396,80.0378594698754853,115.017197938190947],"luv":[87.4975302296396,-33.8472328521792534,72.5287789554594298],"rgb":[0.66666666666666663,0.933333333333333348,0.466666666666666674],"xyz":[0.504798097314210326,0.710257766373501132,0.285030628799776198],"hpluv":[115.017197938190947,282.845349503141222,87.4975302296396],"hsluv":[115.017197938190947,70.4907283307095,87.4975302296396]},"#aaee88":{"lch":[87.7135274362348838,72.2451165326571072,117.856267937731204],"luv":[87.7135274362348838,-33.7569011423620324,63.8735351149597861],"rgb":[0.66666666666666663,0.933333333333333348,0.533333333333333326],"xyz":[0.515938514416154237,0.714713933214278674,0.343703492203348393],"hpluv":[117.856267937731204,260.261444274219798,87.7135274362348838],"hsluv":[117.856267937731204,61.4321883079204412,87.7135274362348838]},"#aaee99":{"lch":[87.9655440812905312,63.7405265694191954,121.874104620002555],"luv":[87.9655440812905312,-33.6584769753751445,54.1291202131068871],"rgb":[0.66666666666666663,0.933333333333333348,0.6],"xyz":[0.528995478525226881,0.719936718857907887,0.412470169844466272],"hpluv":[121.874104620002555,234.922523447188695,87.9655440812905312],"hsluv":[121.874104620002555,51.2814060811362182,87.9655440812905312]},"#aaeeaa":{"lch":[88.2546687059401,54.8509913255605497,127.715012949237604],"luv":[88.2546687059401,-33.5542349686064441,43.3906045713616138],"rgb":[0.66666666666666663,0.933333333333333348,0.66666666666666663],"xyz":[0.544053171490479492,0.725959796044009,0.491774019461464873],"hpluv":[127.715012949237604,207.631017102058365,88.2546687059401],"hsluv":[127.715012949237604,42.8122115000723795,88.2546687059401]},"#aaeebb":{"lch":[88.5817905154621457,46.1299748711590425,136.47329364537066],"luv":[88.5817905154621457,-33.4466969972147226,31.7693726974624511],"rgb":[0.66666666666666663,0.933333333333333348,0.733333333333333282],"xyz":[0.561190763597816056,0.732814832886943712,0.582032004560106619],"hpluv":[136.47329364537066,180.106084736741337,88.5817905154621457],"hsluv":[136.47329364537066,42.5306558804052,88.5817905154621457]},"#aaeecc":{"lch":[88.947610994722524,38.5659339652702471,149.820563383504265],"luv":[88.947610994722524,-33.3385252257337896,19.3874701388989088],"rgb":[0.66666666666666663,0.933333333333333348,0.8],"xyz":[0.58048313904153781,0.740531783064432569,0.683638515230376775],"hpluv":[149.820563383504265,156.025185046421541,88.947610994722524],"hsluv":[149.820563383504265,43.7743007306855176,88.947610994722524]},"#aaeedd":{"lch":[89.3526538659385636,33.8378115459028308,169.14561851222],"luv":[89.3526538659385636,-33.2324178366612202,6.37211856022751721],"rgb":[0.66666666666666663,0.933333333333333348,0.866666666666666696],"xyz":[0.602001464592171409,0.749139113284686076,0.796968363130382773],"hpluv":[169.14561851222,142.575756051086472,89.3526538659385636],"hsluv":[169.14561851222,45.7128350403065866,89.3526538659385636]},"#aaeeee":{"lch":[89.797274219494,33.893604395025335,192.177050630060734],"luv":[89.797274219494,-33.1310138990311174,-7.14928925898844092],"rgb":[0.66666666666666663,0.933333333333333348,0.933333333333333348],"xyz":[0.625813644858346119,0.758663985391156093,0.922379179198906],"hpluv":[192.177050630060734,149.574468983420843,89.797274219494],"hsluv":[192.177050630060734,47.7079369778472326,89.797274219494]},"#aaeeff":{"lch":[90.2816673401601406,39.1749897548907384,212.508271358442045],"luv":[90.2816673401601406,-33.0368122621910558,-21.0534761464356919],"rgb":[0.66666666666666663,0.933333333333333348,1],"xyz":[0.65198469326817754,0.769132404755088817,1.06021336749068773],"hpluv":[212.508271358442045,182.211685385120148,90.2816673401601406],"hsluv":[212.508271358442045,99.9999999999910898,90.2816673401601406]},"#88ff00":{"lch":[90.2073775103659727,121.530167505498795,118.25137340908573],"luv":[90.2073775103659727,-57.5251845782800331,107.053420090856534],"rgb":[0.533333333333333326,1,0],"xyz":[0.459115501285251582,0.767520684123151,0.12395405300874715],"hpluv":[118.25137340908573,560.639311859311,90.2073775103659727],"hsluv":[118.25137340908573,100.00000000000226,90.2073775103659727]},"#88ff11":{"lch":[90.2260397586701828,120.75410845816802,118.424372307304225],"luv":[90.2260397586701828,-57.4787561773275684,106.196738640291272],"rgb":[0.533333333333333326,1,0.0666666666666666657],"xyz":[0.460127166784888686,0.767925350323005906,0.129282157973502787],"hpluv":[118.424372307304225,558.207032378019221,90.2260397586701828],"hsluv":[118.424372307304225,99.9999999999909335,90.2260397586701828]},"#88ff22":{"lch":[90.260617257984066,119.32542599803422,118.749452026898098],"luv":[90.260617257984066,-57.393189210317729,104.616342518179295],"rgb":[0.533333333333333326,1,0.133333333333333331],"xyz":[0.462002524923365743,0.768675493578396707,0.139159044169481966],"hpluv":[118.749452026898098,553.71568515647823,90.260617257984066],"hsluv":[118.749452026898098,99.9999999999907772,90.260617257984066]},"#88ff33":{"lch":[90.3174996442954665,117.001153508636776,119.297411154505227],"luv":[90.3174996442954665,-57.253701051451273,102.035697862378711],"rgb":[0.533333333333333326,1,0.2],"xyz":[0.465090275655823449,0.769910593871379834,0.155421198027093116],"hpluv":[119.297411154505227,546.370637823869743,90.3174996442954665],"hsluv":[119.297411154505227,99.9999999999907914,90.3174996442954665]},"#88ff44":{"lch":[90.399517385893148,113.706822542904789,120.117552028257023],"luv":[90.399517385893148,-57.0553255590242614,98.3561452994036074],"rgb":[0.533333333333333326,1,0.266666666666666663],"xyz":[0.469548270900042364,0.7716937919690674,0.178899972979979754],"hpluv":[120.117552028257023,535.877566613280692,90.399517385893148],"hsluv":[120.117552028257023,99.9999999999907914,90.399517385893148]},"#88ff55":{"lch":[90.5090160073098389,109.413894688598035,121.271093020798972],"luv":[90.5090160073098389,-56.7954345723420317,93.518334901057969],"rgb":[0.533333333333333326,1,0.333333333333333315],"xyz":[0.475510684939404349,0.774078757584812149,0.21030202025395367],"hpluv":[121.271093020798972,522.05545338002139,90.5090160073098389],"hsluv":[121.271093020798972,99.9999999999906493,90.5090160073098389]},"#88ff66":{"lch":[90.6479884721694,104.139810410505333,122.839359042112989],"luv":[90.6479884721694,-56.4735097148607039,87.4976731851854908],"rgb":[0.533333333333333326,1,0.4],"xyz":[0.483095680712912534,0.777112755894215468,0.250249664661097659],"hpluv":[122.839359042112989,504.839052288882328,90.6479884721694],"hsluv":[122.839359042112989,99.9999999999905498,90.6479884721694]},"#88ff77":{"lch":[90.8181461195308515,97.9515013566305441,124.934550835890477],"luv":[90.8181461195308515,-56.0909812525741813,80.3012978733306],"rgb":[0.533333333333333326,1,0.466666666666666674],"xyz":[0.49240969373311444,0.780838361102296319,0.299303466567495513],"hpluv":[124.934550835890477,484.301391198376791,90.8181461195308515],"hsluv":[124.934550835890477,99.9999999999904,90.8181461195308515]},"#88ff88":{"lch":[91.0209609702079803,90.9725812653771,127.715012949239437],"luv":[91.0209609702079803,-55.6510519447396348,71.9650676337452779],"rgb":[0.533333333333333326,1,0.533333333333333326],"xyz":[0.503550110835058295,0.785294527943073861,0.357976329971067708],"hpluv":[127.715012949239437,460.703998076760797,91.0209609702079803],"hsluv":[127.715012949239437,99.9999999999902087,91.0209609702079803]},"#88ff99":{"lch":[91.2576929391802167,83.3964386150156116,131.406800448379954],"luv":[91.2576929391802167,-55.158478848678719,62.5500454417735057],"rgb":[0.533333333333333326,1,0.6],"xyz":[0.51660707494413094,0.790517313586703074,0.426743007612185643],"hpluv":[131.406800448379954,434.595507650037121,91.2576929391802167],"hsluv":[131.406800448379954,99.9999999999900524,91.2576929391802167]},"#88ffaa":{"lch":[91.5294084976530229,75.5094657025462226,136.33125230150921],"luv":[91.5294084976530229,-54.6193101996060264,52.1383770748881048],"rgb":[0.533333333333333326,1,0.66666666666666663],"xyz":[0.531664767909383551,0.796540390772804141,0.506046857229184188],"hpluv":[136.33125230150921,406.99849880976177,91.5294084976530229],"hsluv":[136.33125230150921,99.9999999999897824,91.5294084976530229]},"#88ffbb":{"lch":[91.8369943060547911,67.7301008509963225,142.928263991524119],"luv":[91.8369943060547911,-54.0405872892441,40.8286846067776423],"rgb":[0.533333333333333326,1,0.733333333333333282],"xyz":[0.548802360016720114,0.8033954276157389,0.596304842327826],"hpluv":[142.928263991524119,379.751065707187763,91.8369943060547911],"hsluv":[142.928263991524119,99.9999999999894413,91.8369943060547911]},"#88ffcc":{"lch":[92.1811678623774498,60.665065650155249,151.731515164157571],"luv":[92.1811678623774498,-53.4300279465168941,28.7312078404662543],"rgb":[0.533333333333333326,1,0.8],"xyz":[0.568094735460441869,0.811112377793227757,0.697911352998096146],"hpluv":[151.731515164157571,356.080713038752435,92.1811678623774498],"hsluv":[151.731515164157571,99.9999999999893134,92.1811678623774498]},"#88ffdd":{"lch":[92.5624864174544371,55.1561732277505712,163.177123134509742],"luv":[92.5624864174544371,-52.7957106082625316,15.9629692256241533],"rgb":[0.533333333333333326,1,0.866666666666666696],"xyz":[0.589613061011075468,0.819719708013481263,0.811241200898102144],"hpluv":[163.177123134509742,341.369587308077,92.5624864174544371],"hsluv":[163.177123134509742,99.9999999999887,92.5624864174544371]},"#88ffee":{"lch":[92.9813549493531752,52.2127257219241301,177.098205352907513],"luv":[92.9813549493531752,-52.1457771028834927,2.64322864112605771],"rgb":[0.533333333333333326,1,0.933333333333333348],"xyz":[0.613425241277250177,0.82924458011995128,0.936652016966625367],"hpluv":[177.098205352907513,343.566349205584061,92.9813549493531752],"hsluv":[177.098205352907513,99.9999999999882,92.9813549493531752]},"#88ffff":{"lch":[93.4380337051328524,52.6732939730945162,192.177050630061075],"luv":[93.4380337051328524,-51.4881691068088543,-11.1105508416409933],"rgb":[0.533333333333333326,1,1],"xyz":[0.639596289687081598,0.839712999483884,1.07448620525840721],"hpluv":[192.177050630061075,372.044084252862206,93.4380337051328524],"hsluv":[192.177050630061075,99.9999999999874802,93.4380337051328524]},"#337700":{"lch":[44.0848685544221084,61.4877933810524127,120.932619831412623],"luv":[44.0848685544221084,-31.6065510805688668,52.7425318283298168],"rgb":[0.2,0.466666666666666674,0],"xyz":[0.0796174701869632462,0.138970102735809731,0.0226283985882975332],"hpluv":[120.932619831412623,176.985906279588789,44.0848685544221084],"hsluv":[120.932619831412623,100.000000000002217,44.0848685544221084]},"#337711":{"lch":[44.1431322932100159,59.4532082216814146,121.943929432148849],"luv":[44.1431322932100159,-31.4560442613915434,50.449987584497805],"rgb":[0.2,0.466666666666666674,0.0666666666666666657],"xyz":[0.0806291356866003645,0.139374768935664584,0.0279565035530531664],"hpluv":[121.943929432148849,170.903703930819205,44.1431322932100159],"hsluv":[121.943929432148849,95.223210781581642,44.1431322932100159]},"#337722":{"lch":[44.2508401312458517,55.8308883755444327,123.957293362486936],"luv":[44.2508401312458517,-31.1857277137109214,46.3091619851707605],"rgb":[0.2,0.466666666666666674,0.133333333333333331],"xyz":[0.0825044938250774,0.140124912191055412,0.037833389749032359],"hpluv":[123.957293362486936,160.100373243526178,44.2508401312458517],"hsluv":[123.957293362486936,86.6219708852072,44.2508401312458517]},"#337733":{"lch":[44.4273451577554681,50.2894934834324943,127.715012949239792],"luv":[44.4273451577554681,-30.7638100974309978,39.782171171385329],"rgb":[0.2,0.466666666666666674,0.2],"xyz":[0.0855922445575351271,0.141360012484038511,0.0540955436066435091],"hpluv":[127.715012949239792,143.636966976451419,44.4273451577554681],"hsluv":[127.715012949239792,73.1368174441878409,44.4273451577554681]},"#337744":{"lch":[44.6803728315295743,43.2379901525315873,134.305487238163835],"luv":[44.6803728315295743,-30.2010367205865329,30.9422231494797764],"rgb":[0.2,0.466666666666666674,0.266666666666666663],"xyz":[0.090050239801754,0.143143210581726105,0.0775743185595301477],"hpluv":[134.305487238163835,122.797079037201513,44.6803728315295743],"hsluv":[134.305487238163835,74.2422920898123664,44.6803728315295743]},"#337755":{"lch":[45.0155248592042057,35.7001949681147,145.791078733963843],"luv":[45.0155248592042057,-29.5238129364495734,20.071083439987369],"rgb":[0.2,0.466666666666666674,0.333333333333333315],"xyz":[0.096012653841116,0.145528176197470938,0.108976365833504049],"hpluv":[145.791078733963843,100.634662922797503,45.0155248592042057],"hsluv":[145.791078733963843,75.5860232244433377,45.0155248592042057]},"#337766":{"lch":[45.436632811343884,29.7520619336037022,165.22669317203713],"luv":[45.436632811343884,-28.7685269489331041,7.58663604567268468],"rgb":[0.2,0.466666666666666674,0.4],"xyz":[0.103597649614624171,0.148562174506874228,0.148924010240648025],"hpluv":[165.22669317203713,83.0902864995861847,45.436632811343884],"hsluv":[165.22669317203713,77.1054195363406194,45.436632811343884]},"#337777":{"lch":[45.9459628200325696,28.6191137838588361,192.177050630061018],"luv":[45.9459628200325696,-27.9751968985082726,-6.03672363647301413],"rgb":[0.2,0.466666666666666674,0.466666666666666674],"xyz":[0.11291166263482609,0.152287779714955052,0.197977812147045934],"hpluv":[192.177050630061018,79.0402219352416324,45.9459628200325696],"hsluv":[192.177050630061018,78.7308353184449743,45.9459628200325696]},"#337788":{"lch":[46.5443737533918309,33.948531272854666,216.805091226728479],"luv":[46.5443737533918309,-27.1818468531358306,-20.3383867904182836],"rgb":[0.2,0.466666666666666674,0.533333333333333326],"xyz":[0.124052079736769919,0.156743946555732649,0.256650675550618101],"hpluv":[216.805091226728479,92.5535593562344587,46.5443737533918309],"hsluv":[216.805091226728479,80.3955897349876381,46.5443737533918309]},"#337799":{"lch":[47.2314677007312085,43.7891028043947799,232.889035089769209],"luv":[47.2314677007312085,-26.4206199262946413,-34.9204290798973105],"rgb":[0.2,0.466666666666666674,0.6],"xyz":[0.137109043845842632,0.161966732199361807,0.325417353191736],"hpluv":[232.889035089769209,117.645124104106614,47.2314677007312085],"hsluv":[232.889035089769209,82.0429045074046144,47.2314677007312085]},"#3377aa":{"lch":[48.0057466772197472,55.756363166772573,242.534195481556935],"luv":[48.0057466772197472,-25.7159019754829359,-49.471854818395343],"rgb":[0.2,0.466666666666666674,0.66666666666666663],"xyz":[0.15216673681109516,0.167989809385462902,0.404721202808734581],"hpluv":[242.534195481556935,147.380673097935755,48.0057466772197472],"hsluv":[242.534195481556935,83.6292827510673078,48.0057466772197472]},"#3377bb":{"lch":[48.8647777502949623,68.5281348418467076,248.528316013511841],"luv":[48.8647777502949623,-25.0841318464231762,-63.7721851155626],"rgb":[0.2,0.466666666666666674,0.733333333333333282],"xyz":[0.169304328918431835,0.17484484622839766,0.494979187907376328],"hpluv":[248.528316013511841,177.955866809146045,48.8647777502949623],"hsluv":[248.528316013511841,85.1249045257873,48.8647777502949623]},"#3377cc":{"lch":[49.8053630390326845,81.4640551302433096,252.471981644912631],"luv":[49.8053630390326845,-24.5347040681135518,-77.6816617648812553],"rgb":[0.2,0.466666666666666674,0.8],"xyz":[0.188596704362153561,0.182561796405886462,0.596585698577646539],"hpluv":[252.471981644912631,207.553107999557341,49.8053630390326845],"hsluv":[252.471981644912631,86.5120902950020678,49.8053630390326845]},"#3377dd":{"lch":[50.8237086019957047,94.2508792352234,255.202895611269554],"luv":[50.8237086019957047,-24.0713820337122506,-91.1251710758325],"rgb":[0.2,0.466666666666666674,0.866666666666666696],"xyz":[0.210115029912787105,0.19116912662614,0.709915546477652537],"hpluv":[255.202895611269554,235.319753343529385,50.8237086019957047],"hsluv":[255.202895611269554,87.7828608732328,50.8237086019957047]},"#3377ee":{"lch":[51.9155858415672498,106.73807185779232,257.174602046687482],"luv":[51.9155858415672498,-23.6937959642247655,-104.075069141100855],"rgb":[0.2,0.466666666666666674,0.933333333333333348],"xyz":[0.233927210178961842,0.200693998732610041,0.83532636254617576],"hpluv":[257.174602046687482,260.892095272406607,51.9155858415672498],"hsluv":[257.174602046687482,88.9363454602875692,51.9155858415672498]},"#3377ff":{"lch":[53.0764799083082721,118.861737619173724,258.646767383963777],"luv":[53.0764799083082721,-23.3987809317452253,-116.535873106771263],"rgb":[0.2,0.466666666666666674,1],"xyz":[0.260098258588793207,0.211162418096542737,0.973160550837957605],"hpluv":[258.646767383963777,284.170694785425781,53.0764799083082721],"hsluv":[258.646767383963777,99.9999999999990763,53.0764799083082721]},"#aaff00":{"lch":[91.7137860391432156,115.080534629040301,111.722667154579099],"luv":[91.7137860391432156,-42.5929524944460596,106.908230966149674],"rgb":[0.66666666666666663,1,0],"xyz":[0.523356277296021299,0.800644834253704918,0.126965339384251918],"hpluv":[111.722667154579099,635.020942157405898,91.7137860391432156],"hsluv":[111.722667154579099,100.000000000002359,91.7137860391432156]},"#aaff11":{"lch":[91.7319300755291209,114.302910123776968,111.867287470019974],"luv":[91.7319300755291209,-42.5730312099484394,106.078707931238455],"rgb":[0.66666666666666663,1,0.0666666666666666657],"xyz":[0.524367942795658459,0.801049500453559826,0.132293444349007555],"hpluv":[111.867287470019974,632.205251281199821,91.7319300755291209],"hsluv":[111.867287470019974,99.9999999999902087,91.7319300755291209]},"#aaff22":{"lch":[91.76554812600844,112.870020698142184,112.139393409643191],"luv":[91.76554812600844,-42.5363318976714595,104.548084827461963],"rgb":[0.66666666666666663,1,0.133333333333333331],"xyz":[0.526243300934135405,0.801799643708950627,0.142170330544986734],"hpluv":[112.139393409643191,626.996151229530483,91.76554812600844],"hsluv":[112.139393409643191,99.9999999999901,91.76554812600844]},"#aaff33":{"lch":[91.8208541183991116,110.535111156119868,112.599114759903571],"luv":[91.8208541183991116,-42.4765495373732875,102.047800258971023],"rgb":[0.66666666666666663,1,0.2],"xyz":[0.529331051666593222,0.803034744001933753,0.158432484402597884],"hpluv":[112.599114759903571,618.449193227995465,91.8208541183991116],"hsluv":[112.599114759903571,99.9999999999900808,91.8208541183991116]},"#aaff44":{"lch":[91.9006031807778498,107.217215837920833,113.289723447654],"luv":[91.9006031807778498,-42.3916247074254713,98.4808688360338],"rgb":[0.66666666666666663,1,0.266666666666666663],"xyz":[0.533789046910812082,0.80481794209962132,0.181911259355484523],"hpluv":[113.289723447654,606.175591066234915,91.9006031807778498],"hsluv":[113.289723447654,99.9999999999900808,91.9006031807778498]},"#aaff55":{"lch":[92.0070808640835338,102.877427982590888,114.266397603879824],"luv":[92.0070808640835338,-42.2805422001356135,93.7876374559873796],"rgb":[0.66666666666666663,1,0.333333333333333315],"xyz":[0.539751460950174,0.807202907715366069,0.213313306629458438],"hpluv":[114.266397603879824,589.885725054723707,92.0070808640835338],"hsluv":[114.266397603879824,99.9999999999897,92.0070808640835338]},"#aaff66":{"lch":[92.142232175119787,97.5178938455906,115.604656391492952],"luv":[92.142232175119787,-42.1432392632638226,87.9413839126902559],"rgb":[0.66666666666666663,1,0.4],"xyz":[0.547336456723682252,0.810236906024769388,0.2532609510366024],"hpluv":[115.604656391492952,569.381090837871511,92.142232175119787],"hsluv":[115.604656391492952,99.9999999999898,92.142232175119787]},"#aaff77":{"lch":[92.3077308115560555,91.1840841453542197,117.412488820025033],"luv":[92.3077308115560555,-41.9805406670279666,80.9454841651530899],"rgb":[0.66666666666666663,1,0.466666666666666674],"xyz":[0.556650469743884102,0.813962511232850239,0.302314752943000309],"hpluv":[117.412488820025033,544.56608764574878,92.3077308115560555],"hsluv":[117.412488820025033,99.9999999999895692,92.3077308115560555]},"#aaff88":{"lch":[92.5050204995058749,83.9705472319660657,119.849478645386625],"luv":[92.5050204995058749,-41.7940850853900727,72.8306752289927601],"rgb":[0.66666666666666663,1,0.533333333333333326],"xyz":[0.567790886845828,0.818418678073627781,0.360987616346572504],"hpluv":[119.849478645386625,515.487838204951345,92.5050204995058749],"hsluv":[119.849478645386625,99.9999999999892708,92.5050204995058749]},"#aaff99":{"lch":[92.7353415895377,76.0327408171719,123.158131820453576],"luv":[92.7353415895377,-41.5862309318022625,63.6518897838709137],"rgb":[0.66666666666666663,1,0.6],"xyz":[0.580847850954900657,0.823641463717257,0.429754293987690383],"hpluv":[123.158131820453576,482.430180447041607,92.7353415895377],"hsluv":[123.158131820453576,99.9999999999891145,92.7353415895377]},"#aaffaa":{"lch":[92.9997492696274435,67.6109506527765802,127.715012949238414],"luv":[92.9997492696274435,-41.3599402641421108,53.4845397242865488],"rgb":[0.66666666666666663,1,0.66666666666666663],"xyz":[0.595905543920153269,0.829664540903358061,0.509058143604689],"hpluv":[127.715012949238414,446.121940639593902,92.9997492696274435],"hsluv":[127.715012949238414,99.9999999999887308,92.9997492696274435]},"#aaffbb":{"lch":[93.2991268167713201,59.0781485982363,134.10730048328],"luv":[93.2991268167713201,-41.1186450338129887,42.4203332421914823],"rgb":[0.66666666666666663,1,0.733333333333333282],"xyz":[0.613043136027489832,0.836519577746292819,0.599316128703330731],"hpluv":[134.10730048328,408.190288953842469,93.2991268167713201],"hsluv":[134.10730048328,99.9999999999883613,93.2991268167713201]},"#aaffcc":{"lch":[93.6341958749929404,51.0306218960527929,143.208028901391231],"luv":[93.6341958749929404,-40.8661030238149436,30.5628204644932246],"rgb":[0.66666666666666663,1,0.8],"xyz":[0.632335511471211587,0.844236527923781677,0.700922639373600886],"hpluv":[143.208028901391231,372.11656739719416,93.6341958749929404],"hsluv":[143.208028901391231,99.9999999999879492,93.6341958749929404]},"#aaffdd":{"lch":[94.005524978734,44.4262644213682094,156.066165366624773],"luv":[94.005524978734,-40.6062520520773305,18.0229094410556279],"rgb":[0.66666666666666663,1,0.866666666666666696],"xyz":[0.653853837021845186,0.852843858144035183,0.814252487273606884],"hpluv":[156.066165366624773,345.018188987702331,94.005524978734],"hsluv":[156.066165366624773,99.999999999986926,94.005524978734]},"#aaffee":{"lch":[94.4135370960349576,40.641316399200953,173.054449077896464],"luv":[94.4135370960349576,-40.3430708217409446,4.91459411670529711],"rgb":[0.66666666666666663,1,0.933333333333333348],"xyz":[0.677666017288019895,0.8623687302505052,0.939663303342130107],"hpluv":[173.054449077896464,339.745490646316398,94.4135370960349576],"hsluv":[173.054449077896464,99.9999999999862865,94.4135370960349576]},"#aaffff":{"lch":[94.8585166918378633,41.0030022313427764,192.177050630060705],"luv":[94.8585166918378633,-40.0804535568370639,-8.64889788711415264],"rgb":[0.66666666666666663,1,1],"xyz":[0.703837065697851316,0.872837149614437924,1.07749749163391195],"hpluv":[192.177050630060705,373.711432895013843,94.8585166918378633],"hsluv":[192.177050630060705,99.9999999999852491,94.8585166918378633]},"#338800":{"lch":[49.8717454753508918,71.2965557675853461,122.69380865426514],"luv":[49.8717454753508918,-38.5107906934601871,60.0009821960016509],"rgb":[0.2,0.533333333333333326,0],"xyz":[0.101689839911933699,0.183114842185751275,0.0299858551632874795],"hpluv":[122.69380865426514,181.406693814272955,49.8717454753508918],"hsluv":[122.69380865426514,100.000000000002245,49.8717454753508918]},"#338811":{"lch":[49.9202331837381053,69.5570511040883162,123.47043015419375],"luv":[49.9202331837381053,-38.361169332567485,58.0224443274741475],"rgb":[0.2,0.533333333333333326,0.0666666666666666657],"xyz":[0.102701505411570818,0.183519508385606128,0.0353139601280431092],"hpluv":[123.47043015419375,176.808802540010674,49.9202331837381053],"hsluv":[123.47043015419375,96.3624965314944291,49.9202331837381053]},"#338822":{"lch":[50.0099282713402,66.4316762124597915,124.985970570646856],"luv":[50.0099282713402,-38.0903182709230137,54.426971791721833],"rgb":[0.2,0.533333333333333326,0.133333333333333331],"xyz":[0.104576863550047847,0.184269651640996956,0.0451908463240223088],"hpluv":[124.985970570646856,168.561468288507513,50.0099282713402],"hsluv":[124.985970570646856,89.7672781446156876,50.0099282713402]},"#338833":{"lch":[50.1570811029395429,61.5658815699287487,127.715012949239991],"luv":[50.1570811029395429,-37.6619639194057143,48.7025076070614134],"rgb":[0.2,0.533333333333333326,0.2],"xyz":[0.10766461428250558,0.185504751933980055,0.061453000181633452],"hpluv":[127.715012949239991,155.756856758587162,50.1570811029395429],"hsluv":[127.715012949239991,79.3080015418374416,50.1570811029395429]},"#338844":{"lch":[50.3683877843642165,55.1600753981733334,132.238380805917416],"luv":[50.3683877843642165,-37.0795228857786441,40.8380080377971524],"rgb":[0.2,0.533333333333333326,0.266666666666666663],"xyz":[0.112122609526724454,0.187287950031667649,0.0849317751345200905],"hpluv":[132.238380805917416,138.965222681713072,50.3683877843642165],"hsluv":[132.238380805917416,79.9701630926319922,50.3683877843642165]},"#338855":{"lch":[50.648916869713247,47.7759983149871488,139.558488969535745],"luv":[50.648916869713247,-36.3608093871966886,30.990926990033774],"rgb":[0.2,0.533333333333333326,0.333333333333333315],"xyz":[0.118085023566086453,0.189672915647412482,0.116333822408493992],"hpluv":[139.558488969535745,119.695806374350084,50.648916869713247],"hsluv":[139.558488969535745,80.7922551095087726,50.648916869713247]},"#338866":{"lch":[51.0024095938582747,40.50700493167151,151.3112863122482],"luv":[51.0024095938582747,-35.5343950908498,19.4454162738124445],"rgb":[0.2,0.533333333333333326,0.4],"xyz":[0.125670019339594624,0.192706913956815773,0.156281466815637954],"hpluv":[151.3112863122482,100.78102351571394,51.0024095938582747],"hsluv":[151.3112863122482,81.7453783644028249,51.0024095938582747]},"#338877":{"lch":[51.4314426692160964,35.2513066472794421,169.271441625736571],"luv":[51.4314426692160964,-34.635118433957949,6.56225505495134165],"rgb":[0.2,0.533333333333333326,0.466666666666666674],"xyz":[0.134984032359796557,0.196432519164896596,0.205335268722035863],"hpluv":[169.271441625736571,86.9732781104886499,51.4314426692160964],"hsluv":[169.271441625736571,82.7938072280844182,51.4314426692160964]},"#338888":{"lch":[51.9375397067754818,34.4751674240590873,192.177050630061075],"luv":[51.9375397067754818,-33.6994920276336458,-7.27196025816705482],"rgb":[0.2,0.533333333333333326,0.533333333333333326],"xyz":[0.146124449461740358,0.200888686005674194,0.26400813212560803],"hpluv":[192.177050630061075,84.229522237058,51.9375397067754818],"hsluv":[192.177050630061075,83.8998231764876579,51.9375397067754818]},"#338899":{"lch":[52.5212658253882267,39.2899369869163,213.503984387174484],"luv":[52.5212658253882267,-32.7618132949538179,-21.68784770470414],"rgb":[0.2,0.533333333333333326,0.6],"xyz":[0.159181413570813085,0.206111471649303352,0.332774809766725965],"hpluv":[213.503984387174484,94.9260641143146415,52.5212658253882267],"hsluv":[213.503984387174484,85.0278067813718081,52.5212658253882267]},"#3388aa":{"lch":[53.1823203703714142,48.3403865273999855,228.783963154055925],"luv":[53.1823203703714142,-31.8514822326876157,-36.3631138545534753],"rgb":[0.2,0.533333333333333326,0.66666666666666663],"xyz":[0.174239106536065613,0.212134548835404446,0.412078659383724566],"hpluv":[228.783963154055925,115.340588590435829,53.1823203703714142],"hsluv":[228.783963154055925,86.1470646970195588,53.1823203703714142]},"#3388bb":{"lch":[53.9196335036436238,59.7107302664646866,238.732819450220632],"luv":[53.9196335036436238,-30.9916356267104831,-51.0381213421469],"rgb":[0.2,0.533333333333333326,0.733333333333333282],"xyz":[0.191376698643402288,0.218989585678339205,0.502336644482366257],"hpluv":[238.732819450220632,140.522147305520861,53.9196335036436238],"hsluv":[238.732819450220632,87.2332789223686262,53.9196335036436238]},"#3388cc":{"lch":[54.7314676322995268,72.1439684856409826,245.254262274299492],"luv":[54.7314676322995268,-30.1989009668194051,-65.5192992121664446],"rgb":[0.2,0.533333333333333326,0.8],"xyz":[0.210669074087124014,0.226706535855828,0.603943155152636413],"hpluv":[245.254262274299492,167.263916186866481,54.7314676322995268],"hsluv":[245.254262274299492,88.2687848362996,54.7314676322995268]},"#3388dd":{"lch":[55.6155220749816692,84.9545141717074728,249.692682338977761],"luv":[55.6155220749816692,-29.4839257322198733,-79.6741338300441697],"rgb":[0.2,0.533333333333333326,0.866666666666666696],"xyz":[0.232187399637757558,0.23531386607608154,0.717273003052642411],"hpluv":[249.692682338977761,193.833915517882872,55.6155220749816692],"hsluv":[249.692682338977761,89.2420383366021923,55.6155220749816692]},"#3388ee":{"lch":[56.5690381344568323,97.7754852991564434,252.83721230554255],"luv":[56.5690381344568323,-28.8523290085395629,-93.4215640859675602],"rgb":[0.2,0.533333333333333326,0.933333333333333348],"xyz":[0.255999579903932295,0.244838738182551585,0.842683819121165634],"hpluv":[252.83721230554255,219.32619909500923,56.5690381344568323],"hsluv":[252.83721230554255,90.146641202583325,56.5690381344568323]},"#3388ff":{"lch":[57.5889013880528182,110.410831334845568,255.145344615238457],"luv":[57.5889013880528182,-28.3057941013035759,-106.720821287817699],"rgb":[0.2,0.533333333333333326,1],"xyz":[0.282170628313763716,0.255307157546484254,0.980518007412947479],"hpluv":[255.145344615238457,243.283252172694205,57.5889013880528182],"hsluv":[255.145344615238457,99.9999999999988489,57.5889013880528182]},"#339900":{"lch":[55.5688440832231,80.82821284508357,123.866754715109295],"luv":[55.5688440832231,-45.0426054376311527,67.1145564473163603],"rgb":[0.2,0.6,0],"xyz":[0.127559440364401172,0.23485404309068697,0.0386090553141097345],"hpluv":[123.866754715109295,184.574176757765827,55.5688440832231],"hsluv":[123.866754715109295,100.00000000000226,55.5688440832231]},"#339911":{"lch":[55.6099261578814463,79.3206910999707446,124.475743785225987],"luv":[55.6099261578814463,-44.9000555787807372,65.3892731692238556],"rgb":[0.2,0.6,0.0666666666666666657],"xyz":[0.128571105864038304,0.235258709290541823,0.0439371602788653642],"hpluv":[124.475743785225987,180.997883954149785,55.6099261578814463],"hsluv":[124.475743785225987,97.1571693172972601,55.6099261578814463]},"#339922":{"lch":[55.6859569378682124,76.5942224429011418,125.649114872203555],"luv":[55.6859569378682124,-44.6406262928881503,62.240576763164114],"rgb":[0.2,0.6,0.133333333333333331],"xyz":[0.130446464002515305,0.236008852545932651,0.0538140464748445638],"hpluv":[125.649114872203555,174.537861698610129,55.6859569378682124],"hsluv":[125.649114872203555,91.9778413864117113,55.6859569378682124]},"#339933":{"lch":[55.8107903110879278,72.2971425020977563,127.715012949240148],"luv":[55.8107903110879278,-44.2266447414942618,57.191613973364035],"rgb":[0.2,0.6,0.2],"xyz":[0.133534214734973067,0.23724395283891575,0.070076200332455707],"hpluv":[127.715012949240148,164.377468022308932,55.8107903110879278],"hsluv":[127.715012949240148,83.6974291768240874,55.8107903110879278]},"#339944":{"lch":[55.9902586993563602,66.5149718399310501,131.021169741293448],"luv":[55.9902586993563602,-43.6562926505411042,50.1833597009719128],"rgb":[0.2,0.6,0.266666666666666663],"xyz":[0.137992209979191927,0.239027150936603344,0.0935549752853423455],"hpluv":[131.021169741293448,150.746162046382238,55.9902586993563602],"hsluv":[131.021169741293448,84.1112663411127386,55.9902586993563602]},"#339955":{"lch":[56.2289015921924,59.572114639014508,136.121417864766215],"luv":[56.2289015921924,-42.9401916463123783,41.2913645202220323],"rgb":[0.2,0.6,0.333333333333333315],"xyz":[0.143954624018553912,0.241412116552348177,0.124957022559316261],"hpluv":[136.121417864766215,134.438216783596687,56.2289015921924],"hsluv":[136.121417864766215,84.6329955380286236,56.2289015921924]},"#339966":{"lch":[56.5302268191487514,52.1043875673731947,143.898662284026642],"luv":[56.5302268191487514,-42.0991012865816785,30.700698275986678],"rgb":[0.2,0.6,0.4],"xyz":[0.151539619792062097,0.244446114861751468,0.164904666966460223],"hpluv":[143.898662284026642,116.958797396111564,56.5302268191487514],"hsluv":[143.898662284026642,85.2491724948614689,56.5302268191487514]},"#339977":{"lch":[56.8968484427531678,45.1992705399313124,155.596009487994166],"luv":[56.8968484427531678,-41.1609366004351855,18.6748856895258584],"rgb":[0.2,0.6,0.466666666666666674],"xyz":[0.160853632812264,0.248171720069832291,0.213958468872858132],"hpluv":[155.596009487994166,100.805108459810327,56.8968484427531678],"hsluv":[155.596009487994166,85.9413862611579873,56.8968484427531678]},"#339988":{"lch":[57.330574208667926,40.5351988689668303,172.17134267960472],"luv":[57.330574208667926,-40.1574041849560217,5.52134371985359085],"rgb":[0.2,0.6,0.533333333333333326],"xyz":[0.171994049914207858,0.252627886910609889,0.272631332276430272],"hpluv":[172.17134267960472,89.7191897797317,57.330574208667926],"hsluv":[172.17134267960472,86.6885468018933665,57.330574208667926]},"#339999":{"lch":[57.8324724587931627,40.0212192418936539,192.177050630061103],"luv":[57.8324724587931627,-39.1207602326874735,-8.44180717763071],"rgb":[0.2,0.6,0.6],"xyz":[0.185051014023280558,0.257850672554239047,0.341398009917548206],"hpluv":[192.177050630061103,87.8128114771670312,57.8324724587931627],"hsluv":[192.177050630061103,87.4690863712762194,57.8324724587931627]},"#3399aa":{"lch":[58.4029323329449568,44.4430671798845367,211.035048784986628],"luv":[58.4029323329449568,-38.0811346860811923,-22.913170914918652],"rgb":[0.2,0.6,0.66666666666666663],"xyz":[0.200108706988533114,0.263873749740340169,0.420701859534546807],"hpluv":[211.035048784986628,96.5625435737210154,58.4029323329449568],"hsluv":[211.035048784986628,88.2627766327166,58.4029323329449568]},"#3399bb":{"lch":[59.0417237507550823,52.8166449153409445,225.431517702392057],"luv":[59.0417237507550823,-37.064675814253917,-37.6272213549907448],"rgb":[0.2,0.6,0.733333333333333282],"xyz":[0.217246299095869733,0.270728786583274927,0.510959844633188554],"hpluv":[225.431517702392057,113.514439229551684,59.0417237507550823],"hsluv":[225.431517702392057,89.0519907331041196,59.0417237507550823]},"#3399cc":{"lch":[59.7480598269018373,63.5982744854026194,235.423336237979868],"luv":[59.7480598269018373,-36.0925574956591646,-52.364757336811472],"rgb":[0.2,0.6,0.8],"xyz":[0.236538674539591487,0.278445736760763729,0.612566355303458709],"hpluv":[235.423336237979868,135.070607162709791,59.7480598269018373],"hsluv":[235.423336237979868,89.8223822716188636,59.7480598269018373]},"#3399dd":{"lch":[60.5206621982976856,75.6357863680042186,242.281144195606601],"luv":[60.5206621982976856,-35.1807304699237235,-66.9558689220665286],"rgb":[0.2,0.6,0.866666666666666696],"xyz":[0.25805700009022503,0.287053066981017235,0.725896203203464707],"hpluv":[242.281144195606601,158.58531958905732,60.5206621982976856],"hsluv":[242.281144195606601,90.5630616197976508,60.5206621982976856]},"#3399ee":{"lch":[61.3578284965586818,88.2341933332873083,247.095644636752098],"luv":[61.3578284965586818,-34.3402162860227946,-81.277441019049661],"rgb":[0.2,0.6,0.933333333333333348],"xyz":[0.28186918035639974,0.296577939087487252,0.85130701927198793],"hpluv":[247.095644636752098,182.476215369006297,61.3578284965586818],"hsluv":[247.095644636752098,91.2664056494933504,61.3578284965586818]},"#3399ff":{"lch":[62.2575005434706554,100.992674077385175,250.5808182685887],"luv":[62.2575005434706554,-33.5777301361133595,-95.2473425151972],"rgb":[0.2,0.6,1],"xyz":[0.308040228766231161,0.30704635845142,0.989141207563769775],"hpluv":[250.5808182685887,205.84367033720622,62.2575005434706554],"hsluv":[250.5808182685887,99.9999999999985789,62.2575005434706554]},"#220000":{"lch":[3.07250446727781679,10.3329293192956264,12.1770506300617765],"luv":[3.07250446727781679,10.1004431663672367,2.17955870775360072],"rgb":[0.133333333333333331,0,0],"xyz":[0.00659672420629513,0.00340143591887099878,0.000309221447170077699],"hpluv":[12.1770506300617765,426.746789183125429,3.07250446727781679],"hsluv":[12.1770506300617765,100.000000000002217,3.07250446727781679]},"#220011":{"lch":[3.43803794680403607,8.12070857757986353,344.488545895364155],"luv":[3.43803794680403607,7.82492808895188574,-2.17172931202554675],"rgb":[0.133333333333333331,0,0.0666666666666666657],"xyz":[0.00760838970593225201,0.00380610211872585338,0.00563732641192570948],"hpluv":[344.488545895364155,299.724735916282839,3.43803794680403607],"hsluv":[344.488545895364155,99.9999999999976836,3.43803794680403607]},"#220022":{"lch":[4.11563957101797229,9.37475958111893348,307.715012949243601],"luv":[4.11563957101797229,5.73486236359989565,-7.41602797151862436],"rgb":[0.133333333333333331,0,0.133333333333333331],"xyz":[0.00948374784440927,0.00455624537411667124,0.0155142126079049047],"hpluv":[307.715012949243601,289.042783730483393,4.11563957101797229],"hsluv":[307.715012949243601,99.9999999999988205,4.11563957101797229]},"#220033":{"lch":[5.23130109110515384,14.2535250315243012,286.735013267555587],"luv":[5.23130109110515384,4.10424250296207127,-13.6498413654214126],"rgb":[0.133333333333333331,0,0.2],"xyz":[0.0125714985768670112,0.00579134566709978496,0.0317763664655160497],"hpluv":[286.735013267555587,345.74180296647927,5.23130109110515384],"hsluv":[286.735013267555587,99.9999999999995737,5.23130109110515384]},"#220044":{"lch":[6.84205732813722722,21.3889830656619786,277.641816515271671],"luv":[6.84205732813722722,2.84430225454687724,-21.1990221771654959],"rgb":[0.133333333333333331,0,0.266666666666666663],"xyz":[0.01702949382108589,0.0075745437647873606,0.0552551414184026882],"hpluv":[277.641816515271671,396.682237683346386,6.84205732813722722],"hsluv":[277.641816515271671,100.000000000000085,6.84205732813722722]},"#220055":{"lch":[8.95766614306443,30.4428627575942237,273.263558660643355],"luv":[8.95766614306443,1.73308321478426808,-30.3934913336449455],"rgb":[0.133333333333333331,0,0.333333333333333315],"xyz":[0.0229919078604478855,0.00995950938053219263,0.0866571886923766],"hpluv":[273.263558660643355,431.250830347711485,8.95766614306443],"hsluv":[273.263558660643355,100.000000000000242,8.95766614306443]},"#220066":{"lch":[11.2709410858812937,40.3162667149428913,270.881506896841],"luv":[11.2709410858812937,0.620249265146302853,-40.3114952920317435],"rgb":[0.133333333333333331,0,0.4],"xyz":[0.0305769036339560568,0.0129935076899355059,0.126604833099520558],"hpluv":[270.881506896841,453.899240935372916,11.2709410858812937],"hsluv":[270.881506896841,100.000000000000469,11.2709410858812937]},"#220077":{"lch":[13.6616791408408957,50.492834518379162,269.459540268375122],"luv":[13.6616791408408957,-0.476281836738408071,-50.4905881656414763],"rgb":[0.133333333333333331,0,0.466666666666666674],"xyz":[0.0398909166541579763,0.0167191128980163223,0.175658635005918468],"hpluv":[269.459540268375122,468.991527020998944,13.6616791408408957],"hsluv":[269.459540268375122,100.000000000000711,13.6616791408408957]},"#220088":{"lch":[16.0923146306383913,60.7890037695263104,268.549935621017426],"luv":[16.0923146306383913,-1.53830805749361632,-60.7695366743217278],"rgb":[0.133333333333333331,0,0.533333333333333326],"xyz":[0.0510313337561018043,0.0211752797387939132,0.234331498409490635],"hpluv":[268.549935621017426,479.34239057424071,16.0923146306383913],"hsluv":[268.549935621017426,100.000000000000711,16.0923146306383913]},"#220099":{"lch":[18.5394450926422749,71.1015482986176437,267.936483797094468],"luv":[18.5394450926422749,-2.56017951479828287,-71.0554406876254916],"rgb":[0.133333333333333331,0,0.6],"xyz":[0.0640882978651745178,0.0263980653824230742,0.30309817605060857],"hpluv":[267.936483797094468,486.655519564945394,18.5394450926422749],"hsluv":[267.936483797094468,100.000000000000739,18.5394450926422749]},"#2200aa":{"lch":[20.9885603179873783,81.3727160976321,267.505178931910336],"luv":[20.9885603179873783,-3.54207977840461252,-81.2955878012407851],"rgb":[0.133333333333333331,0,0.66666666666666663],"xyz":[0.0791459908304270598,0.0324211425685241791,0.382402025667607171],"hpluv":[267.505178931910336,491.966452636739518,20.9885603179873783],"hsluv":[267.505178931910336,100.000000000000782,20.9885603179873783]},"#2200bb":{"lch":[23.4306921856835828,91.57073581353,267.191578225858507],"luv":[23.4306921856835828,-4.48665301772878333,-91.4607544366971155],"rgb":[0.133333333333333331,0,0.733333333333333282],"xyz":[0.0962835829377637,0.0392761794114589377,0.472660010766248917],"hpluv":[267.191578225858507,495.919187528698728,23.4306921856835828],"hsluv":[267.191578225858507,100.000000000000909,23.4306921856835828]},"#2200cc":{"lch":[25.860342630381858,101.678845182637474,266.957159441292106],"luv":[25.860342630381858,-5.39738007409318588,-101.535490573545474],"rgb":[0.133333333333333331,0,0.8],"xyz":[0.115575958381485447,0.0469931295889477393,0.574266521436519],"hpluv":[266.957159441292106,498.925449111647538,25.860342630381858],"hsluv":[266.957159441292106,100.000000000000881,25.860342630381858]},"#2200dd":{"lch":[28.2742062228116282,111.689036790699618,266.777814373778199],"luv":[28.2742062228116282,-6.27782958394359714,-111.512464751476173],"rgb":[0.133333333333333331,0,0.866666666666666696],"xyz":[0.137094283932118977,0.0556004598092012733,0.687596369336525],"hpluv":[266.777814373778199,501.255846139694427,28.2742062228116282],"hsluv":[266.777814373778199,100.000000000000838,28.2742062228116282]},"#2200ee":{"lch":[30.6703766456275062,121.598437280905173,266.637867063772376],"luv":[30.6703766456275062,-7.13133722672581882,-121.389142753859758],"rgb":[0.133333333333333331,0,0.933333333333333348],"xyz":[0.160906464198293714,0.0651253319156713,0.813007185405048238],"hpluv":[266.637867063772376,503.092926092128948,30.6703766456275062],"hsluv":[266.637867063772376,100.000000000000838,30.6703766456275062]},"#2200ff":{"lch":[33.0478477502328261,131.407178056457695,266.526788769360394],"luv":[33.0478477502328261,-7.96089030872800674,-131.165813649189772],"rgb":[0.133333333333333331,0,1],"xyz":[0.187077512608125107,0.0755937512796040073,0.950841373696830083],"hpluv":[266.526788769360394,504.562807291912918,33.0478477502328261],"hsluv":[266.526788769360394,100.000000000000824,33.0478477502328261]},"#221100":{"lch":[6.69363913087575835,9.72440836304526535,42.3457761997067053],"luv":[6.69363913087575835,7.18724369375563921,6.55039282011655288],"rgb":[0.133333333333333331,0.0666666666666666657,0],"xyz":[0.00860112446722354,0.00741023644072787233,0.000977354867479528471],"hpluv":[42.3457761997067053,184.348759610596915,6.69363913087575835],"hsluv":[42.3457761997067053,100.000000000002402,6.69363913087575835]},"#221111":{"lch":[7.0591726104019763,6.19439175917428564,12.1770506300621],"luv":[7.0591726104019763,6.05502079617615863,1.30660339200560327],"rgb":[0.133333333333333331,0.0666666666666666657,0.0666666666666666657],"xyz":[0.00961278996686066103,0.00781490264058272606,0.00630545983223516],"hpluv":[12.1770506300621,111.348454543071412,7.0591726104019763],"hsluv":[12.1770506300621,26.092394217240134,7.0591726104019763]},"#221122":{"lch":[7.73677423461591474,7.55259268754738677,307.715012949245249],"luv":[7.73677423461591474,4.62018030186617779,-5.97457866985129],"rgb":[0.133333333333333331,0.0666666666666666657,0.133333333333333331],"xyz":[0.0114881481053376797,0.00856504589597354565,0.0161823460282143547],"hpluv":[307.715012949245249,123.872660774597591,7.73677423461591474],"hsluv":[307.715012949245249,42.856167926372315,7.73677423461591474]},"#221133":{"lch":[8.8238329822443653,14.9761175001236957,282.095598903329574],"luv":[8.8238329822443653,3.13814740657790647,-14.6436377390353236],"rgb":[0.133333333333333331,0.0666666666666666657,0.2],"xyz":[0.0145758988377954202,0.00980014618895665851,0.0324444998858255],"hpluv":[282.095598903329574,215.36805510923017,8.8238329822443653],"hsluv":[282.095598903329574,58.3941618505161273,8.8238329822443653]},"#221144":{"lch":[10.2463738670161,23.9334379374521049,274.255517801158362],"luv":[10.2463738670161,1.77596948547040223,-23.8674544912638211],"rgb":[0.133333333333333331,0.0666666666666666657,0.266666666666666663],"xyz":[0.0190338940820143,0.011583344286644235,0.0559232748387121364],"hpluv":[274.255517801158362,296.397281412249697,10.2463738670161],"hsluv":[274.255517801158362,70.1230959508528287,10.2463738670161]},"#221155":{"lch":[11.9365395500671561,33.3852442414483903,270.945812779521702],"luv":[11.9365395500671561,0.551083463009601,-33.3806956200430349],"rgb":[0.133333333333333331,0.0666666666666666657,0.333333333333333315],"xyz":[0.0249963081213762928,0.0139683099023890662,0.0873253221126860518],"hpluv":[270.945812779521702,354.907717298979946,11.9365395500671561],"hsluv":[270.945812779521702,78.3035236172291,11.9365395500671561]},"#221166":{"lch":[13.8282163263251512,43.1006504094303509,269.247085426223],"luv":[13.8282163263251512,-0.566362377205730683,-43.0969291176716496],"rgb":[0.133333333333333331,0.0666666666666666657,0.4],"xyz":[0.0325813038948844641,0.0170023082117923795,0.12727296651983],"hpluv":[269.247085426223,395.509560036398682,13.8282163263251512],"hsluv":[269.247085426223,83.9084652674952167,13.8282163263251512]},"#221177":{"lch":[15.8647012598499089,52.9790758801604,268.263491631539182],"luv":[15.8647012598499089,-1.60543281970815044,-52.954745458525224],"rgb":[0.133333333333333331,0.0666666666666666657,0.466666666666666674],"xyz":[0.0418953169150863836,0.0207279134198731958,0.176326768426227909],"hpluv":[268.263491631539182,423.75204448359591,15.8647012598499089],"hsluv":[268.263491631539182,87.783734282584831,15.8647012598499089]},"#221188":{"lch":[18.0016522099437424,62.9493123294311872,267.645454528547475],"luv":[18.0016522099437424,-2.58614693443793442,-62.8961665507666297],"rgb":[0.133333333333333331,0.0666666666666666657,0.533333333333333326],"xyz":[0.0530357340170302116,0.0251840802606507867,0.234999631829800076],"hpluv":[267.645454528547475,443.729139668046173,18.0016522099437424],"hsluv":[267.645454528547475,90.5156952975567464,18.0016522099437424]},"#221199":{"lch":[20.2061107483083475,72.9561611588118524,267.23334268313738],"luv":[20.2061107483083475,-3.52148568403582729,-72.8711231531918742],"rgb":[0.133333333333333331,0.0666666666666666657,0.6],"xyz":[0.066092698126102925,0.0304068659042799477,0.303766309470918],"hpluv":[267.23334268313738,458.161478440778865,20.2061107483083475],"hsluv":[267.23334268313738,92.4853336382361704,20.2061107483083475]},"#2211aa":{"lch":[22.4542330055690798,82.9584275230068471,266.945798214496847],"luv":[22.4542330055690798,-4.42007776686241449,-82.8405915576709759],"rgb":[0.133333333333333331,0.0666666666666666657,0.66666666666666663],"xyz":[0.0811503910913554671,0.0364299430903810492,0.383070159087916584],"hpluv":[266.945798214496847,468.815123306781686,22.4542330055690798],"hsluv":[266.945798214496847,93.9373181855700921,22.4542330055690798]},"#2211bb":{"lch":[24.7289983316777295,92.9268656932788701,266.737844101991243],"luv":[24.7289983316777295,-5.28796663316276483,-92.7762888698575097],"rgb":[0.133333333333333331,0.0666666666666666657,0.733333333333333282],"xyz":[0.0982879831986921138,0.0432849799333158078,0.473328144186558331],"hpluv":[266.737844101991243,476.841549380862261,24.7289983316777295],"hsluv":[266.737844101991243,95.0302193246277369,24.7289983316777295]},"#2211cc":{"lch":[27.0183279904475668,102.841627589427389,266.583003116257],"luv":[27.0183279904475668,-6.12961814831514129,-102.658794784462174],"rgb":[0.133333333333333331,0.0666666666666666657,0.8],"xyz":[0.117580358642413854,0.0510019301108046094,0.574934654856828486],"hpluv":[266.583003116257,483.002966655360069,27.0183279904475668],"hsluv":[266.583003116257,95.8686128249461689,27.0183279904475668]},"#2211dd":{"lch":[29.313669578695368,112.689841457512074,266.464886381494523],"luv":[29.313669578695368,-6.94848190374932617,-112.475414944566779],"rgb":[0.133333333333333331,0.0666666666666666657,0.866666666666666696],"xyz":[0.139098684193047384,0.0596092603310581434,0.688264502756834484],"hpluv":[266.464886381494523,487.813602393737767,29.313669578695368],"hsluv":[266.464886381494523,96.5228774582602256,29.313669578695368]},"#2211ee":{"lch":[31.6089746608533417,122.463629630364608,266.372923821556242],"luv":[31.6089746608533417,-7.74731231829930689,-122.21832814306471],"rgb":[0.133333333333333331,0.0666666666666666657,0.933333333333333348],"xyz":[0.162910864459222149,0.0691341324375281813,0.813675318825357707],"hpluv":[266.372923821556242,491.627361233059389,31.6089746608533417],"hsluv":[266.372923821556242,97.0413663214109761,31.6089746608533417]},"#2211ff":{"lch":[33.8999739889387115,132.15860685194221,266.300059947999785],"luv":[33.8999739889387115,-8.52836196764118,-131.883146789857562],"rgb":[0.133333333333333331,0.0666666666666666657,1],"xyz":[0.189081912869053514,0.0796025518014608774,0.951509507117139552],"hpluv":[266.300059947999785,494.692599475339,33.8999739889387115],"hsluv":[266.300059947999785,99.9999999999995737,33.8999739889387115]},"#77aa00":{"lch":[63.8935034159882491,78.4053265973676616,109.262687899665323],"luv":[63.8935034159882491,-25.8658938451783591,74.0158819067222424],"rgb":[0.466666666666666674,0.66666666666666663,0],"xyz":[0.219816749274909073,0.326708497135311,0.0514797056256764834],"hpluv":[109.262687899665323,155.714190603412163,63.8935034159882491],"hsluv":[109.262687899665323,100.000000000002132,63.8935034159882491]},"#77aa11":{"lch":[63.9264755829735662,77.0719876411919,109.595002167467626],"luv":[63.9264755829735662,-25.8475857965541422,72.6084952843247464],"rgb":[0.466666666666666674,0.66666666666666663,0.0666666666666666657],"xyz":[0.220828414774546206,0.32711316333516588,0.0568078105904321132],"hpluv":[109.595002167467626,152.98720995680398,63.9264755829735662],"hsluv":[109.595002167467626,97.9667163347824612,63.9264755829735662]},"#77aa22":{"lch":[63.9875253363426424,74.6349938152274603,110.235118064089221],"luv":[63.9875253363426424,-25.8142561390327501,70.0286118796271],"rgb":[0.466666666666666674,0.66666666666666663,0.133333333333333331],"xyz":[0.222703772913023207,0.32786330659055668,0.0666846967864113127],"hpluv":[110.235118064089221,148.008450888663447,63.9875253363426424],"hsluv":[110.235118064089221,94.2440053809013421,63.9875253363426424]},"#77aa33":{"lch":[64.0878403339217328,70.7199026331045,111.362593229805157],"luv":[64.0878403339217328,-25.7610573917560757,65.8610093340090685],"rgb":[0.466666666666666674,0.66666666666666663,0.2],"xyz":[0.22579152364548094,0.329098406883539807,0.0829468506440224629],"hpluv":[111.362593229805157,140.024923426145421,64.0878403339217328],"hsluv":[111.362593229805157,88.2427941375042,64.0878403339217328]},"#77aa44":{"lch":[64.2322300921174616,65.2796522257345,113.17268826837423],"luv":[64.2322300921174616,-25.6877867579927681,60.0130869576689463],"rgb":[0.466666666666666674,0.66666666666666663,0.266666666666666663],"xyz":[0.230249518889699828,0.330881604981227373,0.106425625596909101],"hpluv":[113.17268826837423,128.962712139229978,64.2322300921174616],"hsluv":[113.17268826837423,79.8488372015295482,64.2322300921174616]},"#77aa55":{"lch":[64.4245377454048338,58.3957340906732298,115.996670283872277],"luv":[64.4245377454048338,-25.5959546947607706,52.487225714952487],"rgb":[0.466666666666666674,0.66666666666666663,0.333333333333333315],"xyz":[0.236211932929061841,0.333266570596972234,0.137827672870883],"hpluv":[115.996670283872277,115.018880896771989,64.4245377454048338],"hsluv":[115.996670283872277,69.0944053471027075,64.4245377454048338]},"#77aa66":{"lch":[64.6678576456364,50.3036055521827663,120.443938093288892],"luv":[64.6678576456364,-25.4885877435648602,43.368013862617552],"rgb":[0.466666666666666674,0.66666666666666663,0.4],"xyz":[0.24379692870257,0.336300568906375552,0.177775317278026979],"hpluv":[120.443938093288892,98.707457943709727,64.6678576456364],"hsluv":[120.443938093288892,56.1391996219007723,64.6678576456364]},"#77aa77":{"lch":[64.964649263009,41.4721527505437351,127.71501294923786],"luv":[64.964649263009,-25.3699399849719889,32.8070967768157118],"rgb":[0.466666666666666674,0.66666666666666663,0.466666666666666674],"xyz":[0.253110941722771932,0.340026174114456348,0.226829119184424888],"hpluv":[127.71501294923786,81.006302212696113,64.964649263009],"hsluv":[127.71501294923786,41.2466460512923874,64.964649263009]},"#77aa88":{"lch":[65.3168057391263375,32.8409027786736161,140.238161573904051],"luv":[65.3168057391263375,-25.2451203613846147,21.004970679758074],"rgb":[0.466666666666666674,0.66666666666666663,0.533333333333333326],"xyz":[0.264251358824715732,0.344482340955233945,0.285501982587997],"hpluv":[140.238161573904051,63.8012923553667,65.3168057391263375],"hsluv":[140.238161573904051,43.6199696205744232,65.3168057391263375]},"#77aa99":{"lch":[65.7257012160132,26.4214783611449491,161.939459903532622],"luv":[65.7257012160132,-25.1196781367095241,8.19123245284666],"rgb":[0.466666666666666674,0.66666666666666663,0.6],"xyz":[0.277308322933788487,0.349705126598863103,0.354268660229114962],"hpluv":[161.939459903532622,51.0106916742292213,65.7257012160132],"hsluv":[161.939459903532622,46.1685656356417766,65.7257012160132]},"#77aaaa":{"lch":[66.1922284915170565,25.5746156232648509,192.177050630060677],"luv":[66.1922284915170565,-24.9991985449953802,-5.39453764336142338],"rgb":[0.466666666666666674,0.66666666666666663,0.66666666666666663],"xyz":[0.292366015899041,0.355728203784964225,0.433572509846113563],"hpluv":[192.177050630060677,49.0276908522131265,66.1922284915170565],"hsluv":[192.177050630060677,48.8357820868943122,66.1922284915170565]},"#77aabb":{"lch":[66.7168329685055568,31.6300901405034409,218.105494045696133],"luv":[66.7168329685055568,-24.8889541052261336,-19.519287021925777],"rgb":[0.466666666666666674,0.66666666666666663,0.733333333333333282],"xyz":[0.309503608006377662,0.362583240627899,0.523830494944755309],"hpluv":[218.105494045696133,60.1595160354738923,66.7168329685055568],"hsluv":[218.105494045696133,51.56699221483656,66.7168329685055568]},"#77aacc":{"lch":[67.2995460165272306,42.0550186755790207,233.874741843371567],"luv":[67.2995460165272306,-24.7936410920562054,-33.9691029790543908],"rgb":[0.466666666666666674,0.66666666666666663,0.8],"xyz":[0.328795983450099416,0.370300190805387786,0.625437005615025465],"hpluv":[233.874741843371567,79.2948573353567099,67.2995460165272306],"hsluv":[233.874741843371567,54.3124963748670382,67.2995460165272306]},"#77aadd":{"lch":[67.9400192524912,54.4863937886276304,243.022531341574677],"luv":[67.9400192524912,-24.7172120267711577,-48.557456046554158],"rgb":[0.466666666666666674,0.66666666666666663,0.866666666666666696],"xyz":[0.350314309000732904,0.378907521025641292,0.738766853515031463],"hpluv":[243.022531341574677,101.765770647841308,67.9400192524912],"hsluv":[243.022531341574677,60.6446157506369659,67.9400192524912]},"#77aaee":{"lch":[68.6375602707836,67.7758398266106781,248.660849953701415],"luv":[68.6375602707836,-24.6627990544268876,-63.1293181256010882],"rgb":[0.466666666666666674,0.66666666666666663,0.933333333333333348],"xyz":[0.374126489266907669,0.388432393132111309,0.864177669583554686],"hpluv":[248.660849953701415,125.300382334337471,68.6375602707836],"hsluv":[248.660849953701415,79.8712566390148453,68.6375602707836]},"#77aaff":{"lch":[69.3911697465266428,81.3794470542267874,252.380781260055755],"luv":[69.3911697465266428,-24.6327125013740549,-77.5618712878715399],"rgb":[0.466666666666666674,0.66666666666666663,1],"xyz":[0.400297537676739035,0.398900812496044033,1.00201185787533653],"hpluv":[252.380781260055755,148.816077288451226,69.3911697465266428],"hsluv":[252.380781260055755,99.9999999999980531,69.3911697465266428]},"#222200":{"lch":[12.5069288045758107,13.787646171799997,85.8743202181747307],"luv":[12.5069288045758107,0.991945128669063814,13.751917387057734],"rgb":[0.133333333333333331,0.133333333333333331,0],"xyz":[0.0123167482019914745,0.014841483910263846,0.002215896112402139],"hpluv":[85.8743202181747307,139.887458074797621,12.5069288045758107],"hsluv":[85.8743202181747307,100.000000000002359,12.5069288045758107]},"#222211":{"lch":[12.7636979604368612,8.34346759842367,85.8743202181729828],"luv":[12.7636979604368612,0.600266494900015157,8.32184665209868513],"rgb":[0.133333333333333331,0.133333333333333331,0.0666666666666666657],"xyz":[0.0133284137016285963,0.0152461501101187,0.00754400107715777046],"hpluv":[85.8743202181729828,82.9486632734846552,12.7636979604368612],"hsluv":[85.8743202181729828,59.2967120963297631,12.7636979604368612]},"#222222":{"lch":[13.2279109842717837,6.86787642036123471e-13,0],"luv":[13.2279109842717837,6.53891093021720259e-13,2.10008818196756883e-13],"rgb":[0.133333333333333331,0.133333333333333331,0.133333333333333331],"xyz":[0.0152037718401056149,0.0159962933655095202,0.0174208872731369674],"hpluv":[0,6.58825703928357502e-12,13.2279109842717837],"hsluv":[0,1.88635445986832e-12,13.2279109842717837]},"#222233":{"lch":[13.9615854376221584,10.5260121123804868,265.874320218180912],"luv":[13.9615854376221584,-0.757288539977712838,-10.4987354027615698],"rgb":[0.133333333333333331,0.133333333333333331,0.2],"xyz":[0.0182915225725633554,0.017231393658492633,0.0336830411307481106],"hpluv":[265.874320218180912,95.6683874279760431,13.9615854376221584],"hsluv":[265.874320218180912,18.6338179823007195,13.9615854376221584]},"#222244":{"lch":[14.9613810506728697,21.7214686924654536,265.874320218179207],"luv":[14.9613810506728697,-1.5627399186581008,-21.6651805001571454],"rgb":[0.133333333333333331,0.133333333333333331,0.266666666666666663],"xyz":[0.0227495178167822359,0.0190145917561802061,0.0571618160836347491],"hpluv":[265.874320218179207,184.228505509793536,14.9613810506728697],"hsluv":[265.874320218179207,35.8831222215914138,14.9613810506728697]},"#222255":{"lch":[16.2052187005970154,32.8139057554865161,265.874320218178639],"luv":[16.2052187005970154,-2.3607796110480268,-32.728873041368395],"rgb":[0.133333333333333331,0.133333333333333331,0.333333333333333315],"xyz":[0.028711931856144228,0.021399557371925039,0.0885638633576086576],"hpluv":[265.874320218178639,256.946292996249099,16.2052187005970154],"hsluv":[265.874320218178639,50.0467352240393097,16.2052187005970154]},"#222266":{"lch":[17.6604729086265309,43.5908485911403716,265.874320218178354],"luv":[17.6604729086265309,-3.13612123314657865,-43.477888915018994],"rgb":[0.133333333333333331,0.133333333333333331,0.4],"xyz":[0.0362969276296524063,0.0244335556813283505,0.128511507764752619],"hpluv":[265.874320218178354,313.207621322876264,17.6604729086265309],"hsluv":[265.874320218178354,61.00504004829466,17.6604729086265309]},"#222277":{"lch":[19.2910482951380544,54.0745009411091573,265.874320218178241],"luv":[19.2910482951380544,-3.89036222175517965,-53.9343743248547867],"rgb":[0.133333333333333331,0.133333333333333331,0.466666666666666674],"xyz":[0.0456109406498543188,0.0281591608894091669,0.177565309671150529],"hpluv":[265.874320218178241,355.693573155256843,19.2910482951380544],"hsluv":[265.874320218178241,69.2802447897283429,19.2910482951380544]},"#222288":{"lch":[21.0622605487373207,64.3390225585563371,265.874320218178184],"luv":[21.0622605487373207,-4.62883796225993471,-64.1722968492601353],"rgb":[0.133333333333333331,0.133333333333333331,0.533333333333333326],"xyz":[0.0567513577517981468,0.0326153277301867578,0.236238173074722696],"hpluv":[265.874320218178184,387.622344883614403,21.0622605487373207],"hsluv":[265.874320218178184,75.4991739133377706,21.0622605487373207]},"#222299":{"lch":[22.9434551626666803,74.4470789880776351,265.874320218178127],"luv":[22.9434551626666803,-5.35605689510984373,-74.2541596437089737],"rgb":[0.133333333333333331,0.133333333333333331,0.6],"xyz":[0.0698083218608708533,0.0378381133738159223,0.305004850715840603],"hpluv":[265.874320218178127,411.744842564929684,22.9434551626666803],"hsluv":[265.874320218178127,80.1976353712613559,22.9434551626666803]},"#2222aa":{"lch":[24.9089307040763188,84.4389391258505526,265.87432021817807],"luv":[24.9089307040763188,-6.07491614537627278,-84.2201272530844705],"rgb":[0.133333333333333331,0.133333333333333331,0.66666666666666663],"xyz":[0.0848660148261234093,0.0438611905599170238,0.384308700332839204],"hpluv":[265.87432021817807,430.157015573344836,24.9089307040763188],"hsluv":[265.87432021817807,83.7838678741945557,24.9089307040763188]},"#2222bb":{"lch":[26.937850813592469,94.3371638934954149,265.87432021817807],"luv":[26.937850813592469,-6.78703884698804139,-94.0927021354881106],"rgb":[0.133333333333333331,0.133333333333333331,0.733333333333333282],"xyz":[0.102003606933460056,0.0507162274028517823,0.47456668543148095],"hpluv":[265.87432021817807,444.384803230596,26.937850813592469],"hsluv":[265.87432021817807,86.5550863782758,26.937850813592469]},"#2222cc":{"lch":[29.0136770200274086,104.153206308830732,265.874320218178],"luv":[29.0136770200274086,-7.49324898143496743,-103.883307629821275],"rgb":[0.133333333333333331,0.133333333333333331,0.8],"xyz":[0.121295982377181782,0.058433177580340584,0.576173196101751106],"hpluv":[265.874320218178,455.521834046362642,29.0136770200274086],"hsluv":[265.874320218178,88.7243024658832695,29.0136770200274086]},"#2222dd":{"lch":[31.1234509916598299,113.892375340460845,265.874320218178],"luv":[31.1234509916598299,-8.19392849973896809,-113.597238947227837],"rgb":[0.133333333333333331,0.133333333333333331,0.866666666666666696],"xyz":[0.142814307927815326,0.067040507800594118,0.689503044001757104],"hpluv":[265.874320218178,464.350835522916555,31.1234509916598299],"hsluv":[265.874320218178,90.4439719502614565,31.1234509916598299]},"#2222ee":{"lch":[33.2570959032629503,123.556928623667645,265.874320218178],"luv":[33.2570959032629503,-8.88923982631188103,-123.236747872639071],"rgb":[0.133333333333333331,0.133333333333333331,0.933333333333333348],"xyz":[0.166626488193990063,0.0765653799070641489,0.814913860070280327],"hpluv":[265.874320218178,471.435310205520636,33.2570959032629503],"hsluv":[265.874320218178,93.8546607467714296,33.2570959032629503]},"#2222ff":{"lch":[35.4068078244889,133.147814572056944,265.874320218177957],"luv":[35.4068078244889,-9.57925119428392335,-132.802780361977625],"rgb":[0.133333333333333331,0.133333333333333331,1],"xyz":[0.192797536603821457,0.0870337992709968589,0.952748048362062172],"hpluv":[265.874320218177957,477.184793215987838,35.4068078244889],"hsluv":[265.874320218177957,99.999999999999531,35.4068078244889]},"#77bb00":{"lch":[69.0844312744863629,87.8096536524333544,113.037133893102563],"luv":[69.0844312744863629,-34.3623439699837476,80.8069588058406225],"rgb":[0.466666666666666674,0.733333333333333282,0],"xyz":[0.253771247183507853,0.394617492952509585,0.0627978715952091093],"hpluv":[113.037133893102563,161.287757631366873,69.0844312744863629],"hsluv":[113.037133893102563,100.000000000002331,69.0844312744863629]},"#77bb11":{"lch":[69.1135050244688216,86.6316159473835654,113.342165034517933],"luv":[69.1135050244688216,-34.3252912529264051,79.5412550948043275],"rgb":[0.466666666666666674,0.733333333333333282,0.0666666666666666657],"xyz":[0.254782912683144958,0.395022159152364438,0.068125976559964746],"hpluv":[113.342165034517933,159.057013433643618,69.1135050244688216],"hsluv":[113.342165034517933,98.3127503818399,69.1135050244688216]},"#77bb22":{"lch":[69.1673475306790664,84.4748154027895595,113.924619678029501],"luv":[69.1673475306790664,-34.2574435126740582,77.2167209955934197],"rgb":[0.466666666666666674,0.733333333333333282,0.133333333333333331],"xyz":[0.256658270821622,0.395772302407755239,0.0780028627559439386],"hpluv":[113.924619678029501,154.976360107776344,69.1673475306790664],"hsluv":[113.924619678029501,95.2170715716625438,69.1673475306790664]},"#77bb33":{"lch":[69.2558504240405313,80.9996568929936132,114.934551128374181],"luv":[69.2558504240405313,-34.1480550559542593,73.4496749664571666],"rgb":[0.466666666666666674,0.733333333333333282,0.2],"xyz":[0.25974602155407972,0.397007402700738365,0.0942650166135550749],"hpluv":[114.934551128374181,148.410982175614635,69.2558504240405313],"hsluv":[114.934551128374181,90.2088459481891363,69.2558504240405313]},"#77bb44":{"lch":[69.3833048234310752,76.148419012573342,116.514961433737128],"luv":[69.3833048234310752,-33.9950520676451049,68.1389620777462426],"rgb":[0.466666666666666674,0.733333333333333282,0.266666666666666663],"xyz":[0.264204016798298635,0.398790600798425932,0.117743791566441713],"hpluv":[116.514961433737128,139.266042804817573,69.3833048234310752],"hsluv":[116.514961433737128,83.166634884803841,69.3833048234310752]},"#77bb55":{"lch":[69.5531781358710788,69.9670725739878918,118.886197685461212],"luv":[69.5531781358710788,-33.7990968432466516,61.2618339356121666],"rgb":[0.466666666666666674,0.733333333333333282,0.333333333333333315],"xyz":[0.270166430837660621,0.401175566414170792,0.149145838840415629],"hpluv":[118.886197685461212,127.648598426560824,69.5531781358710788],"hsluv":[118.886197685461212,74.0801666731923092,69.5531781358710788]},"#77bb66":{"lch":[69.7683097004737647,62.6192143930699672,122.411113057511386],"luv":[69.7683097004737647,-33.5633071802414804,52.8646424591145],"rgb":[0.466666666666666674,0.733333333333333282,0.4],"xyz":[0.277751426611168806,0.404209564723574111,0.189093483247559591],"hpluv":[122.411113057511386,113.8908252780179,69.7683097004737647],"hsluv":[122.411113057511386,63.0377921091212627,69.7683097004737647]},"#77bb77":{"lch":[70.0310134677453391,54.4237865803123384,127.71501294923867],"luv":[70.0310134677453391,-33.2928991557924476,43.0526585885427053],"rgb":[0.466666666666666674,0.733333333333333282,0.466666666666666674],"xyz":[0.287065439631370711,0.407935169931654906,0.2381472851539575],"hpluv":[127.71501294923867,98.6137944921033522,70.0310134677453391],"hsluv":[127.71501294923867,50.2119979074062357,70.0310134677453391]},"#77bb88":{"lch":[70.3431390634792422,45.948041729110173,135.896820739423845],"luv":[70.3431390634792422,-32.9947227526694,31.9776610966863863],"rgb":[0.466666666666666674,0.733333333333333282,0.533333333333333326],"xyz":[0.298205856733314512,0.412391336772432504,0.296820148557529695],"hpluv":[135.896820739423845,82.8866502392756246,70.3431390634792422],"hsluv":[135.896820739423845,51.9268484553617711,70.3431390634792422]},"#77bb99":{"lch":[70.7061124793432612,38.2197788608509725,148.75629343317604],"luv":[70.7061124793432612,-32.6767203094589,19.8238100775241328],"rgb":[0.466666666666666674,0.733333333333333282,0.6],"xyz":[0.311262820842387211,0.417614122416061662,0.365586826198647574],"hpluv":[148.75629343317604,68.5915373148405,70.7061124793432612],"hsluv":[148.75629343317604,53.7921873551213565,70.7061124793432612]},"#77bbaa":{"lch":[71.1209666334754615,33.0529501718716148,168.140026251468868],"luv":[71.1209666334754615,-32.3473621836046874,6.79306078486928744],"rgb":[0.466666666666666674,0.733333333333333282,0.66666666666666663],"xyz":[0.326320513807639767,0.423637199602162784,0.444890675815646175],"hpluv":[168.140026251468868,58.9728212370576585,71.1209666334754615],"hsluv":[168.140026251468868,55.7713219876506372,71.1209666334754615]},"#77bbbb":{"lch":[71.5883672123020744,32.7520226121926044,192.177050630060876],"luv":[71.5883672123020744,-32.0151171807858432,-6.90849166534396097],"rgb":[0.466666666666666674,0.733333333333333282,0.733333333333333282],"xyz":[0.343458105914976441,0.430492236445097542,0.535148660914287921],"hpluv":[192.177050630060876,58.0543804308889762,71.5883672123020744],"hsluv":[192.177050630060876,57.8271385543864938,71.5883672123020744]},"#77bbcc":{"lch":[72.1086367753872111,38.0603267014846267,213.636027248927832],"luv":[72.1086367753872111,-31.6880044447458609,-21.0821925551758049],"rgb":[0.466666666666666674,0.733333333333333282,0.8],"xyz":[0.36275048135869814,0.438209186622586344,0.636755171584558077],"hpluv":[213.636027248927832,66.97682452789428,72.1086367753872111],"hsluv":[213.636027248927832,59.9241419588218278,72.1086367753872111]},"#77bbdd":{"lch":[72.6817787487410101,47.4106862821029651,228.567760630430627],"luv":[72.6817787487410101,-31.3732552756954277,-35.5456330249727728],"rgb":[0.466666666666666674,0.733333333333333282,0.866666666666666696],"xyz":[0.384268806909331739,0.44681651684283985,0.750085019484564075],"hpluv":[228.567760630430627,82.7732525696479371,72.6817787487410101],"hsluv":[228.567760630430627,62.0300015657167449,72.6817787487410101]},"#77bbee":{"lch":[73.3075021126589803,58.9885691422652769,238.208313348868131],"luv":[73.3075021126589803,-31.0770938488335098,-50.1384635520735316],"rgb":[0.466666666666666674,0.733333333333333282,0.933333333333333348],"xyz":[0.408080987175506449,0.456341388949309867,0.875495835553087298],"hpluv":[238.208313348868131,102.107764199280055,73.3075021126589803],"hsluv":[238.208313348868131,76.3238953534044,73.3075021126589803]},"#77bbff":{"lch":[73.9852470697490219,71.6819577745528846,244.548916872628638],"luv":[73.9852470697490219,-30.8046295043453391,-64.7254036023940102],"rgb":[0.466666666666666674,0.733333333333333282,1],"xyz":[0.43425203558533787,0.466809808313242591,1.01333002384486903],"hpluv":[244.548916872628638,122.943070755930805,73.9852470697490219],"hsluv":[244.548916872628638,99.9999999999974,73.9852470697490219]},"#223300":{"lch":[18.8330192465532917,22.9063411551717806,108.204985820955727],"luv":[18.8330192465532917,-7.15634373768739707,21.7597612446731326],"rgb":[0.133333333333333331,0.2,0],"xyz":[0.0184344702910022862,0.0270769280882856428,0.00425513680873902],"hpluv":[108.204985820955727,154.338793470845559,18.8330192465532917],"hsluv":[108.204985820955727,100.000000000002331,18.8330192465532917]},"#223311":{"lch":[19.0056890338669575,18.4529510656336271,112.754551304246377],"luv":[19.0056890338669575,-7.13731020483261602,17.0167625026225657],"rgb":[0.133333333333333331,0.2,0.0666666666666666657],"xyz":[0.0194461357906394079,0.0274815942881404957,0.0095832417734946513],"hpluv":[112.754551304246377,123.203072156705915,19.0056890338669575],"hsluv":[112.754551304246377,76.6034511576994248,19.0056890338669575]},"#223322":{"lch":[19.3213416797184507,11.6344605438365232,127.71501294923759],"luv":[19.3213416797184507,-7.11719904028337247,9.20359440474635],"rgb":[0.133333333333333331,0.2,0.133333333333333331],"xyz":[0.0213214939291164265,0.028231737543531317,0.0194601279694738491],"hpluv":[127.71501294923759,76.4096652359405084,19.3213416797184507],"hsluv":[127.71501294923759,38.9061385447444366,19.3213416797184507]},"#223333":{"lch":[19.8290945906418372,7.27996715422488894,192.177050630060677],"luv":[19.8290945906418372,-7.11617124458192585,-1.53558737438758408],"rgb":[0.133333333333333331,0.2,0.2],"xyz":[0.0244092446615741671,0.0294668378365144298,0.0357222818270849923],"hpluv":[192.177050630060677,46.5871198449043149,19.8290945906418372],"hsluv":[192.177050630060677,46.4047641905018935,19.8290945906418372]},"#223344":{"lch":[20.5377244517829496,15.5714684077650816,242.621028364370432],"luv":[20.5377244517829496,-7.16091210703038339,-13.8272183091687548],"rgb":[0.133333333333333331,0.2,0.266666666666666663],"xyz":[0.0288672399057930476,0.031250035934202,0.0592010567799716309],"hpluv":[242.621028364370432,96.2091932027738181,20.5377244517829496],"hsluv":[242.621028364370432,54.472556800898019,20.5377244517829496]},"#223355":{"lch":[21.4445377167678828,27.4997828393463344,254.670418676715883],"luv":[21.4445377167678828,-7.27014529691604761,-26.5213695644274097],"rgb":[0.133333333333333331,0.2,0.333333333333333315],"xyz":[0.0348296539451550397,0.0336350015499468358,0.0906031040539455323],"hpluv":[254.670418676715883,162.72410902482622,21.4445377167678828],"hsluv":[254.670418676715883,62.1025047738862597,21.4445377167678828]},"#223366":{"lch":[22.538163137523668,39.6650934211933617,259.172698399253136],"luv":[22.538163137523668,-7.45106225263504562,-38.9589695374422647],"rgb":[0.133333333333333331,0.2,0.4],"xyz":[0.042414649718663211,0.0366689998593501473,0.130550748461089494],"hpluv":[259.172698399253136,223.320859110196579,22.538163137523668],"hsluv":[259.172698399253136,68.7622962285398103,22.538163137523668]},"#223377":{"lch":[23.8014699151847751,51.4679604591091,261.393782909523054],"luv":[23.8014699151847751,-7.70180102721624227,-50.8884389105972517],"rgb":[0.133333333333333331,0.2,0.466666666666666674],"xyz":[0.0517286627388651304,0.0403946050674309637,0.179604550367487403],"hpluv":[261.393782909523054,274.392670476726266,23.8014699151847751],"hsluv":[261.393782909523054,74.3066649079193837,23.8014699151847751]},"#223388":{"lch":[25.214303338898695,62.8010579136007649,262.667168962641028],"luv":[25.214303338898695,-8.01548446335257658,-62.2874376089207189],"rgb":[0.133333333333333331,0.2,0.533333333333333326],"xyz":[0.0628690798408089585,0.0448507719082085615,0.238277413771059571],"hpluv":[262.667168962641028,316.052560368409843,25.214303338898695],"hsluv":[262.667168962641028,78.8060188103052184,25.214303338898695]},"#223399":{"lch":[26.7557115473943199,73.7050787305795723,263.468936800572067],"luv":[26.7557115473943199,-8.38335327394953111,-73.2267575314180732],"rgb":[0.133333333333333331,0.2,0.6],"xyz":[0.0759260439498816719,0.0500735575518377191,0.307044091412177478],"hpluv":[263.468936800572067,349.558796760350788,26.7557115473943199],"hsluv":[263.468936800572067,82.4151943494814105,26.7557115473943199]},"#2233aa":{"lch":[28.4055164492709622,84.2578478733767184,264.007358934798901],"luv":[28.4055164492709622,-8.79658068794244485,-83.7974050699281],"rgb":[0.133333333333333331,0.2,0.66666666666666663],"xyz":[0.090983736915134214,0.0560966347379388205,0.386347941029176078],"hpluv":[264.007358934798901,376.397732872534505,28.4055164492709622],"hsluv":[264.007358934798901,85.301735461295209,28.4055164492709622]},"#2233bb":{"lch":[30.1452579578322855,94.5340435151979506,264.386468786418391],"luv":[30.1452579578322855,-9.24712484322681583,-94.0806891209195868],"rgb":[0.133333333333333331,0.2,0.733333333333333282],"xyz":[0.108121329022470861,0.0629516715808735861,0.476605926127817825],"hpluv":[264.386468786418391,397.931717533943186,30.1452579578322855],"hsluv":[264.386468786418391,87.6154589527103553,30.1452579578322855]},"#2233cc":{"lch":[31.9586404471462444,104.593501952517812,264.663323368501551],"luv":[31.9586404471462444,-9.72802821613955615,-104.140127317558722],"rgb":[0.133333333333333331,0.2,0.8],"xyz":[0.127413704466192601,0.0706686217583623877,0.578212436798088],"hpluv":[264.663323368501551,415.294074833826699,31.9586404471462444],"hsluv":[264.663323368501551,89.4797268300864,31.9586404471462444]},"#2233dd":{"lch":[33.8316358854510284,114.480561125644712,264.87147297862515],"luv":[33.8316358854510284,-10.233440845943651,-114.022259072932982],"rgb":[0.133333333333333331,0.2,0.866666666666666696],"xyz":[0.148932030016826145,0.0792759519786159217,0.691542284698094],"hpluv":[264.87147297862515,429.386195390892226,33.8316358854510284],"hsluv":[264.87147297862515,90.9921469937159,33.8316358854510284]},"#2233ee":{"lch":[35.7523793143002209,124.226868169083772,265.031742065807748],"luv":[35.7523793143002209,-10.7585230682670669,-123.760126682580946],"rgb":[0.133333333333333331,0.2,0.933333333333333348],"xyz":[0.172744210283000882,0.0888008240850859387,0.816953100766617202],"hpluv":[265.031742065807748,440.909964314972513,35.7523793143002209],"hsluv":[265.031742065807748,93.1343838757889557,35.7523793143002209]},"#2233ff":{"lch":[37.7109573358094536,133.854664271403067,265.157628752861342],"luv":[37.7109573358094536,-11.2993072928814158,-133.376897556927247],"rgb":[0.133333333333333331,0.2,1],"xyz":[0.198915258692832275,0.0992692434490186487,0.954787289058399],"hpluv":[265.157628752861342,450.407151983715153,37.7109573358094536],"hsluv":[265.157628752861342,99.9999999999994884,37.7109573358094536]},"#77cc00":{"lch":[74.2578384949046892,97.2071675743180776,115.806356387580706],"luv":[74.2578384949046892,-42.3172913249353897,87.5127435448238202],"rgb":[0.466666666666666674,0.8,0],"xyz":[0.291994990493124773,0.47106497957174448,0.0755391193650810505],"hpluv":[115.806356387580706,166.109821583261578,74.2578384949046892],"hsluv":[115.806356387580706,100.000000000002331,74.2578384949046892]},"#77cc11":{"lch":[74.283676291108776,96.1575231653334441,116.077287726142885],"luv":[74.283676291108776,-42.2692272766684525,86.3688698937585144],"rgb":[0.466666666666666674,0.8,0.0666666666666666657],"xyz":[0.293006655992761877,0.471469645771599333,0.0808672243298366872],"hpluv":[116.077287726142885,164.2590118749402,74.283676291108776],"hsluv":[116.077287726142885,98.5840266713216522,74.283676291108776]},"#77cc22":{"lch":[74.3315335987815331,94.2328042547367914,116.591431825394338],"luv":[74.3315335987815331,-42.1809937248656581,84.2649699821603519],"rgb":[0.466666666666666674,0.8,0.133333333333333331],"xyz":[0.294882014131238934,0.472219789026990133,0.0907441105258158798],"hpluv":[116.591431825394338,160.867513369155,74.3315335987815331],"hsluv":[116.591431825394338,95.9817736999432611,74.3315335987815331]},"#77cc33":{"lch":[74.410219680569412,91.1231466477069176,117.473161926834081],"luv":[74.410219680569412,-42.0381214847294515,80.8469182901527148],"rgb":[0.466666666666666674,0.8,0.2],"xyz":[0.29796976486369664,0.47345488931997326,0.10700626438342703],"hpluv":[117.473161926834081,155.394430123968846,74.410219680569412],"hsluv":[117.473161926834081,91.7599970515073551,74.410219680569412]},"#77cc44":{"lch":[74.5235830687713445,86.7634188586395,118.828926444460791],"luv":[74.5235830687713445,-41.8369758074171045,76.0102513305232748],"rgb":[0.466666666666666674,0.8,0.266666666666666663],"xyz":[0.302427760107915555,0.475238087417660826,0.130485039336313668],"hpluv":[118.828926444460791,147.734611978654129,74.5235830687713445],"hsluv":[118.828926444460791,85.7987877580492153,74.5235830687713445]},"#77cc55":{"lch":[74.6747602628398,81.1723246922669688,120.810965560633605],"luv":[74.6747602628398,-41.5770530159641396,69.7158156981220571],"rgb":[0.466666666666666674,0.8,0.333333333333333315],"xyz":[0.30839017414727754,0.477623053033405687,0.161887086610287556],"hpluv":[120.810965560633605,137.934680546119694,74.6747602628398],"hsluv":[120.810965560633605,78.0638956664307671,74.6747602628398]},"#77cc66":{"lch":[74.866352492363319,74.4599116278811692,123.651008617564372],"luv":[74.866352492363319,-41.2606832822808798,61.982533464768764],"rgb":[0.466666666666666674,0.8,0.4],"xyz":[0.315975169920785726,0.480657051342809,0.201834731017431546],"hpluv":[123.651008617564372,126.204595224585091,74.866352492363319],"hsluv":[123.651008617564372,68.5978490432360388,74.866352492363319]},"#77cc77":{"lch":[75.1005189251371519,66.8471540376336719,127.715012949239053],"luv":[75.1005189251371519,-40.8926996459993219,52.8803282761483189],"rgb":[0.466666666666666674,0.8,0.466666666666666674],"xyz":[0.325289182940987631,0.484382656550889801,0.250888532923829455],"hpluv":[127.715012949239053,112.948199149412858,75.1005189251371519],"hsluv":[127.715012949239053,57.5107647824030153,75.1005189251371519]},"#77cc88":{"lch":[75.3790318815133,58.7087525381891311,133.590980823477452],"luv":[75.3790318815133,-40.4800101313413947,42.5215992685696946],"rgb":[0.466666666666666674,0.8,0.533333333333333326],"xyz":[0.336429600042931432,0.488838823391667399,0.309561396327401595],"hpluv":[133.590980823477452,98.8306436104363542,75.3790318815133],"hsluv":[133.590980823477452,58.7660231359317748,75.3790318815133]},"#77cc99":{"lch":[75.7033128937519848,50.6622606125816759,142.200076129410462],"luv":[75.7033128937519848,-40.0310804193600305,31.0512036938324556],"rgb":[0.466666666666666674,0.8,0.6],"xyz":[0.349486564152004187,0.494061609035296556,0.378328073968519529],"hpluv":[142.200076129410462,84.9198084445103802,75.7033128937519848],"hsluv":[142.200076129410462,60.1459848784672815,75.7033128937519848]},"#77ccaa":{"lch":[76.0744587192654,43.7254195479873289,154.773618890386814],"luv":[76.0744587192654,-39.5553661600219684,18.6355928962322395],"rgb":[0.466666666666666674,0.8,0.66666666666666663],"xyz":[0.364544257117256687,0.500084686221397678,0.45763192358551813],"hpluv":[154.773618890386814,73.067319501552376,76.0744587192654],"hsluv":[154.773618890386814,61.6269813218812459,76.0744587192654]},"#77ccbb":{"lch":[76.4932621718819235,39.4413790272598561,172.054536865796422],"luv":[76.4932621718819235,-39.0627454070693716,5.45199970968949721],"rgb":[0.466666666666666674,0.8,0.733333333333333282],"xyz":[0.381681849224593361,0.506939723064332437,0.547889908684159876],"hpluv":[172.054536865796422,67.3385729198675733,76.4932621718819235],"hsluv":[172.054536865796422,63.1840553036415713,76.4932621718819235]},"#77cccc":{"lch":[76.9602305249106,39.4506200876857847,192.177050630060961],"luv":[76.9602305249106,-38.5629992967744357,-8.32144882456723778],"rgb":[0.466666666666666674,0.8,0.8],"xyz":[0.400974224668315116,0.514656673241821183,0.64949641935443],"hpluv":[192.177050630060961,69.0111626451701312,76.9602305249106],"hsluv":[192.177050630060961,64.792316690459316,76.9602305249106]},"#77ccdd":{"lch":[77.4756030772436475,44.2250390945155942,210.602473757279853],"luv":[77.4756030772436475,-38.0653777824919359,-22.5140200139291444],"rgb":[0.466666666666666674,0.8,0.866666666666666696],"xyz":[0.422492550218948604,0.5232640034620748,0.762826267254436],"hpluv":[210.602473757279853,79.5030322309331439,77.4756030772436475],"hsluv":[210.602473757279853,66.4280770246703156,77.4756030772436475]},"#77ccee":{"lch":[78.0393687787239116,52.7144148097026246,224.531483635923479],"luv":[78.0393687787239116,-37.5782716813780482,-36.9686762837126182],"rgb":[0.466666666666666674,0.8,0.933333333333333348],"xyz":[0.446304730485123369,0.532788875568544817,0.888237083322959253],"hpluv":[224.531483635923479,97.6926138158747648,78.0393687787239116],"hsluv":[224.531483635923479,71.3781641956177282,78.0393687787239116]},"#77ccff":{"lch":[78.6512843692400736,63.5145451324089052,234.249283216901347],"luv":[78.6512843692400736,-37.1089966152940249,-51.5462880679385549],"rgb":[0.466666666666666674,0.8,1],"xyz":[0.472475778894954734,0.54325729493247743,1.0260712716147411],"hpluv":[234.249283216901347,121.749546403725816,78.6512843692400736],"hsluv":[234.249283216901347,99.9999999999968168,78.6512843692400736]},"#224400":{"lch":[25.1809799681870601,33.4179584834008523,116.999863609689683],"luv":[25.1809799681870601,-15.1713647924420147,29.7756551486773162],"rgb":[0.133333333333333331,0.266666666666666663,0],"xyz":[0.0272670407739683193,0.0447420690542179589,0.00719932696972761486],"hpluv":[116.999863609689683,168.401755360818214,25.1809799681870601],"hsluv":[116.999863609689683,100.000000000002217,25.1809799681870601]},"#224411":{"lch":[25.304760275593587,29.8643723317269938,120.153298663054528],"luv":[25.304760275593587,-15.0013316265206242,25.8232605261065515],"rgb":[0.133333333333333331,0.266666666666666663,0.0666666666666666657],"xyz":[0.0282787062736054411,0.0451467352540728117,0.0125274319344832463],"hpluv":[120.153298663054528,149.758158325470362,25.304760275593587],"hsluv":[120.153298663054528,85.5029145399767287,25.304760275593587]},"#224422":{"lch":[25.5322735505540379,24.0578500603585184,127.715012949239281],"luv":[25.5322735505540379,-14.7170130248608242,19.0312815425753499],"rgb":[0.133333333333333331,0.266666666666666663,0.133333333333333331],"xyz":[0.0301540644120824597,0.0458968785094636331,0.0224043181304624424],"hpluv":[127.715012949239281,119.565711231297882,25.5322735505540379],"hsluv":[127.715012949239281,60.8802579098014363,25.5322735505540379]},"#224433":{"lch":[25.9015299317797343,16.981905402382786,147.498859327993841],"luv":[25.9015299317797343,-14.3222120947549634,9.12465625699578098],"rgb":[0.133333333333333331,0.266666666666666663,0.2],"xyz":[0.0332418151445402,0.0471319788024467459,0.0386664719880735891],"hpluv":[147.498859327993841,83.1955939146196357,25.9015299317797343],"hsluv":[147.498859327993841,64.09678513773909,25.9015299317797343]},"#224444":{"lch":[26.423438440277998,14.1959776348833024,192.177050630061],"luv":[26.423438440277998,-13.8765746732054378,-2.99440417262938974],"rgb":[0.133333333333333331,0.266666666666666663,0.266666666666666663],"xyz":[0.0376998103887590807,0.048915176900134319,0.0621452469409602276],"hpluv":[192.177050630061,68.1734546180548762,26.423438440277998],"hsluv":[192.177050630061,67.9066037165366367,26.423438440277998]},"#224455":{"lch":[27.1020089847707979,21.1158760403194243,230.453768193421723],"luv":[27.1020089847707979,-13.4444916811297333,-16.2826860310628518],"rgb":[0.133333333333333331,0.266666666666666663,0.333333333333333315],"xyz":[0.0436622244281210728,0.0513001425158791519,0.0935472942149341291],"hpluv":[230.453768193421723,98.865995891455,27.1020089847707979],"hsluv":[230.453768193421723,71.8953118433392717,27.1020089847707979]},"#224466":{"lch":[27.935501760142138,32.6185654266362306,246.366656325875056],"luv":[27.935501760142138,-13.0762038460066634,-29.8828329224226863],"rgb":[0.133333333333333331,0.266666666666666663,0.4],"xyz":[0.0512472202016292511,0.0543341408252824634,0.133494938622078091],"hpluv":[246.366656325875056,148.165710166053657,27.935501760142138],"hsluv":[246.366656325875056,75.7322080769735351,27.935501760142138]},"#224477":{"lch":[28.9175817086007072,45.1016041758277453,253.511262930840303],"luv":[28.9175817086007072,-12.8010466495854338,-43.2468253621948548],"rgb":[0.133333333333333331,0.266666666666666663,0.466666666666666674],"xyz":[0.0605612332218311636,0.0580597460333632798,0.182548740528476],"hpluv":[253.511262930840303,197.910731630760921,28.9175817086007072],"hsluv":[253.511262930840303,79.2164102145581381,28.9175817086007072]},"#224488":{"lch":[30.0385370730522183,57.5093846577101502,257.31357801273],"luv":[30.0385370730522183,-12.6299243743950456,-56.1053859625395432],"rgb":[0.133333333333333331,0.266666666666666663,0.533333333333333326],"xyz":[0.0717016503237749847,0.0625159128741408776,0.241221603932048168],"hpluv":[257.31357801273,242.94013543841632,30.0385370730522183],"hsluv":[257.31357801273,82.2624245727818106,30.0385370730522183]},"#224499":{"lch":[31.2864747985506213,69.5224780150470139,259.59064804278853],"luv":[31.2864747985506213,-12.5612993437317204,-68.3782765807230675],"rgb":[0.133333333333333331,0.266666666666666663,0.6],"xyz":[0.084758614432847712,0.0677386985177700351,0.309988281573166102],"hpluv":[259.59064804278853,281.973268281811727,31.2864747985506213],"hsluv":[259.59064804278853,84.8626039888072796,31.2864747985506213]},"#2244aa":{"lch":[32.6483868166792277,81.0719578322086676,261.068394107427196],"luv":[32.6483868166792277,-12.5868550230291323,-80.0889095154670372],"rgb":[0.133333333333333331,0.266666666666666663,0.66666666666666663],"xyz":[0.0998163073981002402,0.0737617757038711297,0.389292131190164703],"hpluv":[261.068394107427196,315.099896322028769,32.6483868166792277],"hsluv":[261.068394107427196,87.0515845849570695,32.6483868166792277]},"#2244bb":{"lch":[34.1110146972578292,92.183713113584,262.084105297610279],"luv":[34.1110146972578292,-12.6954785449376448,-91.3053217940914266],"rgb":[0.133333333333333331,0.266666666666666663,0.733333333333333282],"xyz":[0.116953899505436887,0.0806168125468058883,0.479550116288806449],"hpluv":[262.084105297610279,342.924793116778346,34.1110146972578292],"hsluv":[262.084105297610279,88.8814901896574128,34.1110146972578292]},"#2244cc":{"lch":[35.6614866183058439,102.915147630289923,262.812952152813068],"luv":[35.6614866183058439,-12.875606592693158,-102.106544191029045],"rgb":[0.133333333333333331,0.266666666666666663,0.8],"xyz":[0.136246274949158641,0.0883337627242946899,0.58115662695907655],"hpluv":[262.812952152813068,366.200711918304478,35.6614866183058439],"hsluv":[262.812952152813068,90.4075680541016453,35.6614866183058439]},"#2244dd":{"lch":[37.2877389569632456,113.32806156453313,263.353781276912969],"luv":[37.2877389569632456,-13.1164125913708496,-112.566465959927598],"rgb":[0.133333333333333331,0.266666666666666663,0.866666666666666696],"xyz":[0.157764600499792185,0.0969410929445482239,0.694486474859082548],"hpluv":[263.353781276912969,385.665452845521429,37.2877389569632456],"hsluv":[263.353781276912969,91.6811227311716408,37.2877389569632456]},"#2244ee":{"lch":[38.9787575249373575,123.477944203962494,263.76603971616106],"luv":[38.9787575249373575,-13.4082956886680194,-122.74779147325674],"rgb":[0.133333333333333331,0.266666666666666663,0.933333333333333348],"xyz":[0.181576780765966922,0.106465965051018269,0.819897290927605771],"hpluv":[263.76603971616106,401.976556214066079,38.9787575249373575],"hsluv":[263.76603971616106,92.7467647141115208,38.9787575249373575]},"#2244ff":{"lch":[40.7246816385265333,133.410810959437413,264.087324287658078],"luv":[40.7246816385265333,-13.7429938745542355,-132.701072340123574],"rgb":[0.133333333333333331,0.266666666666666663,1],"xyz":[0.207747829175798315,0.116934384414950965,0.957731479219387616],"hpluv":[264.087324287658078,415.692943868353552,40.7246816385265333],"hsluv":[264.087324287658078,99.9999999999994174,40.7246816385265333]},"#77dd00":{"lch":[79.4046595803128525,106.500737968556749,117.886764510297155],"luv":[79.4046595803128525,-49.8131268255250319,94.1332012826045457],"rgb":[0.466666666666666674,0.866666666666666696,0],"xyz":[0.3346289810403,0.556332960666096,0.089750449547472369],"hpluv":[117.886764510297155,213.048114553231642,79.4046595803128525],"hsluv":[117.886764510297155,100.000000000002288,79.4046595803128525]},"#77dd11":{"lch":[79.427785829561941,105.558219679332908,118.124490997004173],"luv":[79.427785829561941,-49.7589732732473422,93.0944806133132801],"rgb":[0.466666666666666674,0.866666666666666696,0.0666666666666666657],"xyz":[0.335640646539937082,0.556737626865951,0.095078554512228],"hpluv":[118.124490997004173,211.44368721760469,79.427785829561941],"hsluv":[118.124490997004173,98.7993418471683498,79.427785829561941]},"#77dd22":{"lch":[79.4706261070012658,103.827566318990023,118.57359388187615],"luv":[79.4706261070012658,-49.6593926395600249,91.1817319993116],"rgb":[0.466666666666666674,0.866666666666666696,0.133333333333333331],"xyz":[0.337516004678414139,0.557487770121341764,0.104955440708207198],"hpluv":[118.57359388187615,208.49071074424171,79.4706261070012658],"hsluv":[118.57359388187615,96.5898934808467,79.4706261070012658]},"#77dd33":{"lch":[79.5410783702752582,101.02472031386101,119.337697767432388],"luv":[79.5410783702752582,-49.4976803830995067,88.0680063995226874],"rgb":[0.466666666666666674,0.866666666666666696,0.2],"xyz":[0.340603755410871845,0.55872287041432489,0.121217594565818348],"hpluv":[119.337697767432388,203.689012727245881,79.5410783702752582],"hsluv":[119.337697767432388,92.9973786049096276,79.5410783702752582]},"#77dd44":{"lch":[79.6426121547728485,97.0801788178617073,120.498016398630853],"luv":[79.6426121547728485,-49.2690191092090188,83.6488187323909642],"rgb":[0.466666666666666674,0.866666666666666696,0.266666666666666663],"xyz":[0.34506175065509076,0.560506068512012456,0.144696369518705],"hpluv":[120.498016398630853,196.890303230407255,79.6426121547728485],"hsluv":[120.498016398630853,87.9077551580221126,79.6426121547728485]},"#77dd55":{"lch":[79.7780740091910729,91.9929116678805912,122.163902680224],"luv":[79.7780740091910729,-48.9717875622404577,77.8746417012192325],"rgb":[0.466666666666666674,0.866666666666666696,0.333333333333333315],"xyz":[0.351024164694452745,0.562891034127757206,0.176098416792678902],"hpluv":[122.163902680224,188.049297266091,79.7780740091910729],"hsluv":[122.163902680224,81.2740392578912889,79.7780740091910729]},"#77dd66":{"lch":[79.9498479155991788,85.8342168020908645,124.492086237753256],"luv":[79.9498479155991788,-48.6072648253697466,70.7449403153661],"rgb":[0.466666666666666674,0.866666666666666696,0.4],"xyz":[0.35860916046796093,0.565925032437160525,0.216046061199822836],"hpluv":[124.492086237753256,177.233761467474238,79.9498479155991788],"hsluv":[124.492086237753256,73.1095665987697174,79.9498479155991788]},"#77dd77":{"lch":[80.1599403321921,78.7586110849663896,127.715012949239352],"luv":[80.1599403321921,-48.1793469594900188,62.3030444407821093],"rgb":[0.466666666666666674,0.866666666666666696,0.466666666666666674],"xyz":[0.367923173488162836,0.569650637645241376,0.265099863106220746],"hpluv":[127.715012949239352,164.652954432832814,80.1599403321921],"hsluv":[127.715012949239352,63.4818861677236654,80.1599403321921]},"#77dd88":{"lch":[80.4100305893493754,71.0258644695610855,132.183293417803185],"luv":[80.4100305893493754,-47.69419139775556,52.6301959958607597],"rgb":[0.466666666666666674,0.866666666666666696,0.533333333333333326],"xyz":[0.379063590590106636,0.574106804486018918,0.323772726509792941],"hpluv":[132.183293417803185,150.716476916292407,80.4100305893493754],"hsluv":[132.183293417803185,64.4129914780986184,80.4100305893493754]},"#77dd99":{"lch":[80.7015034668449829,63.0436351039456042,138.421724913218469],"luv":[80.7015034668449829,-47.1597772740100254,41.838443261971527],"rgb":[0.466666666666666674,0.866666666666666696,0.6],"xyz":[0.392120554699179391,0.579329590129648131,0.39253940415091082],"hpluv":[138.421724913218469,136.149613262507529,80.7015034668449829],"hsluv":[138.421724913218469,65.4455974050235909,80.7015034668449829]},"#77ddaa":{"lch":[81.0354720941451916,55.4433276111880673,147.164903113494319],"luv":[81.0354720941451916,-46.5854032558204594,30.0626475895607292],"rgb":[0.466666666666666674,0.866666666666666696,0.66666666666666663],"xyz":[0.407178247664431892,0.585352667315749198,0.471843253767909421],"hpluv":[147.164903113494319,122.204418643173668,81.0354720941451916],"hsluv":[147.164903113494319,66.5644374268903505,81.0354720941451916]},"#77ddbb":{"lch":[81.4127955433910415,49.1817473647014651,159.215751775487576],"luv":[81.4127955433910415,-45.9811599326092804,17.452140415923953],"rgb":[0.466666666666666674,0.866666666666666696,0.733333333333333282],"xyz":[0.424315839771768566,0.592207704158684,0.562101238866551167],"hpluv":[159.215751775487576,110.971854928909636,81.4127955433910415],"hsluv":[159.215751775487576,67.7527973989238461,81.4127955433910415]},"#77ddcc":{"lch":[81.8340936239464298,45.5480287935550479,174.756411210455894],"luv":[81.8340936239464298,-45.3574175840417197,4.16264304083146897],"rgb":[0.466666666666666674,0.866666666666666696,0.8],"xyz":[0.44360821521549032,0.599924654336172813,0.663707749536821323],"hpluv":[174.756411210455894,105.54602277980743,81.8340936239464298],"hsluv":[174.756411210455894,68.9933910523739371,81.8340936239464298]},"#77dddd":{"lch":[82.299760373596115,45.7538051586653296,192.177050630060847],"luv":[82.299760373596115,-44.7243656053231931,-9.65100034703627],"rgb":[0.466666666666666674,0.866666666666666696,0.866666666666666696],"xyz":[0.465126540766123808,0.60853198455642632,0.777037597436827321],"hpluv":[192.177050630060847,109.256318691998032,82.299760373596115],"hsluv":[192.177050630060847,70.2691471280789557,82.299760373596115]},"#77ddee":{"lch":[82.8099771424448221,50.1244355238275574,208.400620203695752],"luv":[82.8099771424448221,-44.0916301090396274,-23.8408722766172367],"rgb":[0.466666666666666674,0.866666666666666696,0.933333333333333348],"xyz":[0.488938721032298573,0.618056856662896337,0.902448413505350544],"hpluv":[208.400620203695752,123.794681382199428,82.8099771424448221],"hsluv":[208.400620203695752,71.5638635335918,82.8099771424448221]},"#77ddff":{"lch":[83.364725787715372,57.9146258331384161,221.361714592462022],"luv":[83.364725787715372,-43.4679842885535521,-38.2705921992655504],"rgb":[0.466666666666666674,0.866666666666666696,1],"xyz":[0.515109769442129939,0.628525276026829061,1.0402826017971325],"hpluv":[221.361714592462022,148.517135389694232,83.364725787715372],"hsluv":[221.361714592462022,99.9999999999953531,83.364725787715372]},"#225500":{"lch":[31.4325909084541877,43.9203091385023825,121.065637009975248],"luv":[31.4325909084541877,-22.6637443991712324,37.6211143459447541],"rgb":[0.133333333333333331,0.333333333333333315,0],"xyz":[0.0390802974883142848,0.0683685824829102229,0.0111370792078428239],"hpluv":[121.065637009975248,177.306450001223254,31.4325909084541877],"hsluv":[121.065637009975248,100.000000000002373,31.4325909084541877]},"#225511":{"lch":[31.5259896590935043,41.027632513747335,123.178290947815412],"luv":[31.5259896590935043,-22.452213479362328,34.3389682366875704],"rgb":[0.133333333333333331,0.333333333333333315,0.0666666666666666657],"xyz":[0.04009196298795141,0.0687732486827650757,0.0164651841725984571],"hpluv":[123.178290947815412,165.138012967735222,31.5259896590935043],"hsluv":[123.178290947815412,90.3912533003173877,31.5259896590935043]},"#225522":{"lch":[31.6981615382414716,36.1013694166085486,127.715012949239792],"luv":[31.6981615382414716,-22.0844473877159331,28.5584673491706482],"rgb":[0.133333333333333331,0.333333333333333315,0.133333333333333331],"xyz":[0.0419673211264284252,0.0695233919381558901,0.0263420703685776497],"hpluv":[127.715012949239792,144.520324593974209,31.6981615382414716],"hsluv":[127.715012949239792,73.5866039174798345,31.6981615382414716]},"#225533":{"lch":[31.9789617713411829,29.2625646618711706,137.400330584271074],"luv":[31.9789617713411829,-21.5402028917408828,19.8070025489176231],"rgb":[0.133333333333333331,0.333333333333333315,0.2],"xyz":[0.0450550718588861657,0.070758492231139,0.0426042242261888],"hpluv":[137.400330584271074,116.114739730974975,31.9789617713411829],"hsluv":[137.400330584271074,75.0932106461487,31.9789617713411829]},"#225544":{"lch":[32.3786649626227785,22.5648709259736577,157.632626155133437],"luv":[32.3786649626227785,-20.8671549807805796,8.58692278490586247],"rgb":[0.133333333333333331,0.333333333333333315,0.266666666666666663],"xyz":[0.0495130671031050462,0.072541690328826583,0.0660829991790754384],"hpluv":[157.632626155133437,88.4327727432137465,32.3786649626227785],"hsluv":[157.632626155133437,76.9882679005547459,32.3786649626227785]},"#225555":{"lch":[32.9031430542149863,20.5945867127178737,192.177050630061132],"luv":[32.9031430542149863,-20.1312179923833199,-4.34408379417313384],"rgb":[0.133333333333333331,0.333333333333333315,0.333333333333333315],"xyz":[0.0554754811424670383,0.0749266559445714159,0.0974850464530493399],"hpluv":[192.177050630061132,79.4245973683706268,32.9031430542149863],"hsluv":[192.177050630061132,79.1137061933639245,32.9031430542149863]},"#225566":{"lch":[33.5545056011551,26.6006796322727546,223.177731373198952],"luv":[33.5545056011551,-19.398136743372234,-18.2018803364993715],"rgb":[0.133333333333333331,0.333333333333333315,0.4],"xyz":[0.0630604769159752165,0.0779606542539747344,0.137432690860193302],"hpluv":[223.177731373198952,100.596116474312993,33.5545056011551],"hsluv":[223.177731373198952,81.3097794801720113,33.5545056011551]},"#225577":{"lch":[34.3316296590174,37.3644949384619807,239.932022094073261],"luv":[34.3316296590174,-18.7206257951117045,-32.3364137134245127],"rgb":[0.133333333333333331,0.333333333333333315,0.466666666666666674],"xyz":[0.0723744899361771221,0.0816862594620555438,0.186486492766591211],"hpluv":[239.932022094073261,138.103289638438355,34.3316296590174],"hsluv":[239.932022094073261,83.4469752602442298,34.3316296590174]},"#225588":{"lch":[35.230707776085,49.7211482448765594,248.610781811292384],"luv":[35.230707776085,-18.1333810040152876,-46.2965773697387775],"rgb":[0.133333333333333331,0.333333333333333315,0.533333333333333326],"xyz":[0.0835149070381209502,0.0861424263028331416,0.245159356170163378],"hpluv":[248.610781811292384,179.084957393431893,35.230707776085],"hsluv":[248.610781811292384,85.4385601139613158,35.230707776085]},"#225599":{"lch":[36.2458273864096512,62.3718238545276336,253.557833057747018],"luv":[36.2458273864096512,-17.6541819100499602,-59.8211858126123],"rgb":[0.133333333333333331,0.333333333333333315,0.6],"xyz":[0.0965718711471936775,0.0913652119464623,0.313926033811281313],"hpluv":[253.557833057747018,218.35832406203005,36.2458273864096512],"hsluv":[253.557833057747018,87.2381583586425791,36.2458273864096512]},"#2255aa":{"lch":[37.3695533294905928,74.8190204360075,256.640324292617947],"luv":[37.3695533294905928,-17.2879233745104131,-72.7943234352841841],"rgb":[0.133333333333333331,0.333333333333333315,0.66666666666666663],"xyz":[0.111629564112446206,0.0973882891325634,0.393229883428279914],"hpluv":[256.640324292617947,254.058329165629146,37.3695533294905928],"hsluv":[256.640324292617947,88.8301308270208807,37.3695533294905928]},"#2255bb":{"lch":[38.5934754222231291,86.8805221786483,258.695157685582501],"luv":[38.5934754222231291,-17.0311035792378,-85.1948745225196831],"rgb":[0.133333333333333331,0.333333333333333315,0.733333333333333282],"xyz":[0.128767156219782852,0.104243325975498152,0.48348786852692166],"hpluv":[258.695157685582501,285.658965815982469,38.5934754222231291],"hsluv":[258.695157685582501,90.2188193496234874,38.5934754222231291]},"#2255cc":{"lch":[39.9086891196534097,98.5112685419302,260.136263381096],"luv":[39.9086891196534097,-16.8755295039118458,-97.0550695930042],"rgb":[0.133333333333333331,0.333333333333333315,0.8],"xyz":[0.148059531663504607,0.111960276152986954,0.585094379197191761],"hpluv":[260.136263381096,313.22597901471056,39.9086891196534097],"hsluv":[260.136263381096,91.4196885710314433,39.9086891196534097]},"#2255dd":{"lch":[41.3061900239028503,109.727240919989157,261.187210775965298],"luv":[41.3061900239028503,-16.8109176424286737,-108.431823962952976],"rgb":[0.133333333333333331,0.333333333333333315,0.866666666666666696],"xyz":[0.16957785721413815,0.120567606373240488,0.698424227097197758],"hpluv":[261.187210775965298,337.084394380702577,41.3061900239028503],"hsluv":[261.187210775965298,92.4531471705562353,41.3061900239028503]},"#2255ee":{"lch":[42.7771763125841602,120.569176865205208,261.977669343247612],"luv":[42.7771763125841602,-16.8265186863462972,-119.389256965822398],"rgb":[0.133333333333333331,0.333333333333333315,0.933333333333333348],"xyz":[0.193390037480312887,0.130092478479710533,0.823835043165721],"hpluv":[261.977669343247612,357.654347674158601,42.7771763125841602],"hsluv":[261.977669343247612,93.3407272081067,42.7771763125841602]},"#2255ff":{"lch":[44.3132637322964129,131.084767922007643,262.587267096581058],"luv":[44.3132637322964129,-16.9120289519133,-129.989229007238322],"rgb":[0.133333333333333331,0.333333333333333315,1],"xyz":[0.219561085890144281,0.140560897843643229,0.961669231457502827],"hpluv":[262.587267096581058,375.368494421854962,44.3132637322964129],"hsluv":[262.587267096581058,99.9999999999993463,44.3132637322964129]},"#77ee00":{"lch":[84.5193058633960703,115.647601499010833,119.483871035599748],"luv":[84.5193058633960703,-56.9192667804191,100.670575649757225],"rgb":[0.466666666666666674,0.933333333333333348,0],"xyz":[0.381807757380814794,0.650690513347127,0.105476708327643554],"hpluv":[119.483871035599748,321.869538605652735,84.5193058633960703],"hsluv":[119.483871035599748,100.000000000002359,84.5193058633960703]},"#77ee11":{"lch":[84.5401392884337355,114.795422022346642,119.691827475064969],"luv":[84.5401392884337355,-56.862163274863434,99.7230329712822083],"rgb":[0.466666666666666674,0.933333333333333348,0.0666666666666666657],"xyz":[0.382819422880451898,0.651095179546981928,0.11080481329239919],"hpluv":[119.691827475064969,319.985367790437692,84.5401392884337355],"hsluv":[119.691827475064969,98.9722780394741477,84.5401392884337355]},"#77ee22":{"lch":[84.5787360835130499,113.228793274865538,120.083373039169615],"luv":[84.5787360835130499,-56.7570256545281637,97.9765260934141651],"rgb":[0.466666666666666674,0.933333333333333348,0.133333333333333331],"xyz":[0.384694781018928955,0.651845322802372729,0.120681699488378383],"hpluv":[120.083373039169615,316.512949618186383,84.5787360835130499],"hsluv":[120.083373039169615,97.0790709390529,84.5787360835130499]},"#77ee33":{"lch":[84.6422206992536275,110.686316006337648,120.745647293955486],"luv":[84.6422206992536275,-56.585921413754825,95.1288286946244313],"rgb":[0.466666666666666674,0.933333333333333348,0.2],"xyz":[0.387782531751386661,0.653080423095355855,0.136943853345989519],"hpluv":[120.745647293955486,310.853610471304819,84.6422206992536275],"hsluv":[120.745647293955486,93.9952250088888093,84.6422206992536275]},"#77ee44":{"lch":[84.7337366993681513,107.096480548503891,121.742158736883837],"luv":[84.7337366993681513,-56.3431952848259598,91.0774422728923412],"rgb":[0.466666666666666674,0.933333333333333348,0.266666666666666663],"xyz":[0.392240526995605576,0.654863621193043421,0.160422628298876158],"hpluv":[121.742158736883837,302.811644310583176,84.7337366993681513],"hsluv":[121.742158736883837,89.6144795711786628,84.7337366993681513]},"#77ee55":{"lch":[84.8558768548969766,102.444399932600575,123.154228511336783],"luv":[84.8558768548969766,-56.0262879596216621,85.7666026785261266],"rgb":[0.466666666666666674,0.933333333333333348,0.333333333333333315],"xyz":[0.398202941034967561,0.657248586808788171,0.191824675572850073],"hpluv":[123.154228511336783,292.298881153811294,84.8558768548969766],"hsluv":[123.154228511336783,83.883891015311761,84.8558768548969766]},"#77ee66":{"lch":[85.0108293450033159,96.7735040486586,125.092887734820366],"luv":[85.0108293450033159,-55.6354444449268186,79.1821217654036],"rgb":[0.466666666666666674,0.933333333333333348,0.4],"xyz":[0.405787936808475747,0.66028258511819149,0.231772319979994035],"hpluv":[125.092887734820366,279.341716913636219,85.0108293450033159],"hsluv":[125.092887734820366,76.7984153057879411,85.0108293450033159]},"#77ee77":{"lch":[85.2004556710930814,90.1918871908529667,127.71501294923965],"luv":[85.2004556710930814,-55.1734745704367882,71.3474892261312306],"rgb":[0.466666666666666674,0.933333333333333348,0.466666666666666674],"xyz":[0.415101949828677652,0.664008190326272341,0.280826121886391944],"hpluv":[127.71501294923965,264.105357222364148,85.2004556710930814],"hsluv":[127.71501294923965,68.3966317942099522,85.2004556710930814]},"#77ee88":{"lch":[85.4263369442757323,82.8846309918514521,131.246169999264879],"luv":[85.4263369442757323,-54.6454688778224167,62.3196179848555],"rgb":[0.466666666666666674,0.933333333333333348,0.533333333333333326],"xyz":[0.426242366930621452,0.668464357167049883,0.339498985289964139],"hpluv":[131.246169999264879,246.94310788397641,85.4263369442757323],"hsluv":[131.246169999264879,69.0963798671032379,85.4263369442757323]},"#77ee99":{"lch":[85.6898036798217,75.1362836057233,136.010896750223054],"luv":[85.6898036798217,-54.0584447513185395,52.1837682153016473],"rgb":[0.466666666666666674,0.933333333333333348,0.6],"xyz":[0.439299331039694207,0.673687142810679096,0.408265662931082],"hpluv":[136.010896750223054,228.489214549916312,85.6898036798217],"hsluv":[136.010896750223054,69.8780652000076827,85.6898036798217]},"#77eeaa":{"lch":[85.9919564191548602,67.3699388554866232,142.461966648640384],"luv":[85.9919564191548602,-53.4209300451477489,41.0476904892764551],"rgb":[0.466666666666666674,0.933333333333333348,0.66666666666666663],"xyz":[0.454357024004946708,0.679710219996780163,0.487569512548080619],"hpluv":[142.461966648640384,209.826142071523691,85.9919564191548602],"hsluv":[142.461966648640384,70.7318226594993575,85.9919564191548602]},"#77eebb":{"lch":[86.3336811163097337,60.2064759054885243,151.166773543866697],"luv":[86.3336811163097337,-52.7425080063862524,29.0352818163428843],"rgb":[0.466666666666666674,0.933333333333333348,0.733333333333333282],"xyz":[0.471494616112283382,0.686565256839714921,0.577827497646722366],"hpluv":[151.166773543866697,192.758378827545073,86.3336811163097337],"hsluv":[151.166773543866697,71.6464628016145895,86.3336811163097337]},"#77eecc":{"lch":[86.7156615657761449,54.5207620102438284,162.626180625161169],"luv":[86.7156615657761449,-52.0333543078463094,16.2801575438255028],"rgb":[0.466666666666666674,0.933333333333333348,0.8],"xyz":[0.490786991556005137,0.694282207017203778,0.679434008316992522],"hpluv":[162.626180625161169,180.150974339718545,86.7156615657761449],"hsluv":[162.626180625161169,72.6100300694190111,86.7156615657761449]},"#77eedd":{"lch":[87.1383902516757445,51.3868015721907483,176.742975614533037],"luv":[87.1383902516757445,-51.3037971188162771,2.91955082350760353],"rgb":[0.466666666666666674,0.933333333333333348,0.866666666666666696],"xyz":[0.512305317106638625,0.702889537237457285,0.792763856216998519],"hpluv":[176.742975614533037,175.997429168902841,87.1383902516757445],"hsluv":[176.742975614533037,73.6103328445444305,87.1383902516757445]},"#77eeee":{"lch":[87.6021784736708327,51.7277775307036,192.177050630061075],"luv":[87.6021784736708327,-50.5639263491039941,-10.9111099540033418],"rgb":[0.466666666666666674,0.933333333333333348,0.933333333333333348],"xyz":[0.536117497372813334,0.712414409343927302,0.918174672285521742],"hpluv":[192.177050630061075,184.503896016801804,87.6021784736708327],"hsluv":[192.177050630061075,74.6354143053272594,87.6021784736708327]},"#77eeff":{"lch":[88.107166277409533,55.7808213308350673,206.722210113893169],"luv":[88.107166277409533,-49.8232704905303336,-25.0826981397535107],"rgb":[0.466666666666666674,0.933333333333333348,1],"xyz":[0.562288545782644755,0.72288282870786,1.05600886057730348],"hpluv":[206.722210113893169,208.278116369071,88.107166277409533],"hsluv":[206.722210113893169,99.9999999999928804,88.107166277409533]},"#226600":{"lch":[37.5582057574881532,54.1200869321592961,123.236537452327113],"luv":[37.5582057574881532,-29.6630419039077431,45.2668505040000824],"rgb":[0.133333333333333331,0.4,0],"xyz":[0.0541083551941607538,0.0984246978946035633,0.0161464317764581713],"hpluv":[123.236537452327113,182.849162381267462,37.5582057574881532],"hsluv":[123.236537452327113,100.000000000002288,37.5582057574881532]},"#226611":{"lch":[37.6315056544729529,51.7196180195473119,124.710513292064419],"luv":[37.6315056544729529,-29.4507212427394194,42.5155725160833242],"rgb":[0.133333333333333331,0.4,0.0666666666666666657],"xyz":[0.0551200206937978721,0.0988293640944584162,0.0214745367412138],"hpluv":[124.710513292064419,174.398618448608886,37.6315056544729529],"hsluv":[124.710513292064419,93.2756924270169918,37.6315056544729529]},"#226622":{"lch":[37.7668566222969062,47.5272711912458519,127.715012949240034],"luv":[37.7668566222969062,-29.0740638670039928,37.5970785719263176],"rgb":[0.133333333333333331,0.4,0.133333333333333331],"xyz":[0.0569953788322748942,0.0995795073498492306,0.031351422937193],"hpluv":[127.715012949240034,159.687663587322874,37.7668566222969062],"hsluv":[127.715012949240034,81.309482828258183,37.7668566222969062]},"#226633":{"lch":[37.9882367851431084,41.3581300307957349,133.555287588173542],"luv":[37.9882367851431084,-28.497993426715972,29.9726423642471254],"rgb":[0.133333333333333331,0.4,0.2],"xyz":[0.0600831295647326347,0.100814607642832343,0.0476135767948041438],"hpluv":[133.555287588173542,138.150062101989391,37.9882367851431084],"hsluv":[133.555287588173542,82.0766642375396742,37.9882367851431084]},"#226644":{"lch":[38.3046909892153806,34.1393686276432291,144.379277801066621],"luv":[38.3046909892153806,-27.7515572052733894,19.8833488873617412],"rgb":[0.133333333333333331,0.4,0.266666666666666663],"xyz":[0.0645411248089515083,0.102597805740519923,0.0710923517476907824],"hpluv":[144.379277801066621,113.094855071532635,38.3046909892153806],"hsluv":[144.379277801066621,83.0794073538424414,38.3046909892153806]},"#226655":{"lch":[38.7222568592555234,28.0005039743963025,163.778220785970291],"luv":[38.7222568592555234,-26.8857357715149732,7.82211191715276755],"rgb":[0.133333333333333331,0.4,0.333333333333333315],"xyz":[0.0705035388483135073,0.104982771356264756,0.102494399021664684],"hpluv":[163.778220785970291,91.7581213405574516,38.7222568592555234],"hsluv":[163.778220785970291,84.2573678500350809,38.7222568592555234]},"#226666":{"lch":[39.2444156655659739,26.5583838540848376,192.177050630061103],"luv":[39.2444156655659739,-25.9608324434988,-5.60204710632589631],"rgb":[0.133333333333333331,0.4,0.4],"xyz":[0.0780885346218216786,0.108016769665668075,0.142442043428808646],"hpluv":[192.177050630061103,85.8742788705857691,39.2444156655659739],"hsluv":[192.177050630061103,85.5381417500271652,39.2444156655659739]},"#226677":{"lch":[39.8723950361637449,31.9118423017057466,218.325872967111877],"luv":[39.8723950361637449,-25.034725973132506,-19.7895976345933065],"rgb":[0.133333333333333331,0.4,0.466666666666666674],"xyz":[0.0874025476420236,0.111742374873748884,0.191495845335206555],"hpluv":[218.325872967111877,101.559108573692257,39.8723950361637449],"hsluv":[218.325872967111877,86.8516914397336137,39.8723950361637449]},"#226688":{"lch":[40.6054458094686836,41.8995680003496318,234.7955790683381],"luv":[40.6054458094686836,-24.1549067561574908,-34.2361545477476241],"rgb":[0.133333333333333331,0.4,0.533333333333333326],"xyz":[0.0985429647439674261,0.116198541714526482,0.250168708738778722],"hpluv":[234.7955790683381,130.937664052949941,40.6054458094686836],"hsluv":[234.7955790683381,88.1401386465251733,40.6054458094686836]},"#226699":{"lch":[41.4411308461218226,53.8933488408681782,244.319142730286046],"luv":[41.4411308461218226,-23.3551142576285748,-48.5698639826860301],"rgb":[0.133333333333333331,0.4,0.6],"xyz":[0.11159992885304014,0.12142132735815564,0.318935386379896657],"hpluv":[244.319142730286046,165.022400136876769,41.4411308461218226],"hsluv":[244.319142730286046,89.3619383181549267,41.4411308461218226]},"#2266aa":{"lch":[42.3756299296545578,66.5269840788925251,250.089735516440328],"luv":[42.3756299296545578,-22.655631138578233,-62.5504755245386193],"rgb":[0.133333333333333331,0.4,0.66666666666666663],"xyz":[0.126657621818292682,0.127444404544256734,0.398239235996895258],"hpluv":[250.089735516440328,199.214522587526545,42.3756299296545578],"hsluv":[250.089735516440328,90.4915899210210597,42.3756299296545578]},"#2266bb":{"lch":[43.404050412459263,79.1834510223872599,253.819475134999237],"luv":[43.404050412459263,-22.0656311263342282,-76.0468726432017803],"rgb":[0.133333333333333331,0.4,0.733333333333333282],"xyz":[0.143795213925629328,0.134299441387191493,0.488497221095537],"hpluv":[253.819475134999237,231.496000814517572,43.404050412459263],"hsluv":[253.819475134999237,91.5168425909476895,43.404050412459263]},"#2266cc":{"lch":[44.520728505208055,91.5877705166709,256.367788484306971],"luv":[44.520728505208055,-21.5861851194902563,-89.0076194502553193],"rgb":[0.133333333333333331,0.4,0.8],"xyz":[0.163087589369351083,0.142016391564680294,0.590103731765807105],"hpluv":[256.367788484306971,261.044502527732277,44.520728505208055],"hsluv":[256.367788484306971,92.43509558526695,44.520728505208055]},"#2266dd":{"lch":[45.7195068588792211,103.627896901795907,258.1878164043369],"luv":[45.7195068588792211,-21.2130654589597789,-101.433460308337743],"rgb":[0.133333333333333331,0.4,0.866666666666666696],"xyz":[0.184605914919984626,0.150623721784933828,0.703433579665813102],"hpluv":[258.1878164043369,287.616948003961852,45.7195068588792211],"hsluv":[258.1878164043369,93.2500413525610696,45.7195068588792211]},"#2266ee":{"lch":[46.9939777237187144,115.273293340910215,259.534328145616598],"luv":[46.9939777237187144,-20.9389771714321675,-113.35559709460216],"rgb":[0.133333333333333331,0.4,0.933333333333333348],"xyz":[0.208418095186159336,0.160148593891403873,0.828844395734336326],"hpluv":[259.534328145616598,311.261797341727515,46.9939777237187144],"hsluv":[259.534328145616598,93.969002023907521,46.9939777237187144]},"#2266ff":{"lch":[48.3376856243364728,126.534150990995641,260.559220542156197],"luv":[48.3376856243364728,-20.75515631493003,-124.820330288598825],"rgb":[0.133333333333333331,0.4,1],"xyz":[0.234589143595990757,0.170617013255336569,0.966678584026118171],"hpluv":[260.559220542156197,332.170629177470857,48.3376856243364728],"hsluv":[260.559220542156197,99.9999999999992184,48.3376856243364728]},"#77ff00":{"lch":[89.5984732569245921,124.632639236881928,120.733702851753719],"luv":[89.5984732569245921,-63.6933378884713406,107.128210438594465],"rgb":[0.466666666666666674,1,0],"xyz":[0.433660129810488626,0.754395258206476127,0.122760832470867665],"hpluv":[120.733702851753719,538.628162219261071,89.5984732569245921],"hsluv":[120.733702851753719,100.000000000002359,89.5984732569245921]},"#77ff11":{"lch":[89.6173512893739144,123.857431845856226,120.915842858481739],"luv":[89.6173512893739144,-63.635285050623331,106.260123846986147],"rgb":[0.466666666666666674,1,0.0666666666666666657],"xyz":[0.43467179531012573,0.754799924406331,0.128088937435623301],"hpluv":[120.915842858481739,536.333532616984598,89.6173512893739144],"hsluv":[120.915842858481739,99.9999999999912461,89.6173512893739144]},"#77ff22":{"lch":[89.6523282897647107,122.430860002153082,121.257903913559275],"luv":[89.6523282897647107,-63.5282943614823736,104.658832863679763],"rgb":[0.466666666666666674,1,0.133333333333333331],"xyz":[0.436547153448602787,0.755550067661721836,0.13796582363160248],"hpluv":[121.257903913559275,532.099457877515,89.6523282897647107],"hsluv":[121.257903913559275,99.9999999999912319,89.6523282897647107]},"#77ff33":{"lch":[89.7098670229763684,120.111567958755899,121.833904144252088],"luv":[89.7098670229763684,-63.3538816193187557,102.044472860004433],"rgb":[0.466666666666666674,1,0.2],"xyz":[0.439634904181060493,0.756785167954705,0.15422797748921363],"hpluv":[121.833904144252088,525.184015431200237,89.7098670229763684],"hsluv":[121.833904144252088,99.9999999999911893,89.7098670229763684]},"#77ff44":{"lch":[89.7928292607091834,116.827732221897932,122.694629127971339],"luv":[89.7928292607091834,-63.1058355300939766,98.317712230097257],"rgb":[0.466666666666666674,1,0.266666666666666663],"xyz":[0.444092899425279408,0.758568366052392529,0.177706752442100269],"hpluv":[122.694629127971339,515.324540814372313,89.7928292607091834],"hsluv":[122.694629127971339,99.9999999999912319,89.7928292607091834]},"#77ff55":{"lch":[89.9035853929870683,112.554947355203538,123.902387884937639],"luv":[89.9035853929870683,-62.7808648215699492,93.4193726503684161],"rgb":[0.466666666666666674,1,0.333333333333333315],"xyz":[0.450055313464641393,0.760953331668137278,0.209108799716074184],"hpluv":[123.902387884937639,502.374863630046946,89.9035853929870683],"hsluv":[123.902387884937639,99.9999999999911466,89.9035853929870683]},"#77ff66":{"lch":[90.0441481999633169,107.316590618570714,125.538864396596409],"luv":[90.0441481999633169,-62.3783098318914213,87.3258099562234662],"rgb":[0.466666666666666674,1,0.4],"xyz":[0.457640309238149579,0.763987329977540597,0.249056444123218146],"hpluv":[125.538864396596409,486.310350268178581,90.0441481999633169],"hsluv":[125.538864396596409,99.9999999999909193,90.0441481999633169]},"#77ff77":{"lch":[90.2162444924982,101.18761180958829,127.715012949239778],"luv":[90.2162444924982,-61.8999369112410065,80.0458031011764746],"rgb":[0.466666666666666674,1,0.466666666666666674],"xyz":[0.466954322258351484,0.767712935185621448,0.298110246029616055],"hpluv":[127.715012949239778,467.252180695244249,90.2162444924982],"hsluv":[127.715012949239778,99.9999999999908908,90.2162444924982]},"#77ff88":{"lch":[90.4213578195287084,94.3018691223763312,130.584388318929172],"luv":[90.4213578195287084,-61.3497133683486666,71.6174223886566352],"rgb":[0.466666666666666674,1,0.533333333333333326],"xyz":[0.478094739360295284,0.772169102026399,0.35678310943318825],"hpluv":[130.584388318929172,445.517691352744919,90.4213578195287084],"hsluv":[130.584388318929172,99.999999999990834,90.4213578195287084]},"#77ff99":{"lch":[90.660755936805927,86.8649116623181,134.360625617567337],"luv":[90.660755936805927,-60.7335297134313734,62.1043577106315],"rgb":[0.466666666666666674,1,0.6],"xyz":[0.491151703469368,0.777391887670028203,0.425549787074306129],"hpluv":[134.360625617567337,421.714412879972315,90.660755936805927],"hsluv":[134.360625617567337,99.9999999999904645,90.660755936805927]},"#77ffaa":{"lch":[90.9355096576679927,79.1755179707932513,139.336843070371486],"luv":[90.9355096576679927,-60.0588662825700368,51.5916197341755947],"rgb":[0.466666666666666674,1,0.66666666666666663],"xyz":[0.506209396434620595,0.78341496485612927,0.504853636691304786],"hpluv":[139.336843070371486,396.909453229520182,90.9355096576679927],"hsluv":[139.336843070371486,99.9999999999902371,90.9355096576679927]},"#77ffbb":{"lch":[91.2465066485729466,71.6593730134265599,145.894485367843032],"luv":[91.2465066485729466,-59.3344173347434776,40.1807498713488229],"rgb":[0.466666666666666674,1,0.733333333333333282],"xyz":[0.523346988541957159,0.790270001699064,0.595111621789946477],"hpluv":[145.894485367843032,372.920765055848051,91.2465066485729466],"hsluv":[145.894485367843032,99.9999999999901803,91.2465066485729466]},"#77ffcc":{"lch":[91.5944622372901591,64.9119206982031329,154.461378490718602],"luv":[91.5944622372901591,-58.5696939322881676,27.9847887504604707],"rgb":[0.466666666666666674,1,0.8],"xyz":[0.542639363985678913,0.797986951876552886,0.696718132460216633],"hpluv":[154.461378490718602,352.767904832744364,91.5944622372901591],"hsluv":[154.461378490718602,99.999999999989825,91.5944622372901591]},"#77ffdd":{"lch":[91.9799284987297,59.7212008687906604,165.331177548206284],"luv":[91.9799284987297,-57.7746296637575298,15.1232933062250314],"rgb":[0.466666666666666674,1,0.866666666666666696],"xyz":[0.564157689536312512,0.806594282096806392,0.81004798036022263],"hpluv":[165.331177548206284,341.200809564626638,91.9799284987297],"hsluv":[165.331177548206284,99.9999999999894698,91.9799284987297]},"#77ffee":{"lch":[92.4033024177180238,56.9851054432815545,178.272694676027839],"luv":[92.4033024177180238,-56.9592119034112,1.71767916801026743],"rgb":[0.466666666666666674,1,0.933333333333333348],"xyz":[0.587969869802487222,0.816119154203276409,0.935458796428745853],"hpluv":[178.272694676027839,344.865805035808421,92.4033024177180238],"hsluv":[178.272694676027839,99.9999999999889582,92.4033024177180238]},"#77ffff":{"lch":[92.8648336399367196,57.4251975820971623,192.177050630061018],"luv":[92.8648336399367196,-56.1331570721439945,-12.112885471963672],"rgb":[0.466666666666666674,1,1],"xyz":[0.614140918212318643,0.826587573567209133,1.0732929847205277],"hpluv":[192.177050630061018,371.354821198433683,92.8648336399367196],"hsluv":[192.177050630061018,99.9999999999883187,92.8648336399367196]},"#227700":{"lch":[43.5559297152692295,63.9882214930525208,124.519604676885976],"luv":[43.5559297152692295,-36.2613695379953711,52.7219647687080268],"rgb":[0.133333333333333331,0.466666666666666674,0],"xyz":[0.0725620932475783825,0.13533217400143932,0.0222976777942638753],"hpluv":[124.519604676885976,186.419817132403381,43.5559297152692295],"hsluv":[124.519604676885976,100.000000000002331,43.5559297152692295]},"#227711":{"lch":[43.6152314308602769,61.9621092027414093,125.591738779589861],"luv":[43.6152314308602769,-36.0623023987336282,50.3866383335378174],"rgb":[0.133333333333333331,0.466666666666666674,0.0666666666666666657],"xyz":[0.0735737587472155,0.135736840201294173,0.0276257827590195085],"hpluv":[125.591738779589861,180.271610265320959,43.6152314308602769],"hsluv":[125.591738779589861,95.0867888092805345,43.6152314308602769]},"#227722":{"lch":[43.7248500006056062,58.3665782213362476,127.715012949240148],"luv":[43.7248500006056062,-35.7048401974777292,46.1716562377823081],"rgb":[0.133333333333333331,0.466666666666666674,0.133333333333333331],"xyz":[0.0754491168856925298,0.136486983456685,0.0375026689549987],"hpluv":[127.715012949240148,169.385110384242353,43.7248500006056062],"hsluv":[127.715012949240148,86.2472116803111248,43.7248500006056062]},"#227733":{"lch":[43.9044636679785,52.8998675233047422,131.63685913347058],"luv":[43.9044636679785,-35.1470498804547518,39.5358175416168365],"rgb":[0.133333333333333331,0.466666666666666674,0.2],"xyz":[0.0785368676181502634,0.137722083749668101,0.0537648228126098443],"hpluv":[131.63685913347058,152.892166506547881,43.9044636679785],"hsluv":[131.63685913347058,86.6671370230467204,43.9044636679785]},"#227744":{"lch":[44.1618994548856207,46.0187725021067919,138.382113458020484],"luv":[44.1618994548856207,-34.403210499316,30.5638107889119937],"rgb":[0.133333333333333331,0.466666666666666674,0.266666666666666663],"xyz":[0.082994862862369137,0.139505281847355694,0.0772435977654964828],"hpluv":[138.382113458020484,132.228969104156789,44.1618994548856207],"hsluv":[138.382113458020484,87.230083060842972,44.1618994548856207]},"#227755":{"lch":[44.5028042963196171,38.7961505601339098,149.7341572603126],"luv":[44.5028042963196171,-33.5080868304533865,19.5537570621958743],"rgb":[0.133333333333333331,0.466666666666666674,0.333333333333333315],"xyz":[0.088957276901731136,0.141890247463100527,0.108645645039470398],"hpluv":[149.7341572603126,110.621765171639552,44.5028042963196171],"hsluv":[149.7341572603126,87.9126674499387235,44.5028042963196171]},"#227766":{"lch":[44.9310046324235657,33.2418513983527504,167.948858330193701],"luv":[44.9310046324235657,-32.5092552143098246,6.94038974417402166],"rgb":[0.133333333333333331,0.466666666666666674,0.4],"xyz":[0.0965422726752393073,0.144924245772503818,0.148593289446614346],"hpluv":[167.948858330193701,93.8811500215461,44.9310046324235657],"hsluv":[167.948858330193701,88.6822605795820778,44.9310046324235657]},"#227777":{"lch":[45.4487163896678652,32.1827345016432886,192.177050630061217],"luv":[45.4487163896678652,-31.4586377906525136,-6.7884098550242733],"rgb":[0.133333333333333331,0.466666666666666674,0.466666666666666674],"xyz":[0.105856285695441227,0.148649850980584641,0.197647091353012255],"hpluv":[192.177050630061217,89.8546686552558,45.4487163896678652],"hsluv":[192.177050630061217,89.5029511213474,45.4487163896678652]},"#227788":{"lch":[46.0567093690380389,37.0457871068229778,214.840569513336618],"luv":[46.0567093690380389,-30.4051407329018595,-21.1640676472289648],"rgb":[0.133333333333333331,0.466666666666666674,0.533333333333333326],"xyz":[0.116996702797385055,0.153106017821362239,0.256319954756584423],"hpluv":[214.840569513336618,102.066975938242322,46.0567093690380389],"hsluv":[214.840569513336618,90.3407286635711415,46.0567093690380389]},"#227799":{"lch":[46.7544651468991219,46.3079141704010908,230.605362437026685],"luv":[46.7544651468991219,-29.3896969252833173,-35.7864308006991223],"rgb":[0.133333333333333331,0.466666666666666674,0.6],"xyz":[0.130053666906457754,0.158328803464991397,0.325086632397702358],"hpluv":[230.605362437026685,125.681528260779189,46.7544651468991219],"hsluv":[230.605362437026685,91.1669787694701,46.7544651468991219]},"#2277aa":{"lch":[47.5403420753171133,57.8256716053654429,240.536105931551504],"luv":[47.5403420753171133,-28.4430017925967782,-50.3468365007961935],"rgb":[0.133333333333333331,0.466666666666666674,0.66666666666666663],"xyz":[0.14511135987171031,0.164351880651092491,0.404390482014700958],"hpluv":[240.536105931551504,154.346828351852139,47.5403420753171133],"hsluv":[240.536105931551504,91.9600907928071365,47.5403420753171133]},"#2277bb":{"lch":[48.4117490016133161,70.2708193466387172,246.886175208709233],"luv":[48.4117490016133161,-27.5854458877112236,-64.6299561103370337],"rgb":[0.133333333333333331,0.466666666666666674,0.733333333333333282],"xyz":[0.162248951979046957,0.17120691749402725,0.494648467113342705],"hpluv":[246.886175208709233,184.188949495161438,48.4117490016133161],"hsluv":[246.886175208709233,92.7055270960754427,48.4117490016133161]},"#2277cc":{"lch":[49.3653235224945348,82.9601291275659634,251.131977113837081],"luv":[49.3653235224945348,-26.8284223951791141,-78.5023488607078],"rgb":[0.133333333333333331,0.466666666666666674,0.8],"xyz":[0.181541327422768684,0.178923867671516051,0.596254977783612805],"hpluv":[251.131977113837081,213.248879712122147,49.3653235224945348],"hsluv":[251.131977113837081,93.3949294454883301,49.3653235224945348]},"#2277dd":{"lch":[50.3971082370692898,95.5506012475210156,254.100456017762497],"luv":[50.3971082370692898,-26.1762366694964186,-91.8951687118820928],"rgb":[0.133333333333333331,0.466666666666666674,0.866666666666666696],"xyz":[0.203059652973402227,0.187531197891769585,0.709584825683618803],"hpluv":[254.100456017762497,240.584217083197558,50.3971082370692898],"hsluv":[254.100456017762497,94.0248036114472399,50.3971082370692898]},"#2277ee":{"lch":[51.5027182397596448,107.874744495734575,256.256689112315712],"luv":[51.5027182397596448,-25.6280715933506258,-104.786270314512635],"rgb":[0.133333333333333331,0.466666666666666674,0.933333333333333348],"xyz":[0.226871833239577,0.19705606999823963,0.834995641752142],"hpluv":[256.256689112315712,265.784074864026707,51.5027182397596448],"hsluv":[256.256689112315712,94.5951642228933594,51.5027182397596448]},"#2277ff":{"lch":[52.6774941409559432,119.859275592882611,257.873120264558906],"luv":[52.6774941409559432,-25.1797078347732324,-117.18459053564186],"rgb":[0.133333333333333331,0.466666666666666674,1],"xyz":[0.253042881649408358,0.207524489362172326,0.972829830043923871],"hpluv":[257.873120264558906,288.725982332353851,52.6774941409559432],"hsluv":[257.873120264558906,99.9999999999990195,52.6774941409559432]},"#228800":{"lch":[49.4326013626652951,73.5543249838887903,125.335546592141156],"luv":[49.4326013626652951,-42.5411625112882845,60.0040683289365475],"rgb":[0.133333333333333331,0.533333333333333326,0],"xyz":[0.0946344629725488357,0.179476913451380865,0.0296551343692538216],"hpluv":[125.335546592141156,188.81394887832684,49.4326013626652951],"hsluv":[125.335546592141156,100.000000000002359,49.4326013626652951]},"#228811":{"lch":[49.4817413630627669,71.8188220709608,126.143293588176633],"luv":[49.4817413630627669,-42.3592238010278379,57.9968909738682825],"rgb":[0.133333333333333331,0.533333333333333326,0.0666666666666666657],"xyz":[0.0956461284721859539,0.179881579651235718,0.0349832393340094513],"hpluv":[126.143293588176633,184.175827324420425,49.4817413630627669],"hsluv":[126.143293588176633,96.2839239867753776,49.4817413630627669]},"#228822":{"lch":[49.5726392440562904,68.7061860444130161,127.715012949240233],"luv":[49.5726392440562904,-42.0299333634258545,54.3509402148249521],"rgb":[0.133333333333333331,0.533333333333333326,0.133333333333333331],"xyz":[0.097521486610662983,0.180631722906626546,0.0448601255299886509],"hpluv":[127.715012949240233,175.870551812838869,49.5726392440562904],"hsluv":[127.715012949240233,89.549457305464,49.5726392440562904]},"#228833":{"lch":[49.7217546026668913,63.8760413965615115,130.529662443073192],"luv":[49.7217546026668913,-41.5093107949551552,48.5502397710151357],"rgb":[0.133333333333333331,0.533333333333333326,0.2],"xyz":[0.100609237343120717,0.181866823199609645,0.0611222793875997941],"hpluv":[130.529662443073192,163.016240956960957,49.7217546026668913],"hsluv":[130.529662443073192,89.7937238944362122,49.7217546026668913]},"#228844":{"lch":[49.9358562328630171,57.5522088774297558,135.149605574971361],"luv":[49.9358562328630171,-40.8016788905052792,40.5891579906186308],"rgb":[0.133333333333333331,0.533333333333333326,0.266666666666666663],"xyz":[0.10506723258733959,0.183650021297297239,0.0846010543404864257],"hpluv":[135.149605574971361,146.247625060139768,49.9358562328630171],"hsluv":[135.149605574971361,90.1269016918236616,49.9358562328630171]},"#228855":{"lch":[50.2200542052193697,50.3265642713731509,142.503880569306347],"luv":[50.2200542052193697,-39.9288227743001443,30.6341669254964764],"rgb":[0.133333333333333331,0.533333333333333326,0.333333333333333315],"xyz":[0.111029646626701589,0.186034986913042072,0.116003101614460341],"hpluv":[142.503880569306347,127.162609675202816,50.2200542052193697],"hsluv":[142.503880569306347,90.5399352865824341,50.2200542052193697]},"#228866":{"lch":[50.5781035519961648,43.3062651916131074,154.006170397495453],"luv":[50.5781035519961648,-38.9254575775356315,18.9800252166796355],"rgb":[0.133333333333333331,0.533333333333333326,0.4],"xyz":[0.11861464240020976,0.189068985222445363,0.155950746021604303],"hpluv":[154.006170397495453,108.649446020320369,50.5781035519961648],"hsluv":[154.006170397495453,91.0179493017372607,50.5781035519961648]},"#228877":{"lch":[51.0125694858746357,38.3061120533697519,170.992189866461246],"luv":[51.0125694858746357,-37.8336830583721451,5.997553408179356],"rgb":[0.133333333333333331,0.533333333333333326,0.466666666666666674],"xyz":[0.12792865542041168,0.192794590430526186,0.205004547928002212],"hpluv":[170.992189866461246,95.2862426106229634,51.0125694858746357],"hsluv":[170.992189866461246,91.5427076584867621,51.0125694858746357]},"#228888":{"lch":[51.5249413470067594,37.5420496271247259,192.177050630061103],"luv":[51.5249413470067594,-36.6973707929670923,-7.91886779085127834],"rgb":[0.133333333333333331,0.533333333333333326,0.533333333333333326],"xyz":[0.139069072522355508,0.197250757271303784,0.263677411331574407],"hpluv":[192.177050630061103,92.4570004995607775,51.5249413470067594],"hsluv":[192.177050630061103,92.0950966753639761,51.5249413470067594]},"#228899":{"lch":[52.1157302062907064,42.0223592343639183,212.203992327233067],"luv":[52.1157302062907064,-35.5574728144251,-22.3951959730954577],"rgb":[0.133333333333333331,0.533333333333333326,0.6],"xyz":[0.152126036631428208,0.202473542914932941,0.332444088972692287],"hpluv":[212.203992327233067,102.317738016510475,52.1157302062907064],"hsluv":[212.203992327233067,92.6571999954113465,52.1157302062907064]},"#2288aa":{"lch":[52.784565077464336,50.6329849579481888,227.127925237574203],"luv":[52.784565077464336,-34.4488478228089221,-37.1076279143892478],"rgb":[0.133333333333333331,0.533333333333333326,0.66666666666666663],"xyz":[0.167183729596680763,0.208496620101034036,0.411747938589690887],"hpluv":[227.127925237574203,121.72111165959474,52.784565077464336],"hsluv":[227.127925237574203,93.213704377986,52.784565077464336]},"#2288bb":{"lch":[53.5302933631107294,61.6316847476891141,237.186375672219185],"luv":[53.5302933631107294,-33.3987075035381409,-51.7975955226846381],"rgb":[0.133333333333333331,0.533333333333333326,0.733333333333333282],"xyz":[0.18432132170401741,0.215351656943968794,0.502005923688332634],"hpluv":[237.186375672219185,146.097822373379188,53.5302933631107294],"hsluv":[237.186375672219185,93.7525919029994,53.5302933631107294]},"#2288cc":{"lch":[54.351086283976727,73.7818378825302261,243.928624140525301],"luv":[54.351086283976727,-32.4264148607849876,-66.274333045306733],"rgb":[0.133333333333333331,0.533333333333333326,0.8],"xyz":[0.203613697147739137,0.223068607121457596,0.60361243435860279],"hpluv":[243.928624140525301,172.258462735913952,54.351086283976727],"hsluv":[243.928624140525301,94.2652369190112864,54.351086283976727]},"#2288dd":{"lch":[55.2445474530087779,86.375042864399532,248.580085361336785],"luv":[55.2445474530087779,-31.544198041281593,-80.4090268549449831],"rgb":[0.133333333333333331,0.533333333333333326,0.866666666666666696],"xyz":[0.22513202269837268,0.23167593734171113,0.716942282258608787],"hpluv":[248.580085361336785,198.39840761978212,55.2445474530087779],"hsluv":[248.580085361336785,94.7460999996689566,55.2445474530087779]},"#2288ee":{"lch":[56.2078215466105604,99.0227420546019772,251.903461744910402],"luv":[56.2078215466105604,-30.7583451142169402,-94.1245326673496265],"rgb":[0.133333333333333331,0.533333333333333326,0.933333333333333348],"xyz":[0.248944202964547445,0.241200809448181175,0.842353098327132],"hpluv":[251.903461744910402,223.551465466634539,56.2078215466105604],"hsluv":[251.903461744910402,95.1922101623356838,56.2078215466105604]},"#2288ff":{"lch":[57.2376997180489866,111.514610807296222,254.356224713070389],"luv":[57.2376997180489866,-30.0705415498761575,-107.383755542446536],"rgb":[0.133333333333333331,0.533333333333333326,1],"xyz":[0.275115251374378811,0.251669228812113843,0.980187286618913856],"hpluv":[254.356224713070389,247.223031548482197,57.2376997180489866],"hsluv":[254.356224713070389,99.9999999999988773,57.2376997180489866]},"#229900":{"lch":[55.1973816023000694,82.8565734474734086,125.883775052172936],"luv":[55.1973816023000694,-48.5657961090338617,67.1310301704979508],"rgb":[0.133333333333333331,0.6,0],"xyz":[0.120504063425016322,0.23121611435631656,0.0382783345200760766],"hpluv":[125.883775052172936,190.479314261094402,55.1973816023000694],"hsluv":[125.883775052172936,100.000000000002331,55.1973816023000694]},"#229911":{"lch":[55.2388931006948951,81.3509781714907376,126.510168490119042],"luv":[55.2388931006948951,-48.4010205856972817,65.3859530459048273],"rgb":[0.133333333333333331,0.6,0.0666666666666666657],"xyz":[0.121515728924653441,0.231620780556171413,0.0436064394848317063],"hpluv":[126.510168490119042,186.877552842351321,55.2388931006948951],"hsluv":[126.510168490119042,97.109403045153627,55.2388931006948951]},"#229922":{"lch":[55.3157166450500739,78.6308396618125869,127.715012949240275],"luv":[55.3157166450500739,-48.1011847922964293,62.2019691609440102],"rgb":[0.133333333333333331,0.6,0.133333333333333331],"xyz":[0.12339108706313047,0.232370923811562241,0.0534833256808109059],"hpluv":[127.715012949240275,180.378053709807,55.3157166450500739],"hsluv":[127.715012949240275,91.8445791693357592,55.3157166450500739]},"#229933":{"lch":[55.4418461137647,74.3518111171957656,129.829614369777261],"luv":[55.4418461137647,-47.6228343175573201,57.0986643273697],"rgb":[0.133333333333333331,0.6,0.2],"xyz":[0.126478837795588217,0.23360602410454534,0.0697454795384220561],"hpluv":[129.829614369777261,170.173995330187722,55.4418461137647],"hsluv":[129.829614369777261,91.9941043082508827,55.4418461137647]},"#229944":{"lch":[55.6231658975890042,68.6117263626113925,133.195472742568398],"luv":[55.6231658975890042,-46.964006542137362,50.0195070344354846],"rgb":[0.133333333333333331,0.6,0.266666666666666663],"xyz":[0.130936833039807077,0.235389222202232934,0.0932242544913087],"hpluv":[133.195472742568398,156.524371813771666,55.6231658975890042],"hsluv":[133.195472742568398,92.2005608183228844,55.6231658975890042]},"#229955":{"lch":[55.8642490130281715,61.7521412094073696,138.342726405552],"luv":[55.8642490130281715,-46.1371272258517706,41.0450049980768625],"rgb":[0.133333333333333331,0.6,0.333333333333333315],"xyz":[0.136899247079169062,0.237774187817977767,0.124626301765282596],"hpluv":[138.342726405552,140.267605312348593,55.8642490130281715],"hsluv":[138.342726405552,92.4605995247666357,55.8642490130281715]},"#229966":{"lch":[56.1686206396836383,54.4254646973719787,146.085824005346524],"luv":[56.1686206396836383,-45.1662924386951516,30.3667126121210664],"rgb":[0.133333333333333331,0.6,0.4],"xyz":[0.144484242852677247,0.240808186127381058,0.164573946172426544],"hpluv":[146.085824005346524,122.955430161041207,56.1686206396836383],"hsluv":[146.085824005346524,92.7673635780271,56.1686206396836383]},"#229977":{"lch":[56.5388973522399,47.7139826201784629,157.505617321427167],"luv":[56.5388973522399,-44.0837619060267798,18.2550287233801534],"rgb":[0.133333333333333331,0.6,0.466666666666666674],"xyz":[0.153798255872879153,0.244533791335461881,0.213627748078824453],"hpluv":[157.505617321427167,107.087223886255089,56.5388973522399],"hsluv":[157.505617321427167,93.1115325865156,56.5388973522399]},"#229988":{"lch":[56.9768757530356,43.2189787336254057,173.325138204180888],"luv":[56.9768757530356,-42.9260293704251126,5.02355703331473169],"rgb":[0.133333333333333331,0.6,0.533333333333333326],"xyz":[0.164938672974823,0.248989958176239479,0.272300611482396648],"hpluv":[173.325138204180888,96.2532040641867,56.9768757530356],"hsluv":[173.325138204180888,93.4824878896153706,56.9768757530356]},"#229999":{"lch":[57.4836007022547477,42.6905833214490045,192.177050630061103],"luv":[57.4836007022547477,-41.7300648492924537,-9.00486490733903366],"rgb":[0.133333333333333331,0.6,0.6],"xyz":[0.177995637083895708,0.254212743819868636,0.341067289123514528],"hpluv":[192.177050630061103,94.2383018299879467,57.4836007022547477],"hsluv":[192.177050630061103,93.8694254698009587,57.4836007022547477]},"#2299aa":{"lch":[58.0594270662980563,46.8633307325653,210.133219640519371],"luv":[58.0594270662980563,-40.5302437993065823,-23.5259666096543114],"rgb":[0.133333333333333331,0.6,0.66666666666666663],"xyz":[0.193053330049148264,0.260235821005969759,0.420371138740513128],"hpluv":[210.133219640519371,102.423528384682896,58.0594270662980563],"hsluv":[210.133219640519371,94.2622655036202701,58.0594270662980563]},"#2299bb":{"lch":[58.704081470592044,54.8976329577059445,224.200669016044458],"luv":[58.704081470592044,-39.3562485070025474,-38.2731734745639],"rgb":[0.133333333333333331,0.6,0.733333333333333282],"xyz":[0.210190922156484883,0.267090857848904517,0.51062912383915493],"hpluv":[224.200669016044458,118.665547847191604,58.704081470592044],"hsluv":[224.200669016044458,94.6522748426748279,58.704081470592044]},"#2299cc":{"lch":[59.4167266489170771,65.3729917945351247,234.209137470411804],"luv":[59.4167266489170771,-38.231976961148348,-53.0277662532618663],"rgb":[0.133333333333333331,0.6,0.8],"xyz":[0.229483297600206637,0.274807808026393319,0.612235634509425086],"hpluv":[234.209137470411804,139.613998456385502,59.4167266489170771],"hsluv":[234.209137470411804,95.032392249276171,59.4167266489170771]},"#2299dd":{"lch":[60.1960287785942114,77.1664383037622201,241.199920521286145],"luv":[60.1960287785942114,-37.1753089722913614,-67.6214137925481],"rgb":[0.133333333333333331,0.6,0.866666666666666696],"xyz":[0.251001623150840181,0.283415138246646825,0.725565482409431084],"hpluv":[241.199920521286145,162.667181112599422,60.1960287785942114],"hsluv":[241.199920521286145,95.397300800485425,60.1960287785942114]},"#2299ee":{"lch":[61.0402269370523243,89.5733454479413211,246.163931095701571],"luv":[61.0402269370523243,-36.1984881015500051,-81.9332269222821],"rgb":[0.133333333333333331,0.6,0.933333333333333348],"xyz":[0.27481380341701489,0.292940010353116842,0.850976298477954307],"hpluv":[246.163931095701571,186.209563381880429,61.0402269370523243],"hsluv":[246.163931095701571,95.74331870201,61.0402269370523243]},"#2299ff":{"lch":[61.9472031658153384,102.178145565387652,249.783903318571561],"luv":[61.9472031658153384,-35.3088685699608078,-95.8835607989752532],"rgb":[0.133333333333333331,0.6,1],"xyz":[0.300984851826846311,0.303408429717049566,0.988810486769736152],"hpluv":[249.783903318571561,209.303089797111312,61.9472031658153384],"hsluv":[249.783903318571561,99.9999999999986,61.9472031658153384]},"#110000":{"lch":[1.07666134976862637,3.62084603829176643,12.1770506300617818],"luv":[1.07666134976862637,3.53937866928378497,0.763756943295526236],"rgb":[0.0666666666666666657,0,0],"xyz":[0.00231161193210362246,0.00119192490249095569,0.000108356809317355026],"hpluv":[12.1770506300617818,426.746789183125145,1.07666134976862637],"hsluv":[12.1770506300617818,100.000000000002203,1.07666134976862637]},"#110011":{"lch":[1.44219482929484544,3.28508596549136378,307.715012949243601],"luv":[1.44219482929484544,2.00959989444743092,-2.59871084672866193],"rgb":[0.0666666666666666657,0,0.0666666666666666657],"xyz":[0.0033232774317407442,0.00159659110234581,0.00543646177407298634],"hpluv":[307.715012949243601,289.042783730483393,1.44219482929484544],"hsluv":[307.715012949243601,99.9999999999988347,1.44219482929484544]},"#110022":{"lch":[2.1197964535087821,6.27745605271938789,280.884754167684719],"luv":[2.1197964535087821,1.18539805862553327,-6.16451830530416167],"rgb":[0.0666666666666666657,0,0.133333333333333331],"xyz":[0.00519863557021776369,0.00234673435773662814,0.0153133479700521824],"hpluv":[280.884754167684719,375.775833064690062,2.1197964535087821],"hsluv":[280.884754167684719,99.9999999999998721,2.1197964535087821]},"#110033":{"lch":[3.23545797359596321,11.0622687483975319,272.972319481398301],"luv":[3.23545797359596321,0.57361730895702967,-11.0473867065762477],"rgb":[0.0666666666666666657,0,0.2],"xyz":[0.00828638630267550247,0.00358183465071974143,0.0315755018276633256],"hpluv":[272.972319481398301,433.858158519435221,3.23545797359596321],"hsluv":[272.972319481398301,100.000000000000355,3.23545797359596321]},"#110044":{"lch":[4.84621421062803659,17.7312810137515946,269.891014646828467],"luv":[4.84621421062803659,-0.0337275934556249754,-17.7312489362161827],"rgb":[0.0666666666666666657,0,0.266666666666666663],"xyz":[0.012744381546894383,0.0053650327484073175,0.0550542767805499642],"hpluv":[269.891014646828467,464.276639746945534,4.84621421062803659],"hsluv":[269.891014646828467,100.000000000000711,4.84621421062803659]},"#110055":{"lch":[7.00054481789469563,26.532890242342738,268.413820694361107],"luv":[7.00054481789469563,-0.734444075336115332,-26.5227233992365541],"rgb":[0.0666666666666666657,0,0.333333333333333315],"xyz":[0.0187067955862563751,0.00774999836415214954,0.0864563240545238726],"hpluv":[268.413820694361107,480.941270902403687,7.00054481789469563],"hsluv":[268.413820694361107,100.000000000000682,7.00054481789469563]},"#110066":{"lch":[9.62818818466394,37.2351477319955,267.604082628906383],"luv":[9.62818818466394,-1.55659527409507947,-37.20259719127408],"rgb":[0.0666666666666666657,0,0.4],"xyz":[0.0262917913597645499,0.010783996673555462,0.126403968461667848],"hpluv":[267.604082628906383,490.735908571457742,9.62818818466394],"hsluv":[267.604082628906383,100.000000000000753,9.62818818466394]},"#110077":{"lch":[12.2928363787590555,48.1341065988899643,267.117295446388],"luv":[12.2928363787590555,-2.42073458662620622,-48.0731969202633138],"rgb":[0.0666666666666666657,0,0.466666666666666674],"xyz":[0.0356058043799664659,0.0145096018816362783,0.175457770368065757],"hpluv":[267.117295446388,496.866985521105335,12.2928363787590555],"hsluv":[267.117295446388,100.000000000000739,12.2928363787590555]},"#110088":{"lch":[14.9348588897968106,58.9551979191609803,266.804247897724281],"luv":[14.9348588897968106,-3.28660375460643372,-58.8635166928348781],"rgb":[0.0666666666666666657,0,0.533333333333333326],"xyz":[0.0467462214819102939,0.0189657687224138727,0.234130633771637925],"hpluv":[266.804247897724281,500.910695182750828,14.9348588897968106],"hsluv":[266.804247897724281,100.000000000000753,14.9348588897968106]},"#110099":{"lch":[17.5475874535139624,69.6538923837914297,266.59230255326986],"luv":[17.5475874535139624,-4.14026096141065292,-69.5307339482636],"rgb":[0.0666666666666666657,0,0.6],"xyz":[0.0598031855909830073,0.0241885543660430302,0.302897311412755832],"hpluv":[266.59230255326986,503.694607743992833,17.5475874535139624],"hsluv":[266.59230255326986,100.000000000000796,17.5475874535139624]},"#1100aa":{"lch":[20.1284543895036734,80.2134478690449,266.442863009455],"luv":[20.1284543895036734,-4.97675334080985809,-80.0589104673847203],"rgb":[0.0666666666666666657,0,0.66666666666666663],"xyz":[0.0748608785562355494,0.0302116315521441317,0.382201161029754433],"hpluv":[266.442863009455,505.680355905096519,20.1284543895036734],"hsluv":[266.442863009455,100.000000000000782,20.1284543895036734]},"#1100bb":{"lch":[22.6769756305364183,90.6302333913987894,266.3339747285724],"luv":[22.6769756305364183,-5.79494806122388795,-90.444777525002138],"rgb":[0.0666666666666666657,0,0.733333333333333282],"xyz":[0.0919984706635722,0.0370666683950788903,0.472459146128396179],"hpluv":[266.3339747285724,507.139328846885462,22.6769756305364183],"hsluv":[266.3339747285724,100.000000000001,22.6769756305364183]},"#1100cc":{"lch":[25.1937235339869332,100.906819147977927,266.252448568601267],"luv":[25.1937235339869332,-6.59531864805210422,-100.691051849175651],"rgb":[0.0666666666666666657,0,0.8],"xyz":[0.111290846107293936,0.0447836185725676919,0.574065656798666279],"hpluv":[266.252448568601267,508.238409831726415,25.1937235339869332],"hsluv":[266.252448568601267,100.000000000000824,25.1937235339869332]},"#1100dd":{"lch":[27.6797893663012289,111.048607057141055,266.189998210144608],"luv":[27.6797893663012289,-7.37896669992084409,-110.803176758488192],"rgb":[0.0666666666666666657,0,0.866666666666666696],"xyz":[0.132809171657927494,0.0533909487928212259,0.687395504698672277],"hpluv":[266.189998210144608,509.084249760461944,27.6797893663012289],"hsluv":[266.189998210144608,100.000000000000938,27.6797893663012289]},"#1100ee":{"lch":[30.1364964584496846,121.062148077250455,266.141219022825339],"luv":[30.1364964584496846,-8.14718371295858823,-120.787694301304626],"rgb":[0.0666666666666666657,0,0.933333333333333348],"xyz":[0.156621351924102231,0.0629158208992912638,0.8128063207671955],"hpluv":[266.141219022825339,509.74730741907581,30.1364964584496846],"hsluv":[266.141219022825339,100.000000000000952,30.1364964584496846]},"#1100ff":{"lch":[32.5652456752648263,130.954293728553409,266.102472093749839],"luv":[32.5652456752648263,-8.90125725083502495,-130.651424275813781],"rgb":[0.0666666666666666657,0,1],"xyz":[0.182792400333933625,0.0733842402632239599,0.950640509058977345],"hpluv":[266.102472093749839,510.275492181060656,32.5652456752648263],"hsluv":[266.102472093749839,100.000000000001108,32.5652456752648263]},"#111100":{"lch":[4.69779601336656771,5.17885327658484673,85.8743202181747307],"luv":[4.69779601336656771,0.372589941443898953,5.16543299210515716],"rgb":[0.0666666666666666657,0.0666666666666666657,0],"xyz":[0.00431601219303203148,0.00520072542434782924,0.000776490229626805866],"hpluv":[85.8743202181747307,139.887458074797621,4.69779601336656771],"hsluv":[85.8743202181747307,100.000000000002359,4.69779601336656771]},"#111111":{"lch":[5.06332949289278655,2.68159353999537178e-13,0],"luv":[5.06332949289278655,2.52120910544652531e-13,9.13481559944393266e-14],"rgb":[0.0666666666666666657,0.0666666666666666657,0.0666666666666666657],"xyz":[0.00532767769266915322,0.00560539162420268383,0.00610459519438243722],"hpluv":[0,6.72041492281092e-12,5.06332949289278655],"hsluv":[0,1.92419399944792277e-12,5.06332949289278655]},"#111122":{"lch":[5.74093111710672321,6.60006851394265048,265.874320218179719],"luv":[5.74093111710672321,-0.474838542395297381,-6.58296534605743222],"rgb":[0.0666666666666666657,0.0666666666666666657,0.133333333333333331],"xyz":[0.00720303583114617271,0.00635553487959350169,0.0159814813903616341],"hpluv":[265.874320218179719,145.883251481840432,5.74093111710672321],"hsluv":[265.874320218179719,28.41442223352254,5.74093111710672321]},"#111133":{"lch":[6.85659263719390388,14.212336546779186,265.874320218178582],"luv":[6.85659263719390388,-1.02249925976518052,-14.1755072354640976],"rgb":[0.0666666666666666657,0.0666666666666666657,0.2],"xyz":[0.0102907865636039132,0.00759063517257661455,0.0322436352479727809],"hpluv":[265.874320218178582,263.024656142887807,6.85659263719390388],"hsluv":[265.874320218178582,51.2306489028398957,6.85659263719390388]},"#111144":{"lch":[8.45853257854777141,22.7927945223118087,265.874320218178241],"luv":[8.45853257854777141,-1.63981590573345759,-22.7337301367732181],"rgb":[0.0666666666666666657,0.0666666666666666657,0.266666666666666663],"xyz":[0.0147487818078227903,0.00937383327026419105,0.0557224102008594194],"hpluv":[265.874320218178241,341.933676209697239,8.45853257854777141],"hsluv":[265.874320218178241,66.600159737267461,8.45853257854777141]},"#111155":{"lch":[10.3782295585045325,32.1242805487719707,265.874320218178127],"luv":[10.3782295585045325,-2.31116487943396587,-32.0410349033279545],"rgb":[0.0666666666666666657,0.0666666666666666657,0.333333333333333315],"xyz":[0.0207111958471847858,0.011758798886009024,0.0871244574748333278],"hpluv":[265.874320218178127,392.780088665713265,10.3782295585045325],"hsluv":[265.874320218178127,76.5037738801481453,10.3782295585045325]},"#111166":{"lch":[12.4757228248048477,41.8651930040424887,265.87432021817807],"luv":[12.4757228248048477,-3.01196982745712916,-41.7567051265328644],"rgb":[0.0666666666666666657,0.0666666666666666657,0.4],"xyz":[0.0282961916206929606,0.0147927971954123355,0.12707210188197729],"hpluv":[265.87432021817807,425.820638501567,12.4757228248048477],"hsluv":[265.87432021817807,82.9392496755345263,12.4757228248048477]},"#111177":{"lch":[14.6896895275036599,51.8467212520223697,265.874320218178],"luv":[14.6896895275036599,-3.73008575521422614,-51.7123676197837199],"rgb":[0.0666666666666666657,0.0666666666666666657,0.466666666666666674],"xyz":[0.0376102046408948731,0.0185184024034931519,0.176125903788375199],"hpluv":[265.874320218178,447.865910041391658,14.6896895275036599],"hsluv":[265.874320218178,87.2331192419333235,14.6896895275036599]},"#111188":{"lch":[16.9766940539391484,61.9476661879793511,265.874320218178],"luv":[16.9766940539391484,-4.45679305530888747,-61.7871373491236469],"rgb":[0.0666666666666666657,0.0666666666666666657,0.533333333333333326],"xyz":[0.0487506217428387,0.0229745692442707428,0.234798767191947366],"hpluv":[265.874320218178,463.03215765547759,16.9766940539391484],"hsluv":[265.874320218178,90.1871263608273495,16.9766940539391484]},"#111199":{"lch":[19.3069968916820471,72.0861980616198537,265.874320218178],"luv":[19.3069968916820471,-5.18620452834737478,-71.8993966147786],"rgb":[0.0666666666666666657,0.0666666666666666657,0.6],"xyz":[0.0618075858519114146,0.0281973548878999072,0.303565444833065246],"hpluv":[265.874320218178,473.779996738615694,19.3069968916820471],"hsluv":[265.874320218178,92.280537596895428,19.3069968916820471]},"#1111aa":{"lch":[21.6605350192491244,82.2093341223612839,265.874320218177957],"luv":[21.6605350192491244,-5.91450835752722703,-81.9962999636616274],"rgb":[0.0666666666666666657,0.0666666666666666657,0.66666666666666663],"xyz":[0.0768652788171639567,0.0342204320740010087,0.382869294450063846],"hpluv":[265.874320218177957,481.605322004481,21.6605350192491244],"hsluv":[265.874320218177957,93.8047159652847569,21.6605350192491244]},"#1111bb":{"lch":[24.0238472654082429,92.2838634174554215,265.874320218177957],"luv":[24.0238472654082429,-6.63931519789526092,-92.0447225046312241],"rgb":[0.0666666666666666657,0.0666666666666666657,0.733333333333333282],"xyz":[0.0940028709245006,0.0410754689169357673,0.473127279548705593],"hpluv":[265.874320218177957,487.441538809997496,24.0238472654082429],"hsluv":[265.874320218177957,94.9414655706975736,24.0238472654082429]},"#1111cc":{"lch":[26.3879200105999,102.289669569688542,265.874320218177957],"luv":[26.3879200105999,-7.35917778701558589,-102.024599989292597],"rgb":[0.0666666666666666657,0.0666666666666666657,0.8],"xyz":[0.113295246368222344,0.0487924190944245689,0.574733790218975749],"hpluv":[265.874320218177957,491.887677819884516,26.3879200105999],"hsluv":[265.874320218177957,95.8074626598259727,26.3879200105999]},"#1111dd":{"lch":[28.7467318202544035,112.215160110792439,265.874320218177957],"luv":[28.7467318202544035,-8.07326211070735766,-111.924369989661315],"rgb":[0.0666666666666666657,0.0666666666666666657,0.866666666666666696],"xyz":[0.134813571918855901,0.0573997493146781,0.688063638118981746],"hpluv":[265.874320218177957,495.338839734480189,28.7467318202544035],"hsluv":[265.874320218177957,96.479663003878315,28.7467318202544035]},"#1111ee":{"lch":[31.096282761883856,122.054240127147821,265.874320218177957],"luv":[31.096282761883856,-8.78112967353786367,-121.737953386246701],"rgb":[0.0666666666666666657,0.0666666666666666657,0.933333333333333348],"xyz":[0.158625752185030638,0.0669246214211481338,0.813474454187505],"hpluv":[265.874320218177957,498.062358817216193,31.096282761883856],"hsluv":[265.874320218177957,97.0101366558694451,31.096282761883856]},"#1111ff":{"lch":[33.4339475813396589,131.804336466263976,265.874320218177957],"luv":[33.4339475813396589,-9.48259535137154863,-131.462783694528071],"rgb":[0.0666666666666666657,0.0666666666666666657,1],"xyz":[0.184796800594862032,0.07739304078508083,0.951308642479286815],"hpluv":[265.874320218177957,500.243401112503761,33.4339475813396589],"hsluv":[265.874320218177957,99.9999999999995168,33.4339475813396589]},"#66aa00":{"lch":[62.9888010115071921,81.5107592316300185,114.758667910078074],"luv":[62.9888010115071921,-34.136471206054587,74.0182761493062884],"rgb":[0.4,0.66666666666666663,0],"xyz":[0.198534632170994735,0.315734905503604946,0.0504821063864305253],"hpluv":[114.758667910078074,164.206718875588678,62.9888010115071921],"hsluv":[114.758667910078074,100.000000000002245,62.9888010115071921]},"#66aa11":{"lch":[63.0225323172591345,80.1801511939703744,115.156040801232848],"luv":[63.0225323172591345,-34.0833758310267285,72.5753411114886262],"rgb":[0.4,0.66666666666666663,0.0666666666666666657],"xyz":[0.199546297670631867,0.316139571703459799,0.055810211351186155],"hpluv":[115.156040801232848,161.439702186697787,63.0225323172591345],"hsluv":[115.156040801232848,97.8915472494395,63.0225323172591345]},"#66aa22":{"lch":[63.0849851082382287,77.7526522520100372,115.919582231606014],"luv":[63.0849851082382287,-33.9864002990590066,69.9313915701248],"rgb":[0.4,0.66666666666666663,0.133333333333333331],"xyz":[0.201421655809108868,0.316889714958850599,0.0656870975471653545],"hpluv":[115.919582231606014,156.397041701241,63.0849851082382287],"hsluv":[115.919582231606014,94.0329763727763748,63.0849851082382287]},"#66aa33":{"lch":[63.1875983682703577,73.8659889058236416,117.258215410479664],"luv":[63.1875983682703577,-33.8307250746429062,65.6632801340230827],"rgb":[0.4,0.66666666666666663,0.2],"xyz":[0.20450940654156663,0.318124815251833726,0.0819492514047764908],"hpluv":[117.258215410479664,148.337854737344315,63.1875983682703577],"hsluv":[117.258215410479664,87.8175568215645228,63.1875983682703577]},"#66aa44":{"lch":[63.3352806074861121,68.495891054581449,119.389904478135335],"luv":[63.3352806074861121,-33.6143748396710436,59.6804900742209057],"rgb":[0.4,0.66666666666666663,0.266666666666666663],"xyz":[0.208967401785785489,0.319908013349521292,0.105428026357663129],"hpluv":[119.389904478135335,137.232870385557277,63.3352806074861121],"hsluv":[119.389904478135335,79.1339200396795093,63.3352806074861121]},"#66aa55":{"lch":[63.5319451116367162,61.7628687774086131,122.670093374403834],"luv":[63.5319451116367162,-33.3396585938880747,51.9915293529473],"rgb":[0.4,0.66666666666666663,0.333333333333333315],"xyz":[0.214929815825147474,0.322292978965266153,0.136830073631637045],"hpluv":[122.670093374403834,123.360077774302084,63.5319451116367162],"hsluv":[122.670093374403834,68.0252461175988401,63.5319451116367162]},"#66aa66":{"lch":[63.7807317293932101,53.9656100581627314,127.715012949238869],"luv":[63.7807317293932101,-33.0126168434810836,42.6902119706049703],"rgb":[0.4,0.66666666666666663,0.4],"xyz":[0.22251481159865566,0.325326977274669471,0.176777718038781],"hpluv":[127.715012949238869,107.366036241042551,63.7807317293932101],"hsluv":[127.715012949238869,54.6684489206366493,63.7807317293932101]},"#66aa77":{"lch":[64.0841229578331308,45.668717811445795,135.623736827110406],"luv":[64.0841229578331308,-32.6422859505805931,31.9392071670853355],"rgb":[0.4,0.66666666666666663,0.466666666666666674],"xyz":[0.231828824618857565,0.329052582482750267,0.225831519945178916],"hpluv":[135.623736827110406,90.428994130424627,64.0841229578331308],"hsluv":[135.623736827110406,56.3153951517164302,64.0841229578331308]},"#66aa88":{"lch":[64.4440140424290888,37.9133385548872752,148.25026899586868],"luv":[64.4440140424290888,-32.239785461804118,19.9503752785341248],"rgb":[0.4,0.66666666666666663,0.533333333333333326],"xyz":[0.242969241720801421,0.333508749323527864,0.284504383348751055],"hpluv":[148.25026899586868,74.65325904191441,64.4440140424290888],"hsluv":[148.25026899586868,58.1346686170252127,64.4440140424290888]},"#66aa99":{"lch":[64.861761772217136,32.5704605989434484,167.654678216446086],"luv":[64.861761772217136,-31.8173259789585323,6.96366793981576304],"rgb":[0.4,0.66666666666666663,0.6],"xyz":[0.256026205829874121,0.338731534967157,0.353271060989869],"hpluv":[167.654678216446086,63.7198120272805681,64.861761772217136],"hsluv":[167.654678216446086,60.083023100845935,64.861761772217136]},"#66aaaa":{"lch":[65.3382237636027,32.1097126044189949,192.177050630060876],"luv":[65.3382237636027,-31.387258852500235,-6.77300710648746396],"rgb":[0.4,0.66666666666666663,0.66666666666666663],"xyz":[0.271083898795126677,0.344754612153258144,0.432574910606867591],"hpluv":[192.177050630060876,62.3603323483304592,65.3382237636027],"hsluv":[192.177050630060876,62.1162357127798757,65.3382237636027]},"#66aabb":{"lch":[65.8737942906507641,37.4229485671739255,214.174175962111633],"luv":[65.8737942906507641,-30.9612713447490577,-21.020864781881972],"rgb":[0.4,0.66666666666666663,0.733333333333333282],"xyz":[0.288221490902463295,0.351609648996192903,0.522832895705509282],"hpluv":[214.174175962111633,72.0882777495769744,65.8737942906507641],"hsluv":[214.174175962111633,64.192083786910942,65.8737942906507641]},"#66aacc":{"lch":[66.4684397846860833,46.8829891397435361,229.336310284400895],"luv":[66.4684397846860833,-30.5497910563422188,-35.5629714322516],"rgb":[0.4,0.66666666666666663,0.8],"xyz":[0.30751386634618505,0.359326599173681704,0.624439406375779438],"hpluv":[229.336310284400895,89.5033179536005,66.4684397846860833],"hsluv":[229.336310284400895,66.2725553364081748,66.4684397846860833]},"#66aadd":{"lch":[67.1217354618507471,58.5746749070863473,239.007496148652194],"luv":[67.1217354618507471,-30.1616186688116876,-50.2122425285710676],"rgb":[0.4,0.66666666666666663,0.866666666666666696],"xyz":[0.329032191896818593,0.367933929393935211,0.737769254275785435],"hpluv":[239.007496148652194,110.735287258409116,67.1217354618507471],"hsluv":[239.007496148652194,68.3252248927570349,67.1217354618507471]},"#66aaee":{"lch":[67.8329035309127,71.3390505041132,245.305718817638592],"luv":[67.8329035309127,-29.803771094245274,-64.8150858627082584],"rgb":[0.4,0.66666666666666663,0.933333333333333348],"xyz":[0.352844372162993358,0.377458801500405228,0.863180070344308659],"hpluv":[245.305718817638592,133.452355648257935,67.8329035309127],"hsluv":[245.305718817638592,80.362890995181445,67.8329035309127]},"#66aaff":{"lch":[68.6008528128324144,84.5574659264264312,249.594848961048797],"luv":[68.6008528128324144,-29.4814940521041038,-79.2515397475312],"rgb":[0.4,0.66666666666666663,1],"xyz":[0.379015420572824724,0.387927220864337952,1.00101425863609061],"hpluv":[249.594848961048797,156.409011428865199,68.6008528128324144],"hsluv":[249.594848961048797,99.9999999999981,68.6008528128324144]},"#112200":{"lch":[11.0156269675282488,14.1286449823385087,113.920199516574741],"luv":[11.0156269675282488,-5.72865521459208082,12.9151507335100835],"rgb":[0.0666666666666666657,0.133333333333333331,0],"xyz":[0.00803163592779996757,0.0126319728938838038,0.00201503147454941628],"hpluv":[113.920199516574741,162.753605553330914,11.0156269675282488],"hsluv":[113.920199516574741,100.000000000002302,11.0156269675282488]},"#112211":{"lch":[11.3010826742418828,9.17677244733547,127.715012949238741],"luv":[11.3010826742418828,-5.61374683501564142,7.25940762201209555],"rgb":[0.0666666666666666657,0.133333333333333331,0.0666666666666666657],"xyz":[0.00904330142743709,0.0130366390937386584,0.00734313643930504731],"hpluv":[127.715012949238741,103.040803658029205,11.3010826742418828],"hsluv":[127.715012949238741,52.4661346244892783,11.3010826742418828]},"#112222":{"lch":[11.8149934741043623,5.60956124878379736,192.177050630060876],"luv":[11.8149934741043623,-5.48334870304322308,-1.18324317225625331],"rgb":[0.0666666666666666657,0.133333333333333331,0.133333333333333331],"xyz":[0.0109186595659141079,0.0137867823491294762,0.0172200226352842434],"hpluv":[192.177050630060876,60.2469040904941551,11.8149934741043623],"hsluv":[192.177050630060876,60.0110800331641911,11.8149934741043623]},"#112233":{"lch":[12.6219648570067733,12.7575995118883281,244.93155638428982],"luv":[12.6219648570067733,-5.40540262923445,-11.5558629154900672],"rgb":[0.0666666666666666657,0.133333333333333331,0.2],"xyz":[0.0140064102983718484,0.0150218826421125891,0.0334821764928953866],"hpluv":[244.93155638428982,128.257072990564865,12.6219648570067733],"hsluv":[244.93155638428982,68.2965554989448265,12.6219648570067733]},"#112244":{"lch":[13.7124312845167182,23.0561698733830092,256.354402060867073],"luv":[13.7124312845167182,-5.43930918870511082,-22.4053762472305387],"rgb":[0.0666666666666666657,0.133333333333333331,0.266666666666666663],"xyz":[0.0184644055425907255,0.0168050807398001656,0.0569609514457820251],"hpluv":[256.354402060867073,213.359519949101497,13.7124312845167182],"hsluv":[256.354402060867073,75.5965994738604508,13.7124312845167182]},"#112255":{"lch":[15.056320299603339,33.5848303856462849,260.40485184836416],"luv":[15.056320299603339,-5.59809589119781581,-33.114983835502386],"rgb":[0.0666666666666666657,0.133333333333333331,0.333333333333333315],"xyz":[0.024426819581952721,0.019190046355545,0.0883629987197559336],"hpluv":[260.40485184836416,283.050313811336878,15.056320299603339],"hsluv":[260.40485184836416,81.3424686793067,15.056320299603339]},"#112266":{"lch":[16.6136212231118279,43.9645077489691118,262.329755848243337],"luv":[16.6136212231118279,-5.86800935048734384,-43.5711419160865958],"rgb":[0.0666666666666666657,0.133333333333333331,0.4],"xyz":[0.0320118153554608958,0.02222404466494831,0.128310643126899909],"hpluv":[262.329755848243337,335.797328537363626,16.6136212231118279],"hsluv":[262.329755848243337,85.6428490187558396,16.6136212231118279]},"#112277":{"lch":[18.3427569840269769,54.1821774694947678,263.400149453671133],"luv":[18.3427569840269769,-6.22740469049246936,-53.8231157232341815],"rgb":[0.0666666666666666657,0.133333333333333331,0.466666666666666674],"xyz":[0.0413258283756628153,0.0259496498730291264,0.177364445033297818],"hpluv":[263.400149453671133,374.827260372181627,18.3427569840269769],"hsluv":[263.400149453671133,88.8099744527525559,18.3427569840269769]},"#112288":{"lch":[20.2056943122802366,64.2803592359499,264.056887374403459],"luv":[20.2056943122802366,-6.65565132438349316,-63.9348644242795103],"rgb":[0.0666666666666666657,0.133333333333333331,0.533333333333333326],"xyz":[0.0524662454776066434,0.0304058167138067173,0.236037308436869986],"hpluv":[264.056887374403459,403.686144257890874,20.2056943122802366],"hsluv":[264.056887374403459,91.1461001738222762,20.2056943122802366]},"#112299":{"lch":[22.17018380613613,74.2918952905243799,264.488199331991609],"luv":[22.17018380613613,-7.13579321215933149,-73.9484020185124677],"rgb":[0.0666666666666666657,0.133333333333333331,0.6],"xyz":[0.0655232095866793568,0.0356286023574358818,0.304803986077987865],"hpluv":[264.488199331991609,425.217833826531262,22.17018380613613],"hsluv":[264.488199331991609,92.8866294242426136,22.17018380613613]},"#1122aa":{"lch":[24.2101316823922517,84.2333021684004848,264.786067280823943],"luv":[24.2101316823922517,-7.6546801533155886,-83.8847725510625537],"rgb":[0.0666666666666666657,0.133333333333333331,0.66666666666666663],"xyz":[0.0805809025519319,0.0416516795435369833,0.384107835694986466],"hpluv":[264.786067280823943,441.495215422381477,24.2101316823922517],"hsluv":[264.786067280823943,94.2012423737010209,24.2101316823922517]},"#1122bb":{"lch":[26.3050242232650149,94.1101405136049891,264.999933480500431],"luv":[26.3050242232650149,-8.20234804116949334,-93.7520134935884926],"rgb":[0.0666666666666666657,0.133333333333333331,0.733333333333333282],"xyz":[0.0977184946592685455,0.0485067163864717418,0.474365820793628212],"hpluv":[264.999933480500431,453.98033637772636,26.3050242232650149],"hsluv":[264.999933480500431,95.2089691602506605,26.3050242232650149]},"#1122cc":{"lch":[28.4390102065576187,103.92243186966887,265.158337172634162],"luv":[28.4390102065576187,-8.77130520241401612,-103.551610565708117],"rgb":[0.0666666666666666657,0.133333333333333331,0.8],"xyz":[0.117010870102990286,0.0562236665639605435,0.575972331463898368],"hpluv":[265.158337172634162,463.69685512523705,28.4390102065576187],"hsluv":[265.158337172634162,95.9928942328389496,28.4390102065576187]},"#1122dd":{"lch":[30.599961250020371,113.668086087716972,265.278693166229971],"luv":[30.599961250020371,-9.35592092097037664,-113.282392888591403],"rgb":[0.0666666666666666657,0.133333333333333331,0.866666666666666696],"xyz":[0.138529195653623816,0.0648309967842140705,0.689302179363904366],"hpluv":[265.278693166229971,471.364637015548908,30.599961250020371],"hsluv":[265.278693166229971,96.6113336559982,30.599961250020371]},"#1122ee":{"lch":[32.7786459144851463,123.344693870669801,265.37211393361406],"luv":[32.7786459144851463,-9.95194954038693247,-122.942556531067964],"rgb":[0.0666666666666666657,0.133333333333333331,0.933333333333333348],"xyz":[0.162341375919798553,0.0743558688906841,0.814712995432427589],"hpluv":[265.37211393361406,477.494956838131543,32.7786459144851463],"hsluv":[265.37211393361406,97.1056530386567118,32.7786459144851463]},"#1122ff":{"lch":[34.9680553815075,132.950321242967135,265.445956583698],"luv":[34.9680553815075,-10.5561742154436597,-132.530581770930752],"rgb":[0.0666666666666666657,0.133333333333333331,1],"xyz":[0.188512424329629946,0.0848242882546168114,0.952547183724209434],"hpluv":[265.445956583698,482.455471693424897,34.9680553815075],"hsluv":[265.445956583698,99.9999999999995595,34.9680553815075]},"#66bb00":{"lch":[68.2883247343563,91.0397787832552297,117.384795663234385],"luv":[68.2883247343563,-41.875036539852637,80.8376313092488914],"rgb":[0.4,0.733333333333333282,0],"xyz":[0.232489130079593515,0.383643901320803504,0.0618002723559631373],"hpluv":[117.384795663234385,169.170277477244,68.2883247343563],"hsluv":[117.384795663234385,100.000000000002402,68.2883247343563]},"#66bb11":{"lch":[68.3179499939719079,89.8644626985519466,117.727722441428654],"luv":[68.3179499939719079,-41.8112733484955896,79.5452014710932644],"rgb":[0.4,0.733333333333333282,0.0666666666666666657],"xyz":[0.233500795579230647,0.384048567520658357,0.0671283773207187739],"hpluv":[117.727722441428654,166.91389144855998,68.3179499939719079],"hsluv":[117.727722441428654,98.2613130840239108,68.3179499939719079]},"#66bb22":{"lch":[68.3728123300379309,87.7153655991844374,118.381366327960222],"luv":[68.3728123300379309,-41.6944557120635579,77.1722600749346839],"rgb":[0.4,0.733333333333333282,0.133333333333333331],"xyz":[0.235376153717707648,0.384798710776049158,0.0770052635166979665],"hpluv":[118.381366327960222,162.791438416492724,68.3728123300379309],"hsluv":[118.381366327960222,95.072259168186676,68.3728123300379309]},"#66bb33":{"lch":[68.4629872592027766,84.2604886941914515,119.511012469656151],"luv":[68.4629872592027766,-41.5059446288263274,73.3286200296498691],"rgb":[0.4,0.733333333333333282,0.2],"xyz":[0.238463904450165409,0.386033811069032284,0.0932674173743091],"hpluv":[119.511012469656151,156.173540237969377,68.4629872592027766],"hsluv":[119.511012469656151,89.9157079277594846,68.4629872592027766]},"#66bb44":{"lch":[68.5928402387875451,79.4555052917154683,121.268984442668796],"luv":[68.5928402387875451,-41.2418962487648457,67.9137932600435761],"rgb":[0.4,0.733333333333333282,0.266666666666666663],"xyz":[0.242921899694384269,0.38781700916671985,0.116746192327195741],"hpluv":[121.268984442668796,146.988898097842537,68.5928402387875451],"hsluv":[121.268984442668796,82.6706505658268,68.5928402387875451]},"#66bb55":{"lch":[68.7658933773114711,73.3682686647690474,123.883282583110088],"luv":[68.7658933773114711,-40.9030232283392365,60.9085013577552417],"rgb":[0.4,0.733333333333333282,0.333333333333333315],"xyz":[0.248884313733746254,0.390201974782464711,0.148148239601169657],"hpluv":[123.883282583110088,135.386233996967292,68.7658933773114711],"hsluv":[123.883282583110088,73.3323147762666565,68.7658933773114711]},"#66bb66":{"lch":[68.985024233854773,66.1955602149500493,127.715012949239338],"luv":[68.985024233854773,-40.4940973290304953,52.3648763359380354],"rgb":[0.4,0.733333333333333282,0.4],"xyz":[0.256469309507254439,0.39323597309186803,0.188095884008313619],"hpluv":[127.715012949239338,121.76244699215377,68.985024233854773],"hsluv":[127.715012949239338,61.9987879490855889,68.985024233854773]},"#66bb77":{"lch":[69.2525700917713,58.3030977404443149,133.351332140289912],"luv":[69.2525700917713,-40.0233333378199134,42.395565742911792],"rgb":[0.4,0.733333333333333282,0.466666666666666674],"xyz":[0.265783322527456345,0.396961578299948825,0.237149685914711528],"hpluv":[133.351332140289912,106.830450835327468,69.2525700917713],"hsluv":[133.351332140289912,63.1630001095548,69.2525700917713]},"#66bb88":{"lch":[69.5703900447947632,50.3125315521488901,141.732198444264128],"luv":[69.5703900447947632,-39.5016033478381487,31.1604583428427624],"rgb":[0.4,0.733333333333333282,0.533333333333333326],"xyz":[0.276923739629400201,0.401417745140726423,0.295822549318283667],"hpluv":[141.732198444264128,91.7679559652102625,69.5703900447947632],"hsluv":[141.732198444264128,64.4651291783298888,69.5703900447947632]},"#66bb99":{"lch":[69.9399065468101924,43.264635747530761,154.168279853010262],"luv":[69.9399065468101924,-38.9415329854338594,18.8516767188195544],"rgb":[0.4,0.733333333333333282,0.6],"xyz":[0.2899807037384729,0.406640530784355581,0.364589226959401602],"hpluv":[154.168279853010262,78.4959645714096865,69.9399065468101924],"hsluv":[154.168279853010262,65.8787579381207848,69.9399065468101924]},"#66bbaa":{"lch":[70.3621368583926881,38.7745898249838348,171.579209782291855],"luv":[70.3621368583926881,-38.3565710720190296,5.67822786553099768],"rgb":[0.4,0.733333333333333282,0.66666666666666663],"xyz":[0.305038396703725456,0.412663607970456703,0.443893076576400203],"hpluv":[171.579209782291855,69.9274221790226278,70.3621368583926881],"hsluv":[171.579209782291855,67.37547943529961,70.3621368583926881]},"#66bbbb":{"lch":[70.8377198879813221,38.6292683935386592,192.177050630060933],"luv":[70.8377198879813221,-37.7601276376370194,-8.14819841495072161],"rgb":[0.4,0.733333333333333282,0.733333333333333282],"xyz":[0.322175988811062075,0.419518644813391461,0.534151061675042],"hpluv":[192.177050630060933,69.1976324805594629,70.8377198879813221],"hsluv":[192.177050630060933,68.9267726464228758,70.8377198879813221]},"#66bbcc":{"lch":[71.3669414392261103,43.4063518114314,211.106579982723787],"luv":[71.3669414392261103,-37.1648552128157,-22.4250956427882215],"rgb":[0.4,0.733333333333333282,0.8],"xyz":[0.341468364254783829,0.427235594990880263,0.635757572345312161],"hpluv":[211.106579982723787,77.1783568223693806,71.3669414392261103],"hsluv":[211.106579982723787,70.5055674968506736,71.3669414392261103]},"#66bbdd":{"lch":[71.9497594848613602,52.0084901368895629,225.300588521911806],"luv":[71.9497594848613602,-36.5821167433876298,-36.9679831866995059],"rgb":[0.4,0.733333333333333282,0.866666666666666696],"xyz":[0.362986689805417373,0.435842925211133769,0.749087420245318159],"hpluv":[225.300588521911806,91.724261948179759,71.9497594848613602],"hsluv":[225.300588521911806,72.0874065633031336,71.9497594848613602]},"#66bbee":{"lch":[72.5858302461357852,62.9426478584387183,235.089705553804919],"luv":[72.5858302461357852,-36.0216507769597953,-51.6160594653851135],"rgb":[0.4,0.733333333333333282,0.933333333333333348],"xyz":[0.386798870071592082,0.445367797317603786,0.874498236313841382],"hpluv":[235.089705553804919,110.035415213757233,72.5858302461357852],"hsluv":[235.089705553804919,76.908955535231712,72.5858302461357852]},"#66bbff":{"lch":[73.2745353232689638,75.1445669264803513,241.815748730615525],"luv":[73.2745353232689638,-35.4914181095182641,-66.2349241650025817],"rgb":[0.4,0.733333333333333282,1],"xyz":[0.412969918481423504,0.45583621668153651,1.01233242460562312],"hpluv":[241.815748730615525,130.131920555189879,73.2745353232689638],"hsluv":[241.815748730615525,99.9999999999976552,73.2745353232689638]},"#113300":{"lch":[17.8585390793191152,25.0449080182821966,121.332554648991049],"luv":[17.8585390793191152,-13.0234653569097247,21.3924465113644295],"rgb":[0.0666666666666666657,0.2,0],"xyz":[0.0141493580168107792,0.0248674170719056023,0.00405427217088629669],"hpluv":[121.332554648991049,177.956083469309505,17.8585390793191152],"hsluv":[121.332554648991049,100.000000000002288,17.8585390793191152]},"#113311":{"lch":[18.041211184449395,20.8015074137336562,127.715012949239792],"luv":[18.041211184449395,-12.7249964056056086,16.4553084796651738],"rgb":[0.0666666666666666657,0.2,0.0666666666666666657],"xyz":[0.015161023516447901,0.0252720832717604552,0.00938237713564192902],"hpluv":[127.715012949239792,146.308124837666583,18.041211184449395],"hsluv":[127.715012949239792,74.4969128915689254,18.041211184449395]},"#113322":{"lch":[18.3747440863758129,14.8635488733567129,145.575764327225926],"luv":[18.3747440863758129,-12.2605616690393529,8.40260154180516672],"rgb":[0.0666666666666666657,0.2,0.133333333333333331],"xyz":[0.0170363816549249196,0.0260222265271512765,0.0192592633316211251],"hpluv":[145.575764327225926,102.645648490479701,18.3747440863758129],"hsluv":[145.575764327225926,76.8412554017051,18.3747440863758129]},"#113333":{"lch":[18.910205854271,11.9516732098830207,192.177050630061075],"luv":[18.910205854271,-11.6827660646039035,-2.5210056714682163],"rgb":[0.0666666666666666657,0.2,0.2],"xyz":[0.0201241323873826601,0.0272573268201343893,0.0355214171892322683],"hpluv":[192.177050630061075,80.19952200231,18.910205854271],"hsluv":[192.177050630061075,79.885597544945341,18.910205854271]},"#113344":{"lch":[19.6554681695294136,18.5554908550806559,233.185939638237187],"luv":[19.6554681695294136,-11.1188227079461566,-14.8552355236207116],"rgb":[0.0666666666666666657,0.2,0.266666666666666663],"xyz":[0.0245821276316015372,0.0290405249178219624,0.0590001921421189068],"hpluv":[233.185939638237187,119.79215597403514,19.6554681695294136],"hsluv":[233.185939638237187,83.0941728600946163,19.6554681695294136]},"#113355":{"lch":[20.6059777210847557,29.4541985213363553,248.778672986371305],"luv":[20.6059777210847557,-10.6615827984222822,-27.4568837045772334],"rgb":[0.0666666666666666657,0.2,0.333333333333333315],"xyz":[0.0305445416709635327,0.0314254905335667953,0.0904022394160928222],"hpluv":[248.778672986371305,181.381634101163,20.6059777210847557],"hsluv":[248.778672986371305,86.0667890851332089,20.6059777210847557]},"#113366":{"lch":[21.7480278014825927,41.0513772817531262,255.392805777322508],"luv":[21.7480278014825927,-10.3527823296753354,-39.7244946445288178],"rgb":[0.0666666666666666657,0.2,0.4],"xyz":[0.0381295374444717075,0.0344594888429701068,0.130349883823236784],"hpluv":[255.392805777322508,239.522976201191227,21.7480278014825927],"hsluv":[255.392805777322508,88.6137215649990537,21.7480278014825927]},"#113377":{"lch":[23.0621320749224097,52.4639032010768602,258.793139915612699],"luv":[23.0621320749224097,-10.1964540550792755,-51.4635158514711293],"rgb":[0.0666666666666666657,0.2,0.466666666666666674],"xyz":[0.04744355046467362,0.0381850940510509232,0.179403685729634693],"hpluv":[258.793139915612699,288.669213908808,23.0621320749224097],"hsluv":[258.793139915612699,90.7010140503724926,23.0621320749224097]},"#113388":{"lch":[24.5260866455155693,63.5079254673071389,260.778240759541745],"luv":[24.5260866455155693,-10.1775299952298717,-62.6871157444433322],"rgb":[0.0666666666666666657,0.2,0.533333333333333326],"xyz":[0.0585839675666174481,0.0426412608918285141,0.238076549133206861],"hpluv":[260.778240759541745,328.5783880762134,24.5260866455155693],"hsluv":[260.778240759541745,92.3732755032704,24.5260866455155693]},"#113399":{"lch":[26.1173586094444445,74.1961224571638667,262.040130643645512],"luv":[26.1173586094444445,-10.2746398160742789,-73.4812653968914447],"rgb":[0.0666666666666666657,0.2,0.6],"xyz":[0.0716409316756901615,0.0478640465354576786,0.30684322677432474],"hpluv":[262.040130643645512,360.488391101723778,26.1173586094444445],"hsluv":[262.040130643645512,93.700931793532277,26.1173586094444445]},"#1133aa":{"lch":[27.8146812937100378,84.589542856674214,262.892366774415223],"luv":[27.8146812937100378,-10.4665753413372666,-83.9395113240792767],"rgb":[0.0666666666666666657,0.2,0.66666666666666663],"xyz":[0.0866986246409427,0.0538871237215587801,0.386147076391323341],"hpluv":[262.892366774415223,385.906342473210088,27.8146812937100378],"hsluv":[262.892366774415223,94.7540719156047544,27.8146812937100378]},"#1133bb":{"lch":[29.5989386642012917,94.7497677250031245,263.494633441352278],"luv":[29.5989386642012917,-10.734795769033445,-94.1396974912241],"rgb":[0.0666666666666666657,0.2,0.733333333333333282],"xyz":[0.10383621674827935,0.0607421605644935386,0.476405061489965087],"hpluv":[263.494633441352278,406.201330660618282,29.5989386642012917],"hsluv":[263.494633441352278,95.59270717643426,29.5989386642012917]},"#1133cc":{"lch":[31.4535171675710927,104.725970292241058,263.935552719695806],"luv":[31.4535171675710927,-11.0639900580249932,-104.139891384844844],"rgb":[0.0666666666666666657,0.2,0.8],"xyz":[0.123128592192001091,0.0684591107419823403,0.578011572160235243],"hpluv":[263.935552719695806,422.497850271701509,31.4535171675710927],"hsluv":[263.935552719695806,96.2648935085394299,31.4535171675710927]},"#1133dd":{"lch":[33.3643121953656845,114.554023382916327,264.267643395871801],"luv":[33.3643121953656845,-11.4418472625073555,-113.981175658242762],"rgb":[0.0666666666666666657,0.2,0.866666666666666696],"xyz":[0.144646917742634634,0.0770664409622358743,0.691341420060241241],"hpluv":[264.267643395871801,435.679872957086786,33.3643121953656845],"hsluv":[264.267643395871801,96.8079128297289913,33.3643121953656845]},"#1133ee":{"lch":[35.3195411096734375,124.259061611723823,264.523680461367292],"luv":[35.3195411096734375,-11.8585821660500468,-123.691909281234786],"rgb":[0.0666666666666666657,0.2,0.933333333333333348],"xyz":[0.168459098008809371,0.0865913130687059,0.816752236128764464],"hpluv":[264.523680461367292,446.428943593210363,35.3195411096734375],"hsluv":[264.523680461367292,97.2502875158067752,35.3195411096734375]},"#1133ff":{"lch":[37.3094684856901466,133.858437412957159,264.724991571549936],"luv":[37.3094684856901466,-12.3064438760062309,-133.291532760957],"rgb":[0.0666666666666666657,0.2,1],"xyz":[0.194630146418640765,0.0970597324326386,0.954586424420546309],"hpluv":[264.724991571549936,455.266836240216,37.3094684856901466],"hsluv":[264.724991571549936,99.9999999999995168,37.3094684856901466]},"#66cc00":{"lch":[73.5514640948473328,100.417876322708906,119.311479215942285],"luv":[73.5514640948473328,-49.1602904566029579,87.5614968315714322],"rgb":[0.4,0.8,0],"xyz":[0.270712873389210462,0.460091387940038399,0.0745415201258350923],"hpluv":[119.311479215942285,173.244332851636557,73.5514640948473328],"hsluv":[119.311479215942285,100.00000000000226,73.5514640948473328]},"#66cc11":{"lch":[73.5777109322390572,99.3703085818509,119.605548775623987],"luv":[73.5777109322390572,-49.0915230219986611,86.397225621155485],"rgb":[0.4,0.8,0.0666666666666666657],"xyz":[0.271724538888847567,0.460496054139893252,0.079869625090590729],"hpluv":[119.605548775623987,171.375877908330068,73.5777109322390572],"hsluv":[119.605548775623987,98.5479766016144652,73.5777109322390572]},"#66cc22":{"lch":[73.626324929263788,97.4510710028789333,120.162888823436575],"luv":[73.626324929263788,-48.965269014871545,84.2562381661406192],"rgb":[0.4,0.8,0.133333333333333331],"xyz":[0.273599897027324623,0.461246197395284052,0.0897465112865699216],"hpluv":[120.162888823436575,167.954954584373922,73.626324929263788],"hsluv":[120.162888823436575,95.8800576342850377,73.626324929263788]},"#66cc33":{"lch":[73.7062524827218084,94.3550745227874,121.116489614327122],"luv":[73.7062524827218084,-48.7607908304490252,80.779114663321],"rgb":[0.4,0.8,0.2],"xyz":[0.276687647759782329,0.462481297688267179,0.106008665144181058],"hpluv":[121.116489614327122,162.442721914772306,73.7062524827218084],"hsluv":[121.116489614327122,91.5533619475712896,73.7062524827218084]},"#66cc44":{"lch":[73.8213986639243,90.0253172969507318,122.577193203242018],"luv":[73.8213986639243,-48.472817822786439,75.8613451418811451],"rgb":[0.4,0.8,0.266666666666666663],"xyz":[0.281145643004001244,0.464264495785954745,0.129487440097067696],"hpluv":[122.577193203242018,154.746814564283426,73.8213986639243],"hsluv":[122.577193203242018,85.4474048693987527,73.8213986639243]},"#66cc55":{"lch":[73.974942724102462,84.4934421806047879,124.700104619680829],"luv":[73.974942724102462,-48.100513339115345,69.4656921655632118],"rgb":[0.4,0.8,0.333333333333333315],"xyz":[0.28710805704336323,0.466649461401699606,0.160889487371041612],"hpluv":[124.700104619680829,144.936474170198323,73.974942724102462],"hsluv":[124.700104619680829,77.5306238992907,73.974942724102462]},"#66cc66":{"lch":[74.1695172801941567,77.8884466842553564,127.715012949239551],"luv":[74.1695172801941567,-47.6470375142611218,61.6146893443493937],"rgb":[0.4,0.8,0.4],"xyz":[0.294693052816871415,0.469683459711102924,0.200837131778185574],"hpluv":[127.715012949239551,133.256044234036153,74.1695172801941567],"hsluv":[127.715012949239551,67.8510775159793,74.1695172801941567]},"#66cc77":{"lch":[74.407302734023375,70.4570986939790203,131.971622948486811],"luv":[74.407302734023375,-47.1190629819757234,52.3831715350808551],"rgb":[0.4,0.8,0.466666666666666674],"xyz":[0.30400706583707332,0.47340906491918372,0.249890933684583483],"hpluv":[131.971622948486811,120.156846155807528,74.407302734023375],"hsluv":[131.971622948486811,68.6882673601907499,74.407302734023375]},"#66cc88":{"lch":[74.6900832163393602,62.6050444414555045,138.002106903522986],"luv":[74.6900832163393602,-46.5261552249599859,41.8892404980031543],"rgb":[0.4,0.8,0.533333333333333326],"xyz":[0.315147482939017121,0.477865231759961318,0.308563797088155622],"hpluv":[138.002106903522986,106.361808066007058,74.6900832163393602],"hsluv":[138.002106903522986,69.6340873295455367,74.6900832163393602]},"#66cc99":{"lch":[75.0192831982140405,54.9734389641357382,146.572693391746668],"luv":[75.0192831982140405,-45.8800303566060634,30.2836887782922481],"rgb":[0.4,0.8,0.6],"xyz":[0.32820444704808982,0.483088017403590475,0.377330474729273557],"hpluv":[146.572693391746668,92.9863760296957338,75.0192831982140405],"hsluv":[146.572693391746668,70.6723780843603,75.0192831982140405]},"#66ccaa":{"lch":[75.3959940236094,48.5503126646653,158.569930493367366],"luv":[75.3959940236094,-45.1937477629490587,17.7386026218441692],"rgb":[0.4,0.8,0.66666666666666663],"xyz":[0.343262140013342376,0.489111094589691597,0.456634324346272158],"hpluv":[158.569930493367366,81.7114817988577187,75.3959940236094],"hsluv":[158.569930493367366,71.7849539596152368,75.3959940236094]},"#66ccbb":{"lch":[75.8209952994642,44.7015709258060667,174.304687468137473],"luv":[75.8209952994642,-44.4809102105153755,4.43610979112772],"rgb":[0.4,0.8,0.733333333333333282],"xyz":[0.360399732120679051,0.495966131432626356,0.546892309444913849],"hpluv":[174.304687468137473,74.8122352806046109,75.8209952994642],"hsluv":[174.304687468137473,72.9527506991265113,75.8209952994642]},"#66cccc":{"lch":[76.2947739303160262,44.7620652034609634,192.177050630061018],"luv":[76.2947739303160262,-43.7549393425641924,-9.44180938207391],"rgb":[0.4,0.8,0.8],"xyz":[0.379692107564400749,0.503683081610115102,0.648498820115184],"hpluv":[192.177050630061018,75.6461904464395,76.2947739303160262],"hsluv":[192.177050630061018,74.1568646821725679,76.2947739303160262]},"#66ccdd":{"lch":[76.8175423984245782,49.1342213212598082,208.868111129197587],"luv":[76.8175423984245782,-43.0284772118039101,-23.7217590764220851],"rgb":[0.4,0.8,0.866666666666666696],"xyz":[0.401210433115034348,0.512290411830368719,0.76182866801519],"hpluv":[208.868111129197587,85.3113130970085791,76.8175423984245782],"hsluv":[208.868111129197587,75.3794120212671714,76.8175423984245782]},"#66ccee":{"lch":[77.3892571801628435,57.0358051623713038,222.109360872917676],"luv":[77.3892571801628435,-42.312941633688304,-38.245235531031426],"rgb":[0.4,0.8,0.933333333333333348],"xyz":[0.425022613381209058,0.521815283936838736,0.887239484083713226],"hpluv":[222.109360872917676,102.061631830010029,77.3892571801628435],"hsluv":[222.109360872917676,76.6041682601332923,77.3892571801628435]},"#66ccff":{"lch":[78.0096377377628158,67.2874731922355664,231.792303901557148],"luv":[78.0096377377628158,-41.6182406850010267,-52.872734853430309],"rgb":[0.4,0.8,1],"xyz":[0.451193661791040479,0.53228370330077146,1.02507367237549518],"hpluv":[231.792303901557148,124.498094909356865,78.0096377377628158],"hsluv":[231.792303901557148,99.9999999999966604,78.0096377377628158]},"#114400":{"lch":[24.4916204196936391,35.767443133059956,124.131260038140155],"luv":[24.4916204196936391,-20.0687794552527912,29.6066559991685239],"rgb":[0.0666666666666666657,0.266666666666666663,0],"xyz":[0.0229819284997768124,0.0425325580378379114,0.00699846233187489172],"hpluv":[124.131260038140155,185.314627891622,24.4916204196936391],"hsluv":[124.131260038140155,100.000000000002416,24.4916204196936391]},"#114411":{"lch":[24.6196313539200702,32.2821952767626144,127.715012949240105],"luv":[24.6196313539200702,-19.7481274165088401,25.5372589646650674],"rgb":[0.0666666666666666657,0.266666666666666663,0.0666666666666666657],"xyz":[0.0239935939994139341,0.0429372242376927643,0.0123265672966305223],"hpluv":[127.715012949240105,166.387555424049935,24.6196313539200702],"hsluv":[127.715012949240105,84.7209219338948,24.6196313539200702]},"#114422":{"lch":[24.8548180969752792,26.7199561105771828,135.968420687644709],"luv":[24.8548180969752792,-19.2104947057918238,18.5718321042894203],"rgb":[0.0666666666666666657,0.266666666666666663,0.133333333333333331],"xyz":[0.0258689521378909527,0.0436873674930835856,0.0222034534926097184],"hpluv":[135.968420687644709,136.415738329938534,24.8548180969752792],"hsluv":[135.968420687644709,85.5945702875542338,24.8548180969752792]},"#114433":{"lch":[25.2362525898650887,20.3101465248311648,155.348193219538018],"luv":[25.2362525898650887,-18.4590663004995292,8.4714180143512],"rgb":[0.0666666666666666657,0.266666666666666663,0.2],"xyz":[0.0289567028703486933,0.0449224677860667,0.0384656073502208651],"hpluv":[155.348193219538018,102.123929581721498,25.2362525898650887],"hsluv":[155.348193219538018,86.8340768870874911,25.2362525898650887]},"#114444":{"lch":[25.774812755707849,18.0038630185053101,192.177050630061132],"luv":[25.774812755707849,-17.5987843886529483,-3.79761393914762779],"rgb":[0.0666666666666666657,0.266666666666666663,0.266666666666666663],"xyz":[0.0334146981145675703,0.0467056658837542715,0.0619443823031075036],"hpluv":[192.177050630061132,88.6358691141452226,25.774812755707849],"hsluv":[192.177050630061132,88.2889223192016743,25.774812755707849]},"#114455":{"lch":[26.4741010086829718,23.9697809957076196,225.699525295295985],"luv":[26.4741010086829718,-16.7410035671662349,-17.1548593857925162],"rgb":[0.0666666666666666657,0.266666666666666663,0.333333333333333315],"xyz":[0.0393771121539295693,0.0490906314994991044,0.0933464295770814],"hpluv":[225.699525295295985,114.889984549549212,26.4741010086829718],"hsluv":[225.699525295295985,89.7968555301121398,26.4741010086829718]},"#114466":{"lch":[27.3316922889079734,34.6428172107851182,242.548035964380944],"luv":[27.3316922889079734,-15.9705048052882308,-30.7419544037807526],"rgb":[0.0666666666666666657,0.266666666666666663,0.4],"xyz":[0.0469621079274377407,0.052124629808902416,0.133294073984225381],"hpluv":[242.548035964380944,160.837015687659374,27.3316922889079734],"hsluv":[242.548035964380944,91.2329185483074525,27.3316922889079734]},"#114477":{"lch":[28.3404051997208484,46.6267191674415,250.798290317077829],"luv":[28.3404051997208484,-15.3352867062553546,-44.0327142242719844],"rgb":[0.0666666666666666657,0.266666666666666663,0.466666666666666674],"xyz":[0.0562761209476396601,0.0558502350169832323,0.18234787589062329],"hpluv":[250.798290317077829,208.770018220734585,28.3404051997208484],"hsluv":[250.798290317077829,92.5248535524246734,28.3404051997208484]},"#114488":{"lch":[29.4896359978219706,58.6954673108201632,255.342505689020953],"luv":[29.4896359978219706,-14.8523182742844106,-56.7852667926718055],"rgb":[0.0666666666666666657,0.266666666666666663,0.533333333333333326],"xyz":[0.0674165380495834882,0.0603064018577608302,0.241020739294195457],"hpluv":[255.342505689020953,252.565763352450517,29.4896359978219706],"hsluv":[255.342505689020953,93.6449802292742817,29.4896359978219706]},"#114499":{"lch":[30.7666487879374699,70.4540899928233699,258.107815399211404],"luv":[30.7666487879374699,-14.5185243824624628,-68.9419411278265102],"rgb":[0.0666666666666666657,0.266666666666666663,0.6],"xyz":[0.0804735021586562,0.0655291875013899877,0.309787416935313364],"hpluv":[258.107815399211404,290.579747717257874,30.7666487879374699],"hsluv":[258.107815399211404,94.5943513350065359,30.7666487879374699]},"#1144aa":{"lch":[32.1577052090601185,81.8040240174920541,259.917940759024589],"luv":[32.1577052090601185,-14.3204852090806973,-80.5408098347099894],"rgb":[0.0666666666666666657,0.266666666666666663,0.66666666666666663],"xyz":[0.0955311951239087437,0.0715522646874911,0.389091266552311965],"hpluv":[259.917940759024589,322.796594575352628,32.1577052090601185],"hsluv":[259.917940759024589,95.3887741756132925,32.1577052090601185]},"#1144bb":{"lch":[33.6489603009756664,92.7573184463875435,261.168522985608377],"luv":[33.6489603009756664,-14.2409127099882671,-91.6576048702508928],"rgb":[0.0666666666666666657,0.266666666666666663,0.733333333333333282],"xyz":[0.11266878723124539,0.0784073015304258547,0.479349251650953712],"hpluv":[261.168522985608377,349.796823816496214,33.6489603009756664],"hsluv":[261.168522985608377,96.0495339612535872,33.6489603009756664]},"#1144cc":{"lch":[35.2271045850644597,103.362934076908545,262.068884255867147],"luv":[35.2271045850644597,-14.262270250582695,-102.374234005860515],"rgb":[0.0666666666666666657,0.266666666666666663,0.8],"xyz":[0.131961162674967131,0.0861242517079146563,0.580955762321223812],"hpluv":[262.068884255867147,372.329293739207799,35.2271045850644597],"hsluv":[262.068884255867147,96.5982694251149638,35.2271045850644597]},"#1144dd":{"lch":[36.8797734412618,113.676357292171801,262.73849416957313],"luv":[36.8797734412618,-14.3684841809298494,-112.764625967365617],"rgb":[0.0666666666666666657,0.266666666666666663,0.866666666666666696],"xyz":[0.153479488225600674,0.0947315819281681903,0.69428561022122981],"hpluv":[262.73849416957313,391.13009227787353,36.8797734412618],"hsluv":[262.73849416957313,97.0546019825808,36.8797734412618]},"#1144ee":{"lch":[38.5957670998368911,123.747928777943088,263.249741523271325],"luv":[38.5957670998368911,-14.5455638799169762,-122.890099065165245],"rgb":[0.0666666666666666657,0.266666666666666663,0.933333333333333348],"xyz":[0.177291668491775412,0.104256454034638207,0.819696426289753],"hpluv":[263.249741523271325,406.853061330967478,38.5957670998368911],"hsluv":[263.249741523271325,97.4353215147193623,38.5957670998368911]},"#1144ff":{"lch":[40.3651306844127546,133.619394536005728,263.648645306126298],"luv":[40.3651306844127546,-14.7816672391382209,-132.799265471613751],"rgb":[0.0666666666666666657,0.266666666666666663,1],"xyz":[0.203462716901606805,0.114724873398570917,0.957530614581534878],"hpluv":[263.648645306126298,420.051425771921231,40.3651306844127546],"hsluv":[263.648645306126298,99.9999999999994458,40.3651306844127546]},"#66dd00":{"lch":[78.7732081443282084,109.616469768408933,120.762072840728067],"luv":[78.7732081443282084,-56.0659919017112145,94.1932853050883],"rgb":[0.4,0.866666666666666696,0],"xyz":[0.313346863936385611,0.54535936903439,0.0887528503082264109],"hpluv":[120.762072840728067,211.559351010719155,78.7732081443282084],"hsluv":[120.762072840728067,100.000000000002444,78.7732081443282084]},"#66dd11":{"lch":[78.7966434753788576,108.675393583239966,121.014553037765893],"luv":[78.7966434753788576,-55.9956244091473678,93.1387739746547],"rgb":[0.4,0.866666666666666696,0.0666666666666666657],"xyz":[0.314358529436022716,0.545764035234244882,0.0940809552729820475],"hpluv":[121.014553037765893,210.019013530063148,78.7966434753788576],"hsluv":[121.014553037765893,98.7735218244661866,78.7966434753788576]},"#66dd22":{"lch":[78.8400557089289435,106.948443645027297,121.491090191754736],"luv":[78.8400557089289435,-55.866227309203758,91.1972271745690506],"rgb":[0.4,0.866666666666666696,0.133333333333333331],"xyz":[0.316233887574499772,0.546514178489635682,0.10395784146896124],"hpluv":[121.491090191754736,207.186246213049145,78.8400557089289435],"hsluv":[121.491090191754736,96.5169147905729,78.8400557089289435]},"#66dd33":{"lch":[78.911446872650572,104.154611952746194,122.300539429107701],"luv":[78.911446872650572,-55.6560904548950788,88.037394249850891],"rgb":[0.4,0.866666666666666696,0.2],"xyz":[0.319321638306957478,0.547749278782618809,0.120219995326572376],"hpluv":[122.300539429107701,202.586476802368111,78.911446872650572],"hsluv":[122.300539429107701,92.8487034899531807,78.911446872650572]},"#66dd44":{"lch":[79.0143300648071687,100.229492569308348,123.526451276321851],"luv":[79.0143300648071687,-55.3589437481663,83.5544045983716899],"rgb":[0.4,0.866666666666666696,0.266666666666666663],"xyz":[0.323779633551176393,0.549532476880306375,0.143698770279459015],"hpluv":[123.526451276321851,196.088207898644384,79.0143300648071687],"hsluv":[123.526451276321851,87.6539206040991843,79.0143300648071687]},"#66dd55":{"lch":[79.1515854502963,95.1800529291645603,125.27945296022996],"luv":[79.1515854502963,-54.9726586351532518,77.699737954393882],"rgb":[0.4,0.866666666666666696,0.333333333333333315],"xyz":[0.329742047590538379,0.551917442496051125,0.17510081755343293],"hpluv":[125.27945296022996,187.665730733793509,79.1515854502963],"hsluv":[125.27945296022996,80.8868034505971707,79.1515854502963]},"#66dd66":{"lch":[79.3256225689869723,89.0890908185611607,127.715012949239735],"luv":[79.3256225689869723,-54.4988561596450722,70.4751075215082921],"rgb":[0.4,0.866666666666666696,0.4],"xyz":[0.337327043364046564,0.554951440805454443,0.215048461960576892],"hpluv":[127.715012949239735,177.410630109117562,79.3256225689869723],"hsluv":[127.715012949239735,72.5638298210149,79.3256225689869723]},"#66dd77":{"lch":[79.538466322575843,82.1265081512392072,131.057978326052336],"luv":[79.538466322575843,-53.9425296262626048,61.9271090770055395],"rgb":[0.4,0.866666666666666696,0.466666666666666674],"xyz":[0.346641056384248469,0.558677046013535294,0.264102263866974774],"hpluv":[131.057978326052336,165.560886464635786,79.538466322575843],"hsluv":[131.057978326052336,73.175897046832489,79.538466322575843]},"#66dd88":{"lch":[79.7918079202835173,74.5708009722257543,135.636001638862723],"luv":[79.7918079202835173,-53.3115731427918,52.1409678341327378],"rgb":[0.4,0.866666666666666696,0.533333333333333326],"xyz":[0.35778147348619227,0.563133212854312837,0.322775127270546969],"hpluv":[135.636001638862723,152.557764790666909,79.7918079202835173],"hsluv":[135.636001638862723,73.8730513922454435,79.7918079202835173]},"#66dd99":{"lch":[80.0870378401123162,66.8478260511747919,141.915708870878916],"luv":[80.0870378401123162,-52.6162023759431392,41.2330825345609924],"rgb":[0.4,0.866666666666666696,0.6],"xyz":[0.370838437595265,0.568355998497942,0.391541804911664904],"hpluv":[141.915708870878916,139.150468179242381,80.0870378401123162],"hsluv":[141.915708870878916,74.6453790933081791,80.0870378401123162]},"#66ddaa":{"lch":[80.4252690581998877,59.592891473004542,150.502508447871207],"luv":[80.4252690581998877,-51.8682972227800931,29.3426729750825572],"rgb":[0.4,0.866666666666666696,0.66666666666666663],"xyz":[0.385896130560517525,0.574379075684043117,0.470845654528663449],"hpluv":[150.502508447871207,126.571308780245914,80.4252690581998877],"hsluv":[150.502508447871207,75.4812281571350638,80.4252690581998877]},"#66ddbb":{"lch":[80.807354973374558,53.7174771102931672,161.973645166837599],"luv":[80.807354973374558,-51.0807157732000334,16.6231111165276104],"rgb":[0.4,0.866666666666666696,0.733333333333333282],"xyz":[0.4030337226678542,0.581234112526977875,0.561103639627305251],"hpluv":[161.973645166837599,116.757770235740637,80.807354973374558],"hsluv":[161.973645166837599,76.3679029554368753,80.807354973374558]},"#66ddcc":{"lch":[81.2339045655681389,50.3705316419042148,176.319314132685548],"luv":[81.2339045655681389,-50.2666331071559256,3.23358221770368903],"rgb":[0.4,0.866666666666666696,0.8],"xyz":[0.422326098111575954,0.588951062704466732,0.662710150297575407],"hpluv":[176.319314132685548,112.393665646206941,81.2339045655681389],"hsluv":[176.319314132685548,77.2923330418296501,81.2339045655681389]},"#66dddd":{"lch":[81.7052962965957903,50.5769089008318389,192.177050630061],"luv":[81.7052962965957903,-49.4389517336029,-10.6683534552210038],"rgb":[0.4,0.866666666666666696,0.866666666666666696],"xyz":[0.443844423662209442,0.597558392924720239,0.776039998197581404],"hpluv":[192.177050630061,116.242714563462513,81.7052962965957903],"hsluv":[192.177050630061,78.2416694753709407,81.7052962965957903]},"#66ddee":{"lch":[82.2216916522674524,54.6311568672274745,207.154140846621715],"luv":[82.2216916522674524,-48.6098170936026577,-24.9328895793911158],"rgb":[0.4,0.866666666666666696,0.933333333333333348],"xyz":[0.467656603928384207,0.607083265031190256,0.901450814266104627],"hpluv":[207.154140846621715,129.793318723999505,82.2216916522674524],"hsluv":[207.154140846621715,79.2037752530793,82.2216916522674524]},"#66ddff":{"lch":[82.7830488398693376,61.9519841783888339,219.519505956683815],"luv":[82.7830488398693376,-47.7902556034158366,-39.4225799891321387],"rgb":[0.4,0.866666666666666696,1],"xyz":[0.493827652338215572,0.617551684395123,1.03928500255788636],"hpluv":[219.519505956683815,152.730665075356086,82.7830488398693376],"hsluv":[219.519505956683815,99.9999999999957,82.7830488398693376]},"#115500":{"lch":[30.9160157060817227,46.0913193883500583,125.457330883646421],"luv":[30.9160157060817227,-26.7374134918097575,37.543580579466358],"rgb":[0.0666666666666666657,0.333333333333333315,0],"xyz":[0.0347951852141227744,0.0661590714665301755,0.0109362145699901016],"hpluv":[125.457330883646421,189.179880792461034,30.9160157060817227],"hsluv":[125.457330883646421,100.000000000002402,30.9160157060817227]},"#115511":{"lch":[31.0114762783458957,43.2230667766736616,127.715012949240275],"luv":[31.0114762783458957,-26.4410342208804181,34.1921805521528697],"rgb":[0.0666666666666666657,0.333333333333333315,0.0666666666666666657],"xyz":[0.0358068507137599,0.0665637376663850283,0.0162643195347457331],"hpluv":[127.715012949240275,176.861157643680144,31.0114762783458957],"hsluv":[127.715012949240275,90.0538522348087156,31.0114762783458957]},"#115522":{"lch":[31.1874163697014737,38.3803455570512071,132.492971129528541],"luv":[31.1874163697014737,-25.925914044022,28.3001396827055132],"rgb":[0.0666666666666666657,0.333333333333333315,0.133333333333333331],"xyz":[0.0376822088522369147,0.0673138809217758427,0.0261412057307249292],"hpluv":[132.492971129528541,156.159643444286843,31.1874163697014737],"hsluv":[132.492971129528541,90.4316047034468653,31.1874163697014737]},"#115533":{"lch":[31.4742731349983,31.7764378074468219,142.363318860140765],"luv":[31.4742731349983,-25.163724938647551,19.4043538140960301],"rgb":[0.0666666666666666657,0.333333333333333315,0.2],"xyz":[0.0407699595846946553,0.0685489812147589556,0.0424033595883360759],"hpluv":[142.363318860140765,128.111709873485438,31.4742731349983],"hsluv":[142.363318860140765,90.9947325890089616,31.4742731349983]},"#115544":{"lch":[31.8824114421380642,25.5202649789159608,161.635705606154772],"luv":[31.8824114421380642,-24.2205825435089714,8.04035483341083435],"rgb":[0.0666666666666666657,0.333333333333333315,0.266666666666666663],"xyz":[0.0452279548289135358,0.0703321793124465355,0.0658821345412227144],"hpluv":[161.635705606154772,101.571845607751229,31.8824114421380642],"hsluv":[161.635705606154772,91.6999843863076194,31.8824114421380642]},"#115555":{"lch":[32.417637609391285,23.7206023942150033,192.177050630061103],"luv":[32.417637609391285,-23.1868997601056,-5.00346454561771115],"rgb":[0.0666666666666666657,0.333333333333333315,0.333333333333333315],"xyz":[0.0511903688682755278,0.0727171449281913684,0.0972841818151966159],"hpluv":[192.177050630061103,92.8503782686988899,32.417637609391285],"hsluv":[192.177050630061103,92.4869346485079,32.417637609391285]},"#115566":{"lch":[33.0818646063754045,29.1355194477524577,220.509575549450261],"luv":[33.0818646063754045,-22.1516601517912761,-18.9257085999416219],"rgb":[0.0666666666666666657,0.333333333333333315,0.4],"xyz":[0.0587753646417837061,0.0757511432375946869,0.137231826222340592],"hpluv":[220.509575549450261,111.756325010930979,33.0818646063754045],"hsluv":[220.509575549450261,93.2955878193037904,33.0818646063754045]},"#115577":{"lch":[33.8736729304774826,39.2775515041961185,237.359341141202208],"luv":[33.8736729304774826,-21.1850732372535866,-33.0744421585153958],"rgb":[0.0666666666666666657,0.333333333333333315,0.466666666666666674],"xyz":[0.0680893776619856117,0.0794767484456755,0.186285628128738501],"hpluv":[237.359341141202208,147.13684637222039,33.8736729304774826],"hsluv":[237.359341141202208,94.078253732623736,33.8736729304774826]},"#115588":{"lch":[34.7888943497230514,51.2161985161337938,246.60972521059881],"luv":[34.7888943497230514,-20.3324266151093482,-47.0073549392562455],"rgb":[0.0666666666666666657,0.333333333333333315,0.533333333333333326],"xyz":[0.0792297947639294398,0.0839329152864531,0.244958491532310668],"hpluv":[246.60972521059881,186.812546427038342,34.7888943497230514],"hsluv":[246.60972521059881,94.8038015691112719,34.7888943497230514]},"#115599":{"lch":[35.8212274371681403,63.5782184467896,252.028930114170464],"luv":[35.8212274371681403,-19.6162163870228632,-60.476391389741444],"rgb":[0.0666666666666666657,0.333333333333333315,0.6],"xyz":[0.0922867588730021671,0.0891557009300822517,0.313725169173428575],"hpluv":[252.028930114170464,225.22013661091745,35.8212274371681403],"hsluv":[252.028930114170464,95.4562831747131355,35.8212274371681403]},"#1155aa":{"lch":[36.9628521043173777,75.808874965898184,255.452401876993463],"luv":[36.9628521043173777,-19.0419916394553752,-73.3783897206670588],"rgb":[0.0666666666666666657,0.333333333333333315,0.66666666666666663],"xyz":[0.107344451838254695,0.0951787781161833601,0.393029018790427176],"hpluv":[255.452401876993463,260.251896817562397,36.9628521043173777],"hsluv":[255.452401876993463,96.0310300088164155,36.9628521043173777]},"#1155bb":{"lch":[38.2050019251475845,87.6984258792502089,257.752076786877694],"luv":[38.2050019251475845,-18.6045414354547205,-85.7023041678273216],"rgb":[0.0666666666666666657,0.333333333333333315,0.733333333333333282],"xyz":[0.124482043945591342,0.102033814959118119,0.483287003889068922],"hpluv":[257.752076786877694,291.280156181798475,38.2050019251475845],"hsluv":[257.752076786877694,96.5305142623785,38.2050019251475845]},"#1155cc":{"lch":[39.5384610498345523,99.1886562531622,259.372402836059223],"luv":[39.5384610498345523,-18.292845239891637,-97.4872368176334447],"rgb":[0.0666666666666666657,0.333333333333333315,0.8],"xyz":[0.143774419389313096,0.10975076513660692,0.584893514559339],"hpluv":[259.372402836059223,318.332933912315752,39.5384610498345523],"hsluv":[259.372402836059223,96.9610449958707,39.5384610498345523]},"#1155dd":{"lch":[40.9539668975822053,110.288480556245688,260.557616930578945],"luv":[40.9539668975822053,-18.0934548393737415,-108.7941902648341],"rgb":[0.0666666666666666657,0.333333333333333315,0.866666666666666696],"xyz":[0.16529274493994664,0.118358095356860454,0.698223362459345],"hpluv":[260.557616930578945,341.722445031840948,40.9539668975822053],"hsluv":[260.557616930578945,97.330522563257,40.9539668975822053]},"#1155ee":{"lch":[42.4425141949683038,121.034132372772049,261.450904748640312],"luv":[42.4425141949683038,-17.992549051743687,-119.689303523123172],"rgb":[0.0666666666666666657,0.333333333333333315,0.933333333333333348],"xyz":[0.189104925206121377,0.127882967463330471,0.823634178527868244],"hpluv":[261.450904748640312,361.864588035447412,42.4425141949683038],"hsluv":[261.450904748640312,97.6470858685672596,42.4425141949683038]},"#1155ff":{"lch":[43.9955669218353762,131.469960671873054,262.140820458865903],"luv":[43.9955669218353762,-17.9770474653633769,-130.235081001594637],"rgb":[0.0666666666666666657,0.333333333333333315,1],"xyz":[0.21527597361595277,0.138351386827263168,0.961468366819650089],"hpluv":[262.140820458865903,379.190057269809415,43.9955669218353762],"hsluv":[262.140820458865903,99.9999999999993321,43.9955669218353762]},"#66ee00":{"lch":[83.9510288300903511,118.631054776009961,121.878900606421581],"luv":[83.9510288300903511,-62.6521043104729145,100.737485489455693],"rgb":[0.4,0.933333333333333348,0],"xyz":[0.360525640276900428,0.639716921715420939,0.104479109088397595],"hpluv":[121.878900606421581,316.932305812441825,83.9510288300903511],"hsluv":[121.878900606421581,100.000000000002245,83.9510288300903511]},"#66ee11":{"lch":[83.9720997528394406,117.779830021225337,122.096631719604488],"luv":[83.9720997528394406,-62.5821687959979371,99.7775551344988401],"rgb":[0.4,0.933333333333333348,0.0666666666666666657],"xyz":[0.361537305776537532,0.640121587915275847,0.109807214053153232],"hpluv":[122.096631719604488,315.12898496103287,83.9720997528394406],"hsluv":[122.096631719604488,98.9534187198870825,83.9720997528394406]},"#66ee22":{"lch":[84.0111361497279461,116.215639794016113,122.506307539641156],"luv":[84.0111361497279461,-62.4534076072217061,98.0084017366813498],"rgb":[0.4,0.933333333333333348,0.133333333333333331],"xyz":[0.363412663915014589,0.640871731170666648,0.119684100249132425],"hpluv":[122.506307539641156,311.807725961995743,84.0111361497279461],"hsluv":[122.506307539641156,97.0256918708191,84.0111361497279461]},"#66ee33":{"lch":[84.0753427139745213,113.679067087327056,123.198426402241765],"luv":[84.0753427139745213,-62.2438639038254564,95.1242960560921],"rgb":[0.4,0.933333333333333348,0.2],"xyz":[0.366500414647472295,0.642106831463649774,0.135946254106743575],"hpluv":[123.198426402241765,306.400922934277446,84.0753427139745213],"hsluv":[123.198426402241765,93.8862320250161133,84.0753427139745213]},"#66ee44":{"lch":[84.1678970009459704,110.10189342016568,124.237870325737177],"luv":[84.1678970009459704,-61.946619900698991,91.0222127702015626],"rgb":[0.4,0.933333333333333348,0.266666666666666663],"xyz":[0.37095840989169121,0.64389002956133734,0.159425029059630213],"hpluv":[124.237870325737177,298.731636810455427,84.1678970009459704],"hsluv":[124.237870325737177,89.4277949312148337,84.1678970009459704]},"#66ee55":{"lch":[84.2914184237995414,105.474359140243067,125.706632503417083],"luv":[84.2914184237995414,-61.5585501093914829,85.6468641835444657],"rgb":[0.4,0.933333333333333348,0.333333333333333315],"xyz":[0.376920823931053195,0.64627499517708209,0.190827076333604129],"hpluv":[125.706632503417083,288.732343582820249,84.2914184237995414],"hsluv":[125.706632503417083,83.5978964235977315,84.2914184237995414]},"#66ee66":{"lch":[84.4481159447294374,99.8471979874678652,127.715012949239849],"luv":[84.4481159447294374,-61.0799597466417339,78.9854509596370633],"rgb":[0.4,0.933333333333333348,0.4],"xyz":[0.38450581970456138,0.649308993486485408,0.230774720740748063],"hpluv":[127.715012949239849,276.453302697114395,84.4481159447294374],"hsluv":[127.715012949239849,76.3932656313124454,84.4481159447294374]},"#66ee77":{"lch":[84.6398667383604391,93.3381964812165,130.416076861551431],"luv":[84.6398667383604391,-60.5142850922984863,71.0636350191446127],"rgb":[0.4,0.933333333333333348,0.466666666666666674],"xyz":[0.393819832724763286,0.65303459869456626,0.279828522647145972],"hpluv":[130.416076861551431,262.087365127001192,84.6398667383604391],"hsluv":[130.416076861551431,76.8478121958162461,84.6398667383604391]},"#66ee88":{"lch":[84.8682629083727704,86.1443361377895513,134.024834696689027],"luv":[84.8682629083727704,-59.8677379892917187,61.9411058721588503],"rgb":[0.4,0.933333333333333348,0.533333333333333326],"xyz":[0.404960249826707086,0.657490765535343802,0.338501386050718167],"hpluv":[134.024834696689027,246.018013362770375,84.8682629083727704],"hsluv":[134.024834696689027,77.3690194462974858,84.8682629083727704]},"#66ee99":{"lch":[85.1346415661787432,78.5628931277068,138.840952739605655],"luv":[85.1346415661787432,-59.1488647733143296,51.7062856200641718],"rgb":[0.4,0.933333333333333348,0.6],"xyz":[0.418017213935779841,0.662713551178973,0.407268063691836046],"hpluv":[138.840952739605655,228.905884969324347,85.1346415661787432],"hsluv":[138.840952739605655,77.9507906120806,85.1346415661787432]},"#66eeaa":{"lch":[85.4401056772853451,71.025817565124143,145.263991147699045],"luv":[85.4401056772853451,-58.3680297483556387,40.4702342974360576],"rgb":[0.4,0.933333333333333348,0.66666666666666663],"xyz":[0.433074906901032342,0.668736628365074082,0.486571913308834647],"hpluv":[145.263991147699045,211.83630636980061,85.4401056772853451],"hsluv":[145.263991147699045,78.5856392083502868,85.4401056772853451]},"#66eebb":{"lch":[85.7855396574798448,64.1465768711300228,153.7611846199909],"luv":[85.7855396574798448,-57.5368534805651,28.3600743271201026],"rgb":[0.4,0.933333333333333348,0.733333333333333282],"xyz":[0.450212499008369,0.67559166520800884,0.576829898407476449],"hpluv":[153.7611846199909,196.542528595596508,85.7855396574798448],"hsluv":[153.7611846199909,79.2651091664321683,85.7855396574798448]},"#66eecc":{"lch":[86.1716220205593,58.7524914026155827,164.690737532459508],"luv":[86.1716220205593,-56.6676444389915517,15.5123602250092176],"rgb":[0.4,0.933333333333333348,0.8],"xyz":[0.46950487445209077,0.683308615385497697,0.678436409077746605],"hpluv":[164.690737532459508,185.645341664818176,86.1716220205593],"hsluv":[164.690737532459508,79.9801993176568118,86.1716220205593]},"#66eedd":{"lch":[86.5988364705929285,55.8111450312658164,177.877712634427581],"luv":[86.5988364705929285,-55.7728621696499403,2.06682246606168096],"rgb":[0.4,0.933333333333333348,0.866666666666666696],"xyz":[0.491023200002724258,0.691915945605751204,0.791766256977752603],"hpluv":[177.877712634427581,182.628088950326941,86.5988364705929285],"hsluv":[177.877712634427581,80.7217641095277543,86.5988364705929285]},"#66eeee":{"lch":[87.0674822997282263,56.1274864183573783,192.177050630061075],"luv":[87.0674822997282263,-54.8646438121880493,-11.8391549953798521],"rgb":[0.4,0.933333333333333348,0.933333333333333348],"xyz":[0.514835380268899,0.701440817712221221,0.917177073046275826],"hpluv":[192.177050630061075,191.066910285097691,87.0674822997282263],"hsluv":[192.177050630061075,81.4808670778618165,87.0674822997282263]},"#66eeff":{"lch":[87.5776846199412518,59.9248574237073512,205.793536431897621],"luv":[87.5776846199412518,-53.9544158989052178,-26.0750751151289606],"rgb":[0.4,0.933333333333333348,1],"xyz":[0.541006428678730389,0.711909237076154,1.05501126133805756],"hpluv":[205.793536431897621,213.276590696447101,87.5776846199412518],"hsluv":[205.793536431897621,99.9999999999933351,87.5776846199412518]},"#116600":{"lch":[37.1543973335168118,56.0416844920186463,126.180156646926719],"luv":[37.1543973335168118,-33.0828721903909511,45.2348755755691201],"rgb":[0.0666666666666666657,0.4,0],"xyz":[0.0498232429199692434,0.0962151868782235159,0.0159455671386054508],"hpluv":[126.180156646926719,191.399273993181851,37.1543973335168118],"hsluv":[126.180156646926719,100.000000000002359,37.1543973335168118]},"#116611":{"lch":[37.2288128297302237,53.6508389550451668,127.715012949240304],"luv":[37.2288128297302237,-32.820060550512963,42.4412081124095124],"rgb":[0.0666666666666666657,0.4,0.0666666666666666657],"xyz":[0.0508349084196063616,0.0966198530780783688,0.021273672103361084],"hpluv":[127.715012949240304,182.867554307566394,37.2288128297302237],"hsluv":[127.715012949240304,93.1121786917857719,37.2288128297302237]},"#116622":{"lch":[37.366211587350719,49.4912288674311,130.823584918521846],"luv":[37.366211587350719,-32.3540076461773722,37.4513006989015125],"rgb":[0.0666666666666666657,0.4,0.133333333333333331],"xyz":[0.0527102665580833837,0.0973699963334691831,0.0311505582993402766],"hpluv":[130.823584918521846,168.069340269208539,37.366211587350719],"hsluv":[130.823584918521846,93.2954788878505639,37.366211587350719]},"#116633":{"lch":[37.5909073580641291,43.4152735453156,136.786924005406348],"luv":[37.5909073580641291,-31.6415889136076061,29.7270218494359924],"rgb":[0.0666666666666666657,0.4,0.2],"xyz":[0.0557980172905411242,0.0986050966264523,0.0474127121569514198],"hpluv":[136.786924005406348,146.554466726503705,37.5909073580641291],"hsluv":[136.786924005406348,93.5769168130898095,37.5909073580641291]},"#116644":{"lch":[37.9120295698984506,36.3990668435195417,147.559563985674146],"luv":[37.9120295698984506,-30.7189764474867033,19.525279846848818],"rgb":[0.0666666666666666657,0.4,0.266666666666666663],"xyz":[0.0602560125347600048,0.100388294724139876,0.0708914871098380583],"hpluv":[147.559563985674146,121.829522477327146,37.9120295698984506],"hsluv":[147.559563985674146,93.9439470857740559,37.9120295698984506]},"#116655":{"lch":[38.335629212958338,30.5483862618043851,166.063087397862887],"luv":[38.335629212958338,-29.6490880228798659,7.35768187759708869],"rgb":[0.0666666666666666657,0.4,0.333333333333333315],"xyz":[0.066218426574122,0.102773260339884709,0.102293534383811974],"hpluv":[166.063087397862887,101.117192726530064,38.335629212958338],"hsluv":[166.063087397862887,94.3739252192313529,38.335629212958338]},"#116666":{"lch":[38.8651381017916293,29.1618890828208741,192.177050630061217],"luv":[38.8651381017916293,-28.5057600031098204,-6.15121301239451324],"rgb":[0.0666666666666666657,0.4,0.4],"xyz":[0.0738034223476301682,0.105807258649288027,0.142241178790955936],"hpluv":[192.177050630061217,95.2126746116157392,38.8651381017916293],"hsluv":[192.177050630061217,94.8399842705083245,38.8651381017916293]},"#116677":{"lch":[39.5016809883423079,34.1234106492309124,216.700227589977857],"luv":[39.5016809883423079,-27.3592385518708738,-20.3931169809293316],"rgb":[0.0666666666666666657,0.4,0.466666666666666674],"xyz":[0.0831174353678320876,0.109532863857368837,0.191294980697353845],"hpluv":[216.700227589977857,109.616563248578402,39.5016809883423079],"hsluv":[216.700227589977857,95.3164106037614687,39.5016809883423079]},"#116688":{"lch":[40.2443638992953723,43.6497103352843823,233.004065811630028],"luv":[40.2443638992953723,-26.2665776267255495,-34.862072688430807],"rgb":[0.0666666666666666657,0.4,0.533333333333333326],"xyz":[0.0942578524697759157,0.113989030698146435,0.249967844100926],"hpluv":[233.004065811630028,137.630797119362086,40.2443638992953723],"hsluv":[233.004065811630028,95.7822055324918864,40.2443638992953723]},"#116699":{"lch":[41.090575936542443,55.3002439505846866,242.81143298809],"luv":[41.090575936542443,-25.2678118474637223,-49.189985418125],"rgb":[0.0666666666666666657,0.4,0.6],"xyz":[0.107314816578848629,0.119211816341775592,0.318734521742043919],"hpluv":[242.81143298809,170.774941475023041,41.090575936542443],"hsluv":[242.81143298809,96.2225162944548202,41.090575936542443]},"#1166aa":{"lch":[42.0363074660961757,67.6887016451143,248.882871092507173],"luv":[42.0363074660961757,-24.3865946332867658,-63.1431257746482615],"rgb":[0.0666666666666666657,0.4,0.66666666666666663],"xyz":[0.122372509544101171,0.125234893527876701,0.39803837135904252],"hpluv":[248.882871092507173,204.329442679703192,42.0363074660961757],"hsluv":[248.882871092507173,96.6284204735347885,42.0363074660961757]},"#1166bb":{"lch":[43.0764730814379746,80.16050208662584,252.853006907061769],"luv":[43.0764730814379746,-23.6332520973097289,-76.5974901030376429],"rgb":[0.0666666666666666657,0.4,0.733333333333333282],"xyz":[0.139510101651437818,0.132089930370811459,0.488296356457684266],"hpluv":[252.853006907061769,236.134594524550181,43.0764730814379746],"hsluv":[252.853006907061769,96.9958197331145,43.0764730814379746]},"#1166cc":{"lch":[44.2052232400861271,92.4179309088515737,255.583916344807051],"luv":[44.2052232400861271,-23.008531750755072,-89.5079964033815259],"rgb":[0.0666666666666666657,0.4,0.8],"xyz":[0.158802477095159544,0.139806880548300261,0.589902867127954367],"hpluv":[255.583916344807051,265.290671800528912,44.2052232400861271],"hsluv":[255.583916344807051,97.3240770235992159,44.2052232400861271]},"#1166dd":{"lch":[45.4162296513266455,104.336857924373376,257.542523527564185],"luv":[45.4162296513266455,-22.507022318245486,-101.880390006599782],"rgb":[0.0666666666666666657,0.4,0.866666666666666696],"xyz":[0.180320802645793088,0.148414210768553795,0.703232715027960364],"hpluv":[257.542523527564185,291.518421142394175,45.4162296513266455],"hsluv":[257.542523527564185,97.6147741074162,45.4162296513266455]},"#1166ee":{"lch":[46.7029335650228674,115.880201424536907,258.995545526323895],"luv":[46.7029335650228674,-22.1198283610194721,-113.74943637429719],"rgb":[0.0666666666666666657,0.4,0.933333333333333348],"xyz":[0.204132982911967853,0.157939082875023812,0.828643531096483588],"hpluv":[258.995545526323895,314.850514307077333,46.7029335650228674],"hsluv":[258.995545526323895,97.870742288996567,46.7029335650228674]},"#1166ff":{"lch":[48.0587511138394348,127.054293237547355,260.103604495506659],"luv":[48.0587511138394348,-21.8364562757409573,-125.163743182322264],"rgb":[0.0666666666666666657,0.4,1],"xyz":[0.230304031321799219,0.168407502238956508,0.966477719388265433],"hpluv":[260.103604495506659,335.471932494038299,48.0587511138394348],"hsluv":[260.103604495506659,99.9999999999992184,48.0587511138394348]},"#66ff00":{"lch":[89.0839511722278417,127.467952451328657,122.755484474710229],"luv":[89.0839511722278417,-68.9671698198214074,107.198919720201],"rgb":[0.4,1,0],"xyz":[0.41237801270657426,0.74342166657477,0.121763233231621706],"hpluv":[122.755484474710229,522.717702913530729,89.0839511722278417],"hsluv":[122.755484474710229,100.000000000002402,89.0839511722278417]},"#66ff11":{"lch":[89.1030144718140917,126.693355761899767,122.944319876693868],"luv":[89.1030144718140917,-68.8988566751164342,106.320994836735167],"rgb":[0.4,1,0.0666666666666666657],"xyz":[0.413389678206211364,0.743826332774625,0.127091338196377329],"hpluv":[122.944319876693868,520.53129302948,89.1030144718140917],"hsluv":[122.944319876693868,99.9999999999913456,89.1030144718140917]},"#66ff22":{"lch":[89.1383344673707825,125.268361506965746,123.29878008449495],"luv":[89.1383344673707825,-68.7729595958538482,104.70168300016438],"rgb":[0.4,1,0.133333333333333331],"xyz":[0.415265036344688421,0.744576476030015755,0.136968224392356536],"hpluv":[123.29878008449495,516.49933125362179,89.1383344673707825],"hsluv":[123.29878008449495,99.9999999999914877,89.1383344673707825]},"#66ff33":{"lch":[89.1964366933732,122.952924407393425,123.895139690212403],"luv":[89.1964366933732,-68.5677350303770368,102.0582546055644],"rgb":[0.4,1,0.2],"xyz":[0.418352787077146127,0.745811576322998881,0.153230378249967686],"hpluv":[123.895139690212403,509.920932540516333,89.1964366933732],"hsluv":[123.895139690212403,99.9999999999913456,89.1964366933732]},"#66ff44":{"lch":[89.2802097655713,119.677402261160566,124.785058224819977],"luv":[89.2802097655713,-68.2758869475835439,98.2908127624369143],"rgb":[0.4,1,0.266666666666666663],"xyz":[0.422810782321365042,0.747594774420686448,0.176709153202854324],"hpluv":[124.785058224819977,500.557479589511445,89.2802097655713],"hsluv":[124.785058224819977,99.9999999999914451,89.2802097655713]},"#66ff55":{"lch":[89.392045372062455,115.420778437487911,126.031255758612545],"luv":[89.392045372062455,-67.8935601171189802,93.3403481337991536],"rgb":[0.4,1,0.333333333333333315],"xyz":[0.428773196360727,0.749979740036431197,0.20811120047682824],"hpluv":[126.031255758612545,488.288652672415253,89.392045372062455],"hsluv":[126.031255758612545,99.9999999999912177,89.392045372062455]},"#66ff66":{"lch":[89.5339732348528088,110.211236984550467,127.715012949239977],"luv":[89.5339732348528088,-67.4199983006921428,87.1840615410833664],"rgb":[0.4,1,0.4],"xyz":[0.436358192134235212,0.753013738345834516,0.248058844883972174],"hpluv":[127.715012949239977,473.1190638884799,89.5339732348528088],"hsluv":[127.715012949239977,99.9999999999912177,89.5339732348528088]},"#66ff77":{"lch":[89.7077333531255,104.130085615398272,129.945267186452298],"luv":[89.7077333531255,-66.8572982376138754,79.8321764869086223],"rgb":[0.4,1,0.466666666666666674],"xyz":[0.445672205154437118,0.756739343553915367,0.297112646790370083],"hpluv":[129.945267186452298,455.203211628206077,89.7077333531255],"hsluv":[129.945267186452298,99.9999999999911466,89.7077333531255]},"#66ff88":{"lch":[89.9148190538961529,97.3190386909276413,132.870301628739924],"luv":[89.9148190538961529,-66.2101394375234378,71.3246992800528687],"rgb":[0.4,1,0.533333333333333326],"xyz":[0.456812622256380918,0.761195510394692909,0.355785510193942278],"hpluv":[132.870301628739924,434.894743355908361,89.9148190538961529],"hsluv":[132.870301628739924,99.999999999990834,89.9148190538961529]},"#66ff99":{"lch":[90.1565046807361,89.9924560427222247,136.692010716646195],"luv":[90.1565046807361,-65.4854512845448795,61.7276098246221707],"rgb":[0.4,1,0.6],"xyz":[0.469869586365453618,0.766418296038322122,0.424552187835060157],"hpluv":[136.692010716646195,412.835114866532763,90.1565046807361],"hsluv":[136.692010716646195,99.9999999999909903,90.1565046807361]},"#66ffaa":{"lch":[90.4338646074596113,82.4570841698328678,141.679424663280656],"luv":[90.4338646074596113,-64.6920148236146,51.1284064669742264],"rgb":[0.4,1,0.66666666666666663],"xyz":[0.484927279330706174,0.772441373224423189,0.503856037452058758],"hpluv":[141.679424663280656,390.10709074414774,90.4338646074596113],"hsluv":[141.679424663280656,99.9999999999905924,90.4338646074596113]},"#66ffbb":{"lch":[90.747787175062669,75.1410408914244101,148.168460326052468],"luv":[90.747787175062669,-63.84001546278364,39.631155067172358],"rgb":[0.4,1,0.733333333333333282],"xyz":[0.502064871438042792,0.779296410067358,0.59411402255070056],"hpluv":[148.168460326052468,368.486167720556807,90.747787175062669],"hsluv":[148.168460326052468,99.9999999999904077,90.747787175062669]},"#66ffcc":{"lch":[91.0989856399247486,68.6265957122477,156.512275503644645],"luv":[91.0989856399247486,-62.9405723747737085,27.3513068826366492],"rgb":[0.4,1,0.8],"xyz":[0.521357246881764547,0.787013360244846805,0.695720533220970716],"hpluv":[156.512275503644645,350.804850059399143,91.0989856399247486],"hsluv":[156.512275503644645,99.9999999999903508,91.0989856399247486]},"#66ffdd":{"lch":[91.4880074096490716,63.6578272942329875,166.916209854529029],"luv":[91.4880074096490716,-62.0052733715472826,14.410588119229697],"rgb":[0.4,1,0.866666666666666696],"xyz":[0.542875572432398146,0.795620690465100311,0.809050381120976714],"hpluv":[166.916209854529029,341.336295176875581,91.4880074096490716],"hsluv":[166.916209854529029,99.9999999999898819,91.4880074096490716]},"#66ffee":{"lch":[91.9152423718395113,61.0528599966611765,179.125088100836763],"luv":[91.9152423718395113,-61.045742111776633,0.93224663816584552],"rgb":[0.4,1,0.933333333333333348],"xyz":[0.566687752698572855,0.805145562571570328,0.934461197189499937],"hpluv":[179.125088100836763,345.840646438583576,91.9152423718395113],"hsluv":[179.125088100836763,99.9999999999894,91.9152423718395113]},"#66ffff":{"lch":[92.3809308294128,61.4559907165056,192.17705063006116],"luv":[92.3809308294128,-60.0732592166006256,-12.9631139022354667],"rgb":[0.4,1,1],"xyz":[0.592858801108404276,0.815613981935503,1.07229538548128178],"hpluv":[192.17705063006116,370.76546272919029,92.3809308294128],"hsluv":[192.17705063006116,99.9999999999889866,92.3809308294128]},"#117700":{"lch":[43.2300348418233042,65.6725964696673685,126.613348243544976],"luv":[43.2300348418233042,-39.1679175007181684,52.7139845365981],"rgb":[0.0666666666666666657,0.466666666666666674,0],"xyz":[0.0682769809733868721,0.133122662985059287,0.0220968131564111547],"hpluv":[126.613348243544976,192.769325646383436,43.2300348418233042],"hsluv":[126.613348243544976,100.000000000002359,43.2300348418233042]},"#117711":{"lch":[43.289989941732955,63.6505577690815443,127.715012949240403],"luv":[43.289989941732955,-38.9372319378938414,50.351618378457772],"rgb":[0.0666666666666666657,0.466666666666666674,0.0666666666666666657],"xyz":[0.0692886464730239904,0.13352732918491414,0.0274249181211667845],"hpluv":[127.715012949240403,186.57525992916959,43.289989941732955],"hsluv":[127.715012949240403,95.0000616991484321,43.289989941732955]},"#117722":{"lch":[43.400811094951429,60.069144786817489,129.889765673233825],"luv":[43.400811094951429,-38.5230987158151308,46.089836414888758],"rgb":[0.0666666666666666657,0.466666666666666674,0.133333333333333331],"xyz":[0.0711640046115010194,0.134277472440304968,0.037301804317145984],"hpluv":[129.889765673233825,175.627665872500842,43.400811094951429],"hsluv":[129.889765673233825,95.0973605906006725,43.400811094951429]},"#117733":{"lch":[43.5823807888255317,54.6433249694405205,133.881596062605809],"luv":[43.5823807888255317,-37.8771324094584756,39.3854770715327476],"rgb":[0.0666666666666666657,0.466666666666666674,0.2],"xyz":[0.074251755343958753,0.135512572733288067,0.0535639581747571272],"hpluv":[133.881596062605809,159.098283206795713,43.5823807888255317],"hsluv":[133.881596062605809,95.249567515942033,43.5823807888255317]},"#117744":{"lch":[43.8425891980029,47.8554364611196803,140.669149905405504],"luv":[43.8425891980029,-37.0161352468332083,30.3306533110056051],"rgb":[0.0666666666666666657,0.466666666666666674,0.266666666666666663],"xyz":[0.0787097505881776266,0.137295770830975661,0.0770427331276437588],"hpluv":[140.669149905405504,138.507858249946878,43.8425891980029],"hsluv":[140.669149905405504,95.4533619015585373,43.8425891980029]},"#117755":{"lch":[44.18711059062651,40.7988283335817243,151.872601466806259],"luv":[44.18711059062651,-35.9805491223838843,19.2339407882209947],"rgb":[0.0666666666666666657,0.466666666666666674,0.333333333333333315],"xyz":[0.0846721646275396256,0.139680736446720494,0.108444780401617674],"hpluv":[151.872601466806259,117.163251003272293,44.18711059062651],"hsluv":[151.872601466806259,95.7000805167539426,44.18711059062651]},"#117766":{"lch":[44.6197667240920879,35.4343089397309186,169.362936023125116],"luv":[44.6197667240920879,-34.8254110013137463,6.54071850990925796],"rgb":[0.0666666666666666657,0.466666666666666674,0.4],"xyz":[0.0922571604010478,0.142714734756123784,0.148392424808761636],"hpluv":[169.362936023125116,100.771099800457392,44.6197667240920879],"hsluv":[169.362936023125116,95.9777414193434453,44.6197667240920879]},"#117777":{"lch":[45.1427402486772138,34.384087641882445,192.177050630061217],"luv":[45.1427402486772138,-33.6104614986274584,-7.25274850066749],"rgb":[0.0666666666666666657,0.466666666666666674,0.466666666666666674],"xyz":[0.101571173421249716,0.146440339964204608,0.197446226715159545],"hpluv":[192.177050630061217,96.651570122263351,45.1427402486772138],"hsluv":[192.177050630061217,96.2732475219964385,45.1427402486772138]},"#117788":{"lch":[45.7567431438856502,38.9735922704815891,213.78628123605418],"luv":[45.7567431438856502,-32.3916401681270685,-21.6730833451154119],"rgb":[0.0666666666666666657,0.466666666666666674,0.533333333333333326],"xyz":[0.112711590523193544,0.150896506804982206,0.256119090118731685],"hpluv":[213.78628123605418,108.082320192335175,45.7567431438856502],"hsluv":[213.78628123605418,96.5742797371803192,45.7567431438856502]},"#117799":{"lch":[46.4611794427891169,47.8902134896154763,229.321579893426758],"luv":[46.4611794427891169,-31.2154548044213769,-36.3189747850083791],"rgb":[0.0666666666666666657,0.466666666666666674,0.6],"xyz":[0.125768554632266272,0.156119292448611363,0.32488576775984962],"hpluv":[229.321579893426758,130.796423620493698,46.4611794427891169],"hsluv":[229.321579893426758,96.8705519561321,46.4611794427891169]},"#1177aa":{"lch":[47.254315604307827,59.1280670765604199,239.379878554404911],"luv":[47.254315604307827,-30.1165063567495856,-50.8834389666627231],"rgb":[0.0666666666666666657,0.466666666666666674,0.66666666666666663],"xyz":[0.1408262475975188,0.162142369634712458,0.40418961737684822],"hpluv":[239.379878554404911,158.77844008322549,47.254315604307827],"hsluv":[239.379878554404911,97.1543662497403488,47.254315604307827]},"#1177bb":{"lch":[48.1334597651774914,71.3648635001192133,245.920143546346225],"luv":[48.1334597651774914,-29.1175429122131746,-65.1545273725937761],"rgb":[0.0666666666666666657,0.466666666666666674,0.733333333333333282],"xyz":[0.157963839704855447,0.168997406477647216,0.494447602475489967],"hpluv":[245.920143546346225,188.138070935962588,48.1334597651774914],"hsluv":[245.920143546346225,97.4206074841270464,48.1334597651774914]},"#1177cc":{"lch":[49.0951452720171488,83.8954152066927463,250.336037436893122],"luv":[49.0951452720171488,-28.2310616920000612,-79.0028344329863756],"rgb":[0.0666666666666666657,0.466666666666666674,0.8],"xyz":[0.177256215148577201,0.176714356655136018,0.596054113145760178],"hpluv":[250.336037436893122,216.83980339157776,49.0951452720171488],"hsluv":[250.336037436893122,97.666394869173061,49.0951452720171488]},"#1177dd":{"lch":[50.1353116048344702,96.3594544857749,253.441700788778064],"luv":[50.1353116048344702,-27.4615589113116805,-92.3634519220491512],"rgb":[0.0666666666666666657,0.466666666666666674,0.866666666666666696],"xyz":[0.198774540699210744,0.185321686875389552,0.709383961045766176],"hpluv":[253.441700788778064,243.887723915279508,50.1353116048344702],"hsluv":[253.441700788778064,97.8905898818146341,50.1353116048344702]},"#1177ee":{"lch":[51.2494756916451593,108.579054392530807,255.706052301270915],"luv":[51.2494756916451593,-26.8078049752198453,-105.217644172385562],"rgb":[0.0666666666666666657,0.466666666666666674,0.933333333333333348],"xyz":[0.222586720965385454,0.194846558981859597,0.834794777114289399],"hpluv":[255.706052301270915,268.841280267375566,51.2494756916451593],"hsluv":[255.706052301270915,98.0932983984315,51.2494756916451593]},"#1177ff":{"lch":[52.4328877873246739,120.474912105814852,257.407785454377859],"luv":[52.4328877873246739,-26.2648114927385947,-117.577056112809359],"rgb":[0.0666666666666666657,0.466666666666666674,1],"xyz":[0.248757769375216875,0.205314978345792293,0.972628965406071133],"hpluv":[257.407785454377859,291.562836812545811,52.4328877873246739],"hsluv":[257.407785454377859,99.9999999999990905,52.4328877873246739]},"#118800":{"lch":[49.1629818744817157,75.0325981068150725,126.891404302910644],"luv":[49.1629818744817157,-45.0420871994947447,60.0091756264985],"rgb":[0.0666666666666666657,0.533333333333333326,0],"xyz":[0.0903493506983573252,0.177267402435000831,0.0294542697314011],"hpluv":[126.891404302910644,193.664979881129256,49.1629818744817157],"hsluv":[126.891404302910644,100.000000000002487,49.1629818744817157]},"#118811":{"lch":[49.2125288978643,73.2988946552939211,127.715012949240403],"luv":[49.2125288978643,-44.8394509336223663,57.9840633075946883],"rgb":[0.0666666666666666657,0.533333333333333326,0.0666666666666666657],"xyz":[0.0913610161979944435,0.177672068634855684,0.0347823746961567343],"hpluv":[127.715012949240403,188.999680167490567,49.2125288978643],"hsluv":[127.715012949240403,96.2345237189928326,49.2125288978643]},"#118822":{"lch":[49.3041772439320312,70.1927728141533,129.31476933948187],"luv":[49.3041772439320312,-44.4727599639014315,54.3065279366352556],"rgb":[0.0666666666666666657,0.533333333333333326,0.133333333333333331],"xyz":[0.0932363743364714725,0.178422211890246513,0.0446592608921359269],"hpluv":[129.31476933948187,180.6541776618526,49.3041772439320312],"hsluv":[129.31476933948187,96.2899748067816859,49.3041772439320312]},"#118833":{"lch":[49.454516912369769,65.3819990709954766,132.170105234646456],"luv":[49.454516912369769,-43.8931572746598917,48.4581938064309767],"rgb":[0.0666666666666666657,0.533333333333333326,0.2],"xyz":[0.0963241250689292,0.179657312183229612,0.060921414749747077],"hpluv":[132.170105234646456,167.761213036429979,49.454516912369769],"hsluv":[132.170105234646456,96.3778002926358,49.454516912369769]},"#118844":{"lch":[49.6703617695526,59.1036258375550787,136.829676092870073],"luv":[49.6703617695526,-43.1056388924535057,40.4368950689726887],"rgb":[0.0666666666666666657,0.533333333333333326,0.266666666666666663],"xyz":[0.10078212031314808,0.181440510280917205,0.0844001897026337156],"hpluv":[136.829676092870073,150.9927614306973,49.6703617695526],"hsluv":[136.829676092870073,96.4975069627829356,49.6703617695526]},"#118855":{"lch":[49.9568473676091145,51.9652717779864091,144.176427678513875],"luv":[49.9568473676091145,-42.1346422468413806,30.4148219408018328],"rgb":[0.0666666666666666657,0.533333333333333326,0.333333333333333315],"xyz":[0.106744534352510079,0.183825475896662038,0.115802236976607617],"hpluv":[144.176427678513875,131.995007799011802,49.9568473676091145],"hsluv":[144.176427678513875,96.6457662191899658,49.9568473676091145]},"#118866":{"lch":[50.3177367885428879,45.0776565581224133,155.49998607369966],"luv":[50.3177367885428879,-41.0189171061503615,18.6934095394821433],"rgb":[0.0666666666666666657,0.533333333333333326,0.4],"xyz":[0.11432953012601825,0.186859474206065329,0.155749881383751593],"hpluv":[155.49998607369966,113.67882025976219,50.3177367885428879],"hsluv":[155.49998607369966,96.8171590628882512,50.3177367885428879]},"#118877":{"lch":[50.7555873970602391,40.2042284802375036,171.921706717236162],"luv":[50.7555873970602391,-39.8052806191025255,5.64974535051283322],"rgb":[0.0666666666666666657,0.533333333333333326,0.466666666666666674],"xyz":[0.12364354314622017,0.190585079414146152,0.204803683290149502],"hpluv":[171.921706717236162,100.514149141729121,50.7555873970602391],"hsluv":[171.921706717236162,97.0050762990714333,50.7555873970602391]},"#118888":{"lch":[51.2718664023781088,39.4294820301430349,192.17705063006116],"luv":[51.2718664023781088,-38.5423368357954814,-8.3169901046866368],"rgb":[0.0666666666666666657,0.533333333333333326,0.533333333333333326],"xyz":[0.134783960248164,0.19504124625492375,0.263476546693721669],"hpluv":[192.17705063006116,97.5845966821491118,51.2718664023781088],"hsluv":[192.17705063006116,97.2026219422035,51.2718664023781088]},"#118899":{"lch":[51.8670503792929907,43.7110075029310678,211.486174513119295],"luv":[51.8670503792929907,-37.2752705782940623,-22.8299448145688864],"rgb":[0.0666666666666666657,0.533333333333333326,0.6],"xyz":[0.147840924357236725,0.200264031898552908,0.332243224334839549],"hpluv":[211.486174513119295,106.93960912970239,51.8670503792929907],"hsluv":[211.486174513119295,97.4033619208845,51.8670503792929907]},"#1188aa":{"lch":[52.5407237145479371,52.059033028958666,226.184651315961702],"luv":[52.5407237145479371,-36.0423686073764102,-37.5644856890150507],"rgb":[0.0666666666666666657,0.533333333333333326,0.66666666666666663],"xyz":[0.162898617322489253,0.206287109084654,0.411547073951838149],"hpluv":[226.184651315961702,125.730132415512543,52.5407237145479371],"hsluv":[226.184651315961702,97.6018250350267,52.5407237145479371]},"#1188bb":{"lch":[53.2916815113449047,62.8295543710454396,236.286042109927791],"luv":[53.2916815113449047,-34.8733609598062557,-52.2628127623381573],"rgb":[0.0666666666666666657,0.533333333333333326,0.733333333333333282],"xyz":[0.1800362094298259,0.213142145927588761,0.501805059050479896],"hpluv":[236.286042109927791,149.604233097343041,53.2916815113449047],"hsluv":[236.286042109927791,97.7937430875757201,53.2916815113449047]},"#1188cc":{"lch":[54.1180375597057548,74.8024459991104607,243.146336149822275],"luv":[54.1180375597057548,-33.7892633498457826,-66.735984369188742],"rgb":[0.0666666666666666657,0.533333333333333326,0.8],"xyz":[0.199328584873547654,0.220859096105077563,0.60341156972075],"hpluv":[243.146336149822275,175.393335022858878,54.1180375597057548],"hsluv":[243.146336149822275,97.9760759990174819,54.1180375597057548]},"#1188dd":{"lch":[55.0173353812408266,87.2581949437380331,247.918019831454984],"luv":[55.0173353812408266,-32.8032215872693484,-80.8575366823396138],"rgb":[0.0666666666666666657,0.533333333333333326,0.866666666666666696],"xyz":[0.220846910424181198,0.229466426325331097,0.716741417620756],"hpluv":[247.918019831454984,201.254684785248685,55.0173353812408266],"hsluv":[247.918019831454984,98.1468934162311513,55.0173353812408266]},"#1188ee":{"lch":[55.9866591638471363,99.7959623087877645,251.344854654704591],"luv":[55.9866591638471363,-31.921869990719685,-94.5527805483930734],"rgb":[0.0666666666666666657,0.533333333333333326,0.933333333333333348],"xyz":[0.244659090690355907,0.238991298431801141,0.842152233689279273],"hpluv":[251.344854654704591,226.187053837960264,55.9866591638471363],"hsluv":[251.344854654704591,98.3051827042817,55.9866591638471363]},"#1188ff":{"lch":[57.0227411270994082,112.196885547184024,253.882464988485651],"luv":[57.0227411270994082,-31.1468293758358783,-107.786901552649141],"rgb":[0.0666666666666666657,0.533333333333333326,1],"xyz":[0.270830139100187328,0.249459717795733837,0.979986421981061118],"hpluv":[253.882464988485651,249.673263359937977,57.0227411270994082],"hsluv":[253.882464988485651,99.9999999999988916,57.0227411270994082]},"#119900":{"lch":[54.9698669410824721,84.160615619067471,127.079428544988929],"luv":[54.9698669410824721,-50.7422517332937772,67.1433772639973],"rgb":[0.0666666666666666657,0.6,0],"xyz":[0.116218951150824812,0.229006603339936526,0.0380774698822233526],"hpluv":[127.079428544988929,194.277964405092661,54.9698669410824721],"hsluv":[127.079428544988929,100.000000000002373,54.9698669410824721]},"#119911":{"lch":[55.0116447857556494,82.6558224500047,127.715012949240403],"luv":[55.0116447857556494,-50.563404981135136,65.3859852078442],"rgb":[0.0666666666666666657,0.6,0.0666666666666666657],"xyz":[0.11723061665046193,0.229411269539791379,0.0434055748469789823],"hpluv":[127.715012949240403,190.659367551848248,55.0116447857556494],"hsluv":[127.715012949240403,97.0796004133795094,55.0116447857556494]},"#119922":{"lch":[55.0889600096002852,79.9388272851777657,128.936266554168185],"luv":[55.0889600096002852,-50.237998627918941,62.1800579091938204],"rgb":[0.0666666666666666657,0.6,0.133333333333333331],"xyz":[0.119105974788938959,0.230161412795182208,0.0532824610429581819],"hpluv":[128.936266554168185,184.133380166819137,55.0889600096002852],"hsluv":[128.936266554168185,97.113065541928691,55.0889600096002852]},"#119933":{"lch":[55.215893256771821,75.6695179958245916,131.075562701176153],"luv":[55.215893256771821,-49.7189430335536,57.0429895547794175],"rgb":[0.0666666666666666657,0.6,0.2],"xyz":[0.122193725521396693,0.231396513088165307,0.0695446149005693182],"hpluv":[131.075562701176153,173.898642472918851,55.215893256771821],"hsluv":[131.075562701176153,97.1665253707361,55.215893256771821]},"#119944":{"lch":[55.398361036949,69.9528706873860671,134.469703140623466],"luv":[55.398361036949,-49.0042253731102591,49.9198358669935303],"rgb":[0.0666666666666666657,0.6,0.266666666666666663],"xyz":[0.126651720765615566,0.2331797111858529,0.0930233898534559567],"hpluv":[134.469703140623466,160.231519707698453,55.398361036949],"hsluv":[134.469703140623466,97.2403070889690184,55.398361036949]},"#119955":{"lch":[55.6409569880907497,63.1400511875114887,139.633471194580181],"luv":[55.6409569880907497,-48.1074656204671172,40.8942271664002206],"rgb":[0.0666666666666666657,0.6,0.333333333333333315],"xyz":[0.132614134804977579,0.235564676801597733,0.124425437127429872],"hpluv":[139.633471194580181,143.995747016857166,55.6409569880907497],"hsluv":[139.633471194580181,97.3331834328701575,55.6409569880907497]},"#119966":{"lch":[55.9472168173363,55.8918514512489466,147.340496807064056],"luv":[55.9472168173363,-47.0549257965888,30.1617807320125095],"rgb":[0.0666666666666666657,0.6,0.4],"xyz":[0.140199130578485737,0.238598675111001024,0.164373081534573834],"hpluv":[147.340496807064056,126.76791164907155,55.9472168173363],"hsluv":[147.340496807064056,97.4426708460479,55.9472168173363]},"#119977":{"lch":[56.319758368673476,49.2851425936320169,158.582299284916047],"luv":[56.319758368673476,-45.8816608646539308,17.9971796894826],"rgb":[0.0666666666666666657,0.6,0.466666666666666674],"xyz":[0.14951314359868767,0.242324280319081847,0.213426883440971743],"hpluv":[158.582299284916047,111.043862853999471,56.319758368673476],"hsluv":[158.582299284916047,97.5654087237770398,56.319758368673476]},"#119988":{"lch":[56.7603710001512951,44.8759084930006864,173.96527373508107],"luv":[56.7603710001512951,-44.6272223318454451,4.71785862613608131],"rgb":[0.0666666666666666657,0.6,0.533333333333333326],"xyz":[0.16065356070063147,0.246780447159859445,0.27209974684454391],"hpluv":[173.96527373508107,100.324581054675164,56.7603710001512951],"hsluv":[173.96527373508107,97.6975811674153647,56.7603710001512951]},"#119999":{"lch":[57.2700846473106822,44.3289506401906692,192.177050630061103],"luv":[57.2700846473106822,-43.3315696575835219,-9.35045110518458422],"rgb":[0.0666666666666666657,0.6,0.6],"xyz":[0.173710524809704198,0.252003232803488575,0.340866424485661845],"hpluv":[192.177050630061103,98.2197789195824384,57.2700846473106822],"hsluv":[192.177050630061103,97.8353178900151903,57.2700846473106822]},"#1199aa":{"lch":[57.849232550626823,48.3524707931101716,209.625127722111756],"luv":[57.849232550626823,-42.0317498411296384,-23.9017454821038378],"rgb":[0.0666666666666666657,0.6,0.66666666666666663],"xyz":[0.188768217774956726,0.258026309989589697,0.42017027410266039],"hpluv":[209.625127722111756,106.062142541807418,57.849232550626823],"hsluv":[209.625127722111756,97.9750198241805492,57.849232550626823]},"#1199bb":{"lch":[58.4975141278551263,56.1838887208170235,223.492153209811363],"luv":[58.4975141278551263,-40.7596491137071553,-38.6688551152037832],"rgb":[0.0666666666666666657,0.6,0.733333333333333282],"xyz":[0.2059058098822934,0.264881346832524456,0.510428259201302192],"hpluv":[223.492153209811363,121.8747424026255,58.4975141278551263],"hsluv":[223.492153209811363,98.1135798876595686,58.4975141278551263]},"#1199cc":{"lch":[59.2140605434028515,66.4726101728698211,233.498474693243395],"luv":[59.2140605434028515,-39.5408457239066138,-53.4334111079625274],"rgb":[0.0666666666666666657,0.6,0.8],"xyz":[0.225198185326015127,0.272598297010013257,0.612034769871572348],"hpluv":[233.498474693243395,142.448281943894045,59.2140605434028515],"hsluv":[233.498474693243395,98.2484961488154482,59.2140605434028515]},"#1199dd":{"lch":[59.9975033067865553,78.1149919905427907,240.560044488236258],"luv":[59.9975033067865553,-38.3943918665613637,-68.0281018909060151],"rgb":[0.0666666666666666657,0.6,0.866666666666666696],"xyz":[0.24671651087664867,0.281205627230266819,0.725364617771578346],"hpluv":[240.560044488236258,165.211601361935521,59.9975033067865553],"hsluv":[240.560044488236258,98.3778942246892285,59.9975033067865553]},"#1199ee":{"lch":[60.8460449735814706,90.4022578402124,245.60857134482],"luv":[60.8460449735814706,-37.3332566635070862,-82.3334450239084106],"rgb":[0.0666666666666666657,0.6,0.933333333333333348],"xyz":[0.270528691142823408,0.290730499336736836,0.850775433840101569],"hpluv":[245.60857134482,188.532510112076068,60.8460449735814706],"hsluv":[245.60857134482,98.5004851129029788,60.8460449735814706]},"#1199ff":{"lch":[61.7575303771721877,102.910627792409826,249.306643617498082],"luv":[61.7575303771721877,-36.3651553748586,-96.2713497733895167],"rgb":[0.0666666666666666657,0.6,1],"xyz":[0.296699739552654829,0.301198918700669505,0.988609622131883414],"hpluv":[249.306643617498082,211.450946466820028,61.7575303771721877],"hsluv":[249.306643617498082,99.9999999999986215,61.7575303771721877]},"#000000":{"lch":[0,0,0],"luv":[0,0,0],"rgb":[0,0,0],"xyz":[0,0,0],"hpluv":[0,0,0],"hsluv":[0,0,0]},"#000011":{"lch":[0.365533479526218952,1.47895322486610792,265.8743202181779],"luv":[0.365533479526218952,-0.106402530834795422,-1.47512072142377915],"rgb":[0,0,0.0666666666666666657],"xyz":[0.00101166549963712174,0.000404666199854854377,0.00532810496475563146],"hpluv":[265.8743202181779,513.41269684428039,0.365533479526218952],"hsluv":[265.8743202181779,100.000000000000867,0.365533479526218952]},"#000022":{"lch":[1.04313510374015572,4.22053823263236,265.8743202181779],"luv":[1.04313510374015572,-0.303644457367982512,-4.20960128950726],"rgb":[0,0,0.133333333333333331],"xyz":[0.0028870236381141408,0.00115480945524567245,0.0152049911607348275],"hpluv":[265.8743202181779,513.41269684428039,1.04313510374015572],"hsluv":[265.8743202181779,100.000000000000838,1.04313510374015572]},"#000033":{"lch":[2.15879662382733661,8.73451929157831,265.8743202181779],"luv":[2.15879662382733661,-0.62840050829424543,-8.71188498868810868],"rgb":[0,0,0.2],"xyz":[0.00597477437057188088,0.00238990974822878574,0.0314671450183459725],"hpluv":[265.8743202181779,513.412696844280276,2.15879662382733661],"hsluv":[265.8743202181779,100.000000000000838,2.15879662382733661]},"#000044":{"lch":[3.76955286085941,15.251660031516769,265.874320218177957],"luv":[3.76955286085941,-1.0972728545435857,-15.2121374566379668],"rgb":[0,0,0.266666666666666663],"xyz":[0.0104327696147907597,0.00417310784591636182,0.054945919971232611],"hpluv":[265.874320218177957,513.41269684428039,3.76955286085941],"hsluv":[265.874320218177957,100.000000000000981,3.76955286085941]},"#000055":{"lch":[5.92388346812606947,23.9681097618519345,265.8743202181779],"luv":[5.92388346812606947,-1.7243733575266309,-23.905999708860417],"rgb":[0,0,0.333333333333333315],"xyz":[0.0163951836541527535,0.00655807346166119385,0.0863479672452065194],"hpluv":[265.8743202181779,513.41269684428039,5.92388346812606947],"hsluv":[265.8743202181779,100.000000000000838,5.92388346812606947]},"#000066":{"lch":[8.64689012997685,34.9854302247980513,265.8743202181779],"luv":[8.64689012997685,-2.51700882467034193,-34.8947703043127149],"rgb":[0,0,0.4],"xyz":[0.0239801794276609283,0.00959207177106450627,0.126295611652350481],"hpluv":[265.8743202181779,513.412696844280276,8.64689012997685],"hsluv":[265.8743202181779,100.000000000000838,8.64689012997685]},"#000077":{"lch":[11.4958709948623863,46.5124439559768703,265.874320218177957],"luv":[11.4958709948623863,-3.34631391244679577,-46.3919133681426672],"rgb":[0,0,0.466666666666666674],"xyz":[0.0332941924478628443,0.0133176769791453226,0.17534941355874839],"hpluv":[265.874320218177957,513.412696844280276,11.4958709948623863],"hsluv":[265.874320218177957,100.000000000001,11.4958709948623863]},"#000088":{"lch":[14.2727431262745554,57.7477048111956535,265.874320218177957],"luv":[14.2727431262745554,-4.15462898927595781,-57.598059593379169],"rgb":[0,0,0.533333333333333326],"xyz":[0.0444346095498066723,0.0177738438199229153,0.234022276962320558],"hpluv":[265.874320218177957,513.41269684428039,14.2727431262745554],"hsluv":[265.874320218177957,100.000000000000952,14.2727431262745554]},"#000099":{"lch":[16.9872454361813823,68.7306165552763701,265.874320218177957],"luv":[16.9872454361813823,-4.94478893879780923,-68.5525106354185567],"rgb":[0,0,0.6],"xyz":[0.0574915736588793858,0.0229966294635520763,0.302788954603438465],"hpluv":[265.874320218177957,513.412696844280163,16.9872454361813823],"hsluv":[265.874320218177957,100.000000000000952,16.9872454361813823]},"#0000aa":{"lch":[19.6469460262523299,79.4917998262647529,265.8743202181779],"luv":[19.6469460262523299,-5.71899674710351302,-79.2858077831434116],"rgb":[0,0,0.66666666666666663],"xyz":[0.0725492666241319278,0.0290197066496531778,0.382092804220437066],"hpluv":[265.8743202181779,513.41269684428039,19.6469460262523299],"hsluv":[265.8743202181779,100.000000000000824,19.6469460262523299]},"#0000bb":{"lch":[22.2578820656552736,90.0556810893410926,265.8743202181779],"luv":[22.2578820656552736,-6.47900976369593895,-89.8223142039161644],"rgb":[0,0,0.733333333333333282],"xyz":[0.0896868587314685745,0.0358747434925879363,0.472350789319078812],"hpluv":[265.8743202181779,513.41269684428039,22.2578820656552736],"hsluv":[265.8743202181779,100.000000000000796,22.2578820656552736]},"#0000cc":{"lch":[24.8249727536546274,100.442163488877583,265.874320218177957],"luv":[24.8249727536546274,-7.22625991008361535,-100.18188146585355],"rgb":[0,0,0.8],"xyz":[0.108979234175190315,0.043591693670076738,0.573957299989349],"hpluv":[265.874320218177957,513.41269684428039,24.8249727536546274],"hsluv":[265.874320218177957,100.000000000001,24.8249727536546274]},"#0000dd":{"lch":[27.3522973211786535,110.667751646404724,265.8743202181779],"luv":[27.3522973211786535,-7.96193460279319343,-110.380971421034161],"rgb":[0,0,0.866666666666666696],"xyz":[0.130497559725823858,0.052199023890330272,0.687287147889355],"hpluv":[265.8743202181779,513.412696844280276,27.3522973211786535],"hsluv":[265.8743202181779,100.000000000000824,27.3522973211786535]},"#0000ee":{"lch":[29.8432887766479737,120.746335558760222,265.8743202181779],"luv":[29.8432887766479737,-8.68703315051946,-120.433438072283309],"rgb":[0,0,0.933333333333333348],"xyz":[0.154309739991998596,0.0617238959968003,0.812697963957878189],"hpluv":[265.8743202181779,513.41269684428039,29.8432887766479737],"hsluv":[265.8743202181779,100.000000000000838,29.8432887766479737]},"#0000ff":{"lch":[32.3008729039800215,130.68975298582734,265.8743202181779],"luv":[32.3008729039800215,-9.40240721482262,-130.351088503561101],"rgb":[0,0,1],"xyz":[0.18048078840183,0.072192315360733,0.95053215224966],"hpluv":[265.8743202181779,513.41269684428039,32.3008729039800215],"hsluv":[265.8743202181779,100.000000000000824,32.3008729039800215]},"#001100":{"lch":[3.62113466359794112,5.60448249758782424,127.715012949240474],"luv":[3.62113466359794112,-3.42845440085753106,4.43350025228474376],"rgb":[0,0.0666666666666666657,0],"xyz":[0.00200440026092840902,0.00400880052185687355,0.00066813342030945088],"hpluv":[127.715012949240474,196.394882900214469,3.62113466359794112],"hsluv":[127.715012949240474,100.000000000002217,3.62113466359794112]},"#001111":{"lch":[3.9866681431241604,3.15408977882195618,192.17705063006116],"luv":[3.9866681431241604,-3.08312421078118115,-0.665302512969894178],"rgb":[0,0.0666666666666666657,0.0666666666666666657],"xyz":[0.00301606576056553076,0.00441346672171172814,0.00599623838506508234],"hpluv":[192.17705063006116,100.392967527320764,3.9866681431241604],"hsluv":[192.17705063006116,99.9999999999914,3.9866681431241604]},"#001122":{"lch":[4.66426976733809706,7.30142401028103372,246.87889630792742],"luv":[4.66426976733809706,-2.86709314837997242,-6.71495118794031054],"rgb":[0,0.0666666666666666657,0.133333333333333331],"xyz":[0.00489142389904254939,0.005163609977102546,0.0158731245810442775],"hpluv":[246.87889630792742,198.638412351210178,4.66426976733809706],"hsluv":[246.87889630792742,99.9999999999921414,4.66426976733809706]},"#001133":{"lch":[5.77993128742527773,13.8979406242137369,257.974087263939282],"luv":[5.77993128742527773,-2.89569220292521434,-13.5929290537429299],"rgb":[0,0.0666666666666666657,0.2],"xyz":[0.00797917463150029,0.00639871027008565886,0.0321352784386554208],"hpluv":[257.974087263939282,305.117489912579458,5.77993128742527773],"hsluv":[257.974087263939282,99.9999999999925,5.77993128742527773]},"#001144":{"lch":[7.39068752445735111,21.802452480470059,261.611708702028636],"luv":[7.39068752445735111,-3.1805605696034065,-21.569213444774455],"rgb":[0,0.0666666666666666657,0.266666666666666663],"xyz":[0.0124371698757191687,0.00818190836777323537,0.0556140533915420593],"hpluv":[261.611708702028636,374.334482048802613,7.39068752445735111],"hsluv":[261.611708702028636,99.9999999999929656,7.39068752445735111]},"#001155":{"lch":[9.4550232844459714,31.0886305445366773,263.238579866128873],"luv":[9.4550232844459714,-3.6602302532303379,-30.8724094237562916],"rgb":[0,0.0666666666666666657,0.333333333333333315],"xyz":[0.0183995839150811608,0.0105668739835180665,0.0870161006655159747],"hpluv":[263.238579866128873,417.232678203522596,9.4550232844459714],"hsluv":[263.238579866128873,99.9999999999929514,9.4550232844459714]},"#001166":{"lch":[11.6894020192987682,40.9340765206813302,264.100423242359113],"luv":[11.6894020192987682,-4.20741678933990659,-40.7172723123955791],"rgb":[0,0.0666666666666666657,0.4],"xyz":[0.025984579688589339,0.0136008722929213798,0.126963745072659923],"hpluv":[264.100423242359113,444.357002567308371,11.6894020192987682],"hsluv":[264.100423242359113,99.9999999999928235,11.6894020192987682]},"#001177":{"lch":[14.0165943101603965,51.0460922578313898,264.608714664977526],"luv":[14.0165943101603965,-4.79613195559092276,-50.8202779710972621],"rgb":[0,0.0666666666666666657,0.466666666666666674],"xyz":[0.0352985927087912515,0.0173264775010021979,0.176017546979057832],"hpluv":[264.608714664977526,462.124851551559573,14.0165943101603965],"hsluv":[264.608714664977526,99.9999999999931504,14.0165943101603965]},"#001188":{"lch":[16.3962585295353378,61.2721603523949625,264.931782730652174],"luv":[16.3962585295353378,-5.41289085195630371,-61.0325998698597871],"rgb":[0,0.0666666666666666657,0.533333333333333326],"xyz":[0.0464390098107350796,0.0217826443417797888,0.23469041038263],"hpluv":[264.931782730652174,474.195864485329537,16.3962585295353378],"hsluv":[264.931782730652174,99.9999999999933209,16.3962585295353378]},"#001199":{"lch":[18.8023327262484941,71.5200065602600148,265.148843888859801],"luv":[18.8023327262484941,-6.04826966448705239,-71.2638040834565771],"rgb":[0,0.0666666666666666657,0.6],"xyz":[0.059495973919807793,0.0270054299854089498,0.303457088023747934],"hpluv":[265.148843888859801,482.675370310212884,18.8023327262484941],"hsluv":[265.148843888859801,99.9999999999930651,18.8023327262484941]},"#0011aa":{"lch":[21.2181090603332123,81.7349311996174919,265.301088447161305],"luv":[21.2181090603332123,-6.69569086805443892,-81.4602154551880488],"rgb":[0,0.0666666666666666657,0.66666666666666663],"xyz":[0.0745536668850603351,0.0330285071715100548,0.382760937640746535],"hpluv":[265.301088447161305,488.81030222212587,21.2181090603332123],"hsluv":[265.301088447161305,99.9999999999931788,21.2181090603332123]},"#0011bb":{"lch":[23.6329047323064216,91.8852368853417,265.411605614461337],"luv":[23.6329047323064216,-7.35054503717070418,-91.590754146539723],"rgb":[0,0.0666666666666666657,0.733333333333333282],"xyz":[0.0916912589923969817,0.0398835440144448133,0.473018922739388281],"hpluv":[265.411605614461337,493.364573724961247,23.6329047323064216],"hsluv":[265.411605614461337,99.999999999993,23.6329047323064216]},"#0011cc":{"lch":[26.0399131129061345,101.953231398784169,265.494123438592396],"luv":[26.0399131129061345,-8.00958293333115,-101.638122640513785],"rgb":[0,0.0666666666666666657,0.8],"xyz":[0.110983634436118722,0.047600494191933615,0.574625433409658437],"hpluv":[265.494123438592396,496.821968194535657,26.0399131129061345],"hsluv":[265.494123438592396,99.9999999999927383,26.0399131129061345]},"#0011dd":{"lch":[28.43483595206839,111.929749681002491,265.557201901085818],"luv":[28.43483595206839,-8.67050070949402496,-111.593419524175076],"rgb":[0,0.0666666666666666657,0.866666666666666696],"xyz":[0.132501959986752266,0.056207824412187149,0.687955281309664435],"hpluv":[265.557201901085818,499.498435149301031,28.43483595206839],"hsluv":[265.557201901085818,99.9999999999932214,28.43483595206839]},"#0011ee":{"lch":[30.8150119654139019,121.810820553676152,265.60639254385444],"luv":[30.8150119654139019,-9.33165721729429798,-121.452855781734542],"rgb":[0,0.0666666666666666657,0.933333333333333348],"xyz":[0.156314140252927,0.0657326965186571799,0.813366097378187658],"hpluv":[265.60639254385444,501.606152289563909,30.8150119654139019],"hsluv":[265.60639254385444,99.9999999999933635,30.8150119654139019]},"#0011ff":{"lch":[33.1788572452669683,131.59562707663585,265.645416939351662],"luv":[33.1788572452669683,-9.99188030865750321,-131.215743695604147],"rgb":[0,0.0666666666666666657,1],"xyz":[0.182485188662758396,0.076201115882589876,0.951200285669969503],"hpluv":[265.645416939351662,503.291227463659,33.1788572452669683],"hsluv":[265.645416939351662,99.9999999999995,33.1788572452669683]},"#55aa00":{"lch":[62.2364297391950743,84.7105424007581291,119.071642820441127],"luv":[62.2364297391950743,-41.1610955154551661,74.0380997176333437],"rgb":[0.333333333333333315,0.66666666666666663,0],"xyz":[0.181203244729902568,0.306798408854291604,0.0496696976001293408],"hpluv":[119.071642820441127,172.715819722381468,62.2364297391950743],"hsluv":[119.071642820441127,100.00000000000216,62.2364297391950743]},"#55aa11":{"lch":[62.270812500354296,83.3839078255156352,119.512873370738717],"luv":[62.270812500354296,-41.0765057562956173,72.5644317769187808],"rgb":[0.333333333333333315,0.66666666666666663,0.0666666666666666657],"xyz":[0.182214910229539701,0.307203075054146457,0.0549978025648849705],"hpluv":[119.512873370738717,169.917081036602212,62.270812500354296],"hsluv":[119.512873370738717,97.826098763204655,62.270812500354296]},"#55aa22":{"lch":[62.3344691942433826,80.9675552156414,120.358690899927907],"luv":[62.3344691942433826,-40.9219560187625078,69.8651451955580285],"rgb":[0.333333333333333315,0.66666666666666663,0.133333333333333331],"xyz":[0.184090268368016702,0.307953218309537258,0.0648746887608641631],"hpluv":[120.358690899927907,164.824621464176317,62.3344691942433826],"hsluv":[120.358690899927907,93.8493385636837729,62.3344691942433826]},"#55aa33":{"lch":[62.4390542004851312,77.1100321042589343,121.835090998601942],"luv":[62.4390542004851312,-40.6737079775314143,65.5103543760705094],"rgb":[0.333333333333333315,0.66666666666666663,0.2],"xyz":[0.187178019100474435,0.309188318602520384,0.0811368426184753133],"hpluv":[121.835090998601942,156.708983850290963,62.4390542004851312],"hsluv":[121.835090998601942,87.4478443822902,62.4390542004851312]},"#55aa44":{"lch":[62.5895604608427192,71.8060360850404322,124.168545167949461],"luv":[62.5895604608427192,-40.3283690350335959,59.4115264003566281],"rgb":[0.333333333333333315,0.66666666666666663,0.266666666666666663],"xyz":[0.191636014344693323,0.310971516700207951,0.104615617571361952],"hpluv":[124.168545167949461,145.578881327618376,62.5895604608427192],"hsluv":[124.168545167949461,78.5131262768233569,62.5895604608427192]},"#55aa55":{"lch":[62.7899606618147317,65.2067785819955361,127.715012949239551],"luv":[62.7899606618147317,-39.8892256495404212,51.582687503865472],"rgb":[0.333333333333333315,0.66666666666666663,0.333333333333333315],"xyz":[0.197598428384055336,0.313356482315952811,0.136017664845335867],"hpluv":[127.715012949239551,131.777681042751937,62.7899606618147317],"hsluv":[127.715012949239551,67.0983271543339583,62.7899606618147317]},"#55aa66":{"lch":[63.0434325957243402,57.6560159218084,133.059858461454269],"luv":[63.0434325957243402,-39.3653397911167744,42.1258376190401904],"rgb":[0.333333333333333315,0.66666666666666663,0.4],"xyz":[0.205183424157563493,0.31639048062535613,0.175965309252479829],"hpluv":[133.059858461454269,116.049721847977636,63.0434325957243402],"hsluv":[133.059858461454269,68.1368400599560289,63.0434325957243402]},"#55aa77":{"lch":[63.3524771250310863,49.7736139598232441,141.163090238883626],"luv":[63.3524771250310863,-38.7703675351212311,31.2133184364163512],"rgb":[0.333333333333333315,0.66666666666666663,0.466666666666666674],"xyz":[0.214497437177765427,0.320116085833436925,0.225019111158877738],"hpluv":[141.163090238883626,99.6953496544650903,63.3524771250310863],"hsluv":[141.163090238883626,69.3257510819996696,63.3524771250310863]},"#55aa88":{"lch":[63.7189896387035901,42.62351374085884,153.427389325734708],"luv":[63.7189896387035901,-38.1211143540371324,19.0668446268281784],"rgb":[0.333333333333333315,0.66666666666666663,0.533333333333333326],"xyz":[0.225637854279709227,0.324572252674214523,0.283691974562449878],"hpluv":[153.427389325734708,84.882799477410984,63.7189896387035901],"hsluv":[153.427389325734708,70.6362499177174783,63.7189896387035901]},"#55aa99":{"lch":[64.1443101574831473,37.9035590936142697,170.991128647613664],"luv":[64.1443101574831473,-37.4359848569684885,5.93521943587048106],"rgb":[0.333333333333333315,0.66666666666666663,0.6],"xyz":[0.238694818388781954,0.329795038317843681,0.352458652203567813],"hpluv":[170.991128647613664,74.9827180661079211,64.1443101574831473],"hsluv":[170.991128647613664,72.0364673991159918,64.1443101574831473]},"#55aaaa":{"lch":[64.6292640862610881,37.5790288142004414,192.177050630061],"luv":[64.6292640862610881,-36.7335179653569526,-7.92666793219602717],"rgb":[0.333333333333333315,0.66666666666666663,0.66666666666666663],"xyz":[0.253752511354034482,0.335818115503944803,0.431762501820566413],"hpluv":[192.177050630061,73.7828909738526,64.6292640862610881],"hsluv":[192.177050630061,73.4940830927894808,64.6292640862610881]},"#55aabb":{"lch":[65.1741997434662466,42.3607987370151307,211.725401595501864],"luv":[65.1741997434662466,-36.0311661131296148,-22.2753751520813346],"rgb":[0.333333333333333315,0.66666666666666663,0.733333333333333282],"xyz":[0.270890103461371157,0.342673152346879561,0.522020486919208104],"hpluv":[211.725401595501864,82.4760322189960249,65.1741997434662466],"hsluv":[211.725401595501864,74.9784994025983,65.1741997434662466]},"#55aacc":{"lch":[65.7790257871148327,51.0903516363502916,226.227071697937646],"luv":[65.7790257871148327,-35.3444111183519212,-36.8916878581455236],"rgb":[0.333333333333333315,0.66666666666666663,0.8],"xyz":[0.290182478905092855,0.350390102524368363,0.62362699758947826],"hpluv":[226.227071697937646,98.5577501957325808,65.7790257871148327],"hsluv":[226.227071697937646,76.4624197891718,65.7790257871148327]},"#55aadd":{"lch":[66.4432499478878071,62.1650528283955595,236.084470311275709],"luv":[66.4432499478878071,-34.6862381636523693,-51.5883579425784404],"rgb":[0.333333333333333315,0.66666666666666663,0.866666666666666696],"xyz":[0.311700804455726455,0.358997432744621869,0.736956845489484258],"hpluv":[236.084470311275709,118.722973851074883,66.4432499478878071],"hsluv":[236.084470311275709,77.9227939155192928,66.4432499478878071]},"#55aaee":{"lch":[67.1660194476775274,74.4631251020179832,242.774049894046698],"luv":[67.1660194476775274,-34.0669326024190866,-66.2133000462974763],"rgb":[0.333333333333333315,0.66666666666666663,0.933333333333333348],"xyz":[0.335512984721901164,0.368522304851091886,0.862367661558007481],"hpluv":[242.774049894046698,140.679551339708695,67.1660194476775274],"hsluv":[242.774049894046698,80.7550915423080085,67.1660194476775274]},"#55aaff":{"lch":[67.9461628502375135,87.3278464079016,247.446578213330071],"luv":[67.9461628502375135,-33.4941307575646476,-80.6492155140842897],"rgb":[0.333333333333333315,0.66666666666666663,1],"xyz":[0.361684033131732585,0.37899072421502461,1.00020184984978933],"hpluv":[247.446578213330071,163.089927997179217,67.9461628502375135],"hsluv":[247.446578213330071,99.9999999999981,67.9461628502375135]},"#002200":{"lch":[10.1376941245203973,15.6902558355344119,127.715012949240474],"luv":[10.1376941245203973,-9.59826829561359141,12.4119850914324186],"rgb":[0,0.133333333333333331,0],"xyz":[0.00572002399569634425,0.0114400479913928481,0.00190667466523206119],"hpluv":[127.715012949240474,196.394882900214583,10.1376941245203973],"hsluv":[127.715012949240474,100.000000000002331,10.1376941245203973]},"#002211":{"lch":[10.4423176349325608,11.2803579121031614,143.951720967420982],"luv":[10.4423176349325608,-9.12041102953238614,6.63811549142769763],"rgb":[0,0.133333333333333331,0.0666666666666666657],"xyz":[0.00673168949533346599,0.0118447141912477027,0.00723477962998769243],"hpluv":[143.951720967420982,137.077225818420459,10.4423176349325608],"hsluv":[143.951720967420982,99.9999999999911,10.4423176349325608]},"#002222":{"lch":[10.9891417742670896,8.69416226881610399,192.17705063006116],"luv":[10.9891417742670896,-8.49854762011842,-1.83388819318003415],"rgb":[0,0.133333333333333331,0.133333333333333331],"xyz":[0.00860704763381048461,0.0125948574466385205,0.0171116658259668902],"hpluv":[192.17705063006116,100.392967527320849,10.9891417742670896],"hsluv":[192.17705063006116,99.9999999999915,10.9891417742670896]},"#002233":{"lch":[11.8439988341371283,14.4341695325786503,236.81663495428262],"luv":[11.8439988341371283,-7.90011340243738758,-12.0802921456333543],"rgb":[0,0.133333333333333331,0.2],"xyz":[0.0116947983662682251,0.0138299577396216334,0.0333738196835780335],"hpluv":[236.81663495428262,154.643892414528665,11.8439988341371283],"hsluv":[236.81663495428262,99.9999999999918572,11.8439988341371283]},"#002244":{"lch":[12.9926705590666103,23.9154033254141893,251.756603241059679],"luv":[12.9926705590666103,-7.48682111947174356,-22.713300635140282],"rgb":[0,0.133333333333333331,0.266666666666666663],"xyz":[0.0161527936104871039,0.0156131558373092099,0.056852594636464672],"hpluv":[251.756603241059679,233.570832873869165,12.9926705590666103],"hsluv":[251.756603241059679,99.9999999999922551,12.9926705590666103]},"#002255":{"lch":[14.3995425627967926,34.0053227001087492,257.612107564284656],"luv":[14.3995425627967926,-7.29512566501762105,-33.2135983216232162],"rgb":[0,0.133333333333333331,0.333333333333333315],"xyz":[0.022115207649849096,0.0179981214530540411,0.0882546419104385804],"hpluv":[257.612107564284656,299.666041626864057,14.3995425627967926],"hsluv":[257.612107564284656,99.9999999999922551,14.3995425627967926]},"#002266":{"lch":[16.0198287291043684,44.1221041927951489,260.479541157990241],"luv":[16.0198287291043684,-7.29778599254304705,-43.514392998258792],"rgb":[0,0.133333333333333331,0.4],"xyz":[0.0297002034233572743,0.0210321197624573561,0.128202286317582542],"hpluv":[260.479541157990241,349.492349810916096,16.0198287291043684],"hsluv":[260.479541157990241,99.9999999999926672,16.0198287291043684]},"#002277":{"lch":[17.8086814865908138,54.1839210795750787,262.094384047744654],"luv":[17.8086814865908138,-7.45254493353373,-53.6689563674502708],"rgb":[0,0.133333333333333331,0.466666666666666674],"xyz":[0.0390142164435591868,0.0247577249705381724,0.177256088223980451],"hpluv":[262.094384047744654,386.080609388904179,17.8086814865908138],"hsluv":[262.094384047744654,99.9999999999926246,17.8086814865908138]},"#002288":{"lch":[19.7262797638069571,64.1945165648047862,263.091662768615947],"luv":[19.7262797638069571,-7.7213996360385595,-63.7284547486409778],"rgb":[0,0.133333333333333331,0.533333333333333326],"xyz":[0.0501546335455030148,0.0292138918113157633,0.235928951627552619],"hpluv":[263.091662768615947,412.944865974292611,19.7262797638069571],"hsluv":[263.091662768615947,99.9999999999928093,19.7262797638069571]},"#002299":{"lch":[21.7396965211461932,74.1610579713059082,263.749129578079874],"luv":[21.7396965211461932,-8.0748025544340809,-73.7201470639492129],"rgb":[0,0.133333333333333331,0.6],"xyz":[0.0632115976545757352,0.0344366774549449278,0.304695629268670554],"hpluv":[263.749129578079874,432.874263951475,21.7396965211461932],"hsluv":[263.749129578079874,99.9999999999928662,21.7396965211461932]},"#0022aa":{"lch":[23.8228560713303921,84.0831956926279389,264.204285416148139],"luv":[23.8228560713303921,-8.49087961251211532,-83.6533846373868641],"rgb":[0,0.133333333333333331,0.66666666666666663],"xyz":[0.0782692906198282773,0.0404597546410460224,0.383999478885669154],"hpluv":[264.204285416148139,447.872821658188343,23.8228560713303921],"hsluv":[264.204285416148139,99.9999999999925251,23.8228560713303921]},"#0022bb":{"lch":[25.9556350824861326,93.9557715434331868,264.531619021467236],"luv":[25.9556350824861326,-8.95364890679069,-93.5281731756572725],"rgb":[0,0.133333333333333331,0.733333333333333282],"xyz":[0.0954068827271649239,0.0473147914839807809,0.474257463984310901],"hpluv":[264.531619021467236,459.336683180505304,25.9556350824861326],"hsluv":[264.531619021467236,99.9999999999932783,25.9556350824861326]},"#0022cc":{"lch":[28.122733334265547,103.772183036952711,264.774345627526145],"luv":[28.122733334265547,-9.45141286238599143,-103.340876555018355],"rgb":[0,0.133333333333333331,0.8],"xyz":[0.114699258170886664,0.0550317416614695826,0.575863974654581057],"hpluv":[264.774345627526145,468.233789407088068,28.122733334265547],"hsluv":[264.774345627526145,99.9999999999932,28.122733334265547]},"#0022dd":{"lch":[30.3126112219004114,113.526334495176528,264.958927468127968],"luv":[30.3126112219004114,-9.97554123069502552,-113.087210599012522],"rgb":[0,0.133333333333333331,0.866666666666666696],"xyz":[0.136217583721520208,0.0636390718817231166,0.689193822554587],"hpluv":[264.958927468127968,475.239568383116307,30.3126112219004114],"hsluv":[264.958927468127968,99.9999999999930651,30.3126112219004114]},"#0022ee":{"lch":[32.516600051948771,123.213441320075319,265.102292473050682],"luv":[32.516600051948771,-10.519601137712538,-122.76355368691101],"rgb":[0,0.133333333333333331,0.933333333333333348],"xyz":[0.160029763987694945,0.0731639439881931475,0.814604638623110278],"hpluv":[265.102292473050682,480.830806343612153,32.516600051948771],"hsluv":[265.102292473050682,99.9999999999931504,32.516600051948771]},"#0022ff":{"lch":[34.728199222084136,132.830192238289243,265.215668718406278],"luv":[34.728199222084136,-11.0787458291525667,-132.367372720447662],"rgb":[0,0.133333333333333331,1],"xyz":[0.186200812397526339,0.0836323633521258575,0.952438826914892123],"hpluv":[265.215668718406278,485.348691920142073,34.728199222084136],"hsluv":[265.215668718406278,99.9999999999995595,34.728199222084136]},"#55bb00":{"lch":[67.6287132051522093,94.1564927152114421,120.799924159261636],"luv":[67.6287132051522093,-48.2120532219748839,80.8767150949587403],"rgb":[0.333333333333333315,0.733333333333333282,0],"xyz":[0.215157742638501348,0.374707404671490163,0.0609878635696619598],"hpluv":[120.799924159261636,176.668237076728246,67.6287132051522093],"hsluv":[120.799924159261636,100.000000000002245,67.6287132051522093]},"#55bb11":{"lch":[67.658807387059241,92.983820197622,121.168613223743336],"luv":[67.658807387059241,-48.1245535730997,79.5614112615755],"rgb":[0.333333333333333315,0.733333333333333282,0.0666666666666666657],"xyz":[0.21616940813813848,0.375112070871345,0.0663159685344176],"hpluv":[121.168613223743336,174.390319462510746,67.658807387059241],"hsluv":[121.168613223743336,98.2170484527892853,67.658807387059241]},"#55bb22":{"lch":[67.7145367797011,90.8418307914021739,121.8702408444057],"luv":[67.7145367797011,-47.9642424389893733,77.1470651987980318],"rgb":[0.333333333333333315,0.733333333333333282,0.133333333333333331],"xyz":[0.218044766276615481,0.375862214126735816,0.076192854730396789],"hpluv":[121.8702408444057,170.232819736279453,67.7145367797011],"hsluv":[121.8702408444057,94.9476871157098401,67.7145367797011]},"#55bb33":{"lch":[67.8061331119394595,87.4049119918652337,123.079288563119889],"luv":[67.8061331119394595,-47.7055226907732077,73.2379802090816128],"rgb":[0.333333333333333315,0.733333333333333282,0.2],"xyz":[0.221132517009073215,0.377097314419718943,0.0924550085880079253],"hpluv":[123.079288563119889,163.570954697809668,67.8061331119394595],"hsluv":[123.079288563119889,89.6636954368763526,67.8061331119394595]},"#55bb44":{"lch":[67.9380247917114701,82.6396215824211851,124.951716096499126],"luv":[67.9380247917114701,-47.3430758547011195,67.7343356349037293],"rgb":[0.333333333333333315,0.733333333333333282,0.266666666666666663],"xyz":[0.225590512253292103,0.378880512517406509,0.115933783540894564],"hpluv":[124.951716096499126,154.352877500253584,67.9380247917114701],"hsluv":[124.951716096499126,82.2446152582935213,67.9380247917114701]},"#55bb55":{"lch":[68.1137800414251,76.6309713561306154,127.715012949239735],"luv":[68.1137800414251,-46.8777966745344372,60.6199467990950964],"rgb":[0.333333333333333315,0.733333333333333282,0.333333333333333315],"xyz":[0.231552926292654115,0.38126547813315137,0.147335830814868479],"hpluv":[127.715012949239735,142.760701907139094,68.1137800414251],"hsluv":[127.715012949239735,72.6906423420812189,68.1137800414251]},"#55bb66":{"lch":[68.3363083667640723,69.6002362161904813,131.717534816394789],"luv":[68.3363083667640723,-46.3160914021311,51.9520216986687728],"rgb":[0.333333333333333315,0.733333333333333282,0.4],"xyz":[0.239137922066162273,0.384299476442554688,0.187283475222012441],"hpluv":[131.717534816394789,129.240469264566769,68.3363083667640723],"hsluv":[131.717534816394789,73.4099839145656432,68.3363083667640723]},"#55bb77":{"lch":[68.6079661831172416,61.943926665161591,137.498849513297245],"luv":[68.6079661831172416,-45.6690129611091,41.8496273084595956],"rgb":[0.333333333333333315,0.733333333333333282,0.466666666666666674],"xyz":[0.248451935086364206,0.388025081650635484,0.23633727712841035],"hpluv":[137.498849513297245,114.568047908441656,68.6079661831172416],"hsluv":[137.498849513297245,74.2430874467708719,68.6079661831172416]},"#55bb88":{"lch":[68.930619778887035,54.3103726013937376,145.860320527647957],"luv":[68.930619778887035,-44.9511677919681389,30.4796503628330058],"rgb":[0.333333333333333315,0.733333333333333282,0.533333333333333326],"xyz":[0.259592352188308,0.392481248491413082,0.29501014053198249],"hpluv":[145.860320527647957,99.9792617157038421,68.930619778887035],"hsluv":[145.860320527647957,75.173468866550067,68.930619778887035]},"#55bb99":{"lch":[69.3056876145919176,47.7211055743842465,157.786981113384826],"luv":[69.3056876145919176,-44.1794697421466793,18.0410191104680564],"rgb":[0.333333333333333315,0.733333333333333282,0.6],"xyz":[0.272649316297380762,0.397704034135042239,0.363776818173100425],"hpluv":[157.786981113384826,87.3737441175344713,69.3056876145919176],"hsluv":[157.786981113384826,76.1818306173187807,69.3056876145919176]},"#55bbaa":{"lch":[69.7341725511637378,43.6310575063277497,173.751690425302456],"luv":[69.7341725511637378,-43.37186937951342,4.74869725787034813],"rgb":[0.333333333333333315,0.733333333333333282,0.66666666666666663],"xyz":[0.287707009262633262,0.403727111321143362,0.443080667790099],"hpluv":[173.751690425302456,79.3943164161001675,69.7341725511637378],"hsluv":[173.751690425302456,77.247554342351421,69.7341725511637378]},"#55bbbb":{"lch":[70.2166895771587605,43.5254926875218899,192.177050630061075],"luv":[70.2166895771587605,-42.5461891389785691,-9.18097508120914796],"rgb":[0.333333333333333315,0.733333333333333282,0.733333333333333282],"xyz":[0.304844601369969936,0.41058214816407812,0.533338652888740716],"hpluv":[192.177050630061075,78.6579587560082274,70.2166895771587605],"hsluv":[192.177050630061075,78.350068429440185,70.2166895771587605]},"#55bbcc":{"lch":[70.753492069254392,47.9033609117661214,209.436295084806801],"luv":[70.753492069254392,-41.719164640327179,-23.5423721905035848],"rgb":[0.333333333333333315,0.733333333333333282,0.8],"xyz":[0.324136976813691691,0.418299098341566922,0.634945163559010872],"hpluv":[209.436295084806801,85.9127126132272849,70.753492069254392],"hsluv":[209.436295084806801,79.4699741443966445,70.753492069254392]},"#55bbdd":{"lch":[71.3444981992470701,55.9344204047748121,223.003151043067675],"luv":[71.3444981992470701,-40.905747403701568,-38.1494327004039633],"rgb":[0.333333333333333315,0.733333333333333282,0.866666666666666696],"xyz":[0.345655302364325179,0.426906428561820428,0.74827501145901687],"hpluv":[223.003151043067675,99.4850863142100081,71.3444981992470701],"hsluv":[223.003151043067675,80.5898663629362,71.3444981992470701]},"#55bbee":{"lch":[71.9893182406489,66.3452770137575385,232.793079173014576],"luv":[71.9893182406489,-40.1186787976363846,-52.8411524624918272],"rgb":[0.333333333333333315,0.733333333333333282,0.933333333333333348],"xyz":[0.369467482630499944,0.436431300668290445,0.873685827527540093],"hpluv":[232.793079173014576,116.944897502912525,71.9893182406489],"hsluv":[232.793079173014576,81.6948376758296888,71.9893182406489]},"#55bbff":{"lch":[72.6872829834048417,78.1278426582451146,239.741904567598624],"luv":[72.6872829834048417,-39.3683093588317803,-67.4840426816504788],"rgb":[0.333333333333333315,0.733333333333333282,1],"xyz":[0.395638531040331309,0.446899720032223169,1.01152001581932205],"hpluv":[239.741904567598624,136.39131713467242,72.6872829834048417],"hsluv":[239.741904567598624,99.9999999999976126,72.6872829834048417]},"#003300":{"lch":[17.3086983277836381,26.7889227675687067,127.71501294924046],"luv":[17.3086983277836381,-16.3877039844862402,21.1917328494772867],"rgb":[0,0.2,0],"xyz":[0.0118377460847071559,0.0236754921694146449,0.00394591536156894181],"hpluv":[127.71501294924046,196.394882900214611,17.3086983277836381],"hsluv":[127.71501294924046,100.000000000002402,17.3086983277836381]},"#003311":{"lch":[17.4974002223845133,22.6621201022865968,134.58430385811792],"luv":[17.4974002223845133,-15.9078557679049606,16.1403783226414816],"rgb":[0,0.2,0.0666666666666666657],"xyz":[0.0128494115843442776,0.0240801583692694977,0.00927402032632457241],"hpluv":[134.58430385811792,164.348724425256108,17.4974002223845133],"hsluv":[134.58430385811792,99.9999999999909335,17.4974002223845133]},"#003322":{"lch":[17.8416856931397234,17.1190432019509622,152.323942273369369],"luv":[17.8416856931397234,-15.1604156821769873,7.95131665159082601],"rgb":[0,0.2,0.133333333333333331],"xyz":[0.0147247697228212963,0.0248303016246603156,0.0191509065223037685],"hpluv":[152.323942273369369,121.753913655152402,17.8416856931397234],"hsluv":[152.323942273369369,99.9999999999912177,17.8416856931397234]},"#003333":{"lch":[18.3937448040413543,14.5523831926532932,192.17705063006116],"luv":[18.3937448040413543,-14.2249612699966086,-3.06958196712752551],"rgb":[0,0.2,0.2],"xyz":[0.017812520455279035,0.0260654019176434319,0.0354130603799149152],"hpluv":[192.17705063006116,100.392967527320849,18.3937448040413543],"hsluv":[192.17705063006116,99.9999999999915,18.3937448040413543]},"#003344":{"lch":[19.1608294605123817,20.3566459399555,229.223567805483242],"luv":[19.1608294605123817,-13.2951121246929258,-15.41535038578591],"rgb":[0,0.2,0.266666666666666663],"xyz":[0.0222705156994979156,0.0278486000153310084,0.0588918353328015537],"hpluv":[229.223567805483242,134.812835768594709,19.1608294605123817],"hsluv":[229.223567805483242,99.9999999999917577,19.1608294605123817]},"#003355":{"lch":[20.1371955335767296,30.6237106081975696,245.893961784182551],"luv":[20.1371955335767296,-12.5075398018694361,-27.9530517031554915],"rgb":[0,0.2,0.333333333333333315],"xyz":[0.0282329297388599076,0.0302335656310758379,0.0902938826067754552],"hpluv":[245.893961784182551,192.973712242731381,20.1371955335767296],"hsluv":[245.893961784182551,99.9999999999920419,20.1371955335767296]},"#003366":{"lch":[21.3076868402923836,41.8514919359335167,253.451236278131262],"luv":[21.3076868402923836,-11.9206140697212764,-40.1179054471226308],"rgb":[0,0.2,0.4],"xyz":[0.0358179255123680859,0.0332675639404791529,0.130241527013919417],"hpluv":[253.451236278131262,249.237832456686277,21.3076868402923836],"hsluv":[253.451236278131262,99.9999999999920846,21.3076868402923836]},"#003377":{"lch":[22.6513946103128916,53.0186284648852251,257.430711853641924],"luv":[22.6513946103128916,-11.5379190314963687,-51.7479602372902434],"rgb":[0,0.2,0.466666666666666674],"xyz":[0.04513193853257,0.0369931691485599692,0.179295328920317326],"hpluv":[257.430711853641924,297.011229333042763,22.6513946103128916],"hsluv":[257.430711853641924,99.9999999999922409,22.6513946103128916]},"#003388":{"lch":[24.1449124481648099,63.8887963004775941,259.778872090702237],"luv":[24.1449124481648099,-11.3369168899634012,-62.8748964862287636],"rgb":[0,0.2,0.533333333333333326],"xyz":[0.0562723556345138265,0.0414493359893375601,0.237968192323889494],"hpluv":[259.778872090702237,335.767299249073346,24.1449124481648099],"hsluv":[259.778872090702237,99.9999999999925677,24.1449124481648099]},"#003399":{"lch":[25.764809398314533,74.4520642325545481,261.279947020055374],"luv":[25.764809398314533,-11.2874373109462987,-73.5914643653724596],"rgb":[0,0.2,0.6],"xyz":[0.0693293197435865399,0.0466721216329667177,0.306734869965007428],"hpluv":[261.279947020055374,366.681615332004242,25.764809398314533],"hsluv":[261.279947020055374,99.9999999999928662,25.764809398314533]},"#0033aa":{"lch":[27.4892253326185596,84.7561178753388447,262.297068677869788],"luv":[27.4892253326185596,-11.360446037840406,-83.9913077831251],"rgb":[0,0.2,0.66666666666666663],"xyz":[0.084387012708839082,0.0526951988190678261,0.386038719582006029],"hpluv":[262.297068677869788,391.244172205097584,27.4892253326185596],"hsluv":[262.297068677869788,99.9999999999925819,27.4892253326185596]},"#0033bb":{"lch":[29.2987082140811808,94.8530383242648725,263.01737082090068],"luv":[29.2987082140811808,-11.531133966499155,-94.1495184734957178],"rgb":[0,0.2,0.733333333333333282],"xyz":[0.101524604816175729,0.0595502356620025847,0.476296704680647776],"hpluv":[263.01737082090068,410.811034734971429,29.2987082140811808],"hsluv":[263.01737082090068,99.999999999992923,29.2987082140811808]},"#0033cc":{"lch":[31.1765026722858281,104.784892642773883,263.545454640352943],"luv":[31.1765026722858281,-11.7793879173059235,-104.120697973319764],"rgb":[0,0.2,0.8],"xyz":[0.120816980259897469,0.0672671858394913863,0.577903215350917931],"hpluv":[263.545454640352943,426.491720029659064,31.1765026722858281],"hsluv":[263.545454640352943,99.9999999999928519,31.1765026722858281]},"#0033dd":{"lch":[33.108496036114694,114.582250296133722,263.943596884481394],"luv":[33.108496036114694,-12.0892798728815123,-113.942711022166648],"rgb":[0,0.2,0.866666666666666696],"xyz":[0.142335305810531026,0.0758745160597449203,0.691233063250923929],"hpluv":[263.943596884481394,439.154381827523366,33.108496036114694],"hsluv":[263.943596884481394,99.999999999992724,33.108496036114694]},"#0033ee":{"lch":[35.0829820911796091,124.266344101148519,264.250786122927309],"luv":[35.0829820911796091,-12.4483077284590724,-123.641271066592637],"rgb":[0,0.2,0.933333333333333348],"xyz":[0.166147486076705764,0.0853993881662149512,0.816643879319447152],"hpluv":[264.250786122927309,449.46548401365061,35.0829820911796091],"hsluv":[264.250786122927309,99.9999999999932214,35.0829820911796091]},"#0033ff":{"lch":[37.0903499028545482,133.851694130242549,264.492451291459133],"luv":[37.0903499028545482,-12.8466699872586325,-133.233776092154926],"rgb":[0,0.2,1],"xyz":[0.192318534486537157,0.0958678075301476473,0.954478067611229],"hpluv":[264.492451291459133,457.933345064777,37.0903499028545482],"hsluv":[264.492451291459133,99.999999999999531,37.0903499028545482]},"#55cc00":{"lch":[72.9678739916599,103.392643433537373,122.072672834653702],"luv":[72.9678739916599,-54.9009234662034089,87.6123696673744661],"rgb":[0.333333333333333315,0.8,0],"xyz":[0.253381485948118268,0.451154891290725057,0.0737291113395339148],"hpluv":[122.072672834653702,179.803140433373983,72.9678739916599],"hsluv":[122.072672834653702,100.000000000002444,72.9678739916599]},"#55cc11":{"lch":[72.9944661394807497,102.34674561848017,122.382691003133885],"luv":[72.9944661394807497,-54.8140205324080085,86.4307786136781431],"rgb":[0.333333333333333315,0.8,0.0666666666666666657],"xyz":[0.254393151447755372,0.45155955749057991,0.0790572163042895515],"hpluv":[122.382691003133885,177.91945009175069,72.9944661394807497],"hsluv":[122.382691003133885,98.5172338886757757,72.9944661394807497]},"#55cc22":{"lch":[73.0437189009647909,100.431941691916791,122.969611448584445],"luv":[73.0437189009647909,-54.6544745496639663,84.2583130836875114],"rgb":[0.333333333333333315,0.8,0.133333333333333331],"xyz":[0.256268509586232429,0.452309700745970711,0.0889341025002687441],"hpluv":[122.969611448584445,174.473032354427772,73.0437189009647909],"hsluv":[122.969611448584445,95.7933392549395,73.0437189009647909]},"#55cc33":{"lch":[73.1246943704287702,97.3470237033586,123.971835615120114],"luv":[73.1246943704287702,-54.3960871275936384,80.7310889875115123],"rgb":[0.333333333333333315,0.8,0.2],"xyz":[0.259356260318690135,0.453544801038953838,0.10519625635787988],"hpluv":[123.971835615120114,168.926560877595364,73.1246943704287702],"hsluv":[123.971835615120114,91.3772697810403542,73.1246943704287702]},"#55cc44":{"lch":[73.2413452172043,93.0415252478239836,125.502056943833935],"luv":[73.2413452172043,-54.0322080150887771,75.7446098244333399],"rgb":[0.333333333333333315,0.8,0.266666666666666663],"xyz":[0.26381425556290905,0.455327999136641404,0.128675031310766519],"hpluv":[125.502056943833935,161.198069131808353,73.2413452172043],"hsluv":[125.502056943833935,85.148140842768953,73.2413452172043]},"#55cc55":{"lch":[73.3968865779486919,87.5572640326508207,127.71501294923992],"luv":[73.3968865779486919,-53.5617851120033066,69.2633356148757144],"rgb":[0.333333333333333315,0.8,0.333333333333333315],"xyz":[0.269776669602271035,0.457712964752386264,0.160077078584740434],"hpluv":[127.71501294923992,151.374900584602614,73.3968865779486919],"hsluv":[127.71501294923992,77.0768048277098,73.3968865779486919]},"#55cc66":{"lch":[73.5939772793636,81.0375847478920832,130.834727778769576],"luv":[73.5939772793636,-52.9887999422805,61.3129449826769175],"rgb":[0.333333333333333315,0.8,0.4],"xyz":[0.277361665375779221,0.460746963061789583,0.200024722991884396],"hpluv":[130.834727778769576,139.728031568505,73.5939772793636],"hsluv":[130.834727778769576,77.5857883184082766,73.5939772793636]},"#55cc77":{"lch":[73.8348152761848553,73.7475179973278898,135.191797127350526],"luv":[73.8348152761848553,-52.3216404431773,51.972515352838883],"rgb":[0.333333333333333315,0.8,0.466666666666666674],"xyz":[0.286675678395981126,0.464472568269870378,0.249078524898282305],"hpluv":[135.191797127350526,126.743455190439619,73.8348152761848553],"hsluv":[135.191797127350526,78.1806978106980779,73.8348152761848553]},"#55cc88":{"lch":[74.1211942127210648,66.1117924559585646,141.267644806662588],"luv":[74.1211942127210648,-51.5723023085178269,41.3650424433311343],"rgb":[0.333333333333333315,0.8,0.533333333333333326],"xyz":[0.297816095497924926,0.468928735110648,0.307751388301854445],"hpluv":[141.267644806662588,113.181605649052202,74.1211942127210648],"hsluv":[141.267644806662588,78.852064841283763,74.1211942127210648]},"#55cc99":{"lch":[74.4545405069311,58.7794373107374923,149.710693018120253],"luv":[74.4545405069311,-50.7554383804248,29.646377947024483],"rgb":[0.333333333333333315,0.8,0.6],"xyz":[0.310873059606997626,0.474151520754277134,0.37651806594297238],"hpluv":[149.710693018120253,100.178278207809555,74.4545405069311],"hsluv":[149.710693018120253,79.5881732610030355,74.4545405069311]},"#55ccaa":{"lch":[74.8359403329188808,52.7021878309829361,161.189357777818884],"luv":[74.8359403329188808,-49.8873315971569866,16.9933736582089097],"rgb":[0.333333333333333315,0.8,0.66666666666666663],"xyz":[0.325930752572250182,0.480174597940378256,0.455821915559971],"hpluv":[161.189357777818884,89.3630022499163772,74.8359403329188808],"hsluv":[161.189357777818884,80.3759073289738097,74.8359403329188808]},"#55ccbb":{"lch":[75.2661614985634,49.1164256219739315,175.805780272408356],"luv":[75.2661614985634,-48.9848849956305372,3.59225665059547428],"rgb":[0.333333333333333315,0.8,0.733333333333333282],"xyz":[0.343068344679586856,0.487029634783313,0.546079900658612782],"hpluv":[175.805780272408356,82.8068592257523619,75.2661614985634],"hsluv":[175.805780272408356,81.2015846585734238,75.2661614985634]},"#55cccc":{"lch":[75.7456730324682894,49.1710405410584386,192.177050630061103],"luv":[75.7456730324682894,-48.0647147647340063,-10.3718090261618983],"rgb":[0.333333333333333315,0.8,0.8],"xyz":[0.362360720123308555,0.494746584960801816,0.647686411328882938],"hpluv":[192.177050630061103,82.3741405590198639,75.7456730324682894],"hsluv":[192.177050630061103,82.0517040066532815,75.7456730324682894]},"#55ccdd":{"lch":[76.2746640882933349,53.2320113470533514,207.674227909684788],"luv":[76.2746640882933349,-47.1424090239802069,-24.7232745296525458],"rgb":[0.333333333333333315,0.8,0.866666666666666696],"xyz":[0.383879045673942154,0.503353915181055322,0.761016259228888936],"hpluv":[207.674227909684788,89.8673986045394,76.2746640882933349],"hsluv":[207.674227909684788,82.913556803619926,76.2746640882933349]},"#55ccee":{"lch":[76.8530630513789674,60.6801737900983298,220.368363670310828],"luv":[76.8530630513789674,-46.2319850937693673,-39.3025068600722207],"rgb":[0.333333333333333315,0.8,0.933333333333333348],"xyz":[0.407691225940116864,0.51287878728752534,0.886427075297412159],"hpluv":[220.368363670310828,105.55411204702996,76.8530630513789674],"hsluv":[220.368363670310828,83.7756757275922865,76.8530630513789674]},"#55ccff":{"lch":[77.4805572724897758,70.4908339109135511,229.9629437526429],"luv":[77.4805572724897758,-45.3455492712466395,-53.9697955040126445],"rgb":[0.333333333333333315,0.8,1],"xyz":[0.433862274349948285,0.523347206651458063,1.02426126358919389],"hpluv":[229.9629437526429,126.754412601721029,77.4805572724897758],"hsluv":[229.9629437526429,99.9999999999968878,77.4805572724897758]},"#004400":{"lch":[24.1097877444294397,37.3150672336374782,127.715012949240432],"luv":[24.1097877444294397,-22.8269080205926969,29.5185791133361732],"rgb":[0,0.266666666666666663,0],"xyz":[0.0206703165676731908,0.0413406331353469575,0.00689010552255753684],"hpluv":[127.715012949240432,196.39488290021464,24.1097877444294397],"hsluv":[127.715012949240432,100.000000000002458,24.1097877444294397]},"#004411":{"lch":[24.2402356883412295,33.8624764720942082,131.447767669063751],"luv":[24.2402356883412295,-22.4148262696793807,25.3819399598065552],"rgb":[0,0.266666666666666663,0.0666666666666666657],"xyz":[0.0216819820673103125,0.0417452993352018104,0.0122182104873131692],"hpluv":[131.447767669063751,177.264269230781338,24.2402356883412295],"hsluv":[131.447767669063751,99.9999999999909335,24.2402356883412295]},"#004422":{"lch":[24.4798388415780295,28.4164365287723264,139.862893984056171],"luv":[24.4798388415780295,-21.7244820008415864,18.3177713379345413],"rgb":[0,0.266666666666666663,0.133333333333333331],"xyz":[0.0235573402057873311,0.0424954425905926317,0.0220950966832923652],"hpluv":[139.862893984056171,147.299199898382369,24.4798388415780295],"hsluv":[139.862893984056171,99.9999999999911466,24.4798388415780295]},"#004433":{"lch":[24.8682723444395748,22.2877633761795622,158.664607016269599],"luv":[24.8682723444395748,-20.760308528761005,8.10888316004269427],"rgb":[0,0.266666666666666663,0.2],"xyz":[0.0266450909382450717,0.0437305428835757445,0.0383572505409035119],"hpluv":[158.664607016269599,113.726114076625834,24.8682723444395748],"hsluv":[158.664607016269599,99.9999999999913172,24.8682723444395748]},"#004444":{"lch":[25.4163828994624552,20.1084089871091685,192.17705063006116],"luv":[25.4163828994624552,-19.6559790417892835,-4.24153273022775057],"rgb":[0,0.266666666666666663,0.266666666666666663],"xyz":[0.0311030861824639487,0.0455137409812633176,0.0618360254937901505],"hpluv":[192.17705063006116,100.392967527320792,25.4163828994624552],"hsluv":[192.17705063006116,99.9999999999914166,25.4163828994624552]},"#004455":{"lch":[26.1275223832094383,25.5944772375096541,223.546306053382096],"luv":[26.1275223832094383,-18.5513329588178841,-17.6330743352507042],"rgb":[0,0.266666666666666663,0.333333333333333315],"xyz":[0.0370655002218259477,0.0478987065970081505,0.093238072767764052],"hpluv":[223.546306053382096,124.304646155287358,26.1275223832094383],"hsluv":[223.546306053382096,99.999999999991644,26.1275223832094383]},"#004466":{"lch":[26.9988561724938734,35.8050932952910514,240.647496291889979],"luv":[26.9988561724938734,-17.5509899640931621,-31.2084516944496499],"rgb":[0,0.266666666666666663,0.4],"xyz":[0.0446504959953341191,0.050932704906411462,0.133185717174908],"hpluv":[240.647496291889979,168.282428552664811,26.9988561724938734],"hsluv":[240.647496291889979,99.9999999999920135,26.9988561724938734]},"#004477":{"lch":[28.0227048150185141,47.4927479988473422,249.396343090395135],"luv":[28.0227048150185141,-16.7127641209025413,-44.4549730392572684],"rgb":[0,0.266666666666666663,0.466666666666666674],"xyz":[0.0539645090155360385,0.0546583101144922784,0.182239519081305923],"hpluv":[249.396343090395135,215.05848085050232,28.0227048150185141],"hsluv":[249.396343090395135,99.9999999999921698,28.0227048150185141]},"#004488":{"lch":[29.1879465441319326,59.3592998069098,254.306666373838311],"luv":[29.1879465441319326,-16.0560040952153962,-57.1465765034181956],"rgb":[0,0.266666666666666663,0.533333333333333326],"xyz":[0.0651049261174798666,0.0591144769552698762,0.24091238248487809],"hpluv":[254.306666373838311,258.06229412425995,29.1879465441319326],"hsluv":[254.306666373838311,99.9999999999923,29.1879465441319326]},"#004499":{"lch":[30.4813623757938217,70.9684349502494,257.321762040288718],"luv":[30.4813623757938217,-15.5758442205369825,-69.2380808233832141],"rgb":[0,0.266666666666666663,0.6],"xyz":[0.07816189022655258,0.0643372625988990338,0.309679060125996],"hpluv":[257.321762040288718,295.440602563868879,30.4813623757938217],"hsluv":[257.321762040288718,99.9999999999926672,30.4813623757938217]},"#0044aa":{"lch":[31.8888011745219231,82.2033012029853,259.305022310013101],"luv":[31.8888011745219231,-15.2553283345918977,-80.7753532092093138],"rgb":[0,0.266666666666666663,0.66666666666666663],"xyz":[0.0932195831918051221,0.0703603397850001422,0.388982909742994598],"hpluv":[259.305022310013101,327.107417663034141,31.8888011745219231],"hsluv":[259.305022310013101,99.9999999999925109,31.8888011745219231]},"#0044bb":{"lch":[33.3960915948532602,93.0667571364503,260.679203518012741],"luv":[33.3960915948532602,-15.0732787327803415,-91.8379962332527],"rgb":[0,0.266666666666666663,0.733333333333333282],"xyz":[0.110357175299141769,0.0772153766279349,0.479240894841636345],"hpluv":[260.679203518012741,353.621176249907,33.3960915948532602],"hsluv":[260.679203518012741,99.9999999999929656,33.3960915948532602]},"#0044cc":{"lch":[34.9896851087579108,103.60206818965716,261.670396128603272],"luv":[34.9896851087579108,-15.0085679377548828,-102.509177255659253],"rgb":[0,0.266666666666666663,0.8],"xyz":[0.129649550742863495,0.0849323268054237,0.5808474055119065],"hpluv":[261.670396128603272,375.722944942957042,34.9896851087579108],"hsluv":[261.670396128603272,99.999999999992923,34.9896851087579108]},"#0044dd":{"lch":[36.6570567010139499,113.860579159150092,262.408492682931296],"luv":[36.6570567010139499,-15.0420602661110987,-112.862606338006245],"rgb":[0,0.266666666666666663,0.866666666666666696],"xyz":[0.151167876293497039,0.0935396570256772364,0.694177253411912498],"hpluv":[262.408492682931296,394.144185167595538,36.6570567010139499],"hsluv":[262.408492682931296,99.9999999999929088,36.6570567010139499]},"#0044ee":{"lch":[38.386911506645724,123.889384104134805,262.972536787865295],"luv":[38.386911506645724,-15.1572566165017264,-122.958680318078251],"rgb":[0,0.266666666666666663,0.933333333333333348],"xyz":[0.174980056559671776,0.103064529132147253,0.819588069480435721],"hpluv":[262.972536787865295,409.534269399062566,38.386911506645724],"hsluv":[262.972536787865295,99.9999999999931,38.386911506645724]},"#0044ff":{"lch":[40.1692504091911928,133.727629508879147,263.412926975584469],"luv":[40.1692504091911928,-15.3403008413028115,-132.844849595919101],"rgb":[0,0.266666666666666663,1],"xyz":[0.201151104969503169,0.113532948496079963,0.957422257772217566],"hpluv":[263.412926975584469,422.441664595501038,40.1692504091911928],"hsluv":[263.412926975584469,99.9999999999994174,40.1692504091911928]},"#55dd00":{"lch":[78.2526895057908121,112.425836873112019,123.034721453117925],"luv":[78.2526895057908121,-61.2886270790004488,94.2511166373683267],"rgb":[0.333333333333333315,0.866666666666666696,0],"xyz":[0.296015476495293473,0.536422872385076577,0.0879404415219252333],"hpluv":[123.034721453117925,210.800433631405241,78.2526895057908121],"hsluv":[123.034721453117925,100.000000000002288,78.2526895057908121]},"#55dd11":{"lch":[78.2763843013059102,111.485784004679431,123.297526334296066],"luv":[78.2763843013059102,-61.2042162992655108,93.1832814529020368],"rgb":[0.333333333333333315,0.866666666666666696,0.0666666666666666657],"xyz":[0.297027141994930577,0.536827538584931485,0.09326854648668087],"hpluv":[123.297526334296066,209.310421322213443,78.2763843013059102],"hsluv":[123.297526334296066,98.7516598856555561,78.2763843013059102]},"#55dd22":{"lch":[78.3202766586626353,109.761570808260174,123.793166282380056],"luv":[78.3202766586626353,-61.0490014413279738,91.2174426812846235],"rgb":[0.333333333333333315,0.866666666666666696,0.133333333333333331],"xyz":[0.298902500133407634,0.537577681840322286,0.103145432682660063],"hpluv":[123.793166282380056,206.571995072092733,78.3202766586626353],"hsluv":[123.793166282380056,96.4551350157602201,78.3202766586626353]},"#55dd33":{"lch":[78.3924559312840898,106.97461234521991,124.633900466047606],"luv":[78.3924559312840898,-60.7969536029841819,88.018737317724927],"rgb":[0.333333333333333315,0.866666666666666696,0.2],"xyz":[0.30199025086586534,0.538812782133305412,0.119407586540271199],"hpluv":[124.633900466047606,202.130538056106332,78.3924559312840898],"hsluv":[124.633900466047606,92.7228817840519355,78.3924559312840898]},"#55dd44":{"lch":[78.4964717161501255,103.064578059178857,125.904361390923313],"luv":[78.4964717161501255,-60.4405744101571756,83.4819993500804],"rgb":[0.333333333333333315,0.866666666666666696,0.266666666666666663],"xyz":[0.306448246110084255,0.540595980230993,0.142886361493157837],"hpluv":[125.904361390923313,195.867385876976442,78.4964717161501255],"hsluv":[125.904361390923313,87.4391970363123221,78.4964717161501255]},"#55dd55":{"lch":[78.635232286968062,98.0447483954765175,127.715012949239977],"luv":[78.635232286968062,-59.9773394353739,77.559599291037074],"rgb":[0.333333333333333315,0.866666666666666696,0.333333333333333315],"xyz":[0.31241066014944624,0.542980945846737728,0.174288408767131753],"hpluv":[127.715012949239977,187.771435495127037,78.635232286968062],"hsluv":[127.715012949239977,80.5594181605674891,78.635232286968062]},"#55dd66":{"lch":[78.8111684825228451,92.0067823672703469,130.218539636235505],"luv":[78.8111684825228451,-59.4092211255214551,70.2551951590567],"rgb":[0.333333333333333315,0.866666666666666696,0.4],"xyz":[0.319995655922954425,0.546014944156141,0.214236053174275715],"hpluv":[130.218539636235505,177.951388767985407,78.8111684825228451],"hsluv":[130.218539636235505,80.9267337864342693,78.8111684825228451]},"#55dd77":{"lch":[79.0263204832261863,85.1319563310668315,133.631202536406704],"luv":[79.0263204832261863,-58.7422260542947043,61.618186170487121],"rgb":[0.333333333333333315,0.866666666666666696,0.466666666666666674],"xyz":[0.329309668943156331,0.549740549364221898,0.263289855080673596],"hpluv":[133.631202536406704,166.66460441184762,79.0263204832261863],"hsluv":[133.631202536406704,81.3592233632428,79.0263204832261863]},"#55dd88":{"lch":[79.2823892178289,77.7115996221609322,138.259418470179128],"luv":[79.2823892178289,-57.9858175415186921,51.7371982221375],"rgb":[0.333333333333333315,0.866666666666666696,0.533333333333333326],"xyz":[0.340450086045100131,0.55419671620499944,0.321962718484245791],"hpluv":[138.259418470179128,154.371102046011828,79.2823892178289],"hsluv":[138.259418470179128,81.8514411788724,79.2823892178289]},"#55dd99":{"lch":[79.5807696492298504,70.1818875082800133,144.522564094970761],"luv":[79.5807696492298504,-57.1522092721799737,40.7323251181885624],"rgb":[0.333333333333333315,0.866666666666666696,0.6],"xyz":[0.353507050154172831,0.559419501848628653,0.390729396125363726],"hpluv":[144.522564094970761,141.828030979619143,79.5807696492298504],"hsluv":[144.522564094970761,82.3962440946128538,79.5807696492298504]},"#55ddaa":{"lch":[79.9225742847085,63.1747442044720913,152.933070337002903],"luv":[79.9225742847085,-56.2555676549498145,28.7464678372812266],"rgb":[0.333333333333333315,0.866666666666666696,0.66666666666666663],"xyz":[0.368564743119425386,0.56544257903472972,0.470033245742362271],"hpluv":[152.933070337002903,130.236824512138128,79.9225742847085],"hsluv":[152.933070337002903,82.9852754707380313,79.9225742847085]},"#55ddbb":{"lch":[80.3086513857730466,57.5612329714098649,163.927126105934775],"luv":[80.3086513857730466,-55.3111838467604926,15.9363886328987263],"rgb":[0.333333333333333315,0.866666666666666696,0.733333333333333282],"xyz":[0.385702335226762061,0.572297615877664478,0.560291230841004073],"hpluv":[163.927126105934775,121.406580229851471,80.3086513857730466],"hsluv":[163.927126105934775,83.6094665313934,80.3086513857730466]},"#55ddcc":{"lch":[80.7396004409482657,54.3905283694756534,177.403333860877041],"luv":[80.7396004409482657,-54.3346805898883076,2.46415533308082235],"rgb":[0.333333333333333315,0.866666666666666696,0.8],"xyz":[0.40499471067048376,0.580014566055153336,0.661897741511274229],"hpluv":[177.403333860877041,117.73427745544555,80.7396004409482657],"hsluv":[177.403333860877041,84.2595162876674664,80.7396004409482657]},"#55dddd":{"lch":[81.2157864208401605,54.5690893966631236,192.177050630061103],"luv":[81.2157864208401605,-53.3413100060750764,-11.5104371948595805],"rgb":[0.333333333333333315,0.866666666666666696,0.866666666666666696],"xyz":[0.426513036221117359,0.588621896275406842,0.775227589411280227],"hpluv":[192.177050630061103,121.625211000731653,81.2157864208401605],"hsluv":[192.177050630061103,84.9263164151063847,81.2157864208401605]},"#55ddee":{"lch":[81.73735371635685,58.3741450028570412,206.269517439458],"luv":[81.73735371635685,-52.3453816136692609,-25.8360567528002605],"rgb":[0.333333333333333315,0.866666666666666696,0.933333333333333348],"xyz":[0.450325216487292068,0.598146768381876859,0.90063840547980345],"hpluv":[206.269517439458,134.436687270459231,81.73735371635685],"hsluv":[206.269517439458,85.6012975649288421,81.73735371635685]},"#55ddff":{"lch":[82.3042402700550753,65.3293790133507599,218.171205050819623],"luv":[82.3042402700550753,-51.3598401525014268,-40.374429801293],"rgb":[0.333333333333333315,0.866666666666666696,1],"xyz":[0.476496264897123489,0.608615187745809583,1.0384725937715853],"hpluv":[218.171205050819623,156.046773818868189,82.3042402700550753],"hsluv":[218.171205050819623,99.9999999999958078,82.3042402700550753]},"#005500":{"lch":[30.6325595368381371,47.4104554868850059,127.715012949240474],"luv":[30.6325595368381371,-29.0026036892131067,37.5046699588244152],"rgb":[0,0.333333333333333315,0],"xyz":[0.0324835732820191528,0.0649671465640392215,0.0108278577606727468],"hpluv":[127.715012949240474,196.39488290021464,30.6325595368381371],"hsluv":[127.715012949240474,100.000000000002331,30.6325595368381371]},"#005511":{"lch":[30.7291805540017933,44.5531719728198325,130.030983014983661],"luv":[30.7291805540017933,-28.6566785608310113,34.1142185415534129],"rgb":[0,0.333333333333333315,0.0666666666666666657],"xyz":[0.033495238781656278,0.0653718127638940744,0.01615596272542838],"hpluv":[130.030983014983661,183.978458821492183,30.7291805540017933],"hsluv":[130.030983014983661,99.9999999999909335,30.7291805540017933]},"#005522":{"lch":[30.9072407208055395,39.7502752239143149,134.89425658266407],"luv":[30.9072407208055395,-28.0557665948475297,28.1595159964153758],"rgb":[0,0.333333333333333315,0.133333333333333331],"xyz":[0.0353705969201332932,0.0661219560192848888,0.0260328489214075726],"hpluv":[134.89425658266407,163.199653312489744,30.9072407208055395],"hsluv":[134.89425658266407,99.9999999999909903,30.9072407208055395]},"#005533":{"lch":[31.1975029455576802,33.2574057268159,144.773587953954916],"luv":[31.1975029455576802,-27.1672793055155033,19.1831689460880241],"rgb":[0,0.333333333333333315,0.2],"xyz":[0.0384583476525910337,0.067357056312268,0.0422950027790187227],"hpluv":[144.773587953954916,135.271984326190278,31.1975029455576802],"hsluv":[144.773587953954916,99.9999999999912177,31.1975029455576802]},"#005544":{"lch":[31.6103799108948778,27.1932751339722678,163.464109831123295],"luv":[31.6103799108948778,-26.0686058468900157,7.73963834500076331],"rgb":[0,0.333333333333333315,0.266666666666666663],"xyz":[0.0429163428968099142,0.0691402544099555816,0.0657737777319053613],"hpluv":[163.464109831123295,109.16191048912313,31.6103799108948778],"hsluv":[163.464109831123295,99.999999999991374,31.6103799108948778]},"#005555":{"lch":[32.1516370434520482,25.4370682812028797,192.17705063006116],"luv":[32.1516370434520482,-24.8647459548099441,-5.36552433088697445],"rgb":[0,0.333333333333333315,0.333333333333333315],"xyz":[0.0488787569361719063,0.0715252200257004145,0.0971758250058792628],"hpluv":[192.17705063006116,100.392967527320877,32.1516370434520482],"hsluv":[192.17705063006116,99.9999999999915,32.1516370434520482]},"#005566":{"lch":[32.8230722751799036,30.545644410021449,219.238547792689275],"luv":[32.8230722751799036,-23.6581848019048806,-19.3216636007977201],"rgb":[0,0.333333333333333315,0.4],"xyz":[0.0564637527096800845,0.074559218335103733,0.137123469413023225],"hpluv":[219.238547792689275,118.088984839520307,32.8230722751799036],"hsluv":[219.238547792689275,99.9999999999916298,32.8230722751799036]},"#005577":{"lch":[33.6230950493472065,40.3511971197610322,236.060106868306946],"luv":[33.6230950493472065,-22.5289967279924532,-33.4763112577822142],"rgb":[0,0.333333333333333315,0.466666666666666674],"xyz":[0.065777765729882,0.0782848235431845424,0.186177271319421134],"hpluv":[236.060106868306946,152.285327594300298,33.6230950493472065],"hsluv":[236.060106868306946,99.9999999999918,33.6230950493472065]},"#005588":{"lch":[34.5473308406039266,52.0529464564925703,245.569923252468897],"luv":[34.5473308406039266,-21.5281838547339461,-47.3924733973576764],"rgb":[0,0.333333333333333315,0.533333333333333326],"xyz":[0.076918182831825832,0.0827409903839621402,0.244850134722993301],"hpluv":[245.569923252468897,191.192188881903292,34.5473308406039266],"hsluv":[245.569923252468897,99.9999999999919709,34.5473308406039266]},"#005599":{"lch":[35.5892574919693772,64.2489447401961655,251.22324643469841],"luv":[35.5892574919693772,-20.6805523421639172,-60.8296116628390067],"rgb":[0,0.333333333333333315,0.6],"xyz":[0.0899751469408985316,0.0879637760275913,0.313616812364111208],"hpluv":[251.22324643469841,229.079590546614583,35.5892574919693772],"hsluv":[251.22324643469841,99.9999999999922125,35.5892574919693772]},"#0055aa":{"lch":[36.7408379507026,76.3552968047486189,254.821646708521541],"luv":[36.7408379507026,-19.9916927982920107,-73.6916791042243347],"rgb":[0,0.333333333333333315,0.66666666666666663],"xyz":[0.105032839906151088,0.0939868532136924,0.392920661981109809],"hpluv":[254.821646708521541,263.711724718685957,36.7408379507026],"hsluv":[254.821646708521541,99.9999999999921556,36.7408379507026]},"#0055bb":{"lch":[37.993106438468665,88.146943006458784,257.249085911334646],"luv":[37.993106438468665,-19.4551758320548949,-85.9731335635018],"rgb":[0,0.333333333333333315,0.733333333333333282],"xyz":[0.122170432013487734,0.100841890056627165,0.483178647079751555],"hpluv":[257.249085911334646,294.402692429224658,37.993106438468665],"hsluv":[257.249085911334646,99.9999999999924114,37.993106438468665]},"#0055cc":{"lch":[39.3366742314503384,99.5579220492412,258.963845190076711],"luv":[39.3366742314503384,-19.0582121518786707,-97.7167559446012888],"rgb":[0,0.333333333333333315,0.8],"xyz":[0.141462807457209461,0.108558840234115966,0.584785157750021711],"hpluv":[258.963845190076711,321.157087606315883,39.3366742314503384],"hsluv":[258.963845190076711,99.9999999999926,39.3366742314503384]},"#0055dd":{"lch":[40.7621365800243538,110.592821589198408,260.220233587680809],"luv":[40.7621365800243538,-18.7854624460211568,-108.985680654613518],"rgb":[0,0.333333333333333315,0.866666666666666696],"xyz":[0.162981133007843,0.1171661704543695,0.698115005650027709],"hpluv":[260.220233587680809,344.278042660470817,40.7621365800243538],"hsluv":[260.220233587680809,99.9999999999926672,40.7621365800243538]},"#0055ee":{"lch":[42.2603772648371105,121.285075365136905,261.168248695532611],"luv":[42.2603772648371105,-18.6213165580406681,-119.847052846418293],"rgb":[0,0.333333333333333315,0.933333333333333348],"xyz":[0.186793313274017742,0.126691042560839517,0.823525821718550932],"hpluv":[261.168248695532611,364.177675198016914,42.2603772648371105],"hsluv":[261.168248695532611,99.9999999999924256,42.2603772648371105]},"#0055ff":{"lch":[43.8227784910393,131.676969611306021,261.90102950371454],"luv":[43.8227784910393,-18.5511048350842884,-130.363648443170376],"rgb":[0,0.333333333333333315,1],"xyz":[0.212964361683849135,0.137159461924772241,0.961360010010332777],"hpluv":[261.90102950371454,381.28457852045068,43.8227784910393],"hsluv":[261.90102950371454,99.9999999999993321,43.8227784910393]},"#55ee00":{"lch":[83.4834241678481277,121.26988118033438,123.77813801339137],"luv":[83.4834241678481277,-67.423446821455,100.799121524975831],"rgb":[0.333333333333333315,0.933333333333333348,0],"xyz":[0.343194252835808289,0.630780425066107542,0.103666700302096418],"hpluv":[123.77813801339137,313.542875178701877,83.4834241678481277],"hsluv":[123.77813801339137,100.000000000002402,83.4834241678481277]},"#55ee11":{"lch":[83.5046935730824487,120.419265504422668,124.002811201886018],"luv":[83.5046935730824487,-67.3424968648776456,99.8287915414615412],"rgb":[0.333333333333333315,0.933333333333333348,0.0666666666666666657],"xyz":[0.344205918335445393,0.63118509126596245,0.108994805266852055],"hpluv":[124.002811201886018,311.80236567126093,83.5046935730824487],"hsluv":[124.002811201886018,98.9375412624106616,83.5046935730824487]},"#55ee22":{"lch":[83.5440973470955868,118.856748008926118,124.425313598414533],"luv":[83.5440973470955868,-67.1934622190367463,98.0406302625408728],"rgb":[0.333333333333333315,0.933333333333333348,0.133333333333333331],"xyz":[0.34608127647392245,0.631935234521353251,0.118871691462831247],"hpluv":[124.425313598414533,308.59848358059196,83.5440973470955868],"hsluv":[124.425313598414533,96.9807587800033133,83.5440973470955868]},"#55ee33":{"lch":[83.6089072227085524,116.32446068797897,125.138397832270286],"luv":[83.6089072227085524,-66.950941309724243,95.1259775880964469],"rgb":[0.333333333333333315,0.933333333333333348,0.2],"xyz":[0.349169027206380156,0.633170334814336377,0.135133845320442397],"hpluv":[125.138397832270286,303.387603747434184,83.6089072227085524],"hsluv":[125.138397832270286,93.7945051225822084,83.6089072227085524]},"#55ee44":{"lch":[83.7023291233000748,112.756808619009803,126.207644663357115],"luv":[83.7023291233000748,-66.6069499756988535,90.9813832873448547],"rgb":[0.333333333333333315,0.933333333333333348,0.266666666666666663],"xyz":[0.353627022450599071,0.634953532912023944,0.158612620273329036],"hpluv":[126.207644663357115,296.007020538140409,83.7023291233000748],"hsluv":[126.207644663357115,89.2707337544585,83.7023291233000748]},"#55ee55":{"lch":[83.8270046653184,108.148092962556504,127.715012949240077],"luv":[83.8270046653184,-66.1579022543843,85.5519840841642747],"rgb":[0.333333333333333315,0.933333333333333348,0.333333333333333315],"xyz":[0.359589436489961056,0.637338498527768693,0.190014667547302951],"hpluv":[127.715012949240077,286.404562223907249,83.8270046653184],"hsluv":[127.715012949240077,83.3573838846113091,83.8270046653184]},"#55ee66":{"lch":[83.985160091985378,102.554744038676162,129.769393513035965],"luv":[83.985160091985378,-65.6041880698479645,78.8261760618539853],"rgb":[0.333333333333333315,0.933333333333333348,0.4],"xyz":[0.367174432263469241,0.640372496837172,0.229962311954446885],"hpluv":[129.769393513035965,274.647728218817576,83.985160091985378],"hsluv":[129.769393513035965,83.6273111034757477,83.985160091985378]},"#55ee77":{"lch":[84.1786855608653752,96.1019099790829756,132.519661951802362],"luv":[84.1786855608653752,-64.9498200787083,70.8314758661090451],"rgb":[0.333333333333333315,0.933333333333333348,0.466666666666666674],"xyz":[0.376488445283671147,0.644098102045252863,0.279016113860844794],"hpluv":[132.519661951802362,260.948457539577589,84.1786855608653752],"hsluv":[132.519661951802362,83.9470254314832687,84.1786855608653752]},"#55ee88":{"lch":[84.4091822183787741,88.9952087097784,136.170997575445568],"luv":[84.4091822183787741,-64.2020140446184371,61.6299323860706],"rgb":[0.333333333333333315,0.933333333333333348,0.533333333333333326],"xyz":[0.387628862385614947,0.648554268886030405,0.337688977264417],"hpluv":[136.170997575445568,245.709397001158351,84.4091822183787741],"hsluv":[136.170997575445568,84.3134084109568533,84.4091822183787741]},"#55ee99":{"lch":[84.6779925165317877,81.540352796223317,141.002136712429774],"luv":[84.6779925165317877,-63.3706695007570531,51.3126434824633151],"rgb":[0.333333333333333315,0.933333333333333348,0.6],"xyz":[0.400685826494687647,0.653777054529659618,0.406455654905534869],"hpluv":[141.002136712429774,229.604367075154897,84.6779925165317877],"hsluv":[141.002136712429774,84.7220894550445394,84.6779925165317877]},"#55eeaa":{"lch":[84.9862212486181363,74.1734332109310373,147.37159021859884],"luv":[84.9862212486181363,-62.4677637576075426,39.9934580327855755],"rgb":[0.333333333333333315,0.933333333333333348,0.66666666666666663],"xyz":[0.415743519459940203,0.659800131715760685,0.48575950452253347],"hpluv":[147.37159021859884,213.709694911287,84.9862212486181363],"hsluv":[147.37159021859884,85.1677250765186358,84.9862212486181363]},"#55eebb":{"lch":[85.334751323756052,67.4984157699475418,155.676120933413],"luv":[85.334751323756052,-61.5066955643592337,27.8022037293077737],"rgb":[0.333333333333333315,0.933333333333333348,0.733333333333333282],"xyz":[0.432881111567276877,0.666655168558695443,0.576017489621175272],"hpluv":[155.676120933413,199.690784145783283,85.334751323756052],"hsluv":[155.676120933413,85.6443005177139298,85.334751323756052]},"#55eecc":{"lch":[85.7242566025865784,62.3040769944455,166.184583472908372],"luv":[85.7242566025865784,-60.5016239571924643,14.8778865660505755],"rgb":[0.333333333333333315,0.933333333333333348,0.8],"xyz":[0.452173487010998576,0.674372118736184301,0.677624000291445427],"hpluv":[166.184583472908372,189.979166061651426,85.7242566025865784],"hsluv":[166.184583472908372,86.1454332210543186,85.7242566025865784]},"#55eedd":{"lch":[86.1552131978466349,59.4824491826881427,178.687660418725557],"luv":[86.1552131978466349,-59.4668469392298462,1.36230535390821395],"rgb":[0.333333333333333315,0.933333333333333348,0.866666666666666696],"xyz":[0.473691812561632175,0.682979448956437807,0.790953848191451425],"hpluv":[178.687660418725557,187.703134777137279,86.1552131978466349],"hsluv":[178.687660418725557,86.6646578889921,86.1552131978466349]},"#55eeee":{"lch":[86.6279101052896578,59.7608483004272202,192.177050630061245],"luv":[86.6279101052896578,-58.4162567245265265,-12.6055519466972967],"rgb":[0.333333333333333315,0.933333333333333348,0.933333333333333348],"xyz":[0.497503992827806885,0.692504321062907824,0.916364664259974648],"hpluv":[192.177050630061245,196.025490067494644,86.6279101052896578],"hsluv":[192.177050630061245,87.195676441965972,86.6279101052896578]},"#55eeff":{"lch":[87.1424596935915901,63.3545065705612274,205.119112492248092],"luv":[87.1424596935915901,-57.3628964007582169,-26.8940814923128677],"rgb":[0.333333333333333315,0.933333333333333348,1],"xyz":[0.523675041237638306,0.702972740426840548,1.05419885255175649],"hpluv":[205.119112492248092,217.06231600799947,87.1424596935915901],"hsluv":[205.119112492248092,99.9999999999933,87.1424596935915901]},"#006600":{"lch":[36.9339903888407548,57.1632711650289735,127.71501294924046],"luv":[36.9339903888407548,-34.9687359497521086,45.2197642227726249],"rgb":[0,0.4,0],"xyz":[0.0475116309878656218,0.0950232619757325619,0.0158372103292880942],"hpluv":[127.71501294924046,196.394882900214554,36.9339903888407548],"hsluv":[127.71501294924046,100.000000000002331,36.9339903888407548]},"#006611":{"lch":[37.0090255636121412,54.7765813256580216,129.276595687178855],"luv":[37.0090255636121412,-34.6771211058740789,42.4024897091546933],"rgb":[0,0.4,0.0666666666666666657],"xyz":[0.04852329648750274,0.0954279281755874148,0.0211653152940437239],"hpluv":[129.276595687178855,187.813410896691579,37.0090255636121412],"hsluv":[129.276595687178855,99.9999999999908908,37.0090255636121412]},"#006622":{"lch":[37.1475616040544949,50.6324758020482761,132.428423847637788],"luv":[37.1475616040544949,-34.160143827310165,37.3728802682170453],"rgb":[0,0.4,0.133333333333333331],"xyz":[0.0503986546259797621,0.0961780714309782292,0.0310422014900229234],"hpluv":[132.428423847637788,172.957013965329963,37.1475616040544949],"hsluv":[132.428423847637788,99.9999999999909619,37.1475616040544949]},"#006633":{"lch":[37.3740982281225911,44.601943170857588,138.432874640413417],"luv":[37.3740982281225911,-33.3702331720845464,29.5932572160807972],"rgb":[0,0.4,0.2],"xyz":[0.0534864053584375,0.0974131717239613421,0.0473043553476340667],"hpluv":[138.432874640413417,151.43364776149042,37.3740982281225911],"hsluv":[138.432874640413417,99.9999999999910187,37.3740982281225911]},"#006644":{"lch":[37.6978110334583292,37.6830106217376226,149.139540405640531],"luv":[37.6978110334583292,-32.3478161181420845,19.3294615006434647],"rgb":[0,0.4,0.266666666666666663],"xyz":[0.0579444006026563832,0.099196369821648922,0.0707831303005207],"hpluv":[149.139540405640531,126.843666215367492,37.6978110334583292],"hsluv":[149.139540405640531,99.9999999999911893,37.6978110334583292]},"#006655":{"lch":[38.1247572916394191,31.9621551107412678,167.158861879927684],"luv":[38.1247572916394191,-31.1627826377188839,7.10354401671241],"rgb":[0,0.4,0.333333333333333315],"xyz":[0.0639068146420183752,0.101581335437393755,0.102185177574494607],"hpluv":[167.158861879927684,106.382034992292617,38.1247572916394191],"hsluv":[167.158861879927684,99.9999999999912461,38.1247572916394191]},"#006666":{"lch":[38.6583399620500714,30.584907136256998,192.177050630061132],"luv":[38.6583399620500714,-29.8967608054288689,-6.45137488264605441],"rgb":[0,0.4,0.4],"xyz":[0.0714918104155265466,0.104615333746797073,0.142132821981638569],"hpluv":[192.177050630061132,100.392967527320849,38.6583399620500714],"hsluv":[192.177050630061132,99.9999999999914877,38.6583399620500714]},"#006677":{"lch":[39.2996251720959648,35.3400629634721852,215.899751113488037],"luv":[39.2996251720959648,-28.6270125920824867,-20.7223116547099835],"rgb":[0,0.4,0.466666666666666674],"xyz":[0.080805823435728466,0.108340938954877883,0.191186623888036478],"hpluv":[215.899751113488037,114.108563264217921,39.2996251720959648],"hsluv":[215.899751113488037,99.999999999991644,39.2996251720959648]},"#006688":{"lch":[40.0476371065618721,44.619030030948764,232.088426656893603],"luv":[40.0476371065618721,-27.4159210327312195,-35.2026293738089109],"rgb":[0,0.4,0.533333333333333326],"xyz":[0.0919462405376723,0.112797105795655481,0.249859487291608645],"hpluv":[232.088426656893603,141.378234692038774,40.0476371065618721],"hsluv":[232.088426656893603,99.9999999999918145,40.0476371065618721]},"#006699":{"lch":[40.8996671875350728,56.0796471869528546,242.024131169727298],"luv":[40.8996671875350728,-26.3069429553173038,-49.5264735364712863],"rgb":[0,0.4,0.6],"xyz":[0.105003204646745008,0.118019891439284638,0.318626164932726552],"hpluv":[242.024131169727298,173.990215160848891,40.8996671875350728],"hsluv":[242.024131169727298,99.9999999999919,40.8996671875350728]},"#0066aa":{"lch":[41.8515997707465104,68.3303466488807345,248.245335088520562],"luv":[41.8515997707465104,-25.3254853434547229,-63.4638169768779861],"rgb":[0,0.4,0.66666666666666663],"xyz":[0.12006089761199755,0.124042968625385747,0.397930014549725153],"hpluv":[248.245335088520562,207.176688473106537,41.8515997707465104],"hsluv":[248.245335088520562,99.9999999999921,41.8515997707465104]},"#0066bb":{"lch":[42.8982420202673396,80.6980154219041452,252.339105133311591],"luv":[42.8982420202673396,-24.4823887435570384,-76.8946183711398],"rgb":[0,0.4,0.733333333333333282],"xyz":[0.137198489719334182,0.130898005468320505,0.488187999648366899],"hpluv":[252.339105133311591,238.705643004687346,42.8982420202673396],"hsluv":[252.339105133311591,99.9999999999922125,42.8982420202673396]},"#0066cc":{"lch":[44.0336413015701211,92.8728169416488356,255.165448618736946],"luv":[44.0336413015701211,-23.7781103155697018,-89.7772888680517696],"rgb":[0,0.4,0.8],"xyz":[0.156490865163055937,0.138614955645809307,0.589794510318637],"hpluv":[255.165448618736946,267.63526922347819,44.0336413015701211],"hsluv":[255.165448618736946,99.9999999999922835,44.0336413015701211]},"#0066dd":{"lch":[45.2513748624169807,104.723900430114114,257.197154574648096],"luv":[45.2513748624169807,-23.2064943358636171,-102.120291528843495],"rgb":[0,0.4,0.866666666666666696],"xyz":[0.17800919071368948,0.147222285866062841,0.703124358218643],"hpluv":[257.197154574648096,293.665789717253858,45.2513748624169807],"hsluv":[257.197154574648096,99.9999999999923119,45.2513748624169807]},"#0066ee":{"lch":[46.5448008930790422,116.210429262859975,258.70668283343889],"luv":[46.5448008930790422,-22.7576936505684415,-113.960305585607557],"rgb":[0,0.4,0.933333333333333348],"xyz":[0.201821370979864217,0.156747157972532858,0.828535174287166276],"hpluv":[258.70668283343889,316.82048544727013,46.5448008930790422],"hsluv":[258.70668283343889,99.9999999999923119,46.5448008930790422]},"#0066ff":{"lch":[47.9072652547968758,127.336469583599694,259.859032010401279],"luv":[47.9072652547968758,-22.4202120236612075,-125.347160234402949],"rgb":[0,0.4,1],"xyz":[0.227992419389695611,0.167215577336465582,0.966369362578948121],"hpluv":[259.859032010401279,337.280125749862,47.9072652547968758],"hsluv":[259.859032010401279,99.9999999999992326,47.9072652547968758]},"#55ff00":{"lch":[88.6611895097861691,129.940408372856581,124.363532639485271],"luv":[88.6611895097861691,-73.3437881830395213,107.262288168144963],"rgb":[0.333333333333333315,1,0],"xyz":[0.395046625265482121,0.734485169925456649,0.120950824445320529],"hpluv":[124.363532639485271,511.214684976108288,88.6611895097861691],"hsluv":[124.363532639485271,100.000000000002203,88.6611895097861691]},"#55ff11":{"lch":[88.6804070841335488,129.16615931328721,124.557188606571273],"luv":[88.6804070841335488,-73.2667318726085597,106.376137890284312],"rgb":[0.333333333333333315,1,0.0666666666666666657],"xyz":[0.396058290765119225,0.734889836125311557,0.126278929410076152],"hpluv":[124.557188606571273,509.111714190739917,88.6804070841335488],"hsluv":[124.557188606571273,99.999999999991374,88.6804070841335488]},"#55ff22":{"lch":[88.7160126920472862,127.742171235629925,124.920549061750862],"luv":[88.7160126920472862,-73.1247263453711867,104.741762009752222],"rgb":[0.333333333333333315,1,0.133333333333333331],"xyz":[0.397933648903596282,0.735639979380702358,0.136155815606055358],"hpluv":[124.920549061750862,505.235489858807625,88.7160126920472862],"hsluv":[124.920549061750862,99.9999999999912461,88.7160126920472862]},"#55ff33":{"lch":[88.7745841250638819,125.429409451765778,125.531442964179078],"luv":[88.7745841250638819,-72.893256299655377,102.074041467218606],"rgb":[0.333333333333333315,1,0.2],"xyz":[0.401021399636054,0.736875079673685485,0.152417969463666508],"hpluv":[125.531442964179078,498.916518871762833,88.7745841250638819],"hsluv":[125.531442964179078,99.9999999999915445,88.7745841250638819]},"#55ff44":{"lch":[88.8590323294941271,122.159967165607114,126.442013329478428],"luv":[88.8590323294941271,-72.5641116581323189,98.2726171279075658],"rgb":[0.333333333333333315,1,0.266666666666666663],"xyz":[0.405479394880272903,0.738658277771373,0.175896744416553147],"hpluv":[126.442013329478428,489.934204596741552,88.8590323294941271],"hsluv":[126.442013329478428,99.9999999999914735,88.8590323294941271]},"#55ff55":{"lch":[88.9717666926620154,117.915518658848484,127.715012949240119],"luv":[88.9717666926620154,-72.1329719647303,93.2786357968462],"rgb":[0.333333333333333315,1,0.333333333333333315],"xyz":[0.411441808919634888,0.7410432433871178,0.207298791690527062],"hpluv":[127.715012949240119,478.187207442594797,88.9717666926620154],"hsluv":[127.715012949240119,99.9999999999912461,88.9717666926620154]},"#55ff66":{"lch":[89.1148309932425,112.728028648536309,129.430986513959965],"luv":[89.1148309932425,-71.5990188667543919,87.0700232014633713],"rgb":[0.333333333333333315,1,0.4],"xyz":[0.419026804693143073,0.744077241696521119,0.247246436097671],"hpluv":[129.430986513959965,463.701047487447568,89.1148309932425],"hsluv":[129.430986513959965,99.999999999991374,89.1148309932425]},"#55ff77":{"lch":[89.2899761450384233,106.6837193332601,131.696695826109391],"luv":[89.2899761450384233,-70.9646547782272705,79.6582308552282825],"rgb":[0.333333333333333315,1,0.466666666666666674],"xyz":[0.428340817713345,0.747802846904602,0.296300238004068905],"hpluv":[131.696695826109391,446.653165807945641,89.2899761450384233],"hsluv":[131.696695826109391,99.9999999999911466,89.2899761450384233]},"#55ff88":{"lch":[89.4987035327786344,99.9302046144725722,134.655503696120093],"luv":[89.4987035327786344,-70.2351927280585784,71.0849034376696807],"rgb":[0.333333333333333315,1,0.533333333333333326],"xyz":[0.439481234815288779,0.752259013745379512,0.354973101407641101],"hpluv":[134.655503696120093,427.420708471833962,89.4987035327786344],"hsluv":[134.655503696120093,99.9999999999910472,89.4987035327786344]},"#55ff99":{"lch":[89.7422928839939544,92.6881300553494185,138.499225093055145],"luv":[89.7422928839939544,-69.4184746025382395,61.4179520744067275],"rgb":[0.333333333333333315,1,0.6],"xyz":[0.452538198924361534,0.757481799389008725,0.423739779048759],"hpluv":[138.499225093055145,406.664135605650245,89.7422928839939544],"hsluv":[138.499225093055145,99.9999999999909193,89.7422928839939544]},"#55ffaa":{"lch":[90.021821419032733,85.2692799565717081,143.477548510033301],"luv":[90.021821419032733,-68.524415632830582,50.7469660816416095],"rgb":[0.333333333333333315,1,0.66666666666666663],"xyz":[0.467595891889614035,0.763504876575109792,0.503043628665757581],"hpluv":[143.477548510033301,385.467603776639692,90.021821419032733],"hsluv":[143.477548510033301,99.9999999999908908,90.021821419032733]},"#55ffbb":{"lch":[90.3381779071049635,78.1017696608261929,149.892156464581973],"luv":[90.3381779071049635,-67.5644942943643514,39.178125719584358],"rgb":[0.333333333333333315,1,0.733333333333333282],"xyz":[0.484733483996950709,0.770359913418044551,0.593301613764399383],"hpluv":[149.892156464581973,365.560319764238727,90.3381779071049635],"hsluv":[149.892156464581973,99.9999999999906,90.3381779071049635]},"#55ffcc":{"lch":[90.6920737330737836,71.7555158590460849,158.04408297895796],"luv":[90.6920737330737836,-66.5512174426729217,26.828893251416094],"rgb":[0.333333333333333315,1,0.8],"xyz":[0.504025859440672463,0.778076863595533408,0.694908124434669539],"hpluv":[158.04408297895796,349.620992563925881,90.6920737330737836],"hsluv":[158.04408297895796,99.9999999999905214,90.6920737330737836]},"#55ffdd":{"lch":[91.0840522607878142,66.9403052018893874,168.083008151042208],"luv":[91.0840522607878142,-65.4975936461766,13.8227959213187273],"rgb":[0.333333333333333315,1,0.866666666666666696],"xyz":[0.525544184991306,0.786684193815786914,0.808237972334675536],"hpluv":[168.083008151042208,341.570927955438208,91.0840522607878142],"hsluv":[168.083008151042208,99.9999999999901092,91.0840522607878142]},"#55ffee":{"lch":[91.5144973031429,64.4172738793593,179.746868091755],"luv":[91.5144973031429,-64.4166452130874347,0.284593639433804613],"rgb":[0.333333333333333315,1,0.933333333333333348],"xyz":[0.549356365257480661,0.796209065922256931,0.933648788403198759],"hpluv":[179.746868091755,346.559914030924404,91.5144973031429],"hsluv":[179.746868091755,99.9999999999898108,91.5144973031429]},"#55ffff":{"lch":[91.9836412143362,64.7784688708661918,192.177050630061103],"luv":[91.9836412143362,-63.3209831419883,-13.663935128132529],"rgb":[0.333333333333333315,1,1],"xyz":[0.575527413667312082,0.806677485286189655,1.07148297669498049],"hpluv":[192.177050630061103,370.276433987554753,91.9836412143362],"hsluv":[192.177050630061103,99.9999999999890719,91.9836412143362]},"#007700":{"lch":[43.052730924646589,66.6333343982289534,127.715012949240503],"luv":[43.052730924646589,-40.7618988300426395,52.7111834129681611],"rgb":[0,0.466666666666666674,0],"xyz":[0.0659653690412832505,0.131930738082568333,0.0219884563470937981],"hpluv":[127.715012949240503,196.394882900214441,43.052730924646589],"hsluv":[127.715012949240503,100.000000000002217,43.052730924646589]},"#007711":{"lch":[43.1130460407029,64.6129906803504497,128.830381027920708],"luv":[43.1130460407029,-40.513441406878222,50.333881531534],"rgb":[0,0.466666666666666674,0.0666666666666666657],"xyz":[0.0669770345409203688,0.132335404282423186,0.0273165613118494313],"hpluv":[128.830381027920708,190.173702516526191,43.1130460407029],"hsluv":[128.830381027920708,99.9999999999908908,43.1130460407029]},"#007722":{"lch":[43.2245297597171856,61.038201507507992,131.028383581415682],"luv":[43.2245297597171856,-40.0674788501528809,46.0462721820529381],"rgb":[0,0.466666666666666674,0.133333333333333331],"xyz":[0.0688523926793974,0.133085547537814014,0.0371934475078286239],"hpluv":[131.028383581415682,179.188765673473426,43.2245297597171856],"hsluv":[131.028383581415682,99.9999999999909193,43.2245297597171856]},"#007733":{"lch":[43.4071769639209251,55.6324991773261601,135.049443606961],"luv":[43.4071769639209251,-39.3720497464739694,39.3041558041433419],"rgb":[0,0.466666666666666674,0.2],"xyz":[0.0719401434118551314,0.134320647830797113,0.0534556013654397671],"hpluv":[135.049443606961,162.632131787412106,43.4071769639209251],"hsluv":[135.049443606961,99.9999999999909193,43.4071769639209251]},"#007744":{"lch":[43.6689123670523855,48.8909209361139787,141.845848120172377],"luv":[43.6689123670523855,-38.4454486392046704,30.2038015639029105],"rgb":[0,0.466666666666666674,0.266666666666666663],"xyz":[0.076398138656074,0.136103845928484707,0.0769343763183264],"hpluv":[141.845848120172377,142.067640978907804,43.6689123670523855],"hsluv":[141.845848120172377,99.9999999999910614,43.6689123670523855]},"#007755":{"lch":[44.0154249216106,41.9153980271179,152.953344682219807],"luv":[44.0154249216106,-37.3313854656975224,19.0595973457790286],"rgb":[0,0.466666666666666674,0.333333333333333315],"xyz":[0.082360552695436,0.13848881154422954,0.108336423592300321],"hpluv":[152.953344682219807,120.839250305189026,44.0154249216106],"hsluv":[152.953344682219807,99.9999999999912461,44.0154249216106]},"#007766":{"lch":[44.4505333250062549,36.6388362985735725,170.062665906075836],"luv":[44.4505333250062549,-36.0891470448365865,6.32279929223085357],"rgb":[0,0.466666666666666674,0.4],"xyz":[0.0899455484689441753,0.141522809853632831,0.148284067999444269],"hpluv":[170.062665906075836,104.593337643625588,44.4505333250062549],"hsluv":[170.062665906075836,99.9999999999913314,44.4505333250062549]},"#007777":{"lch":[44.9764013416840669,35.58350047386471,192.17705063006116],"luv":[44.9764013416840669,-34.7828880940388601,-7.50574458738768],"rgb":[0,0.466666666666666674,0.466666666666666674],"xyz":[0.0992595614891461,0.145248415061713654,0.197337869905842178],"hpluv":[192.17705063006116,100.392967527320835,44.9764013416840669],"hsluv":[192.17705063006116,99.9999999999914451,44.9764013416840669]},"#007788":{"lch":[45.5937085159301603,40.0276538709377,213.25546015720218],"luv":[45.5937085159301603,-33.4724811425817,-21.9500815618326577],"rgb":[0,0.466666666666666674,0.533333333333333326],"xyz":[0.110399978591089923,0.149704581902491252,0.256010733309414373],"hpluv":[213.25546015720218,111.402399127386914,45.5937085159301603],"hsluv":[213.25546015720218,99.9999999999916156,45.5937085159301603]},"#007799":{"lch":[46.3018156057360244,48.7595612734022907,228.659125647543163],"luv":[46.3018156057360244,-32.2075160625452597,-36.6083422822662357],"rgb":[0,0.466666666666666674,0.6],"xyz":[0.123456942700162636,0.154927367546120409,0.324777410950532253],"hpluv":[228.659125647543163,133.62911578541167,46.3018156057360244],"hsluv":[228.659125647543163,99.9999999999917577,46.3018156057360244]},"#0077aa":{"lch":[47.0989379645613795,59.8445186957143,238.773531847525192],"luv":[47.0989379645613795,-31.0247207616125031,-51.1745358511991597],"rgb":[0,0.466666666666666674,0.66666666666666663],"xyz":[0.138514635665415164,0.160950444732221504,0.404081260567530853],"hpluv":[238.773531847525192,161.232500989130415,47.0989379645613795],"hsluv":[238.773531847525192,99.999999999991914,47.0989379645613795]},"#0077bb":{"lch":[47.9823278818304146,71.9659744020705432,245.408717039049918],"luv":[47.9823278818304146,-29.9480972873728,-65.4386196408934495],"rgb":[0,0.466666666666666674,0.733333333333333282],"xyz":[0.155652227772751839,0.167805481575156262,0.4943392456661726],"hpluv":[245.408717039049918,190.32034768447943,47.9823278818304146],"hsluv":[245.408717039049918,99.9999999999920561,47.9823278818304146]},"#0077cc":{"lch":[48.9484610491917067,84.4081580704908276,249.9122747909542],"luv":[48.9484610491917067,-28.9906993044602252,-79.2734287305105454],"rgb":[0,0.466666666666666674,0.8],"xyz":[0.174944603216473565,0.175522431752645064,0.595945756336442756],"hpluv":[249.9122747909542,218.818838178067409,48.9484610491917067],"hsluv":[249.9122747909542,99.9999999999922125,48.9484610491917067]},"#0077dd":{"lch":[49.9932200675849,96.8017840095652389,253.089738624096071],"luv":[49.9932200675849,-28.15707849035525,-92.6162206005108715],"rgb":[0,0.466666666666666674,0.866666666666666696],"xyz":[0.196462928767107109,0.184129761972898598,0.709275604236448753],"hpluv":[253.089738624096071,245.70363248193695,49.9932200675849],"hsluv":[253.089738624096071,99.9999999999921272,49.9932200675849]},"#0077ee":{"lch":[51.1120678627821547,108.963279527823246,255.411176145550684],"luv":[51.1120678627821547,-27.4457353077348785,-105.450120430828804],"rgb":[0,0.466666666666666674,0.933333333333333348],"xyz":[0.220275109033281846,0.193654634079368643,0.834686420304972],"hpluv":[255.411176145550684,270.517920771775039,51.1120678627821547],"hsluv":[255.411176145550684,99.9999999999922551,51.1120678627821547]},"#0077ff":{"lch":[52.300205122294,120.810007187166491,257.158195690943],"luv":[52.300205122294,-26.851223719183885,-117.788240590245493],"rgb":[0,0.466666666666666674,1],"xyz":[0.24644615744311324,0.204123053443301339,0.972520608596753822],"hpluv":[257.158195690943,293.11554041762389,52.300205122294],"hsluv":[257.158195690943,99.9999999999991189,52.300205122294]},"#008800":{"lch":[49.0166039301270473,75.8637069146273291,127.71501294924046],"luv":[49.0166039301270473,-46.4084346679225348,60.0129920808956214],"rgb":[0,0.533333333333333326,0],"xyz":[0.0880377387662537,0.176075477532509878,0.0293459129220837445],"hpluv":[127.71501294924046,196.394882900214583,49.0166039301270473],"hsluv":[127.71501294924046,100.000000000002359,49.0166039301270473]},"#008811":{"lch":[49.066374048408079,74.1307167522113133,128.546257021813432],"luv":[49.066374048408079,-46.1942790787678064,57.9780281364371461],"rgb":[0,0.533333333333333326,0.0666666666666666657],"xyz":[0.0890494042658908219,0.17648014373236473,0.0346740178868393742],"hpluv":[128.546257021813432,191.713881645209739,49.066374048408079],"hsluv":[128.546257021813432,99.9999999999908908,49.066374048408079]},"#008822":{"lch":[49.1584337135343503,71.0276132120671,130.159311596065152],"luv":[49.1584337135343503,-45.8067815452400779,54.2831521106656112],"rgb":[0,0.533333333333333326,0.133333333333333331],"xyz":[0.090924762404367851,0.177230286987755559,0.0445509040828185737],"hpluv":[130.159311596065152,183.344763498744726,49.1584337135343503],"hsluv":[130.159311596065152,99.9999999999909335,49.1584337135343503]},"#008833":{"lch":[49.3094443496477197,66.226384742663825,133.033255321350083],"luv":[49.3094443496477197,-45.1943905199784481,48.4086882864121648],"rgb":[0,0.533333333333333326,0.2],"xyz":[0.0940125131368255845,0.178465387280738658,0.060813057940429717],"hpluv":[133.033255321350083,170.427732437953466,49.3094443496477197],"hsluv":[133.033255321350083,99.9999999999909903,49.3094443496477197]},"#008844":{"lch":[49.5262444349700388,59.9709063982634589,137.708745518338219],"luv":[49.5262444349700388,-44.3625073014275202,40.3543995143041],"rgb":[0,0.533333333333333326,0.266666666666666663],"xyz":[0.0984705083810444581,0.180248585378426252,0.0842918328933163485],"hpluv":[137.708745518338219,153.654237765673173,49.5262444349700388],"hsluv":[137.708745518338219,99.9999999999910756,49.5262444349700388]},"#008855":{"lch":[49.8139833497656355,52.876539169604392,145.043769270071607],"luv":[49.8139833497656355,-43.3370811793054074,30.2956397756013871],"rgb":[0,0.533333333333333326,0.333333333333333315],"xyz":[0.104432922420406457,0.182633550994171084,0.115693880167290264],"hpluv":[145.043769270071607,134.694876863850226,49.8139833497656355],"hsluv":[145.043769270071607,99.9999999999911893,49.8139833497656355]},"#008866":{"lch":[50.1764284055384593,46.0546718070978613,156.264738854980266],"luv":[50.1764284055384593,-42.1591397878491918,18.5375221539472825],"rgb":[0,0.533333333333333326,0.4],"xyz":[0.112017918193914628,0.185667549303574375,0.155641524574434226],"hpluv":[156.264738854980266,116.469784961641182,50.1764284055384593],"hsluv":[156.264738854980266,99.9999999999912461,50.1764284055384593]},"#008877":{"lch":[50.6161324463586766,41.2412500498738694,172.391379993232761],"luv":[50.6161324463586766,-40.8781468825216336,5.46056893805106114],"rgb":[0,0.533333333333333326,0.466666666666666674],"xyz":[0.121331931214116548,0.189393154511655198,0.204695326480832135],"hpluv":[172.391379993232761,103.390869865470918,50.6161324463586766],"hsluv":[172.391379993232761,99.9999999999913456,50.6161324463586766]},"#008888":{"lch":[51.1345503085294695,40.4555776108317602,192.177050630061132],"luv":[51.1345503085294695,-39.545345738280993,-8.53342781453345],"rgb":[0,0.533333333333333326,0.533333333333333326],"xyz":[0.132472348316060362,0.193849321352432796,0.263368189884404302],"hpluv":[192.177050630061132,100.392967527320849,51.1345503085294695],"hsluv":[192.177050630061132,99.9999999999914877,51.1345503085294695]},"#008899":{"lch":[51.7321394091786715,44.6308971675799881,211.11913642158629],"luv":[51.7321394091786715,-38.208266400248,-23.066108485628412],"rgb":[0,0.533333333333333326,0.6],"xyz":[0.145529312425133089,0.199072106996061954,0.332134867525522237],"hpluv":[211.11913642158629,109.474886689832829,51.7321394091786715],"hsluv":[211.11913642158629,99.999999999991573,51.7321394091786715]},"#0088aa":{"lch":[52.4084594351014914,52.8385448128107598,225.694192047300788],"luv":[52.4084594351014914,-36.9070805124816346,-37.8124215831333572],"rgb":[0,0.533333333333333326,0.66666666666666663],"xyz":[0.160587005390385618,0.205095184182163048,0.411438717142520782],"hpluv":[225.694192047300788,127.934825585488483,52.4084594351014914],"hsluv":[225.694192047300788,99.9999999999917,52.4084594351014914]},"#0088bb":{"lch":[53.1622766119302952,63.4852929684367,235.812153399491365],"luv":[53.1622766119302952,-35.672889398211332,-52.5150205681309856],"rgb":[0,0.533333333333333326,0.733333333333333282],"xyz":[0.177724597497722292,0.211950221025097807,0.501696702241162584],"hpluv":[235.812153399491365,151.533580059798538,53.1622766119302952],"hsluv":[235.812153399491365,99.9999999999918572,53.1622766119302952]},"#0088cc":{"lch":[53.9916730817088961,75.3609801883338406,242.731381598031476],"luv":[53.9916730817088961,-34.5275961267233455,-66.9859868976812578],"rgb":[0,0.533333333333333326,0.8],"xyz":[0.197016972941444019,0.219667171202586609,0.60330321291143274],"hpluv":[242.731381598031476,177.116523654060018,53.9916730817088961],"hsluv":[242.731381598031476,99.9999999999919282,53.9916730817088961]},"#0088dd":{"lch":[54.894159312243417,87.7409205251226,247.565131731451658],"luv":[54.894159312243417,-33.4848266090853,-81.1001573460580545],"rgb":[0,0.533333333333333326,0.866666666666666696],"xyz":[0.218535298492077562,0.228274501422840143,0.716633060811438738],"hpluv":[247.565131731451658,202.822146488853946,54.894159312243417],"hsluv":[247.565131731451658,99.9999999999921414,54.894159312243417]},"#0088ee":{"lch":[55.8667862779657725,100.217939448335898,251.046181944553609],"luv":[55.8667862779657725,-32.551381555669181,-94.7841914355319091],"rgb":[0,0.533333333333333326,0.933333333333333348],"xyz":[0.242347478758252299,0.237799373529310187,0.842043876879962],"hpluv":[251.046181944553609,227.630842720065772,55.8667862779657725],"hsluv":[251.046181944553609,99.9999999999923261,55.8667862779657725]},"#0088ff":{"lch":[56.9062538959811803,112.568622459607909,253.628629682131134],"luv":[56.9062538959811803,-31.728824885135996,-108.00452043253614],"rgb":[0,0.533333333333333326,1],"xyz":[0.268518527168083665,0.248267792893242883,0.979878065171743806],"hpluv":[253.628629682131134,251.013269675548315,56.9062538959811803],"hsluv":[253.628629682131134,99.9999999999989,56.9062538959811803]},"#009900":{"lch":[54.8465256129575778,84.8867610313905629,127.71501294924046],"luv":[54.8465256129575778,-51.9281467214630865,67.1507987776363677],"rgb":[0,0.6,0],"xyz":[0.11390733921872119,0.227814678437445572,0.037969113072906],"hpluv":[127.71501294924046,196.394882900214611,54.8465256129575778],"hsluv":[127.71501294924046,100.000000000002359,54.8465256129575778]},"#009911":{"lch":[54.8884489227774139,83.3822613920475533,128.355135015114286],"luv":[54.8884489227774139,-51.7415219578455918,65.3866685214771195],"rgb":[0,0.6,0.0666666666666666657],"xyz":[0.114919004718358309,0.228219344637300425,0.0432972180376616292],"hpluv":[128.355135015114286,192.766711025891595,54.8884489227774139],"hsluv":[128.355135015114286,99.9999999999908908,54.8884489227774139]},"#009922":{"lch":[54.9660326693047665,80.6666974094322882,129.584419925030318],"luv":[54.9660326693047665,-51.4019848556742147,62.168738316310943],"rgb":[0,0.6,0.133333333333333331],"xyz":[0.116794362856835338,0.228969487892691254,0.0531741042336408287],"hpluv":[129.584419925030318,186.225526863887183,54.9660326693047665],"hsluv":[129.584419925030318,99.9999999999908766,54.9660326693047665]},"#009933":{"lch":[55.0934048637144826,76.4021664793699529,131.735569901926],"luv":[55.0934048637144826,-50.8604445821364948,57.0132109221080725],"rgb":[0,0.6,0.2],"xyz":[0.119882113589293071,0.230204588185674353,0.0694362580912519789],"hpluv":[131.735569901926,175.972736191316358,55.0934048637144826],"hsluv":[131.735569901926,99.9999999999909903,55.0934048637144826]},"#009944":{"lch":[55.2764995203901321,70.6973886175228614,135.142608572152881],"luv":[55.2764995203901321,-50.1148739946869739,49.8660221176072795],"rgb":[0,0.6,0.266666666666666663],"xyz":[0.124340108833511945,0.231987786283361946,0.0929150330441386174],"hpluv":[135.142608572152881,162.293888564466016,55.2764995203901321],"hsluv":[135.142608572152881,99.9999999999910472,55.2764995203901321]},"#009955":{"lch":[55.5199214835444792,63.9084670453141044,140.311824754994205],"luv":[55.5199214835444792,-49.1795700812718,40.8125231602173173],"rgb":[0,0.6,0.333333333333333315],"xyz":[0.130302522872873944,0.234372751899106779,0.124317080318112519],"hpluv":[140.311824754994205,146.065915008593578,55.5199214835444792],"hsluv":[140.311824754994205,99.999999999991033,55.5199214835444792]},"#009966":{"lch":[55.8272121342916847,56.7002292022714229,147.995210176352344],"luv":[55.8272121342916847,-48.0820094218291771,30.0505634148387166],"rgb":[0,0.6,0.4],"xyz":[0.137887518646382129,0.23740675020851007,0.164264724725256495],"hpluv":[147.995210176352344,128.877825594911201,55.8272121342916847],"hsluv":[147.995210176352344,99.9999999999911893,55.8272121342916847]},"#009977":{"lch":[56.2009899164422393,50.1460500452165832,159.138923639260469],"luv":[56.2009899164422393,-46.85880632633,17.8571723631952],"rgb":[0,0.6,0.466666666666666674],"xyz":[0.147201531666584035,0.241132355416590893,0.213318526631654404],"hpluv":[159.138923639260469,113.222330796973324,56.2009899164422393],"hsluv":[159.138923639260469,99.9999999999912887,56.2009899164422393]},"#009988":{"lch":[56.6430401241061077,45.7780774967248476,174.293450088826631],"luv":[56.6430401241061077,-45.5512109338885409,4.55187453172192669],"rgb":[0,0.6,0.533333333333333326],"xyz":[0.158341948768527863,0.245588522257368491,0.271991390035226543],"hpluv":[174.293450088826631,102.553461073272217,56.6430401241061077],"hsluv":[174.293450088826631,99.9999999999913456,56.6430401241061077]},"#009999":{"lch":[57.1543844255405133,45.2182256610376498,192.177050630061132],"luv":[57.1543844255405133,-44.2008363998384866,-9.53802880511673301],"rgb":[0,0.6,0.6],"xyz":[0.171398912877600562,0.250811307900997649,0.340758067676344478],"hpluv":[192.177050630061132,100.392967527320849,57.1543844255405133],"hsluv":[192.177050630061132,99.9999999999914877,57.1543844255405133]},"#0099aa":{"lch":[57.7353441317496,49.1617433665336065,209.362441333496832],"luv":[57.7353441317496,-42.8462007667450138,-24.1056028900479831],"rgb":[0,0.6,0.66666666666666663],"xyz":[0.186456605842853118,0.256834385087098771,0.420061917293343079],"hpluv":[209.362441333496832,108.050017888493571,57.7353441317496],"hsluv":[209.362441333496832,99.9999999999915872,57.7353441317496]},"#0099bb":{"lch":[58.3856036871333686,56.8846197873520509,223.121526867409756],"luv":[58.3856036871333686,-41.5203973647636531,-38.8833713947714656],"rgb":[0,0.6,0.733333333333333282],"xyz":[0.203594197950189765,0.26368942193003353,0.51031990239198477],"hpluv":[223.121526867409756,123.631292939903787,58.3856036871333686],"hsluv":[223.121526867409756,99.9999999999917151,58.3856036871333686]},"#0099cc":{"lch":[59.1042769117952531,67.0724902608298237,233.123241992210865],"luv":[59.1042769117952531,-40.2499186561976856,-53.6531732328907225],"rgb":[0,0.6,0.8],"xyz":[0.222886573393911491,0.271406372107522331,0.611926413062254926],"hpluv":[233.123241992210865,144.000781521109104,59.1042769117952531],"hsluv":[233.123241992210865,99.9999999999918572,59.1042769117952531]},"#0099dd":{"lch":[59.889976295668248,78.6325369214165448,240.220044999287609],"luv":[59.889976295668248,-39.0544489896310338,-68.2482664747921888],"rgb":[0,0.6,0.866666666666666696],"xyz":[0.244404898944545035,0.280013702327775837,0.725256260962260924],"hpluv":[240.220044999287609,166.60478591483178,59.889976295668248],"hsluv":[240.220044999287609,99.9999999999918288,59.889976295668248]},"#0099ee":{"lch":[60.7408843834734853,90.8542474807105549,245.312254820906361],"luv":[60.7408843834734853,-37.9473430473261288,-82.5499451298106521],"rgb":[0,0.6,0.933333333333333348],"xyz":[0.2682170792107198,0.289538574434245854,0.850667077030784147],"hpluv":[245.312254820906361,189.803165481490907,60.7408843834734853],"hsluv":[245.312254820906361,99.9999999999919424,60.7408843834734853]},"#0099ff":{"lch":[61.6548256470178444,103.309645725501895,249.051296659176671],"luv":[61.6548256470178444,-36.936501733242423,-96.4809708680364082],"rgb":[0,0.6,1],"xyz":[0.294388127620551165,0.300006993798178578,0.988501265322566],"hpluv":[249.051296659176671,212.624411607996194,61.6548256470178444],"hsluv":[249.051296659176671,99.9999999999986926,61.6548256470178444]},"#44aa00":{"lch":[61.6346835386869714,87.655425968627469,122.331376925101353],"luv":[61.6346835386869714,-46.8794507107122556,74.0661245293922],"rgb":[0.266666666666666663,0.66666666666666663,0],"xyz":[0.167579386406696784,0.29977360690638849,0.0490310792412290836],"hpluv":[122.331376925101353,180.464989524422549,61.6346835386869714],"hsluv":[122.331376925101353,100.00000000000226,61.6346835386869714]},"#44aa11":{"lch":[61.6696010074672927,86.3319887480293175,122.80087722620695],"luv":[61.6696010074672927,-46.7678581574140253,72.5670705248452492],"rgb":[0.266666666666666663,0.66666666666666663,0.0666666666666666657],"xyz":[0.168591051906333916,0.300178273106243343,0.0543591842059847133],"hpluv":[122.80087722620695,177.639660035048053,61.6696010074672927],"hsluv":[122.80087722620695,97.7717273205757778,61.6696010074672927]},"#44aa22":{"lch":[61.7342457720645541,83.9245562706402097,123.699102784065559],"luv":[61.7342457720645541,-46.5639790081192,69.8221097085679],"rgb":[0.266666666666666663,0.66666666666666663,0.133333333333333331],"xyz":[0.170466410044810918,0.300928416361634143,0.0642360704019639128],"hpluv":[123.699102784065559,172.505216938407472,61.7342457720645541],"hsluv":[123.699102784065559,93.6968530578778882,61.7342457720645541]},"#44aa33":{"lch":[61.8404488118369784,80.0901636841586111,125.261260913590505],"luv":[61.8404488118369784,-46.2365065380172098,65.3958697634278],"rgb":[0.266666666666666663,0.66666666666666663,0.2],"xyz":[0.173554160777268651,0.30216351665461727,0.080498224259575063],"hpluv":[125.261260913590505,164.340980941234676,61.8404488118369784],"hsluv":[125.261260913590505,87.1410828818075913,61.8404488118369784]},"#44aa44":{"lch":[61.9932720073472,74.8379874444649573,127.71501294923992],"luv":[61.9932720073472,-45.7809668449718501,59.2015830825281526],"rgb":[0.266666666666666663,0.66666666666666663,0.266666666666666663],"xyz":[0.178012156021487539,0.303946714752304836,0.103976999212461702],"hpluv":[127.71501294923992,153.185220958209158,61.9932720073472],"hsluv":[127.71501294923992,77.998580561819125,61.9932720073472]},"#44aa55":{"lch":[62.1967362447927883,68.3415808764166854,131.40733952388851],"luv":[62.1967362447927883,-45.2016647888952292,51.2579864704043118],"rgb":[0.266666666666666663,0.66666666666666663,0.333333333333333315],"xyz":[0.183974570060849552,0.306331680368049697,0.135379046486435617],"hpluv":[131.40733952388851,139.430168232009549,62.1967362447927883],"hsluv":[131.40733952388851,78.575415606985473,62.1967362447927883]},"#44aa66":{"lch":[62.4540496972210377,60.9745995384144,136.885019691281769],"luv":[62.4540496972210377,-44.510458035487396,41.6739836629655684],"rgb":[0.266666666666666663,0.66666666666666663,0.4],"xyz":[0.191559565834357709,0.309365678677453,0.175326690893579551],"hpluv":[136.885019691281769,123.88755407265441,62.4540496972210377],"hsluv":[136.885019691281769,79.2669246679894854,62.4540496972210377]},"#44aa77":{"lch":[62.7677273349888196,53.3862032124370103,144.988299459670287],"luv":[62.7677273349888196,-43.7251633677153,30.629998072253084],"rgb":[0.266666666666666663,0.66666666666666663,0.466666666666666674],"xyz":[0.200873578854559642,0.313091283885533811,0.22438049279997746],"hpluv":[144.988299459670287,107.927460302012818,62.7677273349888196],"hsluv":[144.988299459670287,80.0573307147673603,62.7677273349888196]},"#44aa88":{"lch":[63.1396635168947142,46.6323085826041606,156.819414130132799],"luv":[63.1396635168947142,-42.8676249510766354,18.3558964585511255],"rgb":[0.266666666666666663,0.66666666666666663,0.533333333333333326],"xyz":[0.212013995956503443,0.317547450726311409,0.283053356203549655],"hpluv":[156.819414130132799,93.7182088199909,63.1396635168947142],"hsluv":[156.819414130132799,80.9270306732118456,63.1396635168947142]},"#44aa99":{"lch":[63.5711832083111,42.2713825005608328,173.059905511526438],"luv":[63.5711832083111,-41.9616613239929848,5.10771548142927578],"rgb":[0.266666666666666663,0.66666666666666663,0.6],"xyz":[0.22507096006557617,0.322770236369940566,0.351820033844667535],"hpluv":[173.059905511526438,84.3772726773670598,63.5711832083111],"hsluv":[173.059905511526438,81.8544924931781281,63.5711832083111]},"#44aaaa":{"lch":[64.0630839897801536,41.9755778813547948,192.177050630061],"luv":[64.0630839897801536,-41.03114670244819,-8.85404646225986802],"rgb":[0.266666666666666663,0.66666666666666663,0.66666666666666663],"xyz":[0.240128653030828698,0.328793313556041689,0.431123883461666135],"hpluv":[192.177050630061,83.1434743556685731,64.0630839897801536],"hsluv":[192.177050630061,82.8180264051213868,64.0630839897801536]},"#44aabb":{"lch":[64.6156750410269893,46.3675567205894481,210.140689328835606],"luv":[64.6156750410269893,-40.0984334486196374,-23.2823098339426302],"rgb":[0.266666666666666663,0.66666666666666663,0.733333333333333282],"xyz":[0.257266245138165373,0.335648350398976447,0.521381868560307882],"hpluv":[210.140689328835606,91.0574853549996135,64.6156750410269893],"hsluv":[210.140689328835606,83.7972417316187,64.6156750410269893]},"#44aacc":{"lch":[65.2288162125558131,54.5527176111565382,224.088695054270687],"luv":[65.2288162125558131,-39.1832309762682058,-37.956203827872514],"rgb":[0.266666666666666663,0.66666666666666663,0.8],"xyz":[0.276558620581887071,0.343365300576465249,0.622988379230578],"hpluv":[224.088695054270687,106.124637545316332,65.2288162125558131],"hsluv":[224.088695054270687,84.7740840933985424,65.2288162125558131]},"#44aadd":{"lch":[65.9019585504415772,65.1392687949415574,233.984713087438024],"luv":[65.9019585504415772,-38.3019605797345406,-52.6885581021924381],"rgb":[0.266666666666666663,0.66666666666666663,0.866666666666666696],"xyz":[0.29807694613252067,0.351972630796718755,0.736318227130584],"hpluv":[233.984713087438024,125.424934833645892,65.9019585504415772],"hsluv":[233.984713087438024,85.7334354760652246,65.9019585504415772]},"#44aaee":{"lch":[66.634186587349916,77.0517400481588,240.904642753345257],"luv":[66.634186587349916,-37.4675316968449081,-67.3287064556787698],"rgb":[0.266666666666666663,0.66666666666666663,0.933333333333333348],"xyz":[0.32188912639869538,0.361497502903188772,0.861729043199107259],"hpluv":[240.904642753345257,146.73194579095005,66.634186587349916],"hsluv":[240.904642753345257,86.6633273618325717,66.634186587349916]},"#44aaff":{"lch":[67.4242620727880677,89.6163291450103827,245.832487512483851],"luv":[67.4242620727880677,-36.6894434071527229,-81.7616731231704534],"rgb":[0.266666666666666663,0.66666666666666663,1],"xyz":[0.348060174808526801,0.371965922267121496,0.999563231490889104],"hpluv":[245.832487512483851,168.659292786049974,67.4242620727880677],"hsluv":[245.832487512483851,99.9999999999982094,67.4242620727880677]},"#44bb00":{"lch":[67.1028050092269126,96.9162111575721497,123.392710981560953],"luv":[67.1028050092269126,-53.3402140179528601,80.9170782570533476],"rgb":[0.266666666666666663,0.733333333333333282,0],"xyz":[0.201533884315295564,0.367682602723587049,0.0603492452107617],"hpluv":[123.392710981560953,183.271561122122193,67.1028050092269126],"hsluv":[123.392710981560953,100.00000000000226,67.1028050092269126]},"#44bb11":{"lch":[67.1332810832727347,95.7453830613523138,123.778355355208646],"luv":[67.1332810832727347,-53.2326764896654581,79.5830417319651673],"rgb":[0.266666666666666663,0.733333333333333282,0.0666666666666666657],"xyz":[0.202545549814932696,0.368087268923441902,0.0656773501755173322],"hpluv":[123.778355355208646,180.975295348072393,67.1332810832727347],"hsluv":[123.778355355208646,98.1806384027583334,67.1332810832727347]},"#44bb22":{"lch":[67.1897165718252438,93.6085464076245728,124.511290753684577],"luv":[67.1897165718252438,-53.03566579282883,77.1348048189646391],"rgb":[0.266666666666666663,0.733333333333333282,0.133333333333333331],"xyz":[0.204420907953409697,0.368837412178832702,0.0755542363714965248],"hpluv":[124.511290753684577,176.787689053856155,67.1897165718252438],"hsluv":[124.511290753684577,94.8452524510698538,67.1897165718252438]},"#44bb33":{"lch":[67.2824703298360873,90.1849869824975627,125.771296969252688],"luv":[67.2824703298360873,-52.7177504009765485,73.1721987485246501],"rgb":[0.266666666666666663,0.733333333333333282,0.2],"xyz":[0.207508658685867431,0.370072512471815829,0.091816390229107675],"hpluv":[125.771296969252688,170.087205132927863,67.2824703298360873],"hsluv":[125.771296969252688,89.4565739304913308,67.2824703298360873]},"#44bb44":{"lch":[67.4160218575577375,85.4495691526201284,127.715012949240077],"luv":[67.4160218575577375,-52.2724357759646807,67.5960156105081182],"rgb":[0.266666666666666663,0.733333333333333282,0.266666666666666663],"xyz":[0.211966653930086318,0.371855710569503395,0.115295165181994314],"hpluv":[127.715012949240077,160.837043785954393,67.4160218575577375],"hsluv":[127.715012949240077,81.8947222100884318,67.4160218575577375]},"#44bb55":{"lch":[67.5939766620447813,79.5000401119176,130.566112214394138],"luv":[67.5939766620447813,-51.7008659583180759,60.3926886051327756],"rgb":[0.266666666666666663,0.733333333333333282,0.333333333333333315],"xyz":[0.217929067969448331,0.374240676185248256,0.146697212455968229],"hpluv":[130.566112214394138,149.244617358403957,67.5939766620447813],"hsluv":[130.566112214394138,82.2871698148834412,67.5939766620447813]},"#44bb66":{"lch":[67.8192698910356313,72.5749222232247,134.657948179728322],"luv":[67.8192698910356313,-51.0109407747319139,51.6236695420221778],"rgb":[0.266666666666666663,0.733333333333333282,0.4],"xyz":[0.225514063742956489,0.377274674494651574,0.186644856863112191],"hpluv":[134.657948179728322,135.791565604529097,67.8192698910356313],"hsluv":[134.657948179728322,82.7624878443234451,67.8192698910356313]},"#44bb77":{"lch":[68.0942730594189527,65.0902087481164671,140.487577627549143],"luv":[68.0942730594189527,-50.2162275054035163,41.4133525568618168],"rgb":[0.266666666666666663,0.733333333333333282,0.466666666666666674],"xyz":[0.234828076763158422,0.38100027970273237,0.2356986587695101],"hpluv":[140.487577627549143,121.295420087000366,68.0942730594189527],"hsluv":[140.487577627549143,83.3123735080707206,68.0942730594189527]},"#44bb88":{"lch":[68.4208577329380461,57.7058903955470939,148.752185803016886],"luv":[68.4208577329380461,-49.3345927236295907,29.9343907092910229],"rgb":[0.266666666666666663,0.733333333333333282,0.533333333333333326],"xyz":[0.245968493865102222,0.385456446543509967,0.294371522173082267],"hpluv":[148.752185803016886,107.021481540968693,68.4208577329380461],"hsluv":[148.752185803016886,83.9257037652282776,68.4208577329380461]},"#44bb99":{"lch":[68.8004384509552267,51.4171630403873507,160.23039633414129],"luv":[68.8004384509552267,-48.3866530594068536,17.3912754227620781],"rgb":[0.266666666666666663,0.733333333333333282,0.6],"xyz":[0.259025457974175,0.390679232187139125,0.363138199814200147],"hpluv":[160.23039633414129,94.8322885243955,68.8004384509552267],"hsluv":[160.23039633414129,84.5895330052649683,68.8004384509552267]},"#44bbaa":{"lch":[69.2340056114394571,47.5630236168925,175.171204236910796],"luv":[69.2340056114394571,-47.3942071553531576,4.003791165451279],"rgb":[0.266666666666666663,0.733333333333333282,0.66666666666666663],"xyz":[0.274083150939427478,0.396702309373240247,0.442442049431198747],"hpluv":[175.171204236910796,87.1744714415039113,69.2340056114394571],"hsluv":[175.171204236910796,85.2901010545764251,69.2340056114394571]},"#44bbbb":{"lch":[69.722153945093,47.4463312905994243,192.177050630061103],"luv":[69.722153945093,-46.3788106784417877,-10.0080104411700219],"rgb":[0.266666666666666663,0.733333333333333282,0.733333333333333282],"xyz":[0.291220743046764152,0.403557346216175,0.532700034529840494],"hpluv":[192.177050630061103,86.3517549054621156,69.722153945093],"hsluv":[192.177050630061103,86.0137488036252,69.722153945093]},"#44bbcc":{"lch":[70.265109629848,51.5238495855336254,208.311647260201596],"luv":[70.265109629848,-45.3606162241423405,-24.4360711219862],"rgb":[0.266666666666666663,0.733333333333333282,0.8],"xyz":[0.310513118490485907,0.411274296393663807,0.63430654520011065],"hpluv":[208.311647260201596,93.0481841100277478,70.265109629848],"hsluv":[208.311647260201596,86.7476639801695484,70.265109629848]},"#44bbdd":{"lch":[70.8627576511434683,59.1258582536945,221.390354970453018],"luv":[70.8627576511434683,-44.357542252504274,-39.0931651258026491],"rgb":[0.266666666666666663,0.733333333333333282,0.866666666666666696],"xyz":[0.332031444041119395,0.419881626613917314,0.747636393100116647],"hpluv":[221.390354970453018,105.876295000483495,70.8627576511434683],"hsluv":[221.390354970453018,87.4804162985680449,70.8627576511434683]},"#44bbee":{"lch":[71.5146701379092207,69.1277260896420813,231.126492355228834],"luv":[71.5146701379092207,-43.3847784652122499,-53.8182451576511269],"rgb":[0.266666666666666663,0.733333333333333282,0.933333333333333348],"xyz":[0.35584362430729416,0.429406498720387331,0.873047209168639871],"hpluv":[231.126492355228834,122.65816352572412,71.5146701379092207],"hsluv":[231.126492355228834,88.202277385306985,71.5146701379092207]},"#44bbff":{"lch":[72.2201358507708,80.5712163793027685,238.202407995552562],"luv":[72.2201358507708,-42.4545914747530801,-68.4786723845625573],"rgb":[0.266666666666666663,0.733333333333333282,1],"xyz":[0.382014672717125525,0.439874918084320055,1.01088139746042183],"hpluv":[238.202407995552562,141.566646923483631,72.2201358507708],"hsluv":[238.202407995552562,99.9999999999976694,72.2201358507708]},"#44cc00":{"lch":[72.503692055952385,105.959797206167082,124.178253965335855],"luv":[72.503692055952385,-59.5249745926526543,87.6598883396283384],"rgb":[0.266666666666666663,0.8,0],"xyz":[0.239757627624912484,0.444130089342821943,0.0730904929806336506],"hpluv":[124.178253965335855,185.447217969921951,72.503692055952385],"hsluv":[124.178253965335855,100.000000000002359,72.503692055952385]},"#44cc11":{"lch":[72.5305637479271752,104.914943747871533,124.498982817725434],"luv":[72.5305637479271752,-59.4229434801529877,86.4642076802510928],"rgb":[0.266666666666666663,0.8,0.0666666666666666657],"xyz":[0.240769293124549616,0.444534755542676796,0.0784185979453892873],"hpluv":[124.498982817725434,183.55052269402043,72.5305637479271752],"hsluv":[124.498982817725434,98.4921383302381628,72.5305637479271752]},"#44cc22":{"lch":[72.5803335982668,103.003123626508128,125.105641856618192],"luv":[72.5803335982668,-59.2356349500081265,84.2661440252673088],"rgb":[0.266666666666666663,0.8,0.133333333333333331],"xyz":[0.242644651263026617,0.445284898798067597,0.0882954841413684799],"hpluv":[125.105641856618192,180.082189217111164,72.5803335982668],"hsluv":[125.105641856618192,95.7225658430248387,72.5803335982668]},"#44cc33":{"lch":[72.6621573160580283,99.9260617146724144,126.139923542820412],"luv":[72.6621573160580283,-58.9323161564504758,80.6982027200153],"rgb":[0.266666666666666663,0.8,0.2],"xyz":[0.245732401995484351,0.446519999091050723,0.10455763799897963],"hpluv":[126.139923542820412,174.505777504147545,72.6621573160580283],"hsluv":[126.139923542820412,91.233607132201584,72.6621573160580283]},"#44cc44":{"lch":[72.780026014363628,95.6382843785450518,127.715012949240148],"luv":[72.780026014363628,-58.5052227586060383,75.6559339961998],"rgb":[0.266666666666666663,0.8,0.266666666666666663],"xyz":[0.250190397239703266,0.448303197188738289,0.128036412951866269],"hpluv":[127.715012949240148,166.747333178852926,72.780026014363628],"hsluv":[127.715012949240148,84.9041129363740339,72.780026014363628]},"#44cc55":{"lch":[72.9371837422115732,90.1892610669535912,129.983942971096695],"luv":[72.9371837422115732,-57.9531752136704,69.1052262456084492],"rgb":[0.266666666666666663,0.8,0.333333333333333315],"xyz":[0.256152811279065251,0.45068816280448315,0.159438460225840184],"hpluv":[129.983942971096695,156.908028239254975,72.9371837422115732],"hsluv":[129.983942971096695,85.1779272269293557,72.9371837422115732]},"#44cc66":{"lch":[73.1363103507417236,83.732792729713168,133.164212643981188],"luv":[73.1363103507417236,-57.28090462038152,61.074368962666],"rgb":[0.266666666666666663,0.8,0.4],"xyz":[0.263737807052573436,0.453722161113886469,0.199386104632984118],"hpluv":[133.164212643981188,145.278670258241675,73.1363103507417236],"hsluv":[133.164212643981188,85.5122241677148764,73.1363103507417236]},"#44cc77":{"lch":[73.3796177536812309,76.5464624175537,137.569101073773794],"luv":[73.3796177536812309,-56.4983001604517625,51.6459387330839],"rgb":[0.266666666666666663,0.8,0.466666666666666674],"xyz":[0.273051820072775342,0.457447766321967264,0.248439906539382027],"hpluv":[137.569101073773794,132.369828459728325,73.3796177536812309],"hsluv":[137.569101073773794,85.9026534082125153,73.3796177536812309]},"#44cc88":{"lch":[73.6689069899719442,69.0664605730878378,143.639563525196422],"luv":[73.6689069899719442,-55.6194534086204087,40.9469459010095278],"rgb":[0.266666666666666663,0.8,0.533333333333333326],"xyz":[0.284192237174719142,0.461903933162744862,0.307112769942954222],"hpluv":[143.639563525196422,118.965846887396481,73.6689069899719442],"hsluv":[143.639563525196422,86.3428682965135863,73.6689069899719442]},"#44cc99":{"lch":[74.0056056952011,61.9424628035573548,151.940118655705163],"luv":[74.0056056952011,-54.661526046940331,29.1373689338922652],"rgb":[0.266666666666666663,0.8,0.6],"xyz":[0.297249201283791842,0.467126718806374,0.375879447584072102],"hpluv":[151.940118655705163,106.209454381597496,74.0056056952011],"hsluv":[151.940118655705163,86.8250568088678,74.0056056952011]},"#44ccaa":{"lch":[74.3907954563299256,56.0938540204294327,163.002493202880316],"luv":[74.3907954563299256,-53.6435329798001206,16.3979214631106132],"rgb":[0.266666666666666663,0.8,0.66666666666666663],"xyz":[0.312306894249044398,0.473149795992475142,0.455183297201070702],"hpluv":[163.002493202880316,95.6831366692641581,74.3907954563299256],"hsluv":[163.002493202880316,87.3405106459777727,74.3907954563299256]},"#44ccbb":{"lch":[74.8252340948823331,52.6660587979454959,176.823724318960615],"luv":[74.8252340948823331,-52.5851528012588929,2.91812511330579927],"rgb":[0.266666666666666663,0.8,0.733333333333333282],"xyz":[0.329444486356381072,0.4800048328354099,0.545441282299712449],"hpluv":[176.823724318960615,89.3145186414393493,74.8252340948823331],"hsluv":[176.823724318960615,87.8801809558037235,74.8252340948823331]},"#44cccc":{"lch":[75.3093757141467393,52.6911947618550442,192.177050630061103],"luv":[75.3093757141467393,-51.5056671360628826,-11.1143267137884898],"rgb":[0.266666666666666663,0.8,0.8],"xyz":[0.348736861800102771,0.487721783012898702,0.647047792969982605],"hpluv":[192.177050630061103,88.7826952764381758,75.3093757141467393],"hsluv":[192.177050630061103,88.4351737608208168,75.3093757141467393]},"#44ccdd":{"lch":[75.8433901234223669,56.5143539908888,206.846753698803184],"luv":[75.8433901234223669,-50.423101427505074,-25.5222069860548118],"rgb":[0.266666666666666663,0.8,0.866666666666666696],"xyz":[0.37025518735073637,0.496329113233152208,0.760377640869988602],"hpluv":[206.846753698803184,94.5540981724771257,75.8433901234223669],"hsluv":[206.846753698803184,88.9971515077065334,75.8433901234223669]},"#44ccee":{"lch":[76.4271825186181104,63.6191993934700264,219.125479385679029],"luv":[76.4271825186181104,-49.3536035237008,-40.1450414209705926],"rgb":[0.266666666666666663,0.8,0.933333333333333348],"xyz":[0.39406736761691108,0.505853985339622225,0.885788456938511826],"hpluv":[219.125479385679029,108.248092211119214,76.4271825186181104],"hsluv":[219.125479385679029,89.5586239337052,76.4271825186181104]},"#44ccff":{"lch":[77.0604138316104752,73.087044724203011,228.6232677289035],"luv":[77.0604138316104752,-48.3110621928290342,-54.8430248647743426],"rgb":[0.266666666666666663,0.8,1],"xyz":[0.420238416026742501,0.516322404703555,1.02362264523029367],"hpluv":[228.6232677289035,128.526456918779161,77.0604138316104752],"hsluv":[228.6232677289035,99.9999999999969731,77.0604138316104752]},"#44dd00":{"lch":[77.8394471675691193,114.806757868746558,124.774603647715026],"luv":[77.8394471675691193,-65.4799812263264869,94.3025116894186],"rgb":[0.266666666666666663,0.866666666666666696,0],"xyz":[0.282391618172087688,0.529398070437173462,0.0873018231630249691],"hpluv":[124.774603647715026,210.465861771712326,77.8394471675691193],"hsluv":[124.774603647715026,100.000000000002174,77.8394471675691193]},"#44dd11":{"lch":[77.8633510332093692,113.867279553553601,125.04447057905567],"luv":[77.8633510332093692,-65.3839645843072503,93.2238946202376724],"rgb":[0.266666666666666663,0.866666666666666696,0.0666666666666666657],"xyz":[0.283403283671724793,0.529802736637028371,0.0926299281277806],"hpluv":[125.04447057905567,209.014039294370775,77.8633510332093692],"hsluv":[125.04447057905567,98.7339197526847272,77.8633510332093692]},"#44dd22":{"lch":[77.9076302523257738,112.144788460185168,125.553114236235714],"luv":[77.9076302523257738,-65.2074178024426914,91.2384033306006472],"rgb":[0.266666666666666663,0.866666666666666696,0.133333333333333331],"xyz":[0.28527864181020185,0.530552879892419171,0.102506814323759798],"hpluv":[125.553114236235714,206.347170822894697,77.9076302523257738],"hsluv":[125.553114236235714,96.4050109160080382,77.9076302523257738]},"#44dd33":{"lch":[77.9804445180848802,109.362510567887881,126.41495586461761],"luv":[77.9804445180848802,-64.9207541848309546,88.0082632130877869],"rgb":[0.266666666666666663,0.866666666666666696,0.2],"xyz":[0.288366392542659555,0.531787980185402298,0.118768968181370949],"hpluv":[126.41495586461761,202.025685311970193,77.9804445180848802],"hsluv":[126.41495586461761,92.6208241654068729,77.9804445180848802]},"#44dd44":{"lch":[78.0853727898892345,105.463232003770898,127.715012949240119],"luv":[78.0853727898892345,-64.5154806081751389,83.428089194092081],"rgb":[0.266666666666666663,0.866666666666666696,0.266666666666666663],"xyz":[0.292824387786878471,0.533571178283089864,0.142247743134257587],"hpluv":[127.715012949240119,195.940425098340825,78.0853727898892345],"hsluv":[127.715012949240119,87.2650912217990395,78.0853727898892345]},"#44dd55":{"lch":[78.2253459168282888,100.46502238820301,129.562971792001804],"luv":[78.2253459168282888,-63.9887749627021662,77.4510000079714303],"rgb":[0.266666666666666663,0.866666666666666696,0.333333333333333315],"xyz":[0.298786801826240456,0.535956143898834614,0.173649790408231475],"hpluv":[129.562971792001804,188.090878204767051,78.2253459168282888],"hsluv":[129.562971792001804,87.4605090914447,78.2253459168282888]},"#44dd66":{"lch":[78.4028117957757615,94.4661355921174,132.108441056441876],"luv":[78.4028117957757615,-63.3429373931831776,70.0822592109557],"rgb":[0.266666666666666663,0.866666666666666696,0.4],"xyz":[0.306371797599748641,0.538990142208237932,0.213597434815375464],"hpluv":[132.108441056441876,178.59774401526758,78.4028117957757615],"hsluv":[132.108441056441876,87.7006053461373654,78.4028117957757615]},"#44dd77":{"lch":[78.6198227824069278,87.656024220764337,135.559861003190832],"luv":[78.6198227824069278,-62.584854150819659,61.3735660778470375],"rgb":[0.266666666666666663,0.866666666666666696,0.466666666666666674],"xyz":[0.315685810619950546,0.542715747416318783,0.262651236721773373],"hpluv":[135.559861003190832,167.73117312681623,78.6198227824069278],"hsluv":[135.559861003190832,87.9831439767702221,78.6198227824069278]},"#44dd88":{"lch":[78.8780874692010201,80.3346414261830404,140.206181380764804],"luv":[78.8780874692010201,-61.7253288138421823,51.416324216113189],"rgb":[0.266666666666666663,0.866666666666666696,0.533333333333333326],"xyz":[0.326826227721894347,0.547171914257096326,0.321324100125345513],"hpluv":[140.206181380764804,155.961921377148798,78.8780874692010201],"hsluv":[140.206181380764804,88.3044935606717729,78.8780874692010201]},"#44dd99":{"lch":[79.1790042342924,72.9438114093828602,146.430978952194238],"luv":[79.1790042342924,-60.7782665628728651,40.3336328210091182],"rgb":[0.266666666666666663,0.866666666666666696,0.6],"xyz":[0.339883191830967046,0.552394699900725539,0.390090777766463448],"hpluv":[146.430978952194238,144.047423549525234,79.1790042342924],"hsluv":[146.430978952194238,88.6599152631773109,79.1790042342924]},"#44ddaa":{"lch":[79.5236849812282,66.109750002698334,154.681927012774025],"luv":[79.5236849812282,-59.7597565852220498,28.2713731236083063],"rgb":[0.266666666666666663,0.866666666666666696,0.66666666666666663],"xyz":[0.354940884796219602,0.558417777086826606,0.469394627383462049],"hpluv":[154.681927012774025,133.15854000611057,79.5236849812282],"hsluv":[154.681927012774025,89.0438856180527267,79.5236849812282]},"#44ddbb":{"lch":[79.9129735834354733,60.6712530747818448,165.306614809553963],"luv":[79.9129735834354733,-58.687123678359157,15.3890371376899697],"rgb":[0.266666666666666663,0.866666666666666696,0.733333333333333282],"xyz":[0.372078476903556277,0.565272813929761364,0.55965261248210374],"hpluv":[165.306614809553963,125.005338667233715,79.9129735834354733],"hsluv":[165.306614809553963,89.4504295982059574,79.9129735834354733]},"#44ddcc":{"lch":[80.3474616163736783,57.6077690930220925,178.158710030216184],"luv":[80.3474616163736783,-57.5780241737671616,1.85099760130491053],"rgb":[0.266666666666666663,0.866666666666666696,0.8],"xyz":[0.391370852347278,0.572989764107250221,0.661259123152373895],"hpluv":[178.158710030216184,121.786592068950441,80.3474616163736783],"hsluv":[178.158710030216184,89.8734379183952399,80.3474616163736783]},"#44dddd":{"lch":[80.8275029051271758,57.7489755309586,192.177050630061132],"luv":[80.8275029051271758,-56.4496501662069505,-12.1811810177875159],"rgb":[0.266666666666666663,0.866666666666666696,0.866666666666666696],"xyz":[0.412889177897911575,0.581597094327503727,0.774588971052379893],"hpluv":[192.177050630061132,125.674721736272474,80.8275029051271758],"hsluv":[192.177050630061132,90.3069463225795204,80.8275029051271758]},"#44ddee":{"lch":[81.3532277894993143,61.361693698739991,205.642938459455962],"luv":[81.3532277894993143,-55.3180860243278758,-26.5549771640468073],"rgb":[0.266666666666666663,0.866666666666666696,0.933333333333333348],"xyz":[0.436701358164086284,0.591121966433973745,0.899999787120903116],"hpluv":[205.642938459455962,137.939634766348263,81.3532277894993143],"hsluv":[205.642938459455962,90.7453615563817806,81.3532277894993143]},"#44ddff":{"lch":[81.9245576129038113,68.0382655080336463,217.195369709248553],"luv":[81.9245576129038113,-54.1978382178125813,-41.1314953029609],"rgb":[0.266666666666666663,0.866666666666666696,1],"xyz":[0.462872406573917705,0.601590385797906468,1.03783397541268507],"hpluv":[217.195369709248553,158.576151866946,81.9245576129038113],"hsluv":[217.195369709248553,99.9999999999957367,81.9245576129038113]},"#44ee00":{"lch":[83.112739541513335,123.476763986331008,125.23710114083579],"luv":[83.112739541513335,-71.241317589729718,100.852297507867192],"rgb":[0.266666666666666663,0.933333333333333348,0],"xyz":[0.329570394512602505,0.623755623118204428,0.103028081943196154],"hpluv":[125.23710114083579,311.240798427125753,83.112739541513335],"hsluv":[125.23710114083579,100.000000000002402,83.112739541513335]},"#44ee11":{"lch":[83.1341682891089135,122.626446998812852,125.466600012922257],"luv":[83.1341682891089135,-71.1513320296005674,99.8735873690646656],"rgb":[0.266666666666666663,0.933333333333333348,0.0666666666666666657],"xyz":[0.330582060012239609,0.624160289318059336,0.10835618690795179],"hpluv":[125.466600012922257,309.547675363147619,83.1341682891089135],"hsluv":[125.466600012922257,98.9247180409442279,83.1341682891089135]},"#44ee22":{"lch":[83.1738669889620184,121.064908518289769,125.897986234483838],"luv":[83.1738669889620184,-70.9856689153146192,98.0701120789979],"rgb":[0.266666666666666663,0.933333333333333348,0.133333333333333331],"xyz":[0.332457418150716666,0.624910432573450136,0.118233073103930983],"hpluv":[125.897986234483838,306.432309176179558,83.1738669889620184],"hsluv":[125.897986234483838,96.9444732717922,83.1738669889620184]},"#44ee33":{"lch":[83.2391611795664517,118.535427876706891,126.625494433478437],"luv":[83.2391611795664517,-70.7161072615436694,95.1308563805026921],"rgb":[0.266666666666666663,0.933333333333333348,0.2],"xyz":[0.335545168883174372,0.626145532866433263,0.134495226961542119],"hpluv":[126.625494433478437,301.369067751793693,83.2391611795664517],"hsluv":[126.625494433478437,93.7204451717133651,83.2391611795664517]},"#44ee44":{"lch":[83.3332795320092714,114.974418092600288,127.715012949240275],"luv":[83.3332795320092714,-70.3337997514069855,90.9520391649414],"rgb":[0.266666666666666663,0.933333333333333348,0.266666666666666663],"xyz":[0.340003164127393287,0.627928730964120829,0.157974001914428758],"hpluv":[127.715012949240275,294.205765091151079,83.3332795320092714],"hsluv":[127.715012949240275,89.1439564147074321,83.3332795320092714]},"#44ee55":{"lch":[83.4588814464859183,110.379279114867671,129.248151137931956],"luv":[83.4588814464859183,-69.8347997913980123,85.479155330485213],"rgb":[0.266666666666666663,0.933333333333333348,0.333333333333333315],"xyz":[0.345965578166755272,0.630313696579865579,0.189376049188402673],"hpluv":[129.248151137931956,284.901382538762221,83.4588814464859183],"hsluv":[129.248151137931956,89.2862876088480419,83.4588814464859183]},"#44ee66":{"lch":[83.6182069813856,104.810737833959209,131.33226272314829],"luv":[83.6182069813856,-69.2195888954281,78.7015837099029],"rgb":[0.266666666666666663,0.933333333333333348,0.4],"xyz":[0.353550573940263457,0.633347694889268897,0.229323693595546635],"hpluv":[131.33226272314829,273.53562680177663,83.6182069813856],"hsluv":[131.33226272314829,89.462046779026835,83.6182069813856]},"#44ee77":{"lch":[83.8131566406418642,98.3993759238413759,134.112401675041724],"luv":[83.8131566406418642,-68.4926783274834889,70.6483559449852123],"rgb":[0.266666666666666663,0.933333333333333348,0.466666666666666674],"xyz":[0.362864586960465363,0.637073300097349748,0.278377495501944572],"hpluv":[134.112401675041724,260.333399951005049,83.8131566406418642],"hsluv":[134.112401675041724,89.6701381262035682,83.8131566406418642]},"#44ee88":{"lch":[84.045338735079568,91.3569443918750892,137.785521400150031],"luv":[84.045338735079568,-67.6621349200187439,61.3834406553211949],"rgb":[0.266666666666666663,0.933333333333333348,0.533333333333333326],"xyz":[0.374005004062409163,0.641529466938127291,0.337050358905516712],"hpluv":[137.785521400150031,245.709311488591595,84.045338735079568],"hsluv":[137.785521400150031,89.9084899734552323,84.045338735079568]},"#44ee99":{"lch":[84.3160998906388386,83.9946679616676306,142.613931790318958],"luv":[84.3160998906388386,-66.738995210465,51.0001055321292895],"rgb":[0.266666666666666663,0.933333333333333348,0.6],"xyz":[0.387061968171481863,0.646752252581756504,0.405817036546634591],"hpluv":[142.613931790318958,230.343048149298568,84.3160998906388386],"hsluv":[142.613931790318958,90.1742147406472725,84.3160998906388386]},"#44eeaa":{"lch":[84.626546237332235,76.7502660373389887,148.925817786423067],"luv":[84.626546237332235,-65.7365837009088239,39.6144531722415607],"rgb":[0.266666666666666663,0.933333333333333348,0.66666666666666663],"xyz":[0.402119661136734419,0.652775329767857571,0.485120886163633247],"hpluv":[148.925817786423067,215.298316825794302,84.626546237332235],"hsluv":[148.925817786423067,90.4637941794664897,84.626546237332235]},"#44eebb":{"lch":[84.9775593290447,70.218708007349818,157.069253127653155],"luv":[84.9775593290447,-64.6697768267590618,27.3584889823731068],"rgb":[0.266666666666666663,0.933333333333333348,0.733333333333333282],"xyz":[0.419257253244071093,0.659630366610792329,0.575378871262274938],"hpluv":[157.069253127653155,202.183693696822303,84.9775593290447],"hsluv":[157.069253127653155,90.7732788992861401,84.9775593290447]},"#44eecc":{"lch":[85.3698091329633826,65.1592886039499462,167.256585364158155],"luv":[85.3698091329633826,-63.5542641697608914,14.3731832665241086],"rgb":[0.266666666666666663,0.933333333333333348,0.8],"xyz":[0.438549628687792792,0.667347316788281186,0.676985381932545094],"hpluv":[167.256585364158155,193.290067765431047,85.3698091329633826],"hsluv":[167.256585364158155,91.0984884260964,85.3698091329633826]},"#44eedd":{"lch":[85.803765500838054,62.4110099600490216,179.263728091065275],"luv":[85.803765500838054,-62.4058570040272613,0.801982435119061421],"rgb":[0.266666666666666663,0.933333333333333348,0.866666666666666696],"xyz":[0.460067954238426391,0.675954647008534693,0.790315229832551092],"hpluv":[179.263728091065275,191.499842549603557,85.803765500838054],"hsluv":[179.263728091065275,91.4351983708881875,85.803765500838054]},"#44eeee":{"lch":[86.2797089909746546,62.6494691870182407,192.17705063006116],"luv":[86.2797089909746546,-61.2398849709435922,-13.2148582346064085],"rgb":[0.266666666666666663,0.933333333333333348,0.933333333333333348],"xyz":[0.4838801345046011,0.68547951911500471,0.915726045901074315],"hpluv":[192.17705063006116,199.700166684316315,86.2797089909746546],"hsluv":[192.17705063006116,91.7793037580661775,86.2797089909746546]},"#44eeff":{"lch":[86.7977415696122847,66.0848691943621134,204.633388514668525],"luv":[86.7977415696122847,-60.0707080483631159,-27.5448719547627086],"rgb":[0.266666666666666663,0.933333333333333348,1],"xyz":[0.510051182914432522,0.695947938478937433,1.05356023419285627],"hpluv":[204.633388514668525,219.870556477974674,86.7977415696122847],"hsluv":[204.633388514668525,99.9999999999936904,86.7977415696122847]},"#44ff00":{"lch":[88.3264513606833,131.987460278186802,125.602389702763816],"luv":[88.3264513606833,-76.837408418496949,107.315899745634312],"rgb":[0.266666666666666663,1,0],"xyz":[0.381422766942276337,0.727460367977553535,0.120312206086420265],"hpluv":[125.602389702763816,502.990651378155178,88.3264513606833],"hsluv":[125.602389702763816,100.000000000002331,88.3264513606833]},"#44ff11":{"lch":[88.3457924202418496,131.213348009411362,125.799444038401859],"luv":[88.3457924202418496,-76.7532223203665609,106.423143908077066],"rgb":[0.266666666666666663,1,0.0666666666666666657],"xyz":[0.382434432441913441,0.727865034177408443,0.125640311051175901],"hpluv":[125.799444038401859,500.950310911531346,88.3457924202418496],"hsluv":[125.799444038401859,99.9999999999917577,88.3457924202418496]},"#44ff22":{"lch":[88.3816266358799538,129.789896608084,126.169061428897493],"luv":[88.3816266358799538,-76.5980824061806089,104.776672180562713],"rgb":[0.266666666666666663,1,0.133333333333333331],"xyz":[0.384309790580390498,0.728615177432799244,0.13551719724715508],"hpluv":[126.169061428897493,497.190929074143924,88.3816266358799538],"hsluv":[126.169061428897493,99.9999999999915445,88.3816266358799538]},"#44ff33":{"lch":[88.4405736189592204,127.478814054469,126.790121098902588],"luv":[88.4405736189592204,-76.3452168675528071,102.089450454884],"rgb":[0.266666666666666663,1,0.2],"xyz":[0.387397541312848204,0.72985027772578237,0.15177935110476623],"hpluv":[126.790121098902588,491.06642972530841,88.4405736189592204],"hsluv":[126.790121098902588,99.9999999999916,88.4405736189592204]},"#44ff44":{"lch":[88.5255621746627099,124.213522374992053,127.715012949240247],"luv":[88.5255621746627099,-75.9856771103925,98.2607552122302],"rgb":[0.266666666666666663,1,0.266666666666666663],"xyz":[0.391855536557067119,0.731633475823469936,0.175258126057652869],"hpluv":[127.715012949240247,482.369437382385513,88.5255621746627099],"hsluv":[127.715012949240247,99.9999999999915872,88.5255621746627099]},"#44ff55":{"lch":[88.6390158335401,119.977757557138,129.006344472088813],"luv":[88.6390158335401,-75.5147735105559832,93.2318684253877734],"rgb":[0.266666666666666663,1,0.333333333333333315],"xyz":[0.397817950596429104,0.734018441439214686,0.206660173331626784],"hpluv":[129.006344472088813,471.012302242813519,88.6390158335401],"hsluv":[129.006344472088813,99.9999999999916724,88.6390158335401]},"#44ff66":{"lch":[88.7829895920100256,114.806361082699226,130.743859599912923],"luv":[88.7829895920100256,-74.9316504675157518,86.9813100801842438],"rgb":[0.266666666666666663,1,0.4],"xyz":[0.405402946369937289,0.737052439748618,0.246607817738770746],"hpluv":[130.743859599912923,457.03528250903878,88.7829895920100256],"hsluv":[130.743859599912923,99.999999999991374,88.7829895920100256]},"#44ff77":{"lch":[88.9592430558717524,108.789243130847709,133.032335199193767],"luv":[88.9592430558717524,-74.2389756563468239,79.5215311376676226],"rgb":[0.266666666666666663,1,0.466666666666666674],"xyz":[0.414716959390139195,0.740778044956698856,0.295661619645168683],"hpluv":[133.032335199193767,440.631455855157412,88.9592430558717524],"hsluv":[133.032335199193767,99.999999999991374,88.9592430558717524]},"#44ff88":{"lch":[89.1692840038805343,102.078340317719523,136.01097660716411],"luv":[89.1692840038805343,-73.4425963051882462,70.8955048643657904],"rgb":[0.266666666666666663,1,0.533333333333333326],"xyz":[0.425857376492083,0.745234211797476398,0.354334483048740823],"hpluv":[136.01097660716411,422.1930512248951,89.1692840038805343],"hsluv":[136.01097660716411,99.9999999999912177,89.1692840038805343]},"#44ff99":{"lch":[89.4143964062191117,94.8987049380611438,139.863519733640288],"luv":[89.4143964062191117,-72.5511163277215303,61.1727040314764139],"rgb":[0.266666666666666663,1,0.6],"xyz":[0.43891434060115575,0.750456997441105611,0.423101160689858702],"hpluv":[139.863519733640288,402.3908266141122,89.4143964062191117],"hsluv":[139.863519733640288,99.9999999999912,89.4143964062191117]},"#44ffaa":{"lch":[89.695659684091666,87.5652599917726207,144.82485232612342],"luv":[89.695659684091666,-71.5753927145854192,50.4444042008586777],"rgb":[0.266666666666666663,1,0.66666666666666663],"xyz":[0.453972033566408251,0.756480074627206678,0.502405010306857358],"hpluv":[144.82485232612342,382.304282325397367,89.695659684091666],"hsluv":[144.82485232612342,99.9999999999909335,89.695659684091666]},"#44ffbb":{"lch":[90.0139628620153616,80.5050918065685153,151.171682460988421],"luv":[90.0139628620153616,-70.527972915407986,38.8184858440859557],"rgb":[0.266666666666666663,1,0.733333333333333282],"xyz":[0.471109625673744925,0.763335111470141436,0.592662995405499],"hpluv":[151.171682460988421,363.621116250194575,90.0139628620153616],"hsluv":[151.171682460988421,99.999999999990834,90.0139628620153616]},"#44ffcc":{"lch":[90.3700157308713443,74.2777558665274853,159.169074542576084],"luv":[90.3700157308713443,-69.4225064855060481,26.4140229771485018],"rgb":[0.266666666666666663,1,0.8],"xyz":[0.490402001117466679,0.771052061647630294,0.694269506075769205],"hpluv":[159.169074542576084,348.900804743837909,90.3700157308713443],"hsluv":[159.169074542576084,99.9999999999905924,90.3700157308713443]},"#44ffdd":{"lch":[90.7643583149998,69.56728840997188,168.931262835156701],"luv":[90.7643583149998,-68.2731674827513899,13.3559806299794577],"rgb":[0.266666666666666663,1,0.866666666666666696],"xyz":[0.511920326668100167,0.7796593918678838,0.807599353975775203],"hpluv":[168.931262835156701,341.810509676969502,90.7643583149998],"hsluv":[168.931262835156701,99.9999999999902798,90.7643583149998]},"#44ffee":{"lch":[91.1973694573754869,67.0945142582603182,180.196137266844971],"luv":[91.1973694573754869,-67.094121132442,-0.229680249688981986],"rgb":[0.266666666666666663,1,0.933333333333333348],"xyz":[0.535732506934274877,0.789184263974353817,0.933010170044298426],"hpluv":[180.196137266844971,347.079488330816218,91.1973694573754869],"hsluv":[180.196137266844971,99.999999999989825,91.1973694573754869]},"#44ffff":{"lch":[91.6692750397398726,67.4158875874256,192.177050630061103],"luv":[91.6692750397398726,-65.8990611515587261,-14.2202545175369188],"rgb":[0.266666666666666663,1,1],"xyz":[0.561903555344106298,0.799652683338286541,1.07084435833608027],"hpluv":[192.177050630061103,369.886157390881351,91.6692750397398726],"hsluv":[192.177050630061103,99.9999999999897,91.6692750397398726]},"#33aa00":{"lch":[61.1785977172963129,90.1064171712311435,124.683940112874311],"luv":[61.1785977172963129,-51.2749716142469723,74.09482911373847],"rgb":[0.2,0.66666666666666663,0],"xyz":[0.157393059993970491,0.294521282349826385,0.0485535951906325494],"hpluv":[124.683940112874311,186.894073454811917,61.1785977172963129],"hsluv":[124.683940112874311,100.000000000002302,61.1785977172963129]},"#33aa11":{"lch":[61.2139288108167818,88.7849168066190089,125.171000261233829],"luv":[61.2139288108167818,-51.1417680861379793,72.5760360544852148],"rgb":[0.2,0.66666666666666663,0.0666666666666666657],"xyz":[0.158404725493607623,0.294925948549681238,0.0538817001553881791],"hpluv":[125.171000261233829,184.046797309440706,61.2139288108167818],"hsluv":[125.171000261233829,97.729263879491441,61.2139288108167818]},"#33aa22":{"lch":[61.2793378507832642,86.3832953662584657,126.10140218084841],"luv":[61.2793378507832642,-50.8984310656693708,69.7955831939783593],"rgb":[0.2,0.66666666666666663,0.133333333333333331],"xyz":[0.160280083632084625,0.295676091805072039,0.0637585863513673717],"hpluv":[126.10140218084841,178.877217305585333,61.2793378507832642],"hsluv":[126.10140218084841,93.5778090815338146,61.2793378507832642]},"#33aa33":{"lch":[61.3867923044640946,82.5646745763668548,127.715012949240119],"luv":[61.3867923044640946,-50.5076466968263134,65.3138814728533],"rgb":[0.2,0.66666666666666663,0.2],"xyz":[0.163367834364542386,0.296911192098055166,0.0800207402089785219],"hpluv":[127.715012949240119,170.670578118814461,61.3867923044640946],"hsluv":[127.715012949240119,86.9017438736093339,61.3867923044640946]},"#33aa44":{"lch":[61.5414071550205364,77.3485744588317488,130.237764523164799],"luv":[61.5414071550205364,-49.9641607354037305,59.0456146789935588],"rgb":[0.2,0.66666666666666663,0.266666666666666663],"xyz":[0.167825829608761246,0.298694390195742732,0.10349951516186516],"hpluv":[130.237764523164799,159.486606837004757,61.5414071550205364],"hsluv":[130.237764523164799,87.1702267355774723,61.5414071550205364]},"#33aa55":{"lch":[61.7472402279952775,70.9239260559490106,134.00596147156574],"luv":[61.7472402279952775,-49.2732069613111605,51.0132763399638876],"rgb":[0.2,0.66666666666666663,0.333333333333333315],"xyz":[0.173788243648123231,0.301079355811487592,0.134901562435839062],"hpluv":[134.00596147156574,145.752006815371971,61.7472402279952775],"hsluv":[134.00596147156574,87.512567621072165,61.7472402279952775]},"#33aa66":{"lch":[62.0075227235960824,63.6834089970413046,139.532932917076664],"luv":[62.0075227235960824,-48.4490087982300253,41.3312246123130436],"rgb":[0.2,0.66666666666666663,0.4],"xyz":[0.181373239421631416,0.304113354120890911,0.174849206842983024],"hpluv":[139.532932917076664,130.323054003441854,62.0075227235960824],"hsluv":[139.532932917076664,87.9225345315596769,62.0075227235960824]},"#33aa77":{"lch":[62.3247799262656201,56.2910074750267,147.571074265173024],"luv":[62.3247799262656201,-47.5128361285441727,30.1862207898839152],"rgb":[0.2,0.66666666666666663,0.466666666666666674],"xyz":[0.190687252441833321,0.307838959328971706,0.223903008749380933],"hpluv":[147.571074265173024,114.608702125460667,62.3247799262656201],"hsluv":[147.571074265173024,88.3905588997681519,62.3247799262656201]},"#33aa88":{"lch":[62.7009046876535052,49.786919253891476,159.033972270618222],"luv":[62.7009046876535052,-46.4906641824602147,17.8144736848221363],"rgb":[0.2,0.66666666666666663,0.533333333333333326],"xyz":[0.201827669543777177,0.312295126169749304,0.2825758721529531],"hpluv":[159.033972270618222,100.758286424528237,62.7009046876535052],"hsluv":[159.033972270618222,88.9048289963628804,62.7009046876535052]},"#33aa99":{"lch":[63.1372095297142835,45.6309193537352797,174.368717478757389],"luv":[63.1372095297142835,-45.4107033068770818,4.47759156711236095],"rgb":[0.2,0.66666666666666663,0.6],"xyz":[0.214884633652849877,0.317517911813378462,0.351342549794071035],"hpluv":[174.368717478757389,91.7092542399893631,63.1372095297142835],"hsluv":[174.368717478757389,89.4524406674979,63.1372095297142835]},"#33aaaa":{"lch":[63.6344696573538897,45.3208071547743288,192.17705063006116],"luv":[63.6344696573538897,-44.3011098571894,-9.5596666563997],"rgb":[0.2,0.66666666666666663,0.66666666666666663],"xyz":[0.229942326618102433,0.323540988999479584,0.430646399411069636],"hpluv":[192.17705063006116,90.3742140686623117,63.6344696573538897],"hsluv":[192.17705063006116,90.0204628815860559,63.6344696573538897]},"#33aabb":{"lch":[64.1929631055189844,49.4317459506583177,209.109442205543161],"luv":[64.1929631055189844,-43.188124160558381,-24.0475245965695663],"rgb":[0.2,0.66666666666666663,0.733333333333333282],"xyz":[0.247079918725439052,0.330396025842414343,0.520904384509711327],"hpluv":[209.109442205543161,97.7142389408223835,64.1929631055189844],"hsluv":[209.109442205543161,90.5968047396532228,64.1929631055189844]},"#33aacc":{"lch":[64.8125111239688181,57.2242456540803062,222.641155468482083],"luv":[64.8125111239688181,-42.0947673064025736,-38.7639633693247347],"rgb":[0.2,0.66666666666666663,0.8],"xyz":[0.266372294169160806,0.338112976019903144,0.622510895179981483],"hpluv":[222.641155468482083,112.036763534802631,64.8125111239688181],"hsluv":[222.641155468482083,91.1708232266795875,64.8125111239688181]},"#33aadd":{"lch":[65.4925201274692199,67.4454999587780151,232.519386199289158],"luv":[65.4925201274692199,-41.0401119544032653,-53.5220017886062465],"rgb":[0.2,0.66666666666666663,0.866666666666666696],"xyz":[0.28789061971979435,0.34672030624015665,0.73584074307998748],"hpluv":[232.519386199289158,130.67743538587149,65.4925201274692199],"hsluv":[232.519386199289158,91.7336648454097485,65.4925201274692199]},"#33aaee":{"lch":[66.23202547083838,79.0605595482254,239.573325902293959],"luv":[66.23202547083838,-40.039054494753934,-68.1721804788773],"rgb":[0.2,0.66666666666666663,0.933333333333333348],"xyz":[0.311702799985969059,0.356245178346626667,0.861251559148510704],"hpluv":[239.573325902293959,151.471586303299148,66.23202547083838],"hsluv":[239.573325902293959,92.278374899274425,66.23202547083838]},"#33aaff":{"lch":[67.0297366624436,91.3892467801412778,244.667711773110682],"luv":[67.0297366624436,-39.1024682991195291,-82.6014007142609898],"rgb":[0.2,0.66666666666666663,1],"xyz":[0.33787384839580048,0.366713597710559391,0.999085747440292549],"hpluv":[244.667711773110682,173.00828905748071,67.0297366624436],"hsluv":[244.667711773110682,99.9999999999982094,67.0297366624436]},"#33bb00":{"lch":[66.705199456007648,99.1588934495857757,125.274120260315158],"luv":[66.705199456007648,-57.2631629787864327,80.9531735993793262],"rgb":[0.2,0.733333333333333282,0],"xyz":[0.191347557902569271,0.362430278167024944,0.0598717611601651684],"hpluv":[125.274120260315158,188.630237299381349,66.705199456007648],"hsluv":[125.274120260315158,100.000000000002331,66.705199456007648]},"#33bb11":{"lch":[66.7359690986495764,97.9890755357957914,125.670572132139952],"luv":[66.7359690986495764,-57.1397853669544133,79.6046723036925385],"rgb":[0.2,0.733333333333333282,0.0666666666666666657],"xyz":[0.192359223402206403,0.362834944366879797,0.0651998661249208],"hpluv":[125.670572132139952,186.318944611331347,66.7359690986495764],"hsluv":[125.670572132139952,98.1524285745497451,66.7359690986495764]},"#33bb22":{"lch":[66.7929473545782,95.8553977164860243,126.423299967719473],"luv":[66.7929473545782,-56.9137739802675,77.1302768224563],"rgb":[0.2,0.733333333333333282,0.133333333333333331],"xyz":[0.194234581540683404,0.363585087622270597,0.0750767523209],"hpluv":[126.423299967719473,182.106434833594022,66.7929473545782],"hsluv":[126.423299967719473,94.7659081903439073,66.7929473545782]},"#33bb33":{"lch":[66.8865907457163,92.4406335233364302,127.715012949240233],"luv":[66.8865907457163,-56.5491099236273058,73.126389853740946],"rgb":[0.2,0.733333333333333282,0.2],"xyz":[0.197322332273141166,0.364820187915253724,0.0913389061785111478],"hpluv":[127.715012949240233,175.373180985258983,66.8865907457163],"hsluv":[127.715012949240233,89.2962069049265637,66.8865907457163]},"#33bb44":{"lch":[67.0214179407225572,87.725631811763563,129.70178400392939],"luv":[67.0214179407225572,-56.0384119529137763,67.4943172612971409],"rgb":[0.2,0.733333333333333282,0.266666666666666663],"xyz":[0.201780327517360025,0.36660338601294129,0.114817681131397786],"hpluv":[129.70178400392939,166.093340387543549,67.0214179407225572],"hsluv":[129.70178400392939,89.4761749642590871,67.0214179407225572]},"#33bb55":{"lch":[67.2010629421400552,81.8171313208689099,132.60288320444127],"luv":[67.2010629421400552,-55.3830806540106479,60.2225651632978796],"rgb":[0.2,0.733333333333333282,0.333333333333333315],"xyz":[0.207742741556722,0.368988351628686151,0.146219728405371674],"hpluv":[132.60288320444127,154.492511096020365,67.2010629421400552],"hsluv":[132.60288320444127,89.7076242739581,67.2010629421400552]},"#33bb66":{"lch":[67.4284803792762091,74.9653268862145,136.738510871982356],"luv":[67.4284803792762091,-54.5922668909562248,51.3759148907695788],"rgb":[0.2,0.733333333333333282,0.4],"xyz":[0.215327737330230196,0.372022349938089469,0.186167372812515663],"hpluv":[136.738510871982356,141.07705768332076,67.4284803792762091],"hsluv":[136.738510871982356,89.9877463438330096,67.4284803792762091]},"#33bb77":{"lch":[67.7060530794905446,67.5982244112705,142.572908280802977],"luv":[67.7060530794905446,-53.681598162732449,41.0829156980295878],"rgb":[0.2,0.733333333333333282,0.466666666666666674],"xyz":[0.224641750350432101,0.375747955146170265,0.235221174718913573],"hpluv":[142.572908280802977,126.69139486293237,67.7060530794905446],"hsluv":[142.572908280802977,90.3115397167098,67.7060530794905446]},"#33bb88":{"lch":[68.0356563096068641,60.380187227113133,150.730801091974854],"luv":[68.0356563096068641,-52.67158330257773,29.5206931148449],"rgb":[0.2,0.733333333333333282,0.533333333333333326],"xyz":[0.235782167452375957,0.380204121986947863,0.293894038122485712],"hpluv":[150.730801091974854,112.615249481580875,68.0356563096068641],"hsluv":[150.730801091974854,90.6723452470342437,68.0356563096068641]},"#33bb99":{"lch":[68.4187011865960244,54.2829584497859159,161.862695711717],"luv":[68.4187011865960244,-51.585814888834193,16.8980259295610082],"rgb":[0.2,0.733333333333333282,0.6],"xyz":[0.248839131561448657,0.385426907630577,0.362660715763603647],"hpluv":[161.862695711717,100.676477021468287,68.4187011865960244],"hsluv":[161.862695711717,91.0624469223214,68.4187011865960244]},"#33bbaa":{"lch":[68.8561680799326439,50.5661966451060749,176.101011456941364],"luv":[68.8561680799326439,-50.4491601398581224,3.43838397135738649],"rgb":[0.2,0.733333333333333282,0.66666666666666663],"xyz":[0.263896824526701212,0.391449984816678143,0.441964565380602248],"hpluv":[176.101011456941364,93.1873079321678404,68.8561680799326439],"hsluv":[176.101011456941364,91.473675634614068,68.8561680799326439]},"#33bbbb":{"lch":[69.3486356756669835,50.4205674478029,192.177050630061103],"luv":[69.3486356756669835,-49.286127891295429,-10.635375839212843],"rgb":[0.2,0.733333333333333282,0.733333333333333282],"xyz":[0.281034416634037831,0.398305021659612901,0.532222550479243939],"hpluv":[192.177050630061103,92.2590830970113132,69.3486356756669835],"hsluv":[192.177050630061103,91.8979539795913922,69.3486356756669835]},"#33bbcc":{"lch":[69.8963087653012423,54.2786660468549442,207.559867588447844],"luv":[69.8963087653012423,-48.1195504219082224,-25.1133919457216273],"rgb":[0.2,0.733333333333333282,0.8],"xyz":[0.300326792077759586,0.406021971837101703,0.633829061149514095],"hpluv":[207.559867588447844,98.540384199822455,69.8963087653012423],"hsluv":[207.559867588447844,92.3277362004695306,69.8963087653012423]},"#33bbdd":{"lch":[70.4990463576295241,61.569428837921933,220.28187220447964],"luv":[70.4990463576295241,-46.9696505240293618,-39.807618580850594],"rgb":[0.2,0.733333333333333282,0.866666666666666696],"xyz":[0.321845117628393129,0.414629302057355209,0.747158909049520092],"hpluv":[220.28187220447964,110.820781636478685,70.4990463576295241],"hsluv":[220.28187220447964,92.7563200135089119,70.4990463576295241]},"#33bbee":{"lch":[71.1563908243766576,71.2672074810155181,229.953995552192254],"luv":[71.1563908243766576,-45.8534981630350487,-54.557048750410388],"rgb":[0.2,0.733333333333333282,0.933333333333333348],"xyz":[0.345657297894567894,0.424154174163825226,0.872569725118043316],"hpluv":[229.953995552192254,127.091105244163856,71.1563908243766576],"hsluv":[229.953995552192254,93.1780289437208893,71.1563908243766576]},"#33bbff":{"lch":[71.8675982303626597,82.4526478797043296,237.101125866277243],"luv":[71.8675982303626597,-44.7848112977892,-69.2297610814592161],"rgb":[0.2,0.733333333333333282,1],"xyz":[0.37182834630439926,0.43462259352775795,1.01040391340982527],"hpluv":[237.101125866277243,145.583046200088774,71.8675982303626597],"hsluv":[237.101125866277243,99.9999999999977831,71.8675982303626597]},"#33cc00":{"lch":[72.1534232831706532,108.011475964841438,125.713046635977918],"luv":[72.1534232831706532,-63.0491190384013507,87.6999859098336287],"rgb":[0.2,0.8,0],"xyz":[0.229571301212186191,0.438877764786259839,0.0726130089300371234],"hpluv":[125.713046635977918,189.955680955455,72.1534232831706532],"hsluv":[125.713046635977918,100.000000000002402,72.1534232831706532]},"#33cc11":{"lch":[72.1805088449519,106.967132064598133,126.040754358939225],"luv":[72.1805088449519,-62.9352412435677095,86.493483868665578],"rgb":[0.2,0.8,0.0666666666666666657],"xyz":[0.230582966711823323,0.439282430986114691,0.0779411138947927601],"hpluv":[126.040754358939225,188.048441784684599,72.1805088449519],"hsluv":[126.040754358939225,98.4728126855506645,72.1805088449519]},"#33cc22":{"lch":[72.2306742907645543,105.057034533260762,126.660198785960176],"luv":[72.2306742907645543,-62.7261976516662614,84.2757653960309199],"rgb":[0.2,0.8,0.133333333333333331],"xyz":[0.232458324850300324,0.440032574241505492,0.0878180000907719527],"hpluv":[126.660198785960176,184.562215611711281,72.2306742907645543],"hsluv":[126.660198785960176,95.6680740449206866,72.2306742907645543]},"#33cc33":{"lch":[72.31314692234902,101.984984863208481,127.715012949240304],"luv":[72.31314692234902,-62.3877173898115416,80.6765756365369668],"rgb":[0.2,0.8,0.2],"xyz":[0.235546075582758085,0.441267674534488619,0.104080153948383103],"hpluv":[127.715012949240304,178.960959976488198,72.31314692234902],"hsluv":[127.715012949240304,91.1230258822071306,72.31314692234902]},"#33cc44":{"lch":[72.4319472107582669,97.7091257880760651,129.318260791805528],"luv":[72.4319472107582669,-61.9111863445413135,75.5915224590797123],"rgb":[0.2,0.8,0.266666666666666663],"xyz":[0.240004070826976945,0.443050872632176185,0.127558928901269741],"hpluv":[129.318260791805528,171.176559629977817,72.4319472107582669],"hsluv":[129.318260791805528,91.2471619418673612,72.4319472107582669]},"#33cc55":{"lch":[72.590341240881628,92.2844112105744756,131.621023493746776],"luv":[72.590341240881628,-61.2953573189119396,68.9876200751215407],"rgb":[0.2,0.8,0.333333333333333315],"xyz":[0.24596648486633893,0.445435838247921045,0.158960976175243629],"hpluv":[131.621023493746776,161.32023063104279,72.590341240881628],"hsluv":[131.621023493746776,91.4078622695478,72.590341240881628]},"#33cc66":{"lch":[72.7910248315973405,85.8719567505974197,134.835055825888389],"luv":[72.7910248315973405,-60.5455878238572112,60.8951948123993319],"rgb":[0.2,0.8,0.4],"xyz":[0.253551480639847115,0.448469836557324364,0.198908620582387619],"hpluv":[134.835055825888389,149.696915507144809,72.7910248315973405],"hsluv":[134.835055825888389,91.6039613293452533,72.7910248315973405]},"#33cc77":{"lch":[73.0362204241858421,78.757716060864837,139.259917231121676],"luv":[73.0362204241858421,-59.6729854923348,51.3995393126768079],"rgb":[0.2,0.8,0.466666666666666674],"xyz":[0.262865493660049,0.452195441765405159,0.247962422488785528],"hpluv":[139.259917231121676,136.834039856532058,73.0362204241858421],"hsluv":[139.259917231121676,91.8328510325735294,73.0362204241858421]},"#33cc88":{"lch":[73.3277345291399,71.3846311778678597,145.306874573990314],"luv":[73.3277345291399,-58.6933246064594201,40.6307668527313197],"rgb":[0.2,0.8,0.533333333333333326],"xyz":[0.274005910761992877,0.456651608606182757,0.306635285892357667],"hpluv":[145.306874573990314,123.530949311180805,73.3277345291399],"hsluv":[145.306874573990314,92.0907512285691894,73.3277345291399]},"#33cc99":{"lch":[73.6669954969027714,64.400374936046,153.483372150156],"luv":[73.6669954969027714,-57.6257667092137709,28.7520312861295437],"rgb":[0.2,0.8,0.6],"xyz":[0.287062874871065576,0.461874394249811915,0.375401963533475602],"hpluv":[153.483372150156,110.931469165383049,73.6669954969027714],"hsluv":[153.483372150156,92.3730273510429072,73.6669954969027714]},"#33ccaa":{"lch":[74.0550811623464114,58.6991946004706691,164.236139418897579],"luv":[74.0550811623464114,-56.4914910882685106,15.9470022690160835],"rgb":[0.2,0.8,0.66666666666666663],"xyz":[0.302120567836318132,0.467897471435913037,0.454705813150474203],"hpluv":[164.236139418897579,100.581152280716978,74.0550811623464114],"hsluv":[164.236139418897579,92.6745296641919794,74.0550811623464114]},"#33ccbb":{"lch":[74.4927414449451106,55.3647402049724846,177.507530206592946],"luv":[74.4927414449451106,-55.3123621552270137,2.40770653799565881],"rgb":[0.2,0.8,0.733333333333333282],"xyz":[0.319258159943654751,0.474752508278847796,0.544963798249115894],"hpluv":[177.507530206592946,94.310193436061823,74.4927414449451106],"hsluv":[177.507530206592946,92.9899230693886,74.4927414449451106]},"#33cccc":{"lch":[74.9804187561532416,55.3552144916165361,192.177050630061132],"luv":[74.9804187561532416,-54.1097476482840918,-11.6762571422475752],"rgb":[0.2,0.8,0.8],"xyz":[0.338550535387376506,0.482469458456336597,0.646570308919386],"hpluv":[192.177050630061132,93.6806731785530928,74.9804187561532416],"hsluv":[192.177050630061132,93.3139795405001422,74.9804187561532416]},"#33ccdd":{"lch":[75.5182678303382602,59.0031963362726231,206.282454691493683],"luv":[75.5182678303382602,-52.9035678654544128,-26.1264173778571198],"rgb":[0.2,0.8,0.866666666666666696],"xyz":[0.360068860938010049,0.491076788676590104,0.759900156819392],"hpluv":[206.282454691493683,99.1431801932779564,75.5182678303382602],"hsluv":[206.282454691493683,93.6418135046530296,75.5182678303382602]},"#33ccee":{"lch":[76.106175853756767,65.8577115847402439,218.26062431545347],"luv":[76.106175853756767,-51.7116147040808585,-40.7817003063324606],"rgb":[0.2,0.8,0.933333333333333348],"xyz":[0.383881041204184759,0.500601660783060121,0.885310972887915271],"hpluv":[218.26062431545347,110.229350215344013,76.106175853756767],"hsluv":[218.26062431545347,93.969050662624,76.106175853756767]},"#33ccff":{"lch":[76.7437832939395435,75.0714180144803,227.674056146546604],"luv":[76.7437832939395435,-50.5491406549608,-55.5022718611574248],"rgb":[0.2,0.8,1],"xyz":[0.41005208961401618,0.511070080146992844,1.02314516117969712],"hpluv":[227.674056146546604,129.845560156838474,76.7437832939395435],"hsluv":[227.674056146546604,99.9999999999969731,76.7437832939395435]},"#33dd00":{"lch":[77.5280782787270653,116.686614644285086,126.047543424376144],"luv":[77.5280782787270653,-68.6649809221669187,94.3445092843369508],"rgb":[0.2,0.866666666666666696,0],"xyz":[0.272205291759361367,0.524145745880611358,0.0868243391124284419],"hpluv":[126.047543424376144,210.356208283509261,77.5280782787270653],"hsluv":[126.047543424376144,100.000000000002416,77.5280782787270653]},"#33dd11":{"lch":[77.5521415069474926,115.747372453695789,126.322097671746874],"luv":[77.5521415069474926,-68.5599423432795,93.2576459912042],"rgb":[0.2,0.866666666666666696,0.0666666666666666657],"xyz":[0.273216957258998472,0.524550412080466266,0.0921524440771840786],"hpluv":[126.322097671746874,208.932074165120611,77.5521415069474926],"hsluv":[126.322097671746874,98.7203227917640902,77.5521415069474926]},"#33dd22":{"lch":[77.5967156031793337,114.025807364398673,126.839335004613],"luv":[77.5967156031793337,-68.36681588768,91.2571270119929778],"rgb":[0.2,0.866666666666666696,0.133333333333333331],"xyz":[0.275092315397475529,0.525300555335857067,0.102029330273163271],"hpluv":[126.839335004613,206.31706664059891,77.5967156031793337],"hsluv":[126.839335004613,96.3665979525037102,77.5967156031793337]},"#33dd33":{"lch":[77.670013861504259,111.246421345384377,127.715012949240332],"luv":[77.670013861504259,-68.0532561222895,88.0029578668175247],"rgb":[0.2,0.866666666666666696,0.2],"xyz":[0.278180066129933234,0.526535655628840193,0.118291484130774421],"hpluv":[127.715012949240332,202.082466523340599,77.670013861504259],"hsluv":[127.715012949240332,92.5426273046004439,77.670013861504259]},"#33dd44":{"lch":[77.7756375941771267,107.354265763003397,129.034195217585733],"luv":[77.7756375941771267,-67.6100090567609726,83.3895979895470134],"rgb":[0.2,0.866666666666666696,0.266666666666666663],"xyz":[0.28263806137415215,0.52831885372652776,0.14177025908366106],"hpluv":[129.034195217585733,196.125875311323085,77.7756375941771267],"hsluv":[129.034195217585733,92.6304308505642098,77.7756375941771267]},"#33dd55":{"lch":[77.9165348137244,102.370875286307594,130.905664069221132],"luv":[77.9165348137244,-67.0340391276217105,77.3707548439410431],"rgb":[0.2,0.866666666666666696,0.333333333333333315],"xyz":[0.288600475413514135,0.530703819342272509,0.173172306357634975],"hpluv":[130.905664069221132,188.454179514464698,77.9165348137244],"hsluv":[130.905664069221132,92.7446831943234287,77.9165348137244]},"#33dd66":{"lch":[78.095166356878579,96.3992072274516261,133.476315028685519],"luv":[78.095166356878579,-66.3279238591037767,69.9529389705828777],"rgb":[0.2,0.866666666666666696,0.4],"xyz":[0.29618547118702232,0.533737817651675828,0.213119950764778909],"hpluv":[133.476315028685519,179.196222734944627,78.095166356878579],"hsluv":[133.476315028685519,92.8850067954864187,78.095166356878579]},"#33dd77":{"lch":[78.3135937781308513,89.6343875602499196,136.948304354896891],"luv":[78.3135937781308513,-65.499258897229538,61.1896275296294192],"rgb":[0.2,0.866666666666666696,0.466666666666666674],"xyz":[0.305499484207224226,0.537463422859756679,0.262173752671176818],"hpluv":[136.948304354896891,168.630388284117117,78.3135937781308513],"hsluv":[136.948304354896891,93.050064801238122,78.3135937781308513]},"#33dd88":{"lch":[78.5735314106716487,82.3820261839553609,141.59738099104726],"luv":[78.5735314106716487,-64.5599157920348432,51.1743638074698],"rgb":[0.2,0.866666666666666696,0.533333333333333326],"xyz":[0.316639901309168,0.541919589700534221,0.320846616074749],"hpluv":[141.59738099104726,157.233383580683977,78.5735314106716487],"hsluv":[141.59738099104726,93.2377028740416449,78.5735314106716487]},"#33dd99":{"lch":[78.8763801167060592,75.0869406053615762,147.781507566587862],"luv":[78.8763801167060592,-63.5251386535812799,40.0325543591259105],"rgb":[0.2,0.866666666666666696,0.6],"xyz":[0.329696865418240725,0.547142375344163434,0.389613293715866893],"hpluv":[147.781507566587862,145.760006886720333,78.8763801167060592],"hsluv":[147.781507566587862,93.4451205095912343,78.8763801167060592]},"#33ddaa":{"lch":[79.2232512041385633,68.3697583649377094,155.904677195463563],"luv":[79.2232512041385633,-62.4125308872686801,27.9123601138582131],"rgb":[0.2,0.866666666666666696,0.66666666666666663],"xyz":[0.344754558383493281,0.553165452530264501,0.468917143332865494],"hpluv":[155.904677195463563,135.355769729163313,79.2232512041385633],"hsluv":[155.904677195463563,93.6690625743759,79.2232512041385633]},"#33ddbb":{"lch":[79.6149850527770866,63.045401416642612,166.259028854183981],"luv":[79.6149850527770866,-61.2410113290283604,14.9753521221847095],"rgb":[0.2,0.866666666666666696,0.733333333333333282],"xyz":[0.361892150490829956,0.560020489373199259,0.559175128431507296],"hpluv":[166.259028854183981,127.658944712944631,79.6149850527770866],"hsluv":[166.259028854183981,93.9060163408359614,79.6149850527770866]},"#33ddcc":{"lch":[80.0521670478692613,60.0458591823856054,178.675787060338223],"luv":[80.0521670478692613,-60.0298228841068138,1.3876488942262355],"rgb":[0.2,0.866666666666666696,0.8],"xyz":[0.381184525934551655,0.567737439550688117,0.660781639101777452],"hpluv":[178.675787060338223,124.734340702728062,80.0521670478692613],"hsluv":[178.675787060338223,94.1523985056595905,80.0521670478692613]},"#33dddd":{"lch":[80.5351423549551555,60.1510343961145963,192.177050630061245],"luv":[80.5351423549551555,-58.7976638126828,-12.6878551809710149],"rgb":[0.2,0.866666666666666696,0.866666666666666696],"xyz":[0.402702851485185254,0.576344769770941623,0.774111487001783449],"hpluv":[192.177050630061245,128.603021497070955,80.5351423549551555],"hsluv":[192.177050630061245,94.4047190696773271,80.5351423549551555]},"#33ddee":{"lch":[81.0640304387754,63.6213092914002303,205.209077734070348],"luv":[81.0640304387754,-57.5619892131040913,-27.0977562499646396],"rgb":[0.2,0.866666666666666696,0.933333333333333348],"xyz":[0.426515031751359963,0.58586964187741164,0.899522303070306672],"hpluv":[205.209077734070348,140.476637056352985,81.0640304387754],"hsluv":[205.209077734070348,94.6597131799347835,81.0640304387754]},"#33ddff":{"lch":[81.6387398294900208,70.0938175080633528,216.50946924270437],"luv":[81.6387398294900208,-56.3385046754299452,-41.7027114680837769],"rgb":[0.2,0.866666666666666696,1],"xyz":[0.452686080161191384,0.596338061241344364,1.03735649136208852],"hpluv":[216.50946924270437,160.421433033358312,81.6387398294900208],"hsluv":[216.50946924270437,99.999999999996,81.6387398294900208]},"#33ee00":{"lch":[82.833762600699373,125.203353646442437,126.3077634478595],"luv":[82.833762600699373,-74.1357070958390239,100.894879442497455],"rgb":[0.2,0.933333333333333348,0],"xyz":[0.319384068099876184,0.618503298561642323,0.102550597892599626],"hpluv":[126.3077634478595,309.713105305240845,82.833762600699373],"hsluv":[126.3077634478595,100.000000000002302,82.833762600699373]},"#33ee11":{"lch":[82.85531245284119,124.353122892884315,126.540515263097504],"luv":[82.85531245284119,-74.0387382831010541,99.9097813362598544],"rgb":[0.2,0.933333333333333348,0.0666666666666666657],"xyz":[0.320395733599513288,0.618907964761497231,0.107878702857355263],"hpluv":[126.540515263097504,308.054239915702169,82.85531245284119],"hsluv":[126.540515263097504,98.9149262576223833,82.85531245284119]},"#33ee22":{"lch":[82.8952353009988,122.792060636983948,126.977870705292972],"luv":[82.8952353009988,-73.860225327277135,98.0946342573363808],"rgb":[0.2,0.933333333333333348,0.133333333333333331],"xyz":[0.322271091737990345,0.619658108016888,0.117755589053334456],"hpluv":[126.977870705292972,305.002845011722627,82.8952353009988],"hsluv":[126.977870705292972,96.9167682151396264,82.8952353009988]},"#33ee33":{"lch":[82.9608975691188846,120.264250910780831,127.715012949240375],"luv":[82.9608975691188846,-73.5697721383487391,95.1366316128687259],"rgb":[0.2,0.933333333333333348,0.2],"xyz":[0.325358842470448051,0.620893208309871159,0.134017742910945592],"hpluv":[127.715012949240375,300.046240285686,82.9608975691188846],"hsluv":[127.715012949240375,93.6639064416312834,82.9608975691188846]},"#33ee44":{"lch":[83.0555452014946241,116.707569363843,128.817932535493583],"luv":[83.0555452014946241,-73.1578713419028,90.9317469728687513],"rgb":[0.2,0.933333333333333348,0.266666666666666663],"xyz":[0.329816837714666966,0.622676406407558725,0.157496517863832231],"hpluv":[128.817932535493583,293.039720989359807,83.0555452014946241],"hsluv":[128.817932535493583,93.7274034182796356,83.0555452014946241]},"#33ee55":{"lch":[83.1818510898783643,112.121671621867506,130.367812557605703],"luv":[83.1818510898783643,-72.6203079673681202,85.4257579305358092],"rgb":[0.2,0.933333333333333348,0.333333333333333315],"xyz":[0.335779251754028951,0.625061372023303474,0.188898565137806146],"hpluv":[130.367812557605703,283.950089878719211,83.1818510898783643],"hsluv":[130.367812557605703,93.8103653792530139,83.1818510898783643]},"#33ee66":{"lch":[83.3420657578551,106.5703857928128,132.470647679843353],"luv":[83.3420657578551,-71.9576476395269,78.6088040502757224],"rgb":[0.2,0.933333333333333348,0.4],"xyz":[0.343364247527537136,0.628095370332706793,0.228846209544950108],"hpluv":[132.470647679843353,272.865433725808,83.3420657578551],"hsluv":[132.470647679843353,93.912785079345241,83.3420657578551]},"#33ee77":{"lch":[83.5380975272703523,100.188150337510052,135.268396470867572],"luv":[83.5380975272703523,-71.1748024762597851,70.5110839550557387],"rgb":[0.2,0.933333333333333348,0.466666666666666674],"xyz":[0.352678260547739042,0.631820975540787644,0.277900011451348],"hpluv":[135.268396470867572,260.019238129472967,83.5380975272703523],"hsluv":[135.268396470867572,94.0340074276028304,83.5380975272703523]},"#33ee88":{"lch":[83.7715600973053682,93.1909370684561651,138.951686086792108],"luv":[83.7715600973053682,-70.2805135444840801,61.1980405537673],"rgb":[0.2,0.933333333333333348,0.533333333333333326],"xyz":[0.363818677649682842,0.636277142381565186,0.336572874854920157],"hpluv":[138.951686086792108,245.83342468256393,83.7715600973053682],"hsluv":[138.951686086792108,94.1728069818675237,83.7715600973053682]},"#33ee99":{"lch":[84.0438031984902807,85.8935006436990278,143.770719305914184],"luv":[84.0438031984902807,-69.2867121669879822,50.7646035138469784],"rgb":[0.2,0.933333333333333348,0.6],"xyz":[0.376875641758755542,0.641499928025194399,0.405339552496038091],"hpluv":[143.770719305914184,230.989810482694878,84.0438031984902807],"hsluv":[143.770719305914184,94.3274826341768886,84.0438031984902807]},"#33eeaa":{"lch":[84.3559338989094698,78.7339796376561907,150.032255922422308],"luv":[84.3559338989094698,-68.2077782157370223,39.328596980513943],"rgb":[0.2,0.933333333333333348,0.66666666666666663],"xyz":[0.391933334724008098,0.647523005211295466,0.484643402113036692],"hpluv":[150.032255922422308,216.540119706931335,84.3559338989094698],"hsluv":[150.032255922422308,94.495967075681591,84.3559338989094698]},"#33eebb":{"lch":[84.7088326356722,72.2999891840671,158.051587623557367],"luv":[84.7088326356722,-67.0597412553262,27.0236847743774931],"rgb":[0.2,0.933333333333333348,0.733333333333333282],"xyz":[0.409070926831344772,0.654378042054230225,0.574901387211678383],"hpluv":[158.051587623557367,204.04938686040532,84.7088326356722],"hsluv":[158.051587623557367,94.6759444498571838,84.7088326356722]},"#33eecc":{"lch":[85.1031663228954,67.3294619946068451,168.005441410177127],"luv":[85.1031663228954,-65.8594808644086,13.992327638881461],"rgb":[0.2,0.933333333333333348,0.8],"xyz":[0.428363302275066471,0.662094992231719082,0.676507897881948539],"hpluv":[168.005441410177127,195.708498626929867,85.1031663228954],"hsluv":[168.005441410177127,94.8649680125767389,85.1031663228954]},"#33eedd":{"lch":[85.539399954776755,64.6250931348259314,179.663789762776076],"luv":[85.539399954776755,-64.6239805156479861,0.37921629457989664],"rgb":[0.2,0.933333333333333348,0.866666666666666696],"xyz":[0.44988162782570007,0.670702322451972588,0.789837745781954537],"hpluv":[179.663789762776076,194.233009793031641,85.539399954776755],"hsluv":[179.663789762776076,95.0605698730458926,85.539399954776755]},"#33eeee":{"lch":[86.0178075751720286,64.8282855412949601,192.177050630061217],"luv":[86.0178075751720286,-63.3696789602654533,-13.6744431219908602],"rgb":[0.2,0.933333333333333348,0.933333333333333348],"xyz":[0.47369380809187478,0.680227194558442605,0.91524856185047776],"hpluv":[192.177050630061217,202.327515221469156,86.0178075751720286],"hsluv":[192.177050630061217,95.2603564020327127,86.0178075751720286]},"#33eeff":{"lch":[86.538483142230433,68.1460620684978124,204.293044736593487],"luv":[86.538483142230433,-62.1119480142598803,-28.035543321245509],"rgb":[0.2,0.933333333333333348,1],"xyz":[0.499864856501706201,0.690695613922375329,1.05308275014225972],"hpluv":[204.293044736593487,221.878852364873978,86.538483142230433],"hsluv":[204.293044736593487,99.999999999993932,86.538483142230433]},"#33ff00":{"lch":[88.074762753062231,133.577745567808222,126.513803819973305],"luv":[88.074762753062231,-79.4809541468946,107.358241597361044],"rgb":[0.2,1,0],"xyz":[0.37123644052955,0.72220804342099143,0.119834722035823737],"hpluv":[126.513803819973305,497.272976699974663,88.074762753062231],"hsluv":[126.513803819973305,100.00000000000226,88.074762753062231]},"#33ff11":{"lch":[88.0941974462199,132.80363803677966,126.71317891025123],"luv":[88.0941974462199,-79.3912833442141448,106.460464045403725],"rgb":[0.2,1,0.0666666666666666657],"xyz":[0.37224810602918712,0.722612709620846339,0.125162827000579374],"hpluv":[126.71317891025123,495.277769978645495,88.0941974462199],"hsluv":[126.71317891025123,99.9999999999917861,88.0941974462199]},"#33ff22":{"lch":[88.1302050034733355,131.38040615815558,127.087058789859782],"luv":[88.1302050034733355,-79.2260405323659285,104.804797713872986],"rgb":[0.2,1,0.133333333333333331],"xyz":[0.374123464167664177,0.723362852876237139,0.135039713196558553],"hpluv":[127.087058789859782,491.602558840386564,88.1302050034733355],"hsluv":[127.087058789859782,99.9999999999915161,88.1302050034733355]},"#33ff33":{"lch":[88.1894367416410745,129.070276381710187,127.715012949240347],"luv":[88.1894367416410745,-78.9567203165017162,102.10275491931047],"rgb":[0.2,1,0.2],"xyz":[0.377211214900121883,0.724597953169220266,0.151301867054169703],"hpluv":[127.715012949240347,485.618062737129037,88.1894367416410745],"hsluv":[127.715012949240347,99.9999999999917577,88.1894367416410745]},"#33ff44":{"lch":[88.2748349985884,125.807640063387211,128.649544439126117],"luv":[88.2748349985884,-78.5738101086462137,98.2533391968394909],"rgb":[0.2,1,0.266666666666666663],"xyz":[0.381669210144340798,0.726381151266907832,0.174780642007056342],"hpluv":[128.649544439126117,477.126267833886629,88.2748349985884],"hsluv":[128.649544439126117,99.9999999999917151,88.2748349985884]},"#33ff55":{"lch":[88.3888340150102181,121.57774004888698,129.95306271607248],"luv":[88.3888340150102181,-78.0723424240601,93.1979410921456122],"rgb":[0.2,1,0.333333333333333315],"xyz":[0.387631624183702783,0.728766116882652581,0.206182689281030257],"hpluv":[129.95306271607248,466.04908765344419,88.3888340150102181],"hsluv":[129.95306271607248,99.999999999991644,88.3888340150102181]},"#33ff66":{"lch":[88.5334972733264,116.417510431790106,131.704600668064415],"luv":[88.5334972733264,-77.4514410423726929,86.9155395518881],"rgb":[0.2,1,0.4],"xyz":[0.395216619957210968,0.7318001151920559,0.246130333688174219],"hpluv":[131.704600668064415,452.43688525451455,88.5334972733264],"hsluv":[131.704600668064415,99.9999999999913882,88.5334972733264]},"#33ff77":{"lch":[88.7105909437740081,110.419515958012653,134.007319384137503],"luv":[88.7105909437740081,-76.7139872603015505,79.419353202025647],"rgb":[0.2,1,0.466666666666666674],"xyz":[0.404530632977412874,0.735525720400136751,0.295184135594572128],"hpluv":[134.007319384137503,436.493157669178117,88.7105909437740081],"hsluv":[134.007319384137503,99.9999999999915,88.7105909437740081]},"#33ff88":{"lch":[88.9216276204312379,103.738746998712813,136.99719245927011],"luv":[88.9216276204312379,-75.8662497359534882,70.7533729221786558],"rgb":[0.2,1,0.533333333333333326],"xyz":[0.415671050079356674,0.739981887240914293,0.353856998998144268],"hpluv":[136.99719245927011,418.619650658891032,88.9216276204312379],"hsluv":[136.99719245927011,99.9999999999912603,88.9216276204312379]},"#33ff99":{"lch":[89.1678944508512359,96.6032590942606788,140.85189111032139],"luv":[89.1678944508512359,-74.9174292298428242,60.9882649796200695],"rgb":[0.2,1,0.6],"xyz":[0.428728014188429429,0.745204672884543506,0.422623676639262202],"hpluv":[140.85189111032139,399.492483487252343,89.1678944508512359],"hsluv":[140.85189111032139,99.9999999999913456,89.1678944508512359]},"#33ffaa":{"lch":[89.4504724790268426,89.3298939826383105,145.795546705853383],"luv":[89.4504724790268426,-73.8791171714821,50.2165909327964926],"rgb":[0.2,1,0.66666666666666663],"xyz":[0.44378570715368193,0.751227750070644573,0.501927526256260803],"hpluv":[145.795546705853383,380.184928602968114,89.4504724790268426],"hsluv":[145.795546705853383,99.9999999999912,89.4504724790268426]},"#33ffbb":{"lch":[89.7702508712150262,82.3444719603705,152.087330110215447],"luv":[89.7702508712150262,-72.7646918614874494,38.5475249625060314],"rgb":[0.2,1,0.733333333333333282],"xyz":[0.460923299261018604,0.758082786913579332,0.592185511354902605],"hpluv":[152.087330110215447,362.351543222333419,89.7702508712150262],"hsluv":[152.087330110215447,99.9999999999909761,89.7702508712150262]},"#33ffcc":{"lch":[90.127938152783571,76.1985663634222,159.968053619612647],"luv":[90.127938152783571,-71.5886883295869723,26.1013643147272063],"rgb":[0.2,1,0.8],"xyz":[0.480215674704740358,0.765799737091068189,0.693792022025172761],"hpluv":[159.968053619612647,348.464440630653087,90.127938152783571],"hsluv":[159.968053619612647,99.999999999990834,90.127938152783571]},"#33ffdd":{"lch":[90.5240717550146314,71.5577226375514357,169.529475161807255],"luv":[90.5240717550146314,-70.3661811113599924,13.0041618290463337],"rgb":[0.2,1,0.866666666666666696],"xyz":[0.501734000255373846,0.774407067311321695,0.807121869925178759],"hpluv":[169.529475161807255,342.013155745428833,90.5240717550146314],"hsluv":[169.529475161807255,99.9999999999904077,90.5240717550146314]},"#33ffee":{"lch":[90.9590266887802,69.1149718308150511,180.51167449693034],"luv":[90.9590266887802,-69.1122158161064561,-0.61721646306864264],"rgb":[0.2,1,0.933333333333333348],"xyz":[0.525546180521548667,0.783931939417791712,0.932532685993702],"hpluv":[180.51167449693034,347.442342228089899,90.9590266887802],"hsluv":[180.51167449693034,99.9999999999901519,90.9590266887802]},"#33ffff":{"lch":[91.4330238629877243,69.4028497051403122,192.177050630061132],"luv":[91.4330238629877243,-67.8413175363212702,-14.6393709608822622],"rgb":[0.2,1,1],"xyz":[0.55171722893138,0.794400358781724436,1.07036687428548372],"hpluv":[192.177050630061132,369.590917988860895,91.4330238629877243],"hsluv":[192.177050630061132,99.9999999999897256,91.4330238629877243]},"#22aa00":{"lch":[60.8595101229647923,91.9296409673314656,126.268252023172565],"luv":[60.8595101229647923,-54.3824975763784053,74.1188427172042594],"rgb":[0.133333333333333331,0.66666666666666663,0],"xyz":[0.150337683054585614,0.290883353615456,0.0482228743965988915],"hpluv":[126.268252023172565,191.675426474830772,60.8595101229647923],"hsluv":[126.268252023172565,100.000000000002288,60.8595101229647923]},"#22aa11":{"lch":[60.8951349805759605,90.6090655032342482,126.765726538166419],"luv":[60.8951349805759605,-54.2335583573106,72.5859759132132893],"rgb":[0.133333333333333331,0.66666666666666663,0.0666666666666666657],"xyz":[0.151349348554222746,0.291288019815310828,0.0535509793613545212],"hpluv":[126.765726538166419,188.811473003651798,60.8951349805759605],"hsluv":[126.765726538166419,97.6988909499644365,60.8951349805759605]},"#22aa22":{"lch":[60.9610867967894592,88.21068058626,127.715012949240347],"luv":[60.9610867967894592,-53.9615024560723953,69.7802294505720226],"rgb":[0.133333333333333331,0.66666666666666663,0.133333333333333331],"xyz":[0.153224706692699747,0.292038163070701628,0.0634278655573337208],"hpluv":[127.715012949240347,183.614848439340193,60.9610867967894592],"hsluv":[127.715012949240347,93.4926845994439475,60.9610867967894592]},"#22aa33":{"lch":[61.0694299105106495,84.4016098893730629,129.358188857231823],"luv":[61.0694299105106495,-53.5246691509727626,65.259034196016259],"rgb":[0.133333333333333331,0.66666666666666663,0.2],"xyz":[0.156312457425157481,0.293273263363684755,0.0796900194149448571],"hpluv":[129.358188857231823,175.374397166590711,61.0694299105106495],"hsluv":[129.358188857231823,93.5882360519160699,61.0694299105106495]},"#22aa44":{"lch":[61.2253168994486145,79.2082340196825214,131.918899994809664],"luv":[61.2253168994486145,-52.917281977470445,58.938150671985575],"rgb":[0.133333333333333331,0.66666666666666663,0.266666666666666663],"xyz":[0.160770452669376368,0.295056461461372321,0.103168794367831496],"hpluv":[131.918899994809664,164.164260791814144,61.2253168994486145],"hsluv":[131.918899994809664,93.7213426507132397,61.2253168994486145]},"#22aa55":{"lch":[61.4328316402448422,72.8294169380228169,135.724592815827151],"luv":[61.4328316402448422,-52.1453123372646488,50.8428005993127883],"rgb":[0.133333333333333331,0.66666666666666663,0.333333333333333315],"xyz":[0.166732866708738381,0.297441427077117182,0.134570841641805411],"hpluv":[135.724592815827151,150.433869175471955,61.4328316402448422],"hsluv":[135.724592815827151,93.8909627694616802,61.4328316402448422]},"#22aa66":{"lch":[61.695221435526193,65.6694032551541511,141.26425661379642],"luv":[61.695221435526193,-51.2247747289881588,41.0912761769754056],"rgb":[0.133333333333333331,0.66666666666666663,0.4],"xyz":[0.174317862482246538,0.3004754253865205,0.174518486048949373],"hpluv":[141.26425661379642,135.067502346464636,61.695221435526193],"hsluv":[141.26425661379642,94.0939374356695737,61.695221435526193]},"#22aa77":{"lch":[62.015018576984005,58.3994247120946,149.232117680428786],"luv":[62.015018576984005,-50.1795183581889,29.8748848373309741],"rgb":[0.133333333333333331,0.66666666666666663,0.466666666666666674],"xyz":[0.183631875502448472,0.304201030594601296,0.223572287955347282],"hpluv":[149.232117680428786,119.495353216490457,62.015018576984005],"hsluv":[149.232117680428786,94.3254538020573534,62.015018576984005]},"#22aa88":{"lch":[62.3941144695078265,52.0455462506657582,160.428514439052776],"luv":[62.3941144695078265,-49.0385773736463904,17.4343572780611709],"rgb":[0.133333333333333331,0.66666666666666663,0.533333333333333326],"xyz":[0.194772292604392272,0.308657197435378894,0.282245151358919477],"hpluv":[160.428514439052776,105.847175197261592,62.3941144695078265],"hsluv":[160.428514439052776,94.5795977554836753,62.3941144695078265]},"#22aa99":{"lch":[62.8338123759312168,48.0032947436357915,175.177921691935865],"luv":[62.8338123759312168,-47.8333890460383486,4.03524455451089725],"rgb":[0.133333333333333331,0.66666666666666663,0.6],"xyz":[0.207829256713465,0.313879983079008051,0.351011829000037356],"hpluv":[175.177921691935865,96.9431131493944918,62.8338123759312168],"hsluv":[175.177921691935865,94.8499327714938119,62.8338123759312168]},"#22aaaa":{"lch":[63.334871160235295,47.6677335272966047,192.177050630061132],"luv":[63.334871160235295,-46.595231466735612,-10.0547115418935782],"rgb":[0.133333333333333331,0.66666666666666663,0.66666666666666663],"xyz":[0.222886949678717528,0.319903060265109174,0.430315678617035957],"hpluv":[192.177050630061132,95.5038628742744748,63.334871160235295],"hsluv":[192.177050630061132,95.1300327368807075,63.334871160235295]},"#22aabb":{"lch":[63.8975462810157211,51.5875561200845425,208.460106210027732],"luv":[63.8975462810157211,-45.3531553267970224,-24.5838818811491713],"rgb":[0.133333333333333331,0.66666666666666663,0.733333333333333282],"xyz":[0.240024541786054202,0.326758097108043932,0.520573663715677704],"hpluv":[208.460106210027732,102.447201536891086,63.8975462810157211],"hsluv":[208.460106210027732,95.4139121453229393,63.8975462810157211]},"#22aacc":{"lch":[64.5216311304052681,59.1142282054053112,221.706391964203618],"luv":[64.5216311304052681,-44.1325525375176184,-39.3295027027292079],"rgb":[0.133333333333333331,0.66666666666666663,0.8],"xyz":[0.259316917229775901,0.334475047285532734,0.62218017438594786],"hpluv":[221.706391964203618,116.258847224370101,64.5216311304052681],"hsluv":[221.706391964203618,95.6963242429470853,64.5216311304052681]},"#22aadd":{"lch":[65.2065000175346796,69.0826091468118619,231.553565124642319],"luv":[65.2065000175346796,-42.9543721979751538,-54.1047945713593279],"rgb":[0.133333333333333331,0.66666666666666663,0.866666666666666696],"xyz":[0.2808352427804095,0.34308237750578624,0.735510022285953857],"hpluv":[231.553565124642319,134.436491082611866,65.2065000175346796],"hsluv":[231.553565124642319,95.9729250289437,65.2065000175346796]},"#22aaee":{"lch":[65.951153016283925,80.4876559434330687,238.683318882444183],"luv":[65.951153016283925,-41.8348964739996418,-68.7612114224159825],"rgb":[0.133333333333333331,0.66666666666666663,0.933333333333333348],"xyz":[0.304647423046584209,0.352607249612256257,0.86092083835447708],"hpluv":[238.683318882444183,154.862481256054423,65.951153016283925],"hsluv":[238.683318882444183,96.2403212652285305,65.951153016283925]},"#22aaff":{"lch":[66.7542622474436911,92.6475815050926741,243.881654723446388],"luv":[66.7542622474436911,-40.785937465112724,-83.187028218555227],"rgb":[0.133333333333333331,0.66666666666666663,1],"xyz":[0.33081847145641563,0.363075668976189,0.998755026646258925],"hpluv":[243.881654723446388,176.114215620682756,66.7542622474436911],"hsluv":[243.881654723446388,99.9999999999982521,66.7542622474436911]},"#22bb00":{"lch":[66.4275479271698117,100.802558180890344,126.547308547849156],"luv":[66.4275479271698117,-60.0265444602621798,80.9812922592122533],"rgb":[0.133333333333333331,0.733333333333333282,0],"xyz":[0.184292180963184393,0.358792349432654534,0.0595410403661315105],"hpluv":[126.547308547849156,192.558484368086766,66.4275479271698117],"hsluv":[126.547308547849156,100.000000000002402,66.4275479271698117]},"#22bb11":{"lch":[66.4585250929908682,99.6331665050874449,126.950333401467461],"luv":[66.4585250929908682,-59.891738470658936,79.6225315522727612],"rgb":[0.133333333333333331,0.733333333333333282,0.0666666666666666657],"xyz":[0.185303846462821525,0.359197015632509387,0.0648691453308871402],"hpluv":[126.950333401467461,190.235936561387632,66.4585250929908682],"hsluv":[126.950333401467461,98.1323711753334464,66.4585250929908682]},"#22bb22":{"lch":[66.5158870179191553,97.5011623585143496,127.715012949240375],"luv":[66.5158870179191553,-59.6448091899021904,77.1295883430057785],"rgb":[0.133333333333333331,0.733333333333333282,0.133333333333333331],"xyz":[0.187179204601298527,0.359947158887900187,0.0747460315268663328],"hpluv":[127.715012949240375,186.004620566556611,66.5158870179191553],"hsluv":[127.715012949240375,94.7095045552014341,66.5158870179191553]},"#22bb33":{"lch":[66.6101592341861561,94.091611241079562,129.025604662043349],"luv":[66.6101592341861561,-59.2464412491434089,73.0964465979998721],"rgb":[0.133333333333333331,0.733333333333333282,0.2],"xyz":[0.19026695533375626,0.361182259180883314,0.091008185384477483],"hpluv":[129.025604662043349,179.246118589082698,66.6101592341861561],"hsluv":[129.025604662043349,94.7728361420699628,66.6101592341861561]},"#22bb44":{"lch":[66.7458880420052907,89.3893698914418735,131.03732282887168],"luv":[66.7458880420052907,-58.6886365964374903,67.424797990356],"rgb":[0.133333333333333331,0.733333333333333282,0.266666666666666663],"xyz":[0.194724950577975148,0.36296545727857088,0.114486960337364121],"hpluv":[131.03732282887168,169.941985039444177,66.7458880420052907],"hsluv":[131.03732282887168,94.8616428317247511,66.7458880420052907]},"#22bb55":{"lch":[66.9267274999506,83.5071173210959472,133.96576260666626],"luv":[66.9267274999506,-57.9730125462468777,60.1046459068846488],"rgb":[0.133333333333333331,0.733333333333333282,0.333333333333333315],"xyz":[0.200687364617337161,0.365350422894315741,0.145889007611338023],"hpluv":[133.96576260666626,158.330006142604873,66.9267274999506],"hsluv":[133.96576260666626,94.9758066387206128,66.9267274999506]},"#22bb66":{"lch":[67.1556458878222315,76.7025221245859541,138.121353671725132],"luv":[67.1556458878222315,-57.1096598103208919,51.2031606116460054],"rgb":[0.133333333333333331,0.733333333333333282,0.4],"xyz":[0.208272360390845318,0.368384421203719059,0.185836652018481985],"hpluv":[138.121353671725132,144.932719296840418,67.1556458878222315],"hsluv":[138.121353671725132,95.1139083236691363,67.1556458878222315]},"#22bb77":{"lch":[67.4350338747947831,69.4107315991336407,143.945643371462126],"luv":[67.4350338747947831,-56.1157304677756557,40.8518598743670935],"rgb":[0.133333333333333331,0.733333333333333282,0.466666666666666674],"xyz":[0.217586373411047251,0.372110026411799855,0.234890453924879894],"hpluv":[143.945643371462126,130.611184627207962,67.4350338747947831],"hsluv":[143.945643371462126,95.2734443978328471,67.4350338747947831]},"#22bb88":{"lch":[67.7667691572368653,62.2973404800357571,152.016434409622292],"luv":[67.7667691572368653,-55.0136735570032656,29.2310511724943218],"rgb":[0.133333333333333331,0.733333333333333282,0.533333333333333326],"xyz":[0.228726790512991052,0.376566193252577452,0.293563317328452089],"hpluv":[152.016434409622292,116.65196328010299,67.7667691572368653],"hsluv":[152.016434409622292,95.4510958201536823,67.7667691572368653]},"#22bb99":{"lch":[68.1522602188863402,56.3167420179958214,162.907285030510934],"luv":[68.1522602188863402,-53.8292536917802948,16.552549003324323],"rgb":[0.133333333333333331,0.733333333333333282,0.6],"xyz":[0.241783754622063779,0.38178897889620661,0.362329994969569968],"hpluv":[162.907285030510934,104.856796539193,68.1522602188863402],"hsluv":[162.907285030510934,95.6430286983925555,68.1522602188863402]},"#22bbaa":{"lch":[68.5924801056558238,52.6774965449754617,176.68900923381463],"luv":[68.5924801056558238,-52.5895649511659542,3.04241688349887474],"rgb":[0.133333333333333331,0.733333333333333282,0.66666666666666663],"xyz":[0.256841447587316307,0.387812056082307732,0.441633844586568569],"hpluv":[176.68900923381463,97.4513697523019,68.5924801056558238],"hsluv":[176.68900923381463,95.8451953079369616,68.5924801056558238]},"#22bbbb":{"lch":[69.087995915136645,52.5025293878432677,192.177050630061075],"luv":[69.087995915136645,-51.3212466461144174,-11.0745309069971647],"rgb":[0.133333333333333331,0.733333333333333282,0.733333333333333282],"xyz":[0.273979039694653,0.394667092925242491,0.531891829685210316],"hpluv":[192.177050630061075,96.4310638968393903,69.087995915136645],"hsluv":[192.177050630061075,96.05360442262905,69.087995915136645]},"#22bbcc":{"lch":[69.6389970716796824,56.2104265974936,207.07804051519031],"luv":[69.6389970716796824,-50.0490518690675117,-25.5871933841835393],"rgb":[0.133333333333333331,0.733333333333333282,0.8],"xyz":[0.293271415138374736,0.402384043102731292,0.633498340355480472],"hpluv":[207.07804051519031,102.424464009042,69.6389970716796824],"hsluv":[207.07804051519031,96.2645382772070519,69.6389970716796824]},"#22bbdd":{"lch":[70.2453239794146924,63.2897284454122868,219.558412279776348],"luv":[70.2453239794146924,-48.7948432782897541,-40.3069844585422956],"rgb":[0.133333333333333331,0.733333333333333282,0.866666666666666696],"xyz":[0.314789740689008224,0.410991373322984799,0.746828188255486469],"hpluv":[219.558412279776348,114.328666738486675,70.2453239794146924],"hsluv":[219.558412279776348,96.4747049793171101,70.2453239794146924]},"#22bbee":{"lch":[70.9064977498674409,72.7777709471329644,229.176572531806158],"luv":[70.9064977498674409,-47.5770176148035588,-55.072963774560229],"rgb":[0.133333333333333331,0.733333333333333282,0.933333333333333348],"xyz":[0.338601920955183,0.420516245429454816,0.872239004324009692],"hpluv":[229.176572531806158,130.242295294742263,70.9064977498674409],"hsluv":[229.176572531806158,96.6813261778791286,70.9064977498674409]},"#22bbff":{"lch":[71.621751136046143,83.782469360031385,236.362391595167765],"luv":[71.621751136046143,-46.4103062114400586,-69.7537500742789121],"rgb":[0.133333333333333331,0.733333333333333282,1],"xyz":[0.364772969365014355,0.43098466479338754,1.01007319261579154],"hpluv":[236.362391595167765,148.438838585801221,71.621751136046143],"hsluv":[236.362391595167765,99.9999999999977405,71.621751136046143]},"#22cc00":{"lch":[71.9091745039523431,109.499123564337054,126.755635680122666],"luv":[71.9091745039523431,-65.5246489265194185,87.7301455852794732],"rgb":[0.133333333333333331,0.8,0],"xyz":[0.222515924272801313,0.435239836051889428,0.0722822881360034586],"hpluv":[126.755635680122666,193.226045742870838,71.9091745039523431],"hsluv":[126.755635680122666,100.000000000002288,71.9091745039523431]},"#22cc11":{"lch":[71.9364107151438077,108.454952609175663,127.087674169957992],"luv":[71.9364107151438077,-65.4022833696805,86.5159989567857508],"rgb":[0.133333333333333331,0.8,0.0666666666666666657],"xyz":[0.223527589772438445,0.435644502251744281,0.0776103931007591],"hpluv":[127.087674169957992,191.311003889673145,71.9364107151438077],"hsluv":[127.087674169957992,98.4591341389350418,71.9364107151438077]},"#22cc22":{"lch":[71.9868548113652196,106.54571101335867,127.715012949240403],"luv":[71.9868548113652196,-65.1776701905061771,84.2843985793322332],"rgb":[0.133333333333333331,0.8,0.133333333333333331],"xyz":[0.225402947910915447,0.436394645507135082,0.0874872792967382878],"hpluv":[127.715012949240403,187.811464536348922,71.9868548113652196],"hsluv":[127.715012949240403,95.6295101801496,71.9868548113652196]},"#22cc33":{"lch":[72.0697845089905229,103.47656324227728,128.782383231673776],"luv":[72.0697845089905229,-64.8140104316899084,80.6631464312780224],"rgb":[0.133333333333333331,0.8,0.2],"xyz":[0.22849069864337318,0.437629745800118208,0.103749433154349424],"hpluv":[128.782383231673776,182.191494825933376,72.0697845089905229],"hsluv":[128.782383231673776,95.6728206524347,72.0697845089905229]},"#22cc44":{"lch":[72.1892409305665126,99.2080881077430092,130.402545810446583],"luv":[72.1892409305665126,-64.3020931154350563,75.5479024657046381],"rgb":[0.133333333333333331,0.8,0.266666666666666663],"xyz":[0.232948693887592068,0.439412943897805774,0.127228208107236063],"hpluv":[130.402545810446583,174.38692971209278,72.1892409305665126],"hsluv":[130.402545810446583,95.7338579762306807,72.1892409305665126]},"#22cc55":{"lch":[72.3485056391290584,93.798910065649892,132.724941359454647],"luv":[72.3485056391290584,-63.6406395178356732,68.9064912128369116],"rgb":[0.133333333333333331,0.8,0.333333333333333315],"xyz":[0.23891110792695408,0.441797909513550635,0.158630255381209978],"hpluv":[132.724941359454647,164.515777124050715,72.3485056391290584],"hsluv":[132.724941359454647,95.8128514989610665,72.3485056391290584]},"#22cc66":{"lch":[72.5502856399570106,87.4149553130202577,135.957009780349864],"luv":[72.5502856399570106,-62.8354766726053597,60.7706942835425821],"rgb":[0.133333333333333331,0.8,0.4],"xyz":[0.246496103700462238,0.444831907822953954,0.19857789978835394],"hpluv":[135.957009780349864,152.89241471165704,72.5502856399570106],"hsluv":[135.957009780349864,95.9092114165347454,72.5502856399570106]},"#22cc77":{"lch":[72.7968107106438,80.347487444586676,140.388595454497391],"luv":[72.7968107106438,-61.8986076052927601,51.2277377519640922],"rgb":[0.133333333333333331,0.8,0.466666666666666674],"xyz":[0.255810116720664171,0.448557513031034749,0.247631701694751849],"hpluv":[140.388595454497391,140.055211607516185,72.7968107106438],"hsluv":[140.388595454497391,96.0216367005683651,72.7968107106438]},"#22cc88":{"lch":[73.0898911189871399,73.0433057087839899,146.410934307510047],"luv":[73.0898911189871399,-60.8470337434031379,40.4099368162836328],"rgb":[0.133333333333333331,0.8,0.533333333333333326],"xyz":[0.266950533822607972,0.453013679871812347,0.306304565098324044],"hpluv":[146.410934307510047,126.812607157634474,73.0898911189871399],"hsluv":[146.410934307510047,96.1482500942118463,73.0898911189871399]},"#22cc99":{"lch":[73.4309556061454316,66.1476907411168,154.494840416347301],"luv":[73.4309556061454316,-59.7013675833161201,28.4826912187770667],"rgb":[0.133333333333333331,0.8,0.6],"xyz":[0.280007497931680671,0.458236465515441505,0.375071242739441923],"hpluv":[154.494840416347301,114.307528246897718,73.4309556061454316],"hsluv":[154.494840416347301,96.2867563581127826,73.4309556061454316]},"#22ccaa":{"lch":[73.8210792378530272,60.5373530055450857,165.03572853292485],"luv":[73.8210792378530272,-58.4843517505691963,15.631753236079188],"rgb":[0.133333333333333331,0.8,0.66666666666666663],"xyz":[0.295065190896933227,0.464259542701542627,0.454375092356440524],"hpluv":[165.03572853292485,104.059650734936554,73.8210792378530272],"hsluv":[165.03572853292485,96.4346108423233233,73.8210792378530272]},"#22ccbb":{"lch":[74.2610062314211916,57.2561659312404601,177.947236116536601],"luv":[74.2610062314211916,-57.2194225987583565,2.05090580243043252],"rgb":[0.133333333333333331,0.8,0.733333333333333282],"xyz":[0.312202783004269901,0.471114579544477385,0.544633077455082271],"hpluv":[177.947236116536601,97.8364666306377302,74.2610062314211916],"hsluv":[177.947236116536601,96.5891828531354406,74.2610062314211916]},"#22cccc":{"lch":[74.7511706210643467,57.2167927817266,192.177050630061132],"luv":[74.7511706210643467,-55.9294412838427633,-12.0689259631595149],"rgb":[0.133333333333333331,0.8,0.8],"xyz":[0.3314951584479916,0.478831529721966187,0.646239588125352427],"hpluv":[192.177050630061132,97.128087782713564,74.7511706210643467],"hsluv":[192.177050630061132,96.747899952527,74.7511706210643467]},"#22ccdd":{"lch":[75.2917163799825602,60.7443465218384091,205.915913497891523],"luv":[75.2917163799825602,-54.6356779140553357,-26.5484148912282159],"rgb":[0.133333333333333331,0.8,0.866666666666666696],"xyz":[0.353013483998625199,0.487438859942219693,0.759569436025358424],"hpluv":[205.915913497891523,102.375961416692178,75.2917163799825602],"hsluv":[205.915913497891523,96.9083635301369,75.2917163799825602]},"#22ccee":{"lch":[75.8825178700112843,67.4282526949852894,217.691288579377613],"luv":[75.8825178700112843,-53.3570890727704779,-41.2260877015904583],"rgb":[0.133333333333333331,0.8,0.933333333333333348],"xyz":[0.376825664264799909,0.49696373204868971,0.884980252093881647],"hpluv":[217.691288579377613,112.755958051566466,75.8825178700112843],"hsluv":[217.691288579377613,97.0684311053177851,75.8825178700112843]},"#22ccff":{"lch":[76.5232010138481,76.4669756721874165,227.041443142980768],"luv":[76.5232010138481,-52.1098871667616095,-55.9621124325938553],"rgb":[0.133333333333333331,0.8,1],"xyz":[0.40299671267463133,0.507432151412622434,1.02281444038566338],"hpluv":[227.041443142980768,130.754689276117347,76.5232010138481],"hsluv":[227.041443142980768,99.999999999997,76.5232010138481]},"#22dd00":{"lch":[77.3111928538645543,118.038829613749726,126.914864539429317],"luv":[77.3111928538645543,-70.8973873693031607,94.3754510494695],"rgb":[0.133333333333333331,0.866666666666666696,0],"xyz":[0.265149914819976518,0.520507817146241,0.0864936183183947771],"hpluv":[126.914864539429317,210.347075729226248,77.3111928538645543],"hsluv":[126.914864539429317,100.000000000002288,77.3111928538645543]},"#22dd11":{"lch":[77.3353680300965323,117.099630973594756,127.192375056145337],"luv":[77.3353680300965323,-70.7859197567446756,93.2827805028547346],"rgb":[0.133333333333333331,0.866666666666666696,0.0666666666666666657],"xyz":[0.266161580319613622,0.520912483346095856,0.0918217232831504138],"hpluv":[127.192375056145337,208.941659016378082,77.3353680300965323],"hsluv":[127.192375056145337,98.7107326231664217,77.3353680300965323]},"#22dd22":{"lch":[77.3801492665193535,115.37848303888174,127.715012949240432],"luv":[77.3801492665193535,-70.5809801545768636,91.2716801027172409],"rgb":[0.133333333333333331,0.866666666666666696,0.133333333333333331],"xyz":[0.268036938458090679,0.521662626601486656,0.101698609479129606],"hpluv":[127.715012949240432,206.361699793513822,77.3801492665193535],"hsluv":[127.715012949240432,96.3395071146262154,77.3801492665193535]},"#22dd33":{"lch":[77.4537875025684315,112.600723810091978,128.59932725776207],"luv":[77.4537875025684315,-70.24826089977104,88.0005956974969195],"rgb":[0.133333333333333331,0.866666666666666696,0.2],"xyz":[0.271124689190548385,0.522897726894469783,0.117960763336740743],"hpluv":[128.59932725776207,202.185786680839726,77.4537875025684315],"hsluv":[128.59932725776207,96.3699377868481122,77.4537875025684315]},"#22dd44":{"lch":[77.5598997380018,108.71293616133481,129.930302741787841],"luv":[77.5598997380018,-69.7779723132927217,83.3638834787812],"rgb":[0.133333333333333331,0.866666666666666696,0.266666666666666663],"xyz":[0.2755826844347673,0.524680924992157349,0.141439538289627381],"hpluv":[129.930302741787841,196.316024449944422,77.5598997380018],"hsluv":[129.930302741787841,96.4129906320409162,77.5598997380018]},"#22dd55":{"lch":[77.7014460191091416,103.73899221962921,131.815952634500974],"luv":[77.7014460191091416,-69.1669361195931,77.3156740549574266],"rgb":[0.133333333333333331,0.866666666666666696,0.333333333333333315],"xyz":[0.281545098474129285,0.527065890607902099,0.172841585563601297],"hpluv":[131.815952634500974,188.764163413831653,77.7014460191091416],"hsluv":[131.815952634500974,96.4690009350202189,77.7014460191091416]},"#22dd66":{"lch":[77.880896240080375,97.784990294992113,134.401120560320578],"luv":[77.880896240080375,-68.4179393254247117,69.8633659756971923],"rgb":[0.133333333333333331,0.866666666666666696,0.4],"xyz":[0.28913009424763747,0.530099888917305417,0.212789229970745258],"hpluv":[134.401120560320578,179.664283635232721,77.880896240080375],"hsluv":[134.401120560320578,96.5377748783722467,77.880896240080375]},"#22dd77":{"lch":[78.1003183749745205,91.0497694522495635,137.883451987021573],"luv":[78.1003183749745205,-67.5390964016577584,61.0616980975421],"rgb":[0.133333333333333331,0.866666666666666696,0.466666666666666674],"xyz":[0.298444107267839376,0.533825494125386268,0.261843031877143195],"hpluv":[137.883451987021573,169.299836923025936,78.1003183749745205],"hsluv":[137.883451987021573,96.6186469084632478,78.1003183749745205]},"#22dd88":{"lch":[78.3614307373917285,83.8424849668191143,142.529576014285681],"luv":[78.3614307373917285,-66.5430534683674608,51.0057283108209205],"rgb":[0.133333333333333331,0.866666666666666696,0.533333333333333326],"xyz":[0.309584524369783176,0.538281660966163811,0.320515895280715335],"hpluv":[142.529576014285681,158.150702843881334,78.3614307373917285],"hsluv":[142.529576014285681,96.7105501690208,78.3614307373917285]},"#22dd99":{"lch":[78.665635872828048,76.6094810635621144,148.680389056502293],"luv":[78.665635872828048,-65.4460211356496586,39.8224924677044854],"rgb":[0.133333333333333331,0.866666666666666696,0.6],"xyz":[0.322641488478855876,0.543504446609793,0.389282572921833214],"hpluv":[148.680389056502293,146.968629494944878,78.665635872828048],"hsluv":[148.680389056502293,96.8121015046769884,78.665635872828048]},"#22ddaa":{"lch":[79.0140446006893882,69.96699558248838,156.711923446039975],"luv":[79.0140446006893882,-64.2666918031728613,27.6617569130368608],"rgb":[0.133333333333333331,0.866666666666666696,0.66666666666666663],"xyz":[0.337699181444108432,0.549527523795894091,0.46858642253883187],"hpluv":[156.711923446039975,136.880679993502099,79.0140446006893882],"hsluv":[156.711923446039975,96.9216963326973513,79.0140446006893882]},"#22ddbb":{"lch":[79.4074947696843196,64.7136880558744849,166.88262774299784],"luv":[79.4074947696843196,-63.0251268096233161,14.6865520944819572],"rgb":[0.133333333333333331,0.866666666666666696,0.733333333333333282],"xyz":[0.354836773551445106,0.556382560638828849,0.558844407637473561],"hpluv":[166.88262774299784,129.476815865977585,79.4074947696843196],"hsluv":[166.88262774299784,97.0376060255481,79.4074947696843196]},"#22ddcc":{"lch":[79.8465673347569123,61.7508733998812431,179.012513434233142],"luv":[79.8465673347569123,-61.7417023409151184,1.06421693934889783],"rgb":[0.133333333333333331,0.866666666666666696,0.8],"xyz":[0.374129148995166805,0.564099510816317706,0.660450918307743717],"hpluv":[179.012513434233142,126.735630147597362,79.8465673347569123],"hsluv":[179.012513434233142,97.1580701030331824,79.8465673347569123]},"#22dddd":{"lch":[80.3316012938198867,61.8272738566169,192.177050630061245],"luv":[80.3316012938198867,-60.4361886569793,-13.0414298740249546],"rgb":[0.133333333333333331,0.866666666666666696,0.866666666666666696],"xyz":[0.395647474545800404,0.572706841036571213,0.773780766207749715],"hpluv":[192.177050630061245,130.583134255532286,80.3316012938198867],"hsluv":[192.177050630061245,97.2813767637234434,80.3316012938198867]},"#22ddee":{"lch":[80.8627083873859078,65.1993477029452606,204.924336649163848],"luv":[80.8627083873859078,-59.1270126845314579,-27.4763773429615092],"rgb":[0.133333333333333331,0.866666666666666696,0.933333333333333348],"xyz":[0.419459654811975113,0.58223171314304123,0.899191582276272938],"hpluv":[204.924336649163848,142.193638870282854,80.8627083873859078],"hsluv":[204.924336649163848,97.405927410883,80.8627083873859078]},"#22ddff":{"lch":[81.4397880620905141,71.5324096951162574,216.054756332513932],"luv":[81.4397880620905141,-57.8307265123863,-42.1009822669203544],"rgb":[0.133333333333333331,0.866666666666666696,1],"xyz":[0.445630703221806534,0.592700132506974,1.03702577056805478],"hpluv":[216.054756332513932,161.676156351457934,81.4397880620905141],"hsluv":[216.054756332513932,99.9999999999961,81.4397880620905141]},"#22ee00":{"lch":[82.639607109796458,126.437751030410212,127.039022267349651],"luv":[82.639607109796458,-76.1608929793909368,100.92583052028732],"rgb":[0.133333333333333331,0.933333333333333348,0],"xyz":[0.312328691160491334,0.614865369827271913,0.102219877098565962],"hpluv":[127.039022267349651,308.746810598848469,82.639607109796458],"hsluv":[127.039022267349651,100.000000000002203,82.639607109796458]},"#22ee11":{"lch":[82.6612418520526262,125.587498690937579,127.273852876359626],"luv":[82.6612418520526262,-76.0589691017437,99.9362449095734462],"rgb":[0.133333333333333331,0.933333333333333348,0.0666666666666666657],"xyz":[0.313340356660128438,0.615270036027126821,0.107547982063321598],"hpluv":[127.273852876359626,307.111076239802628,82.6612418520526262],"hsluv":[127.273852876359626,98.9080389542438638,82.6612418520526262]},"#22ee22":{"lch":[82.7013218186993271,124.026614606467561,127.715012949240375],"luv":[82.7013218186993271,-75.8713392100017643,98.112899341636421],"rgb":[0.133333333333333331,0.933333333333333348,0.133333333333333331],"xyz":[0.315215714798605495,0.616020179282517621,0.117424868259300791],"hpluv":[127.715012949240375,304.102865014696874,82.7013218186993271],"hsluv":[127.715012949240375,96.8972824334497176,82.7013218186993271]},"#22ee33":{"lch":[82.7672420886773921,121.499708898279266,128.458265706389938],"luv":[82.7672420886773921,-75.5660658728233443,95.1417308591278754],"rgb":[0.133333333333333331,0.933333333333333348,0.2],"xyz":[0.318303465531063201,0.617255279575500748,0.133687022116911941],"hpluv":[128.458265706389938,299.21821405622444,82.7672420886773921],"hsluv":[128.458265706389938,96.9191735237910308,82.7672420886773921]},"#22ee44":{"lch":[82.8622607061112575,117.945648419515081,129.569612755667265],"luv":[82.8622607061112575,-75.1331770294334,90.918544261133448],"rgb":[0.133333333333333331,0.933333333333333348,0.266666666666666663],"xyz":[0.322761460775282116,0.619038477673188314,0.15716579706979858],"hpluv":[129.569612755667265,292.317409010606752,82.8622607061112575],"hsluv":[129.569612755667265,96.9502397298715692,82.8622607061112575]},"#22ee55":{"lch":[82.9890600071846194,113.365618159982461,131.129866929811442],"luv":[82.9890600071846194,-74.5682726576598185,85.3893207236587],"rgb":[0.133333333333333331,0.933333333333333348,0.333333333333333315],"xyz":[0.328723874814644101,0.621423443288933064,0.188567844343772495],"hpluv":[131.129866929811442,283.372415217622233,82.9890600071846194],"hsluv":[131.129866929811442,96.9908233877961266,82.9890600071846194]},"#22ee66":{"lch":[83.1498978333136,107.825536766413322,133.243989823694022],"luv":[83.1498978333136,-73.8719849852999175,78.5447402013449647],"rgb":[0.133333333333333331,0.933333333333333348,0.4],"xyz":[0.336308870588152287,0.624457441598336382,0.228515488750916429],"hpluv":[133.243989823694022,272.476761047092111,83.1498978333136],"hsluv":[133.243989823694022,97.0409162623008683,83.1498978333136]},"#22ee77":{"lch":[83.3466879629012709,101.462411308546436,136.05169958656856],"luv":[83.3466879629012709,-73.0495185954435726,70.415827350948561],"rgb":[0.133333333333333331,0.933333333333333348,0.466666666666666674],"xyz":[0.345622883608354192,0.628183046806417233,0.277569290657314338],"hpluv":[136.05169958656856,259.869348467080897,83.3466879629012709],"hsluv":[136.05169958656856,97.1001922741487391,83.3466879629012709]},"#22ee88":{"lch":[83.5810478428977746,94.494960715205238,139.739189865999265],"luv":[83.5810478428977746,-72.1101014829990277,61.0690663485185681],"rgb":[0.133333333333333331,0.933333333333333348,0.533333333333333326],"xyz":[0.356763300710298,0.632639213647194776,0.336242154060886533],"hpluv":[139.739189865999265,245.976403795765407,83.5810478428977746],"hsluv":[139.739189865999265,97.1680458209452098,83.5810478428977746]},"#22ee99":{"lch":[83.8543293451422187,87.2401092672494514,144.548413258572367],"luv":[83.8543293451422187,-71.0663081347816,50.6005584263049286],"rgb":[0.133333333333333331,0.933333333333333348,0.6],"xyz":[0.369820264819370692,0.637861999290824,0.405008831702004413],"hpluv":[144.548413258572367,231.480208097577446,83.8543293451422187],"hsluv":[144.548413258572367,97.2436385928483844,83.8543293451422187]},"#22eeaa":{"lch":[84.1676401551603846,80.1359348037682508,150.771943883792943],"luv":[84.1676401551603846,-69.9332745317766324,39.1293388665967328],"rgb":[0.133333333333333331,0.933333333333333348,0.66666666666666663],"xyz":[0.384877957784623248,0.643885076476925056,0.484312681319003],"hpluv":[150.771943883792943,217.42312560604816,84.1676401551603846],"hsluv":[150.771943883792943,97.3259536357082311,84.1676401551603846]},"#22eebb":{"lch":[84.5218598825754697,73.7647249619211181,158.704077932293842],"luv":[84.5218598825754697,-68.7278540770417834,26.7902355844945639],"rgb":[0.133333333333333331,0.933333333333333348,0.733333333333333282],"xyz":[0.402015549891959922,0.650740113319859814,0.57457066641764476],"hpluv":[158.704077932293842,205.339796192481117,84.5218598825754697],"hsluv":[158.704077932293842,97.4138533690930331,84.5218598825754697]},"#22eecc":{"lch":[84.9176532530853621,68.8500130904050422,168.499772582144715],"luv":[84.9176532530853621,-67.467774257192545,13.7267526869778429],"rgb":[0.133333333333333331,0.933333333333333348,0.8],"xyz":[0.421307925335681621,0.658457063497348671,0.676177177087914916],"hpluv":[168.499772582144715,197.354512375483154,84.9176532530853621],"hsluv":[168.499772582144715,97.5061375012374896,84.9176532530853621]},"#22eedd":{"lch":[85.3554818050158275,66.1709053937965166,179.926877690260085],"luv":[85.3554818050158275,-66.170851505859261,0.0844489448895467398],"rgb":[0.133333333333333331,0.933333333333333348,0.866666666666666696],"xyz":[0.44282625088631522,0.667064393717602178,0.789507024987920913],"hpluv":[179.926877690260085,196.075052309852396,85.3554818050158275],"hsluv":[179.926877690260085,97.6015969291830174,85.3554818050158275]},"#22eeee":{"lch":[85.8356149635753667,66.3470894225537648,192.177050630061245],"luv":[85.8356149635753667,-64.8543104533760868,-13.9948094114017536],"rgb":[0.133333333333333331,0.933333333333333348,0.933333333333333348],"xyz":[0.46663843115248993,0.676589265824072195,0.914917841056444137],"hpluv":[192.177050630061245,204.089886920334152,85.8356149635753667],"hsluv":[192.177050630061245,97.6990604766853608,85.8356149635753667]},"#22eeff":{"lch":[86.35814102124138,69.583621560973242,204.067857145017655],"luv":[86.35814102124138,-63.5342376580599435,-28.377474072755291],"rgb":[0.133333333333333331,0.933333333333333348,1],"xyz":[0.492809479562321351,0.687057685188004919,1.05275202934822598],"hpluv":[204.067857145017655,223.225826840448832,86.35814102124138],"hsluv":[204.067857145017655,99.9999999999940883,86.35814102124138]},"#22ff00":{"lch":[87.8997189713237361,134.70927246092154,127.137510750393233],"luv":[87.8997189713237361,-81.328032504319566,107.388729464162736],"rgb":[0.133333333333333331,1,0],"xyz":[0.364181063590165166,0.718570114686621,0.119504001241790073],"hpluv":[127.137510750393233,493.515561032875894,87.8997189713237361],"hsluv":[127.137510750393233,100.000000000002359,87.8997189713237361]},"#22ff11":{"lch":[87.9192191859362708,133.935112153716517,127.338384986715198],"luv":[87.9192191859362708,-81.2344832365115792,106.487431187561],"rgb":[0.133333333333333331,1,0.0666666666666666657],"xyz":[0.36519272908980227,0.718974780886475928,0.124832106206545709],"hpluv":[127.338384986715198,491.550771148457443,87.9192191859362708],"hsluv":[127.338384986715198,99.9999999999918572,87.9192191859362708]},"#22ff22":{"lch":[87.9553480404818089,132.511927889398493,127.71501294924046],"luv":[87.9553480404818089,-81.0620967295481449,104.825319015849075],"rgb":[0.133333333333333331,1,0.133333333333333331],"xyz":[0.367068087228279327,0.719724924141866729,0.134708992402524902],"hpluv":[127.71501294924046,487.932270281505453,87.9553480404818089],"hsluv":[127.71501294924046,99.9999999999918,87.9553480404818089]},"#22ff33":{"lch":[88.0147790356886,130.202284180175667,128.347396099003475],"luv":[88.0147790356886,-80.7811428723405101,102.112887345201102],"rgb":[0.133333333333333331,1,0.2],"xyz":[0.370155837960737033,0.720960024434849855,0.150971146260136052],"hpluv":[128.347396099003475,482.0420586134328,88.0147790356886],"hsluv":[128.347396099003475,99.9999999999918572,88.0147790356886]},"#22ff44":{"lch":[88.1004639745127349,126.941230298117631,129.288082018787549],"luv":[88.1004639745127349,-80.3817123888383,98.2489504424236486],"rgb":[0.133333333333333331,1,0.266666666666666663],"xyz":[0.374613833204955948,0.722743222532537422,0.174449921213022691],"hpluv":[129.288082018787549,473.688351575452941,88.1004639745127349],"hsluv":[129.288082018787549,99.9999999999917719,88.1004639745127349]},"#22ff55":{"lch":[88.2148445849976497,122.715034192366474,130.599301535876663],"luv":[88.2148445849976497,-79.8586444797792865,93.1749779645044498],"rgb":[0.133333333333333331,1,0.333333333333333315],"xyz":[0.380576247244317933,0.725128188148282171,0.205851968486996606],"hpluv":[130.599301535876663,462.799362736769183,88.2148445849976497],"hsluv":[130.599301535876663,99.9999999999917,88.2148445849976497]},"#22ff66":{"lch":[88.3599902775167863,117.562049147645283,132.359544385640646],"luv":[88.3599902775167863,-79.2110524978463104,86.8702743288911279],"rgb":[0.133333333333333331,1,0.4],"xyz":[0.388161243017826119,0.72816218645768549,0.24579961289414054],"hpluv":[132.359544385640646,449.432018335727776,88.3599902775167863],"hsluv":[132.359544385640646,99.999999999991644,88.3599902775167863]},"#22ff77":{"lch":[88.5376718023346427,111.576626717172417,134.67079586388752],"luv":[88.5376718023346427,-78.441973739162,79.3486004003085839],"rgb":[0.133333333333333331,1,0.466666666666666674],"xyz":[0.397475256038028,0.731887791665766341,0.294853414800538449],"hpluv":[134.67079586388752,433.796433649144,88.5376718023346427],"hsluv":[134.67079586388752,99.9999999999914593,88.5376718023346427]},"#22ff88":{"lch":[88.7494051061703,104.915784817642518,137.666744209541747],"luv":[88.7494051061703,-77.5579802767934581,70.6546643845003786],"rgb":[0.133333333333333331,1,0.533333333333333326],"xyz":[0.408615673139971824,0.736343958506543883,0.353526278204110644],"hpluv":[137.666744209541747,416.300130961303353,88.7494051061703],"hsluv":[137.666744209541747,99.9999999999915161,88.7494051061703]},"#22ff99":{"lch":[88.996479539624346,97.8095196496336143,141.520869213027311],"luv":[88.996479539624346,-76.5687003963823827,60.8599725082183696],"rgb":[0.133333333333333331,1,0.6],"xyz":[0.42167263724904458,0.741566744150173096,0.422292955845228524],"hpluv":[141.520869213027311,397.621886071746928,88.996479539624346],"hsluv":[141.520869213027311,99.9999999999913882,88.996479539624346]},"#22ffaa":{"lch":[89.2799772586324281,90.5758041558366784,146.450029989774293],"luv":[89.2799772586324281,-75.4862499862398,50.057989986528554],"rgb":[0.133333333333333331,1,0.66666666666666663],"xyz":[0.43673033021429708,0.747589821336274163,0.50159680546222718],"hpluv":[146.450029989774293,378.829469872945424,89.2799772586324281],"hsluv":[146.450029989774293,99.9999999999911893,89.2799772586324281]},"#22ffbb":{"lch":[89.6007875020334552,83.6393655876379825,152.701818689515648],"luv":[89.6007875020334552,-74.3245992165371661,38.3587985630895787],"rgb":[0.133333333333333331,1,0.733333333333333282],"xyz":[0.453867922321633754,0.754444858179208921,0.591854790560868871],"hpluv":[152.701818689515648,361.553698033539774,89.6007875020334552],"hsluv":[152.701818689515648,99.9999999999909903,89.6007875020334552]},"#22ffcc":{"lch":[89.9596178804745,77.5461751086222,160.50148390925915],"luv":[89.9596178804745,-73.0989125181650223,25.8835519710636532],"rgb":[0.133333333333333331,1,0.8],"xyz":[0.473160297765355509,0.762161808356697779,0.693461301231139],"hpluv":[160.50148390925915,348.207300802542932,89.9596178804745],"hsluv":[160.50148390925915,99.999999999990834,89.9596178804745]},"#22ffdd":{"lch":[90.3570039795250466,72.9493687180361,169.926987012389134],"luv":[90.3570039795250466,-71.8249031216737421,12.7590629719491808],"rgb":[0.133333333333333331,1,0.866666666666666696],"xyz":[0.494678623315989,0.770769138576951285,0.806791149131145],"hpluv":[169.926987012389134,342.16275562632859,90.3570039795250466],"hsluv":[169.926987012389134,99.9999999999906,90.3570039795250466]},"#22ffee":{"lch":[90.793318095908873,70.5238201303846637,180.720785562676866],"luv":[90.793318095908873,-70.5182397089352,-0.887171987837557796],"rgb":[0.133333333333333331,1,0.933333333333333348],"xyz":[0.518490803582163817,0.780294010683421302,0.932201965199668248],"hpluv":[180.720785562676866,347.681124246536797,90.793318095908873],"hsluv":[180.720785562676866,99.9999999999901661,90.793318095908873]},"#22ffff":{"lch":[91.2687776254429082,70.7867026205843786,192.177050630061217],"luv":[91.2687776254429082,-69.1940343982234225,-14.9312715999851058],"rgb":[0.133333333333333331,1,1],"xyz":[0.544661851991995127,0.790762430047354,1.0700361534914502],"hpluv":[192.177050630061217,369.384676987995,91.2687776254429082],"hsluv":[192.177050630061217,99.9999999999901803,91.2687776254429082]},"#11aa00":{"lch":[60.6644104521350869,93.0873160838275,127.211890667698796],"luv":[60.6644104521350869,-56.2958954857129186,74.1351506854346241],"rgb":[0.0666666666666666657,0.66666666666666663,0],"xyz":[0.146052570780394131,0.288673842599075969,0.0480220097587461675],"hpluv":[127.211890667698796,194.713406103753528,60.6644104521350869],"hsluv":[127.211890667698796,100.000000000002444,60.6644104521350869]},"#11aa11":{"lch":[60.7002167335786424,91.7670835597914447,127.715012949240375],"luv":[60.7002167335786424,-56.1370762813229547,72.5935692169401],"rgb":[0.0666666666666666657,0.66666666666666663,0.0666666666666666657],"xyz":[0.147064236280031263,0.289078508798930822,0.0533501147235018],"hpluv":[127.715012949240375,191.838607973199288,60.7002167335786424],"hsluv":[127.715012949240375,97.6800439707354826,60.7002167335786424]},"#11aa22":{"lch":[60.7665037483511696,89.3702510768545153,128.6744569519864],"luv":[60.7665037483511696,-55.8469935821418844,69.7721655488506229],"rgb":[0.0666666666666666657,0.66666666666666663,0.133333333333333331],"xyz":[0.148939594418508264,0.289828652054321623,0.063227000919481],"hpluv":[128.6744569519864,186.624241227076766,60.7665037483511696],"hsluv":[128.6744569519864,97.7012125574833163,60.7665037483511696]},"#11aa33":{"lch":[60.8753956347493101,85.5662665428975799,130.333267948257316],"luv":[60.8753956347493101,-55.3812688292774595,65.2265362636212274],"rgb":[0.0666666666666666657,0.66666666666666663,0.2],"xyz":[0.152027345150966,0.291063752347304749,0.0794891547770921469],"hpluv":[130.333267948257316,178.361088002118152,60.8753956347493101],"hsluv":[130.333267948257316,97.7352371443594876,60.8753956347493101]},"#11aa44":{"lch":[61.0320681383245898,80.3855440613202603,132.913331110856149],"luv":[61.0320681383245898,-54.7338170014505394,58.8731260464924233],"rgb":[0.0666666666666666657,0.66666666666666663,0.266666666666666663],"xyz":[0.156485340395184885,0.292846950444992316,0.102967929729978785],"hpluv":[132.913331110856149,167.131840298358668,61.0320681383245898],"hsluv":[132.913331110856149,97.7826211010278428,61.0320681383245898]},"#11aa55":{"lch":[61.2406211479126199,74.0326893716562466,136.73626291081149],"luv":[61.2406211479126199,-53.9110982897111626,50.7388665304739064],"rgb":[0.0666666666666666657,0.66666666666666663,0.333333333333333315],"xyz":[0.162447754434546898,0.295231916060737176,0.134369977003952701],"hpluv":[136.73626291081149,153.399260409180499,61.2406211479126199],"hsluv":[136.73626291081149,97.8429805383323412,61.2406211479126199]},"#11aa66":{"lch":[61.5043118059827236,66.9183608277608926,142.276062400218507],"luv":[61.5043118059827236,-52.9302802927860938,40.944504442006675],"rgb":[0.0666666666666666657,0.66666666666666663,0.4],"xyz":[0.170032750208055056,0.298265914370140495,0.174317621411096635],"hpluv":[142.276062400218507,138.063556785316223,61.5043118059827236],"hsluv":[142.276062400218507,97.9151756761398246,61.5043118059827236]},"#11aa77":{"lch":[61.8256765996828648,59.7171413308715628,150.193024237310198],"luv":[61.8256765996828648,-51.8168585560505335,29.6841731923518672],"rgb":[0.0666666666666666657,0.66666666666666663,0.466666666666666674],"xyz":[0.179346763228257,0.30199151957822129,0.223371423317494544],"hpluv":[150.193024237310198,122.565843528602272,61.8256765996828648],"hsluv":[150.193024237310198,97.9974781059027578,61.8256765996828648]},"#11aa88":{"lch":[62.2066058842594,53.445591933814967,161.225226782668472],"luv":[62.2066058842594,-50.6018085779820197,17.201403018159084],"rgb":[0.0666666666666666657,0.66666666666666663,0.533333333333333326],"xyz":[0.190487180330200789,0.306447686418998888,0.282044286721066739],"hpluv":[161.225226782668472,109.022142353571084,62.2066058842594],"hsluv":[161.225226782668472,98.0877698343988698,62.2066058842594]},"#11aa99":{"lch":[62.6483970296267643,49.4620441969123803,175.635441576327452],"luv":[62.6483970296267643,-49.3186051456987613,3.76417356400704],"rgb":[0.0666666666666666657,0.66666666666666663,0.6],"xyz":[0.203544144439273517,0.311670472062628046,0.350810964362184619],"hpluv":[175.635441576327452,100.184705161952,62.6483970296267643],"hsluv":[175.635441576327452,98.1837511724305756,62.6483970296267643]},"#11aaaa":{"lch":[63.1517986220979424,49.10533458105958,192.177050630061103],"luv":[63.1517986220979424,-48.0004871585874326,-10.3579494522848794],"rgb":[0.0666666666666666657,0.66666666666666663,0.66666666666666663],"xyz":[0.218601837404526045,0.317693549248729168,0.430114813979183219],"hpluv":[192.177050630061103,98.6693521766944741,63.1517986220979424],"hsluv":[192.177050630061103,98.283131385506934,63.1517986220979424]},"#11aabb":{"lch":[63.7170519890822931,52.9100997091116483,208.088870357104184],"luv":[63.7170519890822931,-46.6782604891356812,-24.9122188681885817],"rgb":[0.0666666666666666657,0.66666666666666663,0.733333333333333282],"xyz":[0.235739429511862719,0.324548586091663926,0.520372799077825],"hpluv":[208.088870357104184,105.371274370578277,63.7170519890822931],"hsluv":[208.088870357104184,98.3837818799450474,63.7170519890822931]},"#11aacc":{"lch":[64.3439331362496603,60.2774830024396,221.163749704229559],"luv":[64.3439331362496603,-45.3787880982832661,-39.6754401089704345],"rgb":[0.0666666666666666657,0.66666666666666663,0.8],"xyz":[0.255031804955584418,0.332265536269152728,0.621979309748095122],"hpluv":[221.163749704229559,118.873987633214512,64.3439331362496603],"hsluv":[221.163749704229559,98.4838416101877385,64.3439331362496603]},"#11aadd":{"lch":[65.0317963778061738,70.0923801470555,230.985682804055784],"luv":[65.0317963778061738,-44.1241742926816372,-54.4609860144708762],"rgb":[0.0666666666666666657,0.66666666666666663,0.866666666666666696],"xyz":[0.276550130506218,0.340872866489406234,0.735309157648101119],"hpluv":[230.985682804055784,136.767964522831733,65.0317963778061738],"hsluv":[230.985682804055784,98.5817742563244,65.0317963778061738]},"#11aaee":{"lch":[65.7796198544585877,81.3683973110580325,238.155251398024461],"luv":[65.7796198544585877,-42.9315457639956293,-69.1208974137644248],"rgb":[0.0666666666666666657,0.66666666666666663,0.933333333333333348],"xyz":[0.300362310772392727,0.350397738595876251,0.860719973716624343],"hpluv":[238.155251398024461,156.965326989669,65.7796198544585877],"hsluv":[238.155251398024461,98.676383948407647,65.7796198544585877]},"#11aaff":{"lch":[66.5860524818013317,93.423779787985481,243.412392023658668],"luv":[66.5860524818013317,-41.8132782993845566,-83.5443139162218529],"rgb":[0.0666666666666666657,0.66666666666666663,1],"xyz":[0.326533359182224148,0.360866157959809,0.998554162008406188],"hpluv":[243.412392023658668,178.038321821181739,66.5860524818013317],"hsluv":[243.412392023658668,99.9999999999982805,66.5860524818013317]},"#11bb00":{"lch":[66.2579979425279788,101.837028338191359,127.308350947248712],"luv":[66.2579979425279788,-61.7238643700190792,80.9996599251199285],"rgb":[0.0666666666666666657,0.733333333333333282,0],"xyz":[0.180007068688992911,0.356582838416274528,0.0593401757282787864],"hpluv":[127.308350947248712,195.032386644097869,66.2579979425279788],"hsluv":[127.308350947248712,100.000000000002416,66.2579979425279788]},"#11bb11":{"lch":[66.2891028676776,100.667761827005108,127.715012949240403],"luv":[66.2891028676776,-61.5819268253258301,79.6345688739434507],"rgb":[0.0666666666666666657,0.733333333333333282,0.0666666666666666657],"xyz":[0.181018734188630043,0.356987504616129381,0.0646682806930344162],"hpluv":[127.715012949240403,192.702610495025482,66.2891028676776],"hsluv":[127.715012949240403,98.1199752505464318,66.2891028676776]},"#11bb22":{"lch":[66.3467009890152895,98.5365229927559199,128.48627008521666],"luv":[66.3467009890152895,-61.3219466901703356,77.130183570569983],"rgb":[0.0666666666666666657,0.733333333333333282,0.133333333333333331],"xyz":[0.182894092327107044,0.357737647871520181,0.0745451668890136088],"hpluv":[128.48627008521666,188.459149582366734,66.3467009890152895],"hsluv":[128.48627008521666,98.1339007760711155,66.3467009890152895]},"#11bb33":{"lch":[66.4413603116689586,95.1297105779412107,129.807139434656818],"luv":[66.4413603116689586,-60.9025570517959949,73.0790009455219121],"rgb":[0.0666666666666666657,0.733333333333333282,0.2],"xyz":[0.185981843059564778,0.358972748164503308,0.0908073207466247589],"hpluv":[129.807139434656818,181.684126992490178,66.4413603116689586],"hsluv":[129.807139434656818,98.1563849168539093,66.4413603116689586]},"#11bb44":{"lch":[66.5776441235544,90.4345556189602888,131.832147550242752],"luv":[66.5776441235544,-60.3153845158839061,67.3829595721343679],"rgb":[0.0666666666666666657,0.733333333333333282,0.266666666666666663],"xyz":[0.190439838303783665,0.360755946262190874,0.114286095699511397],"hpluv":[131.832147550242752,172.363503065423913,66.5776441235544],"hsluv":[131.832147550242752,98.1879073212924567,66.5776441235544]},"#11bb55":{"lch":[66.7592187944261,84.5672269635890501,134.774448398028227],"luv":[66.7592187944261,-59.5621947933412841,60.0329978237906374],"rgb":[0.0666666666666666657,0.733333333333333282,0.333333333333333315],"xyz":[0.196402252343145678,0.363140911877935735,0.145688142973485313],"hpluv":[134.774448398028227,160.742297130584,66.7592187944261],"hsluv":[134.774448398028227,98.2284201297941451,66.7592187944261]},"#11bb66":{"lch":[66.9890609579081513,77.7896938122995749,138.938350400658521],"luv":[66.9890609579081513,-58.6536805127572336,51.0977712402284752],"rgb":[0.0666666666666666657,0.733333333333333282,0.4],"xyz":[0.203987248116653835,0.366174910187339053,0.185635787380629275],"hpluv":[138.938350400658521,147.352496635070423,66.9890609579081513],"hsluv":[138.938350400658521,98.2774122804504486,66.9890609579081513]},"#11bb77":{"lch":[67.2695660469751573,70.5410036497719375,144.751753478195667],"luv":[67.2695660469751573,-57.6079608572489548,40.7106379437464625],"rgb":[0.0666666666666666657,0.733333333333333282,0.466666666666666674],"xyz":[0.213301261136855769,0.369900515395419849,0.234689589287027184],"hpluv":[144.751753478195667,133.064539371584743,67.2695660469751573],"hsluv":[144.751753478195667,98.33398740837616,67.2695660469751573]},"#11bb88":{"lch":[67.6026131767386289,63.4868829762913904,152.765342955174589],"luv":[67.6026131767386289,-56.44870944299889,29.0538725863731493],"rgb":[0.0666666666666666657,0.733333333333333282,0.533333333333333326],"xyz":[0.224441678238799569,0.374356682236197447,0.293362452690599351],"hpluv":[152.765342955174589,119.168054047142519,67.6026131767386289],"hsluv":[152.765342955174589,98.3969602233376293,67.6026131767386289]},"#11bb99":{"lch":[67.9896091217093357,57.5709210660889568,163.510238814203348],"luv":[67.9896091217093357,-55.2030563361408468,16.3411604100414145],"rgb":[0.0666666666666666657,0.733333333333333282,0.6],"xyz":[0.237498642347872296,0.379579467879826604,0.362129130331717231],"hpluv":[163.510238814203348,107.448401728013394,67.9896091217093357],"hsluv":[163.510238814203348,98.464964167861,67.9896091217093357]},"#11bbaa":{"lch":[68.431522322705149,53.97217733059707,177.026074660918823],"luv":[68.431522322705149,-53.8994902384006807,2.80015675382041573],"rgb":[0.0666666666666666657,0.733333333333333282,0.66666666666666663],"xyz":[0.252556335313124825,0.385602545065927726,0.441432979948715831],"hpluv":[177.026074660918823,100.081328983600983,68.431522322705149],"hsluv":[177.026074660918823,98.5365589333087684,68.431522322705149]},"#11bbbb":{"lch":[68.9289126417652511,53.7759127589290102,192.177050630061103],"luv":[68.9289126417652511,-52.5659794775517426,-11.3431298424003177],"rgb":[0.0666666666666666657,0.733333333333333282,0.733333333333333282],"xyz":[0.269693927420461499,0.392457581908862485,0.531690965047357578],"hpluv":[192.177050630061103,98.9978332941913095,68.9289126417652511],"hsluv":[192.177050630061103,98.6103267315429122,68.9289126417652511]},"#11bbcc":{"lch":[69.4819599404948463,57.3930965266865485,206.799543430538137],"luv":[69.4819599404948463,-51.2284702417124365,-25.8768499940688805],"rgb":[0.0666666666666666657,0.733333333333333282,0.8],"xyz":[0.288986302864183253,0.400174532086351287,0.633297475717627734],"hpluv":[206.799543430538137,104.81584090136549,69.4819599404948463],"hsluv":[206.799543430538137,98.6849492658553658,69.4819599404948463]},"#11bbdd":{"lch":[70.0904930703520535,64.3454332007566876,219.135570681285316],"luv":[70.0904930703520535,-49.9098388382008054,-40.6121011637893901],"rgb":[0.0666666666666666657,0.733333333333333282,0.866666666666666696],"xyz":[0.310504628414816741,0.408781862306604793,0.746627323617633731],"hpluv":[219.135570681285316,116.492493254234162,70.0904930703520535],"hsluv":[219.135570681285316,98.7592614999562244,70.0904930703520535]},"#11bbee":{"lch":[70.7540199625255184,73.7064384587933858,228.717665412779098],"luv":[70.7540199625255184,-48.6292974270947838,-55.3879996211006826],"rgb":[0.0666666666666666657,0.733333333333333282,0.933333333333333348],"xyz":[0.334316808680991506,0.41830673441307481,0.872038139686157],"hpluv":[228.717665412779098,132.188487390259695,70.7540199625255184],"hsluv":[228.717665412779098,98.8322822642660412,70.7540199625255184]},"#11bbff":{"lch":[71.471758937406932,84.600620314641418,235.923069973878228],"luv":[71.471758937406932,-47.4021956671632836,-70.0735099988154246],"rgb":[0.0666666666666666657,0.733333333333333282,1],"xyz":[0.360487857090822872,0.428775153777007534,1.00987232797793891],"hpluv":[235.923069973878228,150.202929688167188,71.471758937406932],"hsluv":[235.923069973878228,99.9999999999978115,71.471758937406932]},"#11cc00":{"lch":[71.760164015117,110.429324102022079,127.380540485202317],"luv":[71.760164015117,-67.042304751477019,87.7494444155603617],"rgb":[0.0666666666666666657,0.8,0],"xyz":[0.21823081199860983,0.433030325035509422,0.0720814234981507346],"hpluv":[127.380540485202317,195.272154443078705,71.760164015117],"hsluv":[127.380540485202317,100.000000000002245,71.760164015117]},"#11cc11":{"lch":[71.7874927519263366,109.385174124956521,127.715012949240432],"luv":[71.7874927519263366,-66.9146672826053219,86.5305935539869466],"rgb":[0.0666666666666666657,0.8,0.0666666666666666657],"xyz":[0.219242477498246963,0.433434991235364275,0.0774095284629063712],"hpluv":[127.715012949240432,193.352149077988855,71.7874927519263366],"hsluv":[127.715012949240432,98.4507061603193563,71.7874927519263366]},"#11cc22":{"lch":[71.8381079866900905,107.476295008714118,128.346772012349533],"luv":[71.8381079866900905,-66.680384726115463,84.2904519004221129],"rgb":[0.0666666666666666657,0.8,0.133333333333333331],"xyz":[0.221117835636723964,0.434185134490755076,0.0872864146588855638],"hpluv":[128.346772012349533,189.84411001864018,71.8381079866900905],"hsluv":[128.346772012349533,98.4601754700601361,71.8381079866900905]},"#11cc33":{"lch":[71.9213183931711626,104.40864440796355,129.421122123890029],"luv":[71.9213183931711626,-66.3010906987881441,80.6556284412913556],"rgb":[0.0666666666666666657,0.8,0.2],"xyz":[0.224205586369181697,0.435420234783738203,0.103548568516496714],"hpluv":[129.421122123890029,184.212095875088124,71.9213183931711626],"hsluv":[129.421122123890029,98.4755168761512749,71.9213183931711626]},"#11cc44":{"lch":[72.0411777660314669,100.144250866202455,131.050559631523186],"luv":[72.0411777660314669,-65.7672084530810395,75.5218198525557085],"rgb":[0.0666666666666666657,0.8,0.266666666666666663],"xyz":[0.228663581613400585,0.437203432881425769,0.127027343469383353],"hpluv":[131.050559631523186,176.394298837834185,72.0411777660314669],"hsluv":[131.050559631523186,98.4971346697200261,72.0411777660314669]},"#11cc55":{"lch":[72.2009771566369523,94.7439152050601621,133.383427271112737],"luv":[72.2009771566369523,-65.077446685205,68.8573554627095],"rgb":[0.0666666666666666657,0.8,0.333333333333333315],"xyz":[0.234625995652762598,0.439588398497170629,0.158429390743357268],"hpluv":[133.383427271112737,166.512782767528847,72.2009771566369523],"hsluv":[133.383427271112737,98.5251071985599225,72.2009771566369523]},"#11cc66":{"lch":[72.4034304155724,88.37638367841096,136.624435218533876],"luv":[72.4034304155724,-64.2379326004453333,60.6949191225620339],"rgb":[0.0666666666666666657,0.8,0.4],"xyz":[0.242210991426270755,0.442622396806573948,0.198377035150501202],"hpluv":[136.624435218533876,154.887514188688357,72.4034304155724],"hsluv":[136.624435218533876,98.5592219307307289,72.4034304155724]},"#11cc77":{"lch":[72.6507717937069657,81.3359578844494422,141.057484765247835],"luv":[72.6507717937069657,-63.261234579889333,51.1229326663597],"rgb":[0.0666666666666666657,0.8,0.466666666666666674],"xyz":[0.251525004446472689,0.446348002014654743,0.247430837056899111],"hpluv":[141.057484765247835,142.063228414279422,72.6507717937069657],"hsluv":[141.057484765247835,98.5990140248714795,72.6507717937069657]},"#11cc88":{"lch":[72.9448138267759703,74.0714793913140284,147.061910762632237],"luv":[72.9448138267759703,-62.1651250648783815,40.2750702654370087],"rgb":[0.0666666666666666657,0.8,0.533333333333333326],"xyz":[0.262665421548416489,0.450804168855432341,0.306103700460471306],"hpluv":[147.061910762632237,128.853412583983044,72.9448138267759703],"hsluv":[147.061910762632237,98.6438145792393755,72.9448138267759703]},"#11cc99":{"lch":[73.286985449663689,67.2264361640895203,155.087429558943455],"luv":[73.286985449663689,-60.9711251229010074,28.3181147072320734],"rgb":[0.0666666666666666657,0.8,0.6],"xyz":[0.275722385657489188,0.456026954499061499,0.374870378101589186],"hpluv":[155.087429558943455,116.399886643338576,73.286985449663689],"hsluv":[155.087429558943455,98.6928071276572609,73.286985449663689]},"#11ccaa":{"lch":[73.6783599756885224,61.6669147974486336,165.501022011161467],"luv":[73.6783599756885224,-59.7029534543248275,15.4390974304365383],"rgb":[0.0666666666666666657,0.8,0.66666666666666663],"xyz":[0.290780078622741744,0.462050031685162621,0.454174227718587786],"hpluv":[165.501022011161467,106.206622375239988,73.6783599756885224],"hsluv":[165.501022011161467,98.7450877264532494,73.6783599756885224]},"#11ccbb":{"lch":[74.1196780643846864,58.4137876130139801,178.201908682105085],"luv":[74.1196780643846864,-58.3850250256368426,1.83287644266177074],"rgb":[0.0666666666666666657,0.8,0.733333333333333282],"xyz":[0.307917670730078419,0.46890506852809738,0.544432212817229533],"hpluv":[178.201908682105085,100.004874571957387,74.1196780643846864],"hsluv":[178.201908682105085,98.7997230732590452,74.1196780643846864]},"#11cccc":{"lch":[74.6113685470067,58.3540675645504,192.177050630061103],"luv":[74.6113685470067,-57.0411279075965751,-12.3088150671508707],"rgb":[0.0666666666666666657,0.8,0.8],"xyz":[0.327210046173800118,0.476622018705586181,0.646038723487499689],"hpluv":[192.177050630061103,99.244272920381249,74.6113685470067],"hsluv":[192.177050630061103,98.8558017207376167,74.6113685470067]},"#11ccdd":{"lch":[75.1535687293590087,61.8087365466066316,205.702276410621693],"luv":[75.1535687293590087,-55.6933672323303881,-26.8061328768737823],"rgb":[0.0666666666666666657,0.8,0.866666666666666696],"xyz":[0.348728371724433717,0.485229348925839687,0.759368571387505686],"hpluv":[205.702276410621693,104.361325002032586,75.1535687293590087],"hsluv":[205.702276410621693,98.9124749687685352,75.1535687293590087]},"#11ccee":{"lch":[75.7461450403856418,68.3900229325434168,217.356690237772426],"luv":[75.7461450403856418,-54.3614174191380712,-41.4973677827407],"rgb":[0.0666666666666666657,0.8,0.933333333333333348],"xyz":[0.372540551990608426,0.494754221032309704,0.88477938745602891],"hpluv":[217.356690237772426,114.570165581500433,75.7461450403856418],"hsluv":[217.356690237772426,98.968985855810871,75.7461450403856418]},"#11ccff":{"lch":[76.3887144168947714,77.3228649101567811,226.666757851513921],"luv":[76.3887144168947714,-53.0620799518220849,-56.2426982736496726],"rgb":[0.0666666666666666657,0.8,1],"xyz":[0.398711600400439847,0.505222640396242428,1.02261357574781075],"hpluv":[226.666757851513921,131.304642630845649,76.3887144168947714],"hsluv":[226.666757851513921,99.9999999999969162,76.3887144168947714]},"#11dd00":{"lch":[77.1789729208637851,118.880191052714352,127.435820588671049],"luv":[77.1789729208637851,-72.2639845338074,94.3950017957916572],"rgb":[0.0666666666666666657,0.866666666666666696,0],"xyz":[0.260864802545785,0.518298306129860942,0.0862927536805420531],"hpluv":[127.435820588671049,210.367240137055802,77.1789729208637851],"hsluv":[127.435820588671049,100.000000000002302,77.1789729208637851]},"#11dd11":{"lch":[77.2032167276219,117.940964566200989,127.715012949240474],"luv":[77.2032167276219,-72.148538100067,93.2987651195291],"rgb":[0.0666666666666666657,0.866666666666666696,0.0666666666666666657],"xyz":[0.261876468045422084,0.51870297232971585,0.0916208586452976897],"hpluv":[127.715012949240474,208.973000844217893,77.2032167276219],"hsluv":[127.715012949240474,98.7048375113237739,77.2032167276219]},"#11dd22":{"lch":[77.2481249515021773,116.219968574506154,128.240715222563949],"luv":[77.2481249515021773,-71.936288170647174,91.2811674974022509],"rgb":[0.0666666666666666657,0.866666666666666696,0.133333333333333331],"xyz":[0.263751826183899141,0.519453115585106651,0.101497744841276882],"hpluv":[128.240715222563949,206.413967447437244,77.2481249515021773],"hsluv":[128.240715222563949,98.7114617332334348,77.2481249515021773]},"#11dd33":{"lch":[77.3219716074714114,113.443027450646795,129.129905575085218],"luv":[77.3219716074714114,-71.591714193384675,87.9996984996024],"rgb":[0.0666666666666666657,0.866666666666666696,0.2],"xyz":[0.266839576916356847,0.520688215878089777,0.117759898698888033],"hpluv":[129.129905575085218,202.273081507843187,77.3219716074714114],"hsluv":[129.129905575085218,98.7222220245650419,77.3219716074714114]},"#11dd44":{"lch":[77.4283833065767,109.557638087167803,130.467479357182611],"luv":[77.4283833065767,-71.1046976382296378,83.3486534805139],"rgb":[0.0666666666666666657,0.866666666666666696,0.266666666666666663],"xyz":[0.271297572160575762,0.522471413975777343,0.141238673651774671],"hpluv":[130.467479357182611,196.45511110559741,77.4283833065767],"hsluv":[130.467479357182611,98.737444128486942,77.4283833065767]},"#11dd55":{"lch":[77.5703274630482156,104.589066335953675,132.360930841179908],"luv":[77.5703274630482156,-70.4719757705036471,77.2824263854860192],"rgb":[0.0666666666666666657,0.866666666666666696,0.333333333333333315],"xyz":[0.277259986199937747,0.524856379591522093,0.172640720925748559],"hpluv":[132.360930841179908,188.974657198429043,77.5703274630482156],"hsluv":[132.360930841179908,98.7572451358875583,77.5703274630482156]},"#11dd66":{"lch":[77.7502795105496176,98.645271303892585,134.953797592355841],"luv":[77.7502795105496176,-69.6964700953403167,69.8089650895062732],"rgb":[0.0666666666666666657,0.866666666666666696,0.4],"xyz":[0.284844981973445932,0.527890377900925412,0.212588365332892548],"hpluv":[134.953797592355841,179.968822287066047,77.7502795105496176],"hsluv":[134.953797592355841,98.7815546318288114,77.7502795105496176]},"#11dd77":{"lch":[77.9703113413929714,91.9272626112809377,138.440937564009943],"luv":[77.9703113413929714,-68.7866216277350588,60.9837871589344616],"rgb":[0.0666666666666666657,0.866666666666666696,0.466666666666666674],"xyz":[0.294158994993647838,0.531615983109006263,0.261642167239290457],"hpluv":[138.440937564009943,169.723893920939275,77.9703113413929714],"hsluv":[138.440937564009943,98.8101351189296,77.9703113413929714]},"#11dd88":{"lch":[78.2321436880382919,84.7462074021241705,143.083472555296623],"luv":[78.2321436880382919,-67.7555613828794492,50.90288371727776],"rgb":[0.0666666666666666657,0.866666666666666696,0.533333333333333326],"xyz":[0.305299412095591638,0.536072149949783805,0.320315030642862597],"hpluv":[143.083472555296623,158.721324423216174,78.2321436880382919],"hsluv":[143.083472555296623,98.842607114853692,78.2321436880382919]},"#11dd99":{"lch":[78.5371801027425,77.5491781494168748,149.212222309724666],"luv":[78.5371801027425,-66.6201031545698,39.6942928810235145],"rgb":[0.0666666666666666657,0.866666666666666696,0.6],"xyz":[0.318356376204664393,0.541294935593413,0.389081708283980532],"hpluv":[149.212222309724666,147.710574340426348,78.5371801027425],"hsluv":[149.212222309724666,98.8784794246756746,78.5371801027425]},"#11ddaa":{"lch":[78.8865310768390771,70.9495750262721288,157.187121587348372],"luv":[78.8865310768390771,-65.3996173248364414,27.5087667875819264],"rgb":[0.0666666666666666657,0.866666666666666696,0.66666666666666663],"xyz":[0.333414069169916893,0.547318012779514085,0.468385557900979133],"hpluv":[157.187121587348372,137.807232739715857,78.8865310768390771],"hsluv":[157.187121587348372,98.9171828916172728,78.8865310768390771]},"#11ddbb":{"lch":[79.2810328759594398,65.7363215025974483,167.247861929956969],"luv":[79.2810328759594398,-64.1148749316804611,14.5102300873497096],"rgb":[0.0666666666666666657,0.866666666666666696,0.733333333333333282],"xyz":[0.350551661277253568,0.554173049622448843,0.558643542999620824],"hpluv":[167.247861929956969,130.572542181043048,79.2810328759594398],"hsluv":[167.247861929956969,98.9581049946704496,79.2810328759594398]},"#11ddcc":{"lch":[79.7212637056701396,62.7929370759791,179.209087927276954],"luv":[79.7212637056701396,-62.7869545437069903,0.866767416521026846],"rgb":[0.0666666666666666657,0.866666666666666696,0.8],"xyz":[0.369844036720975322,0.561889999799937701,0.660250053669891],"hpluv":[179.209087927276954,127.935201467087722,79.7212637056701396],"hsluv":[179.209087927276954,99.0006225499112,79.7212637056701396]},"#11dddd":{"lch":[80.2075587483664378,62.8503941808937796,192.177050630061132],"luv":[80.2075587483664378,-61.4362892449526,-13.2572400032679489],"rgb":[0.0666666666666666657,0.866666666666666696,0.866666666666666696],"xyz":[0.39136236227160881,0.570497330020191207,0.773579901569897],"hpluv":[192.177050630061132,131.767009082741112,80.2075587483664378],"hsluv":[192.177050630061132,99.0441302201931109,80.2075587483664378]},"#11ddee":{"lch":[80.7400249746916643,66.1629514334268691,204.757295278220823],"luv":[80.7400249746916643,-60.0819052998990202,-27.707414132610225],"rgb":[0.0666666666666666657,0.866666666666666696,0.933333333333333348],"xyz":[0.415174542537783575,0.580022202126661224,0.8989907176384202],"hpluv":[204.757295278220823,143.22067561241397,80.7400249746916643],"hsluv":[204.757295278220823,99.0880633014724594,80.7400249746916643]},"#11ddff":{"lch":[81.3185562290371848,72.4120095186264194,215.786316478612605],"luv":[81.3185562290371848,-58.7408753400219084,-42.3439332940817934],"rgb":[0.0666666666666666657,0.866666666666666696,1],"xyz":[0.441345590947614941,0.590490621490594,1.03682490593020216],"hpluv":[215.786316478612605,162.428807277722512,81.3185562290371848],"hsluv":[215.786316478612605,99.9999999999959925,81.3185562290371848]}}
\ No newline at end of file
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go b/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go
new file mode 100644
index 00000000..d19fb644
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go
@@ -0,0 +1,207 @@
+package colorful
+
+import "math"
+
+// Source: https://github.com/hsluv/hsluv-go
+// Under MIT License
+// Modified so that Saturation and Luminance are in [0..1] instead of [0..100].
+
+// HSLuv uses a rounded version of the D65. This has no impact on the final RGB
+// values, but to keep high levels of accuracy for internal operations and when
+// comparing to the test values, this modified white reference is used internally.
+//
+// See this GitHub thread for details on these values:
+// https://github.com/hsluv/hsluv/issues/79
+var hSLuvD65 = [3]float64{0.95045592705167, 1.0, 1.089057750759878}
+
+func LuvLChToHSLuv(l, c, h float64) (float64, float64, float64) {
+ // [-1..1] but the code expects it to be [-100..100]
+ c *= 100.0
+ l *= 100.0
+
+ var s, max float64
+ if l > 99.9999999 || l < 0.00000001 {
+ s = 0.0
+ } else {
+ max = maxChromaForLH(l, h)
+ s = c / max * 100.0
+ }
+ return h, clamp01(s / 100.0), clamp01(l / 100.0)
+}
+
+func HSLuvToLuvLCh(h, s, l float64) (float64, float64, float64) {
+ l *= 100.0
+ s *= 100.0
+
+ var c, max float64
+ if l > 99.9999999 || l < 0.00000001 {
+ c = 0.0
+ } else {
+ max = maxChromaForLH(l, h)
+ c = max / 100.0 * s
+ }
+
+ // c is [-100..100], but for LCh it's supposed to be almost [-1..1]
+ return clamp01(l / 100.0), c / 100.0, h
+}
+
+func LuvLChToHPLuv(l, c, h float64) (float64, float64, float64) {
+ // [-1..1] but the code expects it to be [-100..100]
+ c *= 100.0
+ l *= 100.0
+
+ var s, max float64
+ if l > 99.9999999 || l < 0.00000001 {
+ s = 0.0
+ } else {
+ max = maxSafeChromaForL(l)
+ s = c / max * 100.0
+ }
+ return h, s / 100.0, l / 100.0
+}
+
+func HPLuvToLuvLCh(h, s, l float64) (float64, float64, float64) {
+ // [-1..1] but the code expects it to be [-100..100]
+ l *= 100.0
+ s *= 100.0
+
+ var c, max float64
+ if l > 99.9999999 || l < 0.00000001 {
+ c = 0.0
+ } else {
+ max = maxSafeChromaForL(l)
+ c = max / 100.0 * s
+ }
+ return l / 100.0, c / 100.0, h
+}
+
+// HSLuv creates a new Color from values in the HSLuv color space.
+// Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1].
+//
+// The returned color values are clamped (using .Clamped), so this will never output
+// an invalid color.
+func HSLuv(h, s, l float64) Color {
+ // HSLuv -> LuvLCh -> CIELUV -> CIEXYZ -> Linear RGB -> sRGB
+ l, u, v := LuvLChToLuv(HSLuvToLuvLCh(h, s, l))
+ return LinearRgb(XyzToLinearRgb(LuvToXyzWhiteRef(l, u, v, hSLuvD65))).Clamped()
+}
+
+// HPLuv creates a new Color from values in the HPLuv color space.
+// Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1].
+//
+// The returned color values are clamped (using .Clamped), so this will never output
+// an invalid color.
+func HPLuv(h, s, l float64) Color {
+ // HPLuv -> LuvLCh -> CIELUV -> CIEXYZ -> Linear RGB -> sRGB
+ l, u, v := LuvLChToLuv(HPLuvToLuvLCh(h, s, l))
+ return LinearRgb(XyzToLinearRgb(LuvToXyzWhiteRef(l, u, v, hSLuvD65))).Clamped()
+}
+
+// HSLuv returns the Hue, Saturation and Luminance of the color in the HSLuv
+// color space. Hue in [0..360], a Saturation [0..1], and a Luminance
+// (lightness) in [0..1].
+func (col Color) HSLuv() (h, s, l float64) {
+ // sRGB -> Linear RGB -> CIEXYZ -> CIELUV -> LuvLCh -> HSLuv
+ return LuvLChToHSLuv(col.LuvLChWhiteRef(hSLuvD65))
+}
+
+// HPLuv returns the Hue, Saturation and Luminance of the color in the HSLuv
+// color space. Hue in [0..360], a Saturation [0..1], and a Luminance
+// (lightness) in [0..1].
+//
+// Note that HPLuv can only represent pastel colors, and so the Saturation
+// value could be much larger than 1 for colors it can't represent.
+func (col Color) HPLuv() (h, s, l float64) {
+ return LuvLChToHPLuv(col.LuvLChWhiteRef(hSLuvD65))
+}
+
+// DistanceHSLuv calculates Euclidan distance in the HSLuv colorspace. No idea
+// how useful this is.
+//
+// The Hue value is divided by 100 before the calculation, so that H, S, and L
+// have the same relative ranges.
+func (c1 Color) DistanceHSLuv(c2 Color) float64 {
+ h1, s1, l1 := c1.HSLuv()
+ h2, s2, l2 := c2.HSLuv()
+ return math.Sqrt(sq((h1-h2)/100.0) + sq(s1-s2) + sq(l1-l2))
+}
+
+// DistanceHPLuv calculates Euclidean distance in the HPLuv colorspace. No idea
+// how useful this is.
+//
+// The Hue value is divided by 100 before the calculation, so that H, S, and L
+// have the same relative ranges.
+func (c1 Color) DistanceHPLuv(c2 Color) float64 {
+ h1, s1, l1 := c1.HPLuv()
+ h2, s2, l2 := c2.HPLuv()
+ return math.Sqrt(sq((h1-h2)/100.0) + sq(s1-s2) + sq(l1-l2))
+}
+
+var m = [3][3]float64{
+ {3.2409699419045214, -1.5373831775700935, -0.49861076029300328},
+ {-0.96924363628087983, 1.8759675015077207, 0.041555057407175613},
+ {0.055630079696993609, -0.20397695888897657, 1.0569715142428786},
+}
+
+const kappa = 903.2962962962963
+const epsilon = 0.0088564516790356308
+
+func maxChromaForLH(l, h float64) float64 {
+ hRad := h / 360.0 * math.Pi * 2.0
+ minLength := math.MaxFloat64
+ for _, line := range getBounds(l) {
+ length := lengthOfRayUntilIntersect(hRad, line[0], line[1])
+ if length > 0.0 && length < minLength {
+ minLength = length
+ }
+ }
+ return minLength
+}
+
+func getBounds(l float64) [6][2]float64 {
+ var sub2 float64
+ var ret [6][2]float64
+ sub1 := math.Pow(l+16.0, 3.0) / 1560896.0
+ if sub1 > epsilon {
+ sub2 = sub1
+ } else {
+ sub2 = l / kappa
+ }
+ for i := range m {
+ for k := 0; k < 2; k++ {
+ top1 := (284517.0*m[i][0] - 94839.0*m[i][2]) * sub2
+ top2 := (838422.0*m[i][2]+769860.0*m[i][1]+731718.0*m[i][0])*l*sub2 - 769860.0*float64(k)*l
+ bottom := (632260.0*m[i][2]-126452.0*m[i][1])*sub2 + 126452.0*float64(k)
+ ret[i*2+k][0] = top1 / bottom
+ ret[i*2+k][1] = top2 / bottom
+ }
+ }
+ return ret
+}
+
+func lengthOfRayUntilIntersect(theta, x, y float64) (length float64) {
+ length = y / (math.Sin(theta) - x*math.Cos(theta))
+ return
+}
+
+func maxSafeChromaForL(l float64) float64 {
+ minLength := math.MaxFloat64
+ for _, line := range getBounds(l) {
+ m1 := line[0]
+ b1 := line[1]
+ x := intersectLineLine(m1, b1, -1.0/m1, 0.0)
+ dist := distanceFromPole(x, b1+x*m1)
+ if dist < minLength {
+ minLength = dist
+ }
+ }
+ return minLength
+}
+
+func intersectLineLine(x1, y1, x2, y2 float64) float64 {
+ return (y1 - y2) / (x2 - x1)
+}
+
+func distanceFromPole(x, y float64) float64 {
+ return math.Sqrt(math.Pow(x, 2.0) + math.Pow(y, 2.0))
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go
new file mode 100644
index 00000000..9f7bf6f7
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go
@@ -0,0 +1,185 @@
+// Largely inspired by the descriptions in http://lab.medialab.sciences-po.fr/iwanthue/
+// but written from scratch.
+
+package colorful
+
+import (
+ "fmt"
+ "math"
+ "math/rand"
+)
+
+// The algorithm works in L*a*b* color space and converts to RGB in the end.
+// L* in [0..1], a* and b* in [-1..1]
+type lab_t struct {
+ L, A, B float64
+}
+
+type SoftPaletteSettings struct {
+ // A function which can be used to restrict the allowed color-space.
+ CheckColor func(l, a, b float64) bool
+
+ // The higher, the better quality but the slower. Usually two figures.
+ Iterations int
+
+ // Use up to 160000 or 8000 samples of the L*a*b* space (and thus calls to CheckColor).
+ // Set this to true only if your CheckColor shapes the Lab space weirdly.
+ ManySamples bool
+}
+
+// Yeah, windows-stype Foo, FooEx, screw you golang...
+// Uses K-means to cluster the color-space and return the means of the clusters
+// as a new palette of distinctive colors. Falls back to K-medoid if the mean
+// happens to fall outside of the color-space, which can only happen if you
+// specify a CheckColor function.
+func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, error) {
+
+ // Checks whether it's a valid RGB and also fulfills the potentially provided constraint.
+ check := func(col lab_t) bool {
+ c := Lab(col.L, col.A, col.B)
+ return c.IsValid() && (settings.CheckColor == nil || settings.CheckColor(col.L, col.A, col.B))
+ }
+
+ // Sample the color space. These will be the points k-means is run on.
+ dl := 0.05
+ dab := 0.1
+ if settings.ManySamples {
+ dl = 0.01
+ dab = 0.05
+ }
+
+ samples := make([]lab_t, 0, int(1.0/dl*2.0/dab*2.0/dab))
+ for l := 0.0; l <= 1.0; l += dl {
+ for a := -1.0; a <= 1.0; a += dab {
+ for b := -1.0; b <= 1.0; b += dab {
+ if check(lab_t{l, a, b}) {
+ samples = append(samples, lab_t{l, a, b})
+ }
+ }
+ }
+ }
+
+ // That would cause some infinite loops down there...
+ if len(samples) < colorsCount {
+ return nil, fmt.Errorf("palettegen: more colors requested (%v) than samples available (%v). Your requested color count may be wrong, you might want to use many samples or your constraint function makes the valid color space too small", colorsCount, len(samples))
+ } else if len(samples) == colorsCount {
+ return labs2cols(samples), nil // Oops?
+ }
+
+ // We take the initial means out of the samples, so they are in fact medoids.
+ // This helps us avoid infinite loops or arbitrary cutoffs with too restrictive constraints.
+ means := make([]lab_t, colorsCount)
+ for i := 0; i < colorsCount; i++ {
+ for means[i] = samples[rand.Intn(len(samples))]; in(means, i, means[i]); means[i] = samples[rand.Intn(len(samples))] {
+ }
+ }
+
+ clusters := make([]int, len(samples))
+ samples_used := make([]bool, len(samples))
+
+ // The actual k-means/medoid iterations
+ for i := 0; i < settings.Iterations; i++ {
+ // Reassing the samples to clusters, i.e. to their closest mean.
+ // By the way, also check if any sample is used as a medoid and if so, mark that.
+ for isample, sample := range samples {
+ samples_used[isample] = false
+ mindist := math.Inf(+1)
+ for imean, mean := range means {
+ dist := lab_dist(sample, mean)
+ if dist < mindist {
+ mindist = dist
+ clusters[isample] = imean
+ }
+
+ // Mark samples which are used as a medoid.
+ if lab_eq(sample, mean) {
+ samples_used[isample] = true
+ }
+ }
+ }
+
+ // Compute new means according to the samples.
+ for imean := range means {
+ // The new mean is the average of all samples belonging to it..
+ nsamples := 0
+ newmean := lab_t{0.0, 0.0, 0.0}
+ for isample, sample := range samples {
+ if clusters[isample] == imean {
+ nsamples++
+ newmean.L += sample.L
+ newmean.A += sample.A
+ newmean.B += sample.B
+ }
+ }
+ if nsamples > 0 {
+ newmean.L /= float64(nsamples)
+ newmean.A /= float64(nsamples)
+ newmean.B /= float64(nsamples)
+ } else {
+ // That mean doesn't have any samples? Get a new mean from the sample list!
+ var inewmean int
+ for inewmean = rand.Intn(len(samples_used)); samples_used[inewmean]; inewmean = rand.Intn(len(samples_used)) {
+ }
+ newmean = samples[inewmean]
+ samples_used[inewmean] = true
+ }
+
+ // But now we still need to check whether the new mean is an allowed color.
+ if nsamples > 0 && check(newmean) {
+ // It does, life's good (TM)
+ means[imean] = newmean
+ } else {
+ // New mean isn't an allowed color or doesn't have any samples!
+ // Switch to medoid mode and pick the closest (unused) sample.
+ // This should always find something thanks to len(samples) >= colorsCount
+ mindist := math.Inf(+1)
+ for isample, sample := range samples {
+ if !samples_used[isample] {
+ dist := lab_dist(sample, newmean)
+ if dist < mindist {
+ mindist = dist
+ newmean = sample
+ }
+ }
+ }
+ }
+ }
+ }
+ return labs2cols(means), nil
+}
+
+// A wrapper which uses common parameters.
+func SoftPalette(colorsCount int) ([]Color, error) {
+ return SoftPaletteEx(colorsCount, SoftPaletteSettings{nil, 50, false})
+}
+
+func in(haystack []lab_t, upto int, needle lab_t) bool {
+ for i := 0; i < upto && i < len(haystack); i++ {
+ if haystack[i] == needle {
+ return true
+ }
+ }
+ return false
+}
+
+const LAB_DELTA = 1e-6
+
+func lab_eq(lab1, lab2 lab_t) bool {
+ return math.Abs(lab1.L-lab2.L) < LAB_DELTA &&
+ math.Abs(lab1.A-lab2.A) < LAB_DELTA &&
+ math.Abs(lab1.B-lab2.B) < LAB_DELTA
+}
+
+// That's faster than using colorful's DistanceLab since we would have to
+// convert back and forth for that. Here is no conversion.
+func lab_dist(lab1, lab2 lab_t) float64 {
+ return math.Sqrt(sq(lab1.L-lab2.L) + sq(lab1.A-lab2.A) + sq(lab1.B-lab2.B))
+}
+
+func labs2cols(labs []lab_t) (cols []Color) {
+ cols = make([]Color, len(labs))
+ for k, v := range labs {
+ cols[k] = Lab(v.L, v.A, v.B)
+ }
+ return cols
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go
new file mode 100644
index 00000000..00f42a5c
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go
@@ -0,0 +1,25 @@
+package colorful
+
+import (
+ "math/rand"
+)
+
+// Uses the HSV color space to generate colors with similar S,V but distributed
+// evenly along their Hue. This is fast but not always pretty.
+// If you've got time to spare, use Lab (the non-fast below).
+func FastWarmPalette(colorsCount int) (colors []Color) {
+ colors = make([]Color, colorsCount)
+
+ for i := 0; i < colorsCount; i++ {
+ colors[i] = Hsv(float64(i)*(360.0/float64(colorsCount)), 0.55+rand.Float64()*0.2, 0.35+rand.Float64()*0.2)
+ }
+ return
+}
+
+func WarmPalette(colorsCount int) ([]Color, error) {
+ warmy := func(l, a, b float64) bool {
+ _, c, _ := LabToHcl(l, a, b)
+ return 0.1 <= c && c <= 0.4 && 0.2 <= l && l <= 0.5
+ }
+ return SoftPaletteEx(colorsCount, SoftPaletteSettings{warmy, 50, true})
+}
diff --git a/vendor/github.com/macabu/inamedparam/.golangci.yml b/vendor/github.com/macabu/inamedparam/.golangci.yml
index f0efa1cb..7f301af5 100644
--- a/vendor/github.com/macabu/inamedparam/.golangci.yml
+++ b/vendor/github.com/macabu/inamedparam/.golangci.yml
@@ -1,33 +1,21 @@
run:
- deadline: 30s
+ timeout: 30s
linters:
enable-all: true
disable:
- cyclop
- - deadcode
- depguard
- - exhaustivestruct
- exhaustruct
- forcetypeassert
- gochecknoglobals
- gocognit
- - golint
- - ifshort
- - interfacer
- - maligned
- nilnil
- - nosnakecase
- paralleltest
- - scopelint
- - structcheck
- - varcheck
linters-settings:
gci:
sections:
- standard
- default
- - prefix(github.com/macabu/inamedparam)
- section-separators:
- - newLine
+ - localmodule
diff --git a/vendor/github.com/macabu/inamedparam/README.md b/vendor/github.com/macabu/inamedparam/README.md
index 3336cb95..56fce4ff 100644
--- a/vendor/github.com/macabu/inamedparam/README.md
+++ b/vendor/github.com/macabu/inamedparam/README.md
@@ -15,7 +15,7 @@ You can run it standalone through `go vet`.
You must install the binary to your `$GOBIN` folder like so:
```sh
-$ go install github.com/macabu/inamedparam/cmd/inamedparam
+$ go install github.com/macabu/inamedparam/cmd/inamedparam@latest
```
And then navigate to your Go project's root folder, where can run `go vet` in the following way:
@@ -29,10 +29,16 @@ $ go vet -vettool=$(which inamedparam) ./...
To enable it, you can add it to your `.golangci.yml` file, as such:
```yaml
run:
- deadline: 30s
+ timeout: 30s
linters:
disable-all: true
enable:
- inamedparam
+
+linters-settings:
+ inamedparam:
+ # Skips check for interface methods with only a single parameter.
+ # Default: false
+ skip-single-param: true
```
diff --git a/vendor/github.com/macabu/inamedparam/inamedparam.go b/vendor/github.com/macabu/inamedparam/inamedparam.go
index 8ba7fe18..932bd3b5 100644
--- a/vendor/github.com/macabu/inamedparam/inamedparam.go
+++ b/vendor/github.com/macabu/inamedparam/inamedparam.go
@@ -33,14 +33,17 @@ func flags() flag.FlagSet {
return *flags
}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
types := []ast.Node{
&ast.InterfaceType{},
}
- skipSingleParam := pass.Analyzer.Flags.Lookup(flagSkipSingleParam).Value.(flag.Getter).Get().(bool)
+ var skipSingleParam bool
+ if f := pass.Analyzer.Flags.Lookup(flagSkipSingleParam); f != nil {
+ skipSingleParam, _ = f.Value.(flag.Getter).Get().(bool)
+ }
inspect.Preorder(types, func(n ast.Node) {
interfaceType, ok := n.(*ast.InterfaceType)
diff --git a/vendor/github.com/manuelarte/funcorder/LICENSE b/vendor/github.com/manuelarte/funcorder/LICENSE
new file mode 100644
index 00000000..261eeb9e
--- /dev/null
+++ b/vendor/github.com/manuelarte/funcorder/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/manuelarte/funcorder/analyzer/analyzer.go b/vendor/github.com/manuelarte/funcorder/analyzer/analyzer.go
new file mode 100644
index 00000000..f8aabbfc
--- /dev/null
+++ b/vendor/github.com/manuelarte/funcorder/analyzer/analyzer.go
@@ -0,0 +1,90 @@
+package analyzer
+
+import (
+ "go/ast"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/inspector"
+
+ "github.com/manuelarte/funcorder/internal/features"
+ "github.com/manuelarte/funcorder/internal/fileprocessor"
+)
+
+const (
+ ConstructorCheckName = "constructor"
+ StructMethodCheckName = "struct-method"
+)
+
+func NewAnalyzer() *analysis.Analyzer {
+ f := funcorder{}
+
+ a := &analysis.Analyzer{
+ Name: "funcorder",
+ Doc: "checks the order of functions, methods, and constructors",
+ Run: f.run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ }
+
+ a.Flags.BoolVar(&f.constructorCheck, ConstructorCheckName, true,
+ "Enable/disable feature to check constructors are placed after struct declaration")
+ a.Flags.BoolVar(&f.structMethodCheck, StructMethodCheckName, true,
+ "Enable/disable feature to check whether the exported struct's methods "+
+ "are placed before the non-exported")
+
+ return a
+}
+
+type funcorder struct {
+ constructorCheck bool
+ structMethodCheck bool
+}
+
+func (f *funcorder) run(pass *analysis.Pass) (any, error) {
+ var enabledCheckers features.Feature
+ if f.constructorCheck {
+ enabledCheckers |= features.ConstructorCheck
+ }
+
+ if f.structMethodCheck {
+ enabledCheckers |= features.StructMethodCheck
+ }
+
+ fp := fileprocessor.NewFileProcessor(enabledCheckers)
+
+ insp, found := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+ if !found {
+ //nolint:nilnil // impossible case.
+ return nil, nil
+ }
+
+ nodeFilter := []ast.Node{
+ (*ast.File)(nil),
+ (*ast.FuncDecl)(nil),
+ (*ast.TypeSpec)(nil),
+ }
+
+ insp.Preorder(nodeFilter, func(n ast.Node) {
+ switch node := n.(type) {
+ case *ast.File:
+ for _, report := range fp.Analyze() {
+ pass.Report(report)
+ }
+
+ fp.NewFileNode(node)
+
+ case *ast.FuncDecl:
+ fp.NewFuncDecl(node)
+
+ case *ast.TypeSpec:
+ fp.NewTypeSpec(node)
+ }
+ })
+
+ for _, report := range fp.Analyze() {
+ pass.Report(report)
+ }
+
+ //nolint:nilnil //any, error
+ return nil, nil
+}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/astutils/utils.go b/vendor/github.com/manuelarte/funcorder/internal/astutils/utils.go
new file mode 100644
index 00000000..78839976
--- /dev/null
+++ b/vendor/github.com/manuelarte/funcorder/internal/astutils/utils.go
@@ -0,0 +1,54 @@
+package astutils
+
+import (
+ "go/ast"
+ "strings"
+)
+
+func FuncCanBeConstructor(n *ast.FuncDecl) bool {
+ if !n.Name.IsExported() || n.Recv != nil {
+ return false
+ }
+
+ if n.Type.Results == nil || len(n.Type.Results.List) == 0 {
+ return false
+ }
+
+ for _, prefix := range []string{"new", "must"} {
+ if strings.HasPrefix(strings.ToLower(n.Name.Name), prefix) &&
+ len(n.Name.Name) > len(prefix) { // TODO(ldez): bug if the name is just `New`.
+ return true
+ }
+ }
+
+ return false
+}
+
+func FuncIsMethod(n *ast.FuncDecl) (*ast.Ident, bool) {
+ if n.Recv == nil {
+ return nil, false
+ }
+
+ if len(n.Recv.List) != 1 {
+ return nil, false
+ }
+
+ if recv, ok := GetIdent(n.Recv.List[0].Type); ok {
+ return recv, true
+ }
+
+ return nil, false
+}
+
+func GetIdent(expr ast.Expr) (*ast.Ident, bool) {
+ switch exp := expr.(type) {
+ case *ast.StarExpr:
+ return GetIdent(exp.X)
+
+ case *ast.Ident:
+ return exp, true
+
+ default:
+ return nil, false
+ }
+}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/diag/diag.go b/vendor/github.com/manuelarte/funcorder/internal/diag/diag.go
new file mode 100644
index 00000000..3a5012b1
--- /dev/null
+++ b/vendor/github.com/manuelarte/funcorder/internal/diag/diag.go
@@ -0,0 +1,40 @@
+package diag
+
+import (
+ "fmt"
+ "go/ast"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+func NewConstructorNotAfterStructType(structSpec *ast.TypeSpec, constructor *ast.FuncDecl) analysis.Diagnostic {
+ return analysis.Diagnostic{
+ Pos: constructor.Pos(),
+ Message: fmt.Sprintf("function %q for struct %q should be placed after the struct declaration",
+ constructor.Name, structSpec.Name),
+ }
+}
+
+func NewConstructorNotBeforeStructMethod(
+ structSpec *ast.TypeSpec,
+ constructor *ast.FuncDecl,
+ method *ast.FuncDecl,
+) analysis.Diagnostic {
+ return analysis.Diagnostic{
+ Pos: constructor.Pos(),
+ Message: fmt.Sprintf("constructor %q for struct %q should be placed before struct method %q",
+ constructor.Name, structSpec.Name, method.Name),
+ }
+}
+
+func NewNonExportedMethodBeforeExportedForStruct(
+ structSpec *ast.TypeSpec,
+ privateMethod *ast.FuncDecl,
+ publicMethod *ast.FuncDecl,
+) analysis.Diagnostic {
+ return analysis.Diagnostic{
+ Pos: privateMethod.Pos(),
+ Message: fmt.Sprintf("unexported method %q for struct %q should be placed after the exported method %q",
+ privateMethod.Name, structSpec.Name, publicMethod.Name),
+ }
+}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/features/features.go b/vendor/github.com/manuelarte/funcorder/internal/features/features.go
new file mode 100644
index 00000000..244ea64b
--- /dev/null
+++ b/vendor/github.com/manuelarte/funcorder/internal/features/features.go
@@ -0,0 +1,12 @@
+package features
+
+const (
+ ConstructorCheck Feature = 1 << iota
+ StructMethodCheck
+)
+
+type Feature uint8
+
+func (c Feature) IsEnabled(other Feature) bool {
+ return c&other != 0
+}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/fileprocessor/file_processor.go b/vendor/github.com/manuelarte/funcorder/internal/fileprocessor/file_processor.go
new file mode 100644
index 00000000..8a2fb0e3
--- /dev/null
+++ b/vendor/github.com/manuelarte/funcorder/internal/fileprocessor/file_processor.go
@@ -0,0 +1,80 @@
+package fileprocessor
+
+import (
+ "go/ast"
+
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/manuelarte/funcorder/internal/astutils"
+ "github.com/manuelarte/funcorder/internal/features"
+ "github.com/manuelarte/funcorder/internal/models"
+)
+
+// FileProcessor Holder to store all the functions that are potential to be constructors and all the structs.
+type FileProcessor struct {
+ structs map[string]*models.StructHolder
+ features features.Feature
+}
+
+// NewFileProcessor creates a new file processor.
+func NewFileProcessor(checkers features.Feature) *FileProcessor {
+ return &FileProcessor{
+ structs: make(map[string]*models.StructHolder),
+ features: checkers,
+ }
+}
+
+// Analyze check whether the order of the methods in the constructor is correct.
+func (fp *FileProcessor) Analyze() []analysis.Diagnostic {
+ var reports []analysis.Diagnostic
+
+ for _, sh := range fp.structs {
+ // filter out structs that are not declared inside that file
+ if sh.Struct != nil {
+ reports = append(reports, sh.Analyze()...)
+ }
+ }
+
+ return reports
+}
+
+func (fp *FileProcessor) addConstructor(sc models.StructConstructor) {
+ sh := fp.getOrCreate(sc.GetStructReturn().Name)
+ sh.AddConstructor(sc.GetConstructor())
+}
+
+func (fp *FileProcessor) addMethod(st string, n *ast.FuncDecl) {
+ sh := fp.getOrCreate(st)
+ sh.AddMethod(n)
+}
+
+func (fp *FileProcessor) NewFileNode(_ *ast.File) {
+ fp.structs = make(map[string]*models.StructHolder)
+}
+
+func (fp *FileProcessor) NewFuncDecl(n *ast.FuncDecl) {
+ if sc, ok := models.NewStructConstructor(n); ok {
+ fp.addConstructor(sc)
+ return
+ }
+
+ if st, ok := astutils.FuncIsMethod(n); ok {
+ fp.addMethod(st.Name, n)
+ }
+}
+
+func (fp *FileProcessor) NewTypeSpec(n *ast.TypeSpec) {
+ sh := fp.getOrCreate(n.Name.Name)
+ sh.Struct = n
+}
+
+func (fp *FileProcessor) getOrCreate(structName string) *models.StructHolder {
+ if holder, ok := fp.structs[structName]; ok {
+ return holder
+ }
+
+ created := &models.StructHolder{Features: fp.features}
+ fp.structs[structName] = created
+
+ return created
+}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/models/struct_constructor.go b/vendor/github.com/manuelarte/funcorder/internal/models/struct_constructor.go
new file mode 100644
index 00000000..668ab346
--- /dev/null
+++ b/vendor/github.com/manuelarte/funcorder/internal/models/struct_constructor.go
@@ -0,0 +1,39 @@
+package models
+
+import (
+ "go/ast"
+
+ "github.com/manuelarte/funcorder/internal/astutils"
+)
+
+type StructConstructor struct {
+ constructor *ast.FuncDecl
+ structReturn *ast.Ident
+}
+
+func NewStructConstructor(funcDec *ast.FuncDecl) (StructConstructor, bool) {
+ if !astutils.FuncCanBeConstructor(funcDec) {
+ return StructConstructor{}, false
+ }
+
+ expr := funcDec.Type.Results.List[0].Type
+
+ returnType, ok := astutils.GetIdent(expr)
+ if !ok {
+ return StructConstructor{}, false
+ }
+
+ return StructConstructor{
+ constructor: funcDec,
+ structReturn: returnType,
+ }, true
+}
+
+// GetStructReturn Return the struct linked to this "constructor".
+func (sc StructConstructor) GetStructReturn() *ast.Ident {
+ return sc.structReturn
+}
+
+func (sc StructConstructor) GetConstructor() *ast.FuncDecl {
+ return sc.constructor
+}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/models/struct_holder.go b/vendor/github.com/manuelarte/funcorder/internal/models/struct_holder.go
new file mode 100644
index 00000000..4b832f3a
--- /dev/null
+++ b/vendor/github.com/manuelarte/funcorder/internal/models/struct_holder.go
@@ -0,0 +1,91 @@
+package models
+
+import (
+ "cmp"
+ "go/ast"
+ "slices"
+
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/manuelarte/funcorder/internal/diag"
+ "github.com/manuelarte/funcorder/internal/features"
+)
+
+// StructHolder contains all the information around a Go struct.
+type StructHolder struct {
+ // The features to be analyzed
+ Features features.Feature
+
+ // The struct declaration
+ Struct *ast.TypeSpec
+
+ // A Struct constructor is considered if starts with `New...` and the 1st output parameter is a struct
+ Constructors []*ast.FuncDecl
+
+ // Struct methods
+ StructMethods []*ast.FuncDecl
+}
+
+func (sh *StructHolder) AddConstructor(fn *ast.FuncDecl) {
+ sh.Constructors = append(sh.Constructors, fn)
+}
+
+func (sh *StructHolder) AddMethod(fn *ast.FuncDecl) {
+ sh.StructMethods = append(sh.StructMethods, fn)
+}
+
+//nolint:gocognit,nestif // refactor later
+func (sh *StructHolder) Analyze() []analysis.Diagnostic {
+ // TODO maybe sort constructors and then report also, like NewXXX before MustXXX
+
+ slices.SortFunc(sh.StructMethods, func(a, b *ast.FuncDecl) int {
+ return cmp.Compare(a.Pos(), b.Pos())
+ })
+
+ var reports []analysis.Diagnostic
+
+ if sh.Features.IsEnabled(features.ConstructorCheck) {
+ structPos := sh.Struct.Pos()
+
+ for _, c := range sh.Constructors {
+ if c.Pos() < structPos {
+ reports = append(reports, diag.NewConstructorNotAfterStructType(sh.Struct, c))
+ }
+
+ if len(sh.StructMethods) > 0 && c.Pos() > sh.StructMethods[0].Pos() {
+ reports = append(reports, diag.NewConstructorNotBeforeStructMethod(sh.Struct, c, sh.StructMethods[0]))
+ }
+ }
+ }
+
+ if sh.Features.IsEnabled(features.StructMethodCheck) {
+ var lastExportedMethod *ast.FuncDecl
+
+ for _, m := range sh.StructMethods {
+ if !m.Name.IsExported() {
+ continue
+ }
+
+ if lastExportedMethod == nil {
+ lastExportedMethod = m
+ }
+
+ if lastExportedMethod.Pos() < m.Pos() {
+ lastExportedMethod = m
+ }
+ }
+
+ if lastExportedMethod != nil {
+ for _, m := range sh.StructMethods {
+ if m.Name.IsExported() || m.Pos() >= lastExportedMethod.Pos() {
+ continue
+ }
+
+ reports = append(reports, diag.NewNonExportedMethodBeforeExportedForStruct(sh.Struct, m, lastExportedMethod))
+ }
+ }
+ }
+
+ // TODO also check that the methods are declared after the struct
+ return reports
+}
diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/args.go b/vendor/github.com/mgechev/revive/internal/ifelse/args.go
index fc65b70a..8ea19647 100644
--- a/vendor/github.com/mgechev/revive/internal/ifelse/args.go
+++ b/vendor/github.com/mgechev/revive/internal/ifelse/args.go
@@ -1,15 +1,5 @@
package ifelse
-// PreserveScope is a configuration argument that prevents suggestions
-// that would enlarge variable scope
-const PreserveScope = "preserveScope"
-
-// AllowJump is a configuration argument that permits early-return to
-// suggest introducing a new jump (return, continue, etc) statement
-// to reduce nesting. By default, suggestions only bring existing jumps
-// earlier.
-const AllowJump = "allowJump"
-
// Args contains arguments common to the early-return, indent-error-flow
// and superfluous-else rules
type Args struct {
diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/rule.go b/vendor/github.com/mgechev/revive/internal/ifelse/rule.go
index 94f02218..799f8b83 100644
--- a/vendor/github.com/mgechev/revive/internal/ifelse/rule.go
+++ b/vendor/github.com/mgechev/revive/internal/ifelse/rule.go
@@ -10,7 +10,7 @@ import (
// CheckFunc evaluates a rule against the given if-else chain and returns a message
// describing the proposed refactor, along with a indicator of whether such a refactor
// could be found.
-type CheckFunc func(Chain, Args) (string, bool)
+type CheckFunc func(Chain) (string, bool)
// Apply evaluates the given Rule on if-else chains found within the given AST,
// and returns the failures.
@@ -28,16 +28,9 @@ type CheckFunc func(Chain, Args) (string, bool)
//
// Only the block following "bar" is linted. This is because the rules that use this function
// do not presently have anything to say about earlier blocks in the chain.
-func Apply(check CheckFunc, node ast.Node, target Target, args lint.Arguments) []lint.Failure {
+func Apply(check CheckFunc, node ast.Node, target Target, args Args) []lint.Failure {
v := &visitor{check: check, target: target}
- for _, arg := range args {
- switch arg {
- case PreserveScope:
- v.args.PreserveScope = true
- case AllowJump:
- v.args.AllowJump = true
- }
- }
+ v.args = args
ast.Walk(v, node)
return v.failures
}
@@ -126,7 +119,7 @@ func (v *visitor) visitIf(ifStmt *ast.IfStmt, chain Chain) {
}
func (v *visitor) checkRule(ifStmt *ast.IfStmt, chain Chain) {
- msg, found := v.check(chain, v.args)
+ msg, found := v.check(chain)
if !found {
return // passed the check
}
diff --git a/vendor/github.com/mgechev/revive/lint/file.go b/vendor/github.com/mgechev/revive/lint/file.go
index 0311210e..950d756d 100644
--- a/vendor/github.com/mgechev/revive/lint/file.go
+++ b/vendor/github.com/mgechev/revive/lint/file.go
@@ -135,15 +135,16 @@ type enableDisableConfig struct {
position int
}
+type disabledIntervalsMap = map[string][]DisabledInterval
+
const (
- directiveRE = `^//[\s]*revive:(enable|disable)(?:-(line|next-line))?(?::([^\s]+))?[\s]*(?: (.+))?$`
directivePos = 1
modifierPos = 2
rulesPos = 3
reasonPos = 4
)
-var re = regexp.MustCompile(directiveRE)
+var directiveRegexp = regexp.MustCompile(`^//[\s]*revive:(enable|disable)(?:-(line|next-line))?(?::([^\s]+))?[\s]*(?: (.+))?$`)
func (f *File) disabledIntervals(rules []Rule, mustSpecifyDisableReason bool, failures chan Failure) disabledIntervalsMap {
enabledDisabledRulesMap := map[string][]enableDisableConfig{}
@@ -153,7 +154,7 @@ func (f *File) disabledIntervals(rules []Rule, mustSpecifyDisableReason bool, fa
for ruleName, disabledArr := range enabledDisabledRulesMap {
ruleResult := []DisabledInterval{}
- for i := 0; i < len(disabledArr); i++ {
+ for i := range disabledArr {
interval := DisabledInterval{
RuleName: ruleName,
From: token.Position{
@@ -194,8 +195,7 @@ func (f *File) disabledIntervals(rules []Rule, mustSpecifyDisableReason bool, fa
enabledDisabledRulesMap[name] = existing
}
- handleRules := func(_, modifier string, isEnabled bool, line int, ruleNames []string) []DisabledInterval {
- var result []DisabledInterval
+ handleRules := func(modifier string, isEnabled bool, line int, ruleNames []string) {
for _, name := range ruleNames {
switch modifier {
case "line":
@@ -208,13 +208,12 @@ func (f *File) disabledIntervals(rules []Rule, mustSpecifyDisableReason bool, fa
handleConfig(isEnabled, line, name)
}
}
- return result
}
- handleComment := func(filename string, c *ast.CommentGroup, line int) {
+ handleComment := func(c *ast.CommentGroup, line int) {
comments := c.List
for _, c := range comments {
- match := re.FindStringSubmatch(c.Text)
+ match := directiveRegexp.FindStringSubmatch(c.Text)
if len(match) == 0 {
continue
}
@@ -247,13 +246,12 @@ func (f *File) disabledIntervals(rules []Rule, mustSpecifyDisableReason bool, fa
}
}
- handleRules(filename, match[modifierPos], match[directivePos] == "enable", line, ruleNames)
+ handleRules(match[modifierPos], match[directivePos] == "enable", line, ruleNames)
}
}
- comments := f.AST.Comments
- for _, c := range comments {
- handleComment(f.Name, c, f.ToPosition(c.End()).Line)
+ for _, c := range f.AST.Comments {
+ handleComment(c, f.ToPosition(c.End()).Line)
}
return getEnabledDisabledIntervals()
diff --git a/vendor/github.com/mgechev/revive/lint/filefilter.go b/vendor/github.com/mgechev/revive/lint/filefilter.go
index fb2c9bba..0e81fede 100644
--- a/vendor/github.com/mgechev/revive/lint/filefilter.go
+++ b/vendor/github.com/mgechev/revive/lint/filefilter.go
@@ -117,7 +117,7 @@ func (ff *FileFilter) prepareRegexp() error {
return nil
}
- // it's whole file mask, just escape dots and normilze separators
+ // it's whole file mask, just escape dots and normalize separators
fillRx := src
fillRx = strings.ReplaceAll(fillRx, "\\", "/")
fillRx = strings.ReplaceAll(fillRx, ".", `\.`)
diff --git a/vendor/github.com/mgechev/revive/lint/linter.go b/vendor/github.com/mgechev/revive/lint/linter.go
index 73b5341b..38f4ae75 100644
--- a/vendor/github.com/mgechev/revive/lint/linter.go
+++ b/vendor/github.com/mgechev/revive/lint/linter.go
@@ -19,8 +19,6 @@ import (
// ReadFile defines an abstraction for reading files.
type ReadFile func(path string) (result []byte, err error)
-type disabledIntervalsMap = map[string][]DisabledInterval
-
// Linter is used for linting set of files.
type Linter struct {
reader ReadFile
diff --git a/vendor/github.com/mgechev/revive/lint/package.go b/vendor/github.com/mgechev/revive/lint/package.go
index dfc701f7..f0c249e6 100644
--- a/vendor/github.com/mgechev/revive/lint/package.go
+++ b/vendor/github.com/mgechev/revive/lint/package.go
@@ -35,14 +35,21 @@ var (
trueValue = 1
falseValue = 2
- go115 = goversion.Must(goversion.NewVersion("1.15"))
- go121 = goversion.Must(goversion.NewVersion("1.21"))
- go122 = goversion.Must(goversion.NewVersion("1.22"))
- go124 = goversion.Must(goversion.NewVersion("1.24"))
+ // Go115 is a constant representing the Go version 1.15
+ Go115 = goversion.Must(goversion.NewVersion("1.15"))
+ // Go121 is a constant representing the Go version 1.21
+ Go121 = goversion.Must(goversion.NewVersion("1.21"))
+ // Go122 is a constant representing the Go version 1.22
+ Go122 = goversion.Must(goversion.NewVersion("1.22"))
+ // Go124 is a constant representing the Go version 1.24
+ Go124 = goversion.Must(goversion.NewVersion("1.24"))
)
// Files return package's files.
func (p *Package) Files() map[string]*File {
+ p.RLock()
+ defer p.RUnlock()
+
return p.files
}
@@ -70,6 +77,7 @@ func (p *Package) IsMain() bool {
func (p *Package) TypesPkg() *types.Package {
p.RLock()
defer p.RUnlock()
+
return p.typesPkg
}
@@ -77,6 +85,7 @@ func (p *Package) TypesPkg() *types.Package {
func (p *Package) TypesInfo() *types.Info {
p.RLock()
defer p.RUnlock()
+
return p.typesInfo
}
@@ -84,6 +93,7 @@ func (p *Package) TypesInfo() *types.Info {
func (p *Package) Sortable() map[string]bool {
p.RLock()
defer p.RUnlock()
+
return p.sortable
}
@@ -146,9 +156,13 @@ func check(config *types.Config, n string, fset *token.FileSet, astFiles []*ast.
// TypeOf returns the type of expression.
func (p *Package) TypeOf(expr ast.Expr) types.Type {
+ p.RLock()
+ defer p.RUnlock()
+
if p.typesInfo == nil {
return nil
}
+
return p.typesInfo.TypeOf(expr)
}
@@ -162,6 +176,9 @@ const (
)
func (p *Package) scanSortable() {
+ p.Lock()
+ defer p.Unlock()
+
sortableFlags := map[string]sortableMethodsFlags{}
for _, f := range p.files {
for _, decl := range f.AST.Decls {
@@ -187,7 +204,7 @@ func (p *Package) scanSortable() {
func (p *Package) lint(rules []Rule, config Config, failures chan Failure) error {
p.scanSortable()
var eg errgroup.Group
- for _, file := range p.files {
+ for _, file := range p.Files() {
eg.Go(func() error {
return file.lint(rules, config, failures)
})
@@ -196,24 +213,12 @@ func (p *Package) lint(rules []Rule, config Config, failures chan Failure) error
return eg.Wait()
}
-// IsAtLeastGo115 returns true if the Go version for this package is 1.15 or higher, false otherwise
-func (p *Package) IsAtLeastGo115() bool {
- return p.goVersion.GreaterThanOrEqual(go115)
-}
-
-// IsAtLeastGo121 returns true if the Go version for this package is 1.21 or higher, false otherwise
-func (p *Package) IsAtLeastGo121() bool {
- return p.goVersion.GreaterThanOrEqual(go121)
-}
-
-// IsAtLeastGo122 returns true if the Go version for this package is 1.22 or higher, false otherwise
-func (p *Package) IsAtLeastGo122() bool {
- return p.goVersion.GreaterThanOrEqual(go122)
-}
+// IsAtLeastGoVersion returns true if the Go version for this package is v or higher, false otherwise
+func (p *Package) IsAtLeastGoVersion(v *goversion.Version) bool {
+ p.RLock()
+ defer p.RUnlock()
-// IsAtLeastGo124 returns true if the Go version for this package is 1.24 or higher, false otherwise
-func (p *Package) IsAtLeastGo124() bool {
- return p.goVersion.GreaterThanOrEqual(go124)
+ return p.goVersion.GreaterThanOrEqual(v)
}
func getSortableMethodFlagForFunction(fn *ast.FuncDecl) sortableMethodsFlags {
diff --git a/vendor/github.com/mgechev/revive/rule/add_constant.go b/vendor/github.com/mgechev/revive/rule/add_constant.go
index c58c369e..90abd4e6 100644
--- a/vendor/github.com/mgechev/revive/rule/add_constant.go
+++ b/vendor/github.com/mgechev/revive/rule/add_constant.go
@@ -212,16 +212,16 @@ func (r *AddConstantRule) Configure(arguments lint.Arguments) error {
}
for k, v := range args {
kind := ""
- switch k {
- case "allowFloats":
+ switch {
+ case isRuleOption(k, "allowFloats"):
kind = kindFLOAT
fallthrough
- case "allowInts":
+ case isRuleOption(k, "allowInts"):
if kind == "" {
kind = kindINT
}
fallthrough
- case "allowStrs":
+ case isRuleOption(k, "allowStrs"):
if kind == "" {
kind = kindSTRING
}
@@ -230,7 +230,7 @@ func (r *AddConstantRule) Configure(arguments lint.Arguments) error {
return fmt.Errorf("invalid argument to the add-constant rule, string expected. Got '%v' (%T)", v, v)
}
r.allowList.add(kind, list)
- case "maxLitCount":
+ case isRuleOption(k, "maxLitCount"):
sl, ok := v.(string)
if !ok {
return fmt.Errorf("invalid argument to the add-constant rule, expecting string representation of an integer. Got '%v' (%T)", v, v)
@@ -241,7 +241,7 @@ func (r *AddConstantRule) Configure(arguments lint.Arguments) error {
return fmt.Errorf("invalid argument to the add-constant rule, expecting string representation of an integer. Got '%v'", v)
}
r.strLitLimit = limit
- case "ignoreFuncs":
+ case isRuleOption(k, "ignoreFuncs"):
excludes, ok := v.(string)
if !ok {
return fmt.Errorf("invalid argument to the ignoreFuncs parameter of add-constant rule, string expected. Got '%v' (%T)", v, v)
diff --git a/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go b/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go
index 0c95c544..53aeae19 100644
--- a/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go
+++ b/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go
@@ -98,8 +98,7 @@ func (v *cognitiveComplexityVisitor) subTreeComplexity(n ast.Node) int {
func (v *cognitiveComplexityVisitor) Visit(n ast.Node) ast.Visitor {
switch n := n.(type) {
case *ast.IfStmt:
- targets := []ast.Node{n.Cond, n.Body, n.Else}
- v.walk(1, targets...)
+ v.walkIfElse(n)
return nil
case *ast.ForStmt:
targets := []ast.Node{n.Cond, n.Body}
@@ -156,6 +155,29 @@ func (v *cognitiveComplexityVisitor) walk(complexityIncrement int, targets ...as
v.nestingLevel = nesting
}
+func (v *cognitiveComplexityVisitor) walkIfElse(n *ast.IfStmt) {
+ var w func(n *ast.IfStmt)
+ w = func(n *ast.IfStmt) {
+ ast.Walk(v, n.Cond)
+ ast.Walk(v, n.Body)
+ if n.Else != nil {
+ if elif, ok := n.Else.(*ast.IfStmt); ok {
+ v.complexity++
+ w(elif)
+ } else {
+ ast.Walk(v, n.Else)
+ }
+ }
+ }
+
+ // Nesting level is incremented in 'if' and 'else' blocks, but only the first 'if' in an 'if-else-if' chain sees its
+ // complexity increased by the nesting level.
+ v.complexity += 1 + v.nestingLevel
+ v.nestingLevel++
+ w(n)
+ v.nestingLevel--
+}
+
func (*cognitiveComplexityVisitor) binExpComplexity(n *ast.BinaryExpr) int {
calculator := binExprComplexityCalculator{opsStack: []token.Token{}}
diff --git a/vendor/github.com/mgechev/revive/rule/context_as_argument.go b/vendor/github.com/mgechev/revive/rule/context_as_argument.go
index f6a1d8ca..273d9695 100644
--- a/vendor/github.com/mgechev/revive/rule/context_as_argument.go
+++ b/vendor/github.com/mgechev/revive/rule/context_as_argument.go
@@ -74,16 +74,14 @@ func (*ContextAsArgumentRule) getAllowTypesFromArguments(args lint.Arguments) (m
return nil, fmt.Errorf("invalid argument to the context-as-argument rule. Expecting a k,v map, got %T", args[0])
}
for k, v := range argKV {
- switch k {
- case "allowTypesBefore":
- typesBefore, ok := v.(string)
- if !ok {
- return nil, fmt.Errorf("invalid argument to the context-as-argument.allowTypesBefore rule. Expecting a string, got %T", v)
- }
- allowTypesBefore = append(allowTypesBefore, strings.Split(typesBefore, ",")...)
- default:
+ if !isRuleOption(k, "allowTypesBefore") {
return nil, fmt.Errorf("invalid argument to the context-as-argument rule. Unrecognized key %s", k)
}
+ typesBefore, ok := v.(string)
+ if !ok {
+ return nil, fmt.Errorf("invalid argument to the context-as-argument.allowTypesBefore rule. Expecting a string, got %T", v)
+ }
+ allowTypesBefore = append(allowTypesBefore, strings.Split(typesBefore, ",")...)
}
}
diff --git a/vendor/github.com/mgechev/revive/rule/datarace.go b/vendor/github.com/mgechev/revive/rule/datarace.go
index a189bc3a..4092c06c 100644
--- a/vendor/github.com/mgechev/revive/rule/datarace.go
+++ b/vendor/github.com/mgechev/revive/rule/datarace.go
@@ -12,7 +12,7 @@ type DataRaceRule struct{}
// Apply applies the rule to given file.
func (r *DataRaceRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
- isGo122 := file.Pkg.IsAtLeastGo122()
+ isGo122 := file.Pkg.IsAtLeastGoVersion(lint.Go122)
var failures []lint.Failure
for _, decl := range file.AST.Decls {
funcDecl, ok := decl.(*ast.FuncDecl)
diff --git a/vendor/github.com/mgechev/revive/rule/defer.go b/vendor/github.com/mgechev/revive/rule/defer.go
index 47771f4f..70213aed 100644
--- a/vendor/github.com/mgechev/revive/rule/defer.go
+++ b/vendor/github.com/mgechev/revive/rule/defer.go
@@ -7,6 +7,15 @@ import (
"github.com/mgechev/revive/lint"
)
+var (
+ deferOptionLoop = normalizeRuleOption("loop")
+ deferOptionCallChain = normalizeRuleOption("callChain")
+ deferOptionMethodCall = normalizeRuleOption("methodCall")
+ deferOptionReturn = normalizeRuleOption("return")
+ deferOptionRecover = normalizeRuleOption("recover")
+ deferOptionImmediateRecover = normalizeRuleOption("immediateRecover")
+)
+
// DeferRule lints gotchas in defer statements.
type DeferRule struct {
allow map[string]bool
@@ -45,12 +54,12 @@ func (*DeferRule) Name() string {
func (*DeferRule) allowFromArgs(args lint.Arguments) (map[string]bool, error) {
if len(args) < 1 {
allow := map[string]bool{
- "loop": true,
- "call-chain": true,
- "method-call": true,
- "return": true,
- "recover": true,
- "immediate-recover": true,
+ deferOptionLoop: true,
+ deferOptionCallChain: true,
+ deferOptionMethodCall: true,
+ deferOptionReturn: true,
+ deferOptionRecover: true,
+ deferOptionImmediateRecover: true,
}
return allow, nil
@@ -67,7 +76,7 @@ func (*DeferRule) allowFromArgs(args lint.Arguments) (map[string]bool, error) {
if !ok {
return nil, fmt.Errorf("invalid argument '%v' for 'defer' rule. Expecting string, got %T", subcase, subcase)
}
- allow[sc] = true
+ allow[normalizeRuleOption(sc)] = true
}
return allow, nil
@@ -94,7 +103,7 @@ func (w lintDeferRule) Visit(node ast.Node) ast.Visitor {
return nil
case *ast.ReturnStmt:
if len(n.Results) != 0 && w.inADefer && w.inAFuncLit {
- w.newFailure("return in a defer function has no effect", n, 1.0, lint.FailureCategoryLogic, "return")
+ w.newFailure("return in a defer function has no effect", n, 1.0, lint.FailureCategoryLogic, deferOptionReturn)
}
case *ast.CallExpr:
isCallToRecover := isIdent(n.Fun, "recover")
@@ -103,13 +112,13 @@ func (w lintDeferRule) Visit(node ast.Node) ast.Visitor {
// func fn() { recover() }
//
// confidence is not 1 because recover can be in a function that is deferred elsewhere
- w.newFailure("recover must be called inside a deferred function", n, 0.8, lint.FailureCategoryLogic, "recover")
+ w.newFailure("recover must be called inside a deferred function", n, 0.8, lint.FailureCategoryLogic, deferOptionRecover)
case w.inADefer && !w.inAFuncLit && isCallToRecover:
// defer helper(recover())
//
// confidence is not truly 1 because this could be in a correctly-deferred func,
// but it is very likely to be a misunderstanding of defer's behavior around arguments.
- w.newFailure("recover must be called inside a deferred function, this is executing recover immediately", n, 1, lint.FailureCategoryLogic, "immediate-recover")
+ w.newFailure("recover must be called inside a deferred function, this is executing recover immediately", n, 1, lint.FailureCategoryLogic, deferOptionImmediateRecover)
}
return nil // no need to analyze the arguments of the function call
case *ast.DeferStmt:
@@ -118,7 +127,7 @@ func (w lintDeferRule) Visit(node ast.Node) ast.Visitor {
//
// confidence is not truly 1 because this could be in a correctly-deferred func,
// but normally this doesn't suppress a panic, and even if it did it would silently discard the value.
- w.newFailure("recover must be called inside a deferred function, this is executing recover immediately", n, 1, lint.FailureCategoryLogic, "immediate-recover")
+ w.newFailure("recover must be called inside a deferred function, this is executing recover immediately", n, 1, lint.FailureCategoryLogic, deferOptionImmediateRecover)
}
w.visitSubtree(n.Call.Fun, true, false, false)
for _, a := range n.Call.Args {
@@ -131,17 +140,17 @@ func (w lintDeferRule) Visit(node ast.Node) ast.Visitor {
}
if w.inALoop {
- w.newFailure("prefer not to defer inside loops", n, 1.0, lint.FailureCategoryBadPractice, "loop")
+ w.newFailure("prefer not to defer inside loops", n, 1.0, lint.FailureCategoryBadPractice, deferOptionLoop)
}
switch fn := n.Call.Fun.(type) {
case *ast.CallExpr:
- w.newFailure("prefer not to defer chains of function calls", fn, 1.0, lint.FailureCategoryBadPractice, "call-chain")
+ w.newFailure("prefer not to defer chains of function calls", fn, 1.0, lint.FailureCategoryBadPractice, deferOptionCallChain)
case *ast.SelectorExpr:
if id, ok := fn.X.(*ast.Ident); ok {
isMethodCall := id != nil && id.Obj != nil && id.Obj.Kind == ast.Typ
if isMethodCall {
- w.newFailure("be careful when deferring calls to methods without pointer receiver", fn, 0.8, lint.FailureCategoryBadPractice, "method-call")
+ w.newFailure("be careful when deferring calls to methods without pointer receiver", fn, 0.8, lint.FailureCategoryBadPractice, deferOptionMethodCall)
}
}
}
diff --git a/vendor/github.com/mgechev/revive/rule/dot_imports.go b/vendor/github.com/mgechev/revive/rule/dot_imports.go
index 3ee4999a..bb86a733 100644
--- a/vendor/github.com/mgechev/revive/rule/dot_imports.go
+++ b/vendor/github.com/mgechev/revive/rule/dot_imports.go
@@ -50,10 +50,13 @@ func (r *DotImportsRule) Configure(arguments lint.Arguments) error {
return fmt.Errorf("invalid argument to the dot-imports rule. Expecting a k,v map, got %T", arguments[0])
}
- if allowedPkgArg, ok := args["allowedPackages"]; ok {
- pkgs, ok := allowedPkgArg.([]any)
+ for k, v := range args {
+ if !isRuleOption(k, "allowedPackages") {
+ continue
+ }
+ pkgs, ok := v.([]any)
if !ok {
- return fmt.Errorf("invalid argument to the dot-imports rule, []string expected. Got '%v' (%T)", allowedPkgArg, allowedPkgArg)
+ return fmt.Errorf("invalid argument to the dot-imports rule, []string expected. Got '%v' (%T)", v, v)
}
for _, p := range pkgs {
pkg, ok := p.(string)
diff --git a/vendor/github.com/mgechev/revive/rule/early_return.go b/vendor/github.com/mgechev/revive/rule/early_return.go
index 41557b01..95ba0676 100644
--- a/vendor/github.com/mgechev/revive/rule/early_return.go
+++ b/vendor/github.com/mgechev/revive/rule/early_return.go
@@ -9,11 +9,40 @@ import (
// EarlyReturnRule finds opportunities to reduce nesting by inverting
// the condition of an "if" block.
-type EarlyReturnRule struct{}
+type EarlyReturnRule struct {
+ // preserveScope prevents suggestions that would enlarge variable scope.
+ preserveScope bool
+ // allowJump permits early-return to suggest introducing a new jump
+ // (return, continue, etc) statement to reduce nesting.
+ // By default, suggestions only bring existing jumps earlier.
+ allowJump bool
+}
+
+// Configure validates the rule configuration, and configures the rule accordingly.
+//
+// Configuration implements the [lint.ConfigurableRule] interface.
+func (e *EarlyReturnRule) Configure(arguments lint.Arguments) error {
+ for _, arg := range arguments {
+ sarg, ok := arg.(string)
+ if !ok {
+ continue
+ }
+ switch {
+ case isRuleOption(sarg, "preserveScope"):
+ e.preserveScope = true
+ case isRuleOption(sarg, "allowJump"):
+ e.allowJump = true
+ }
+ }
+ return nil
+}
// Apply applies the rule to given file.
-func (e *EarlyReturnRule) Apply(file *lint.File, args lint.Arguments) []lint.Failure {
- return ifelse.Apply(e.checkIfElse, file.AST, ifelse.TargetIf, args)
+func (e *EarlyReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ return ifelse.Apply(e.checkIfElse, file.AST, ifelse.TargetIf, ifelse.Args{
+ PreserveScope: e.preserveScope,
+ AllowJump: e.allowJump,
+ })
}
// Name returns the rule name.
@@ -21,13 +50,13 @@ func (*EarlyReturnRule) Name() string {
return "early-return"
}
-func (*EarlyReturnRule) checkIfElse(chain ifelse.Chain, args ifelse.Args) (string, bool) {
+func (e *EarlyReturnRule) checkIfElse(chain ifelse.Chain) (string, bool) {
if chain.HasElse {
if !chain.Else.BranchKind.Deviates() {
// this rule only applies if the else-block deviates control flow
return "", false
}
- } else if !args.AllowJump || !chain.AtBlockEnd || !chain.BlockEndKind.Deviates() || chain.If.IsShort() {
+ } else if !e.allowJump || !chain.AtBlockEnd || !chain.BlockEndKind.Deviates() || chain.If.IsShort() {
// this kind of refactor requires introducing a new indented "return", "continue" or "break" statement,
// so ignore unless we are able to outdent multiple statements in exchange.
return "", false
@@ -44,7 +73,7 @@ func (*EarlyReturnRule) checkIfElse(chain ifelse.Chain, args ifelse.Args) (strin
return "", false
}
- if args.PreserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.If.HasDecls()) {
+ if e.preserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.If.HasDecls()) {
// avoid increasing variable scope
return "", false
}
diff --git a/vendor/github.com/mgechev/revive/rule/enforce_repeated_arg_type_style.go b/vendor/github.com/mgechev/revive/rule/enforce_repeated_arg_type_style.go
index ab466f5f..8a5d9b36 100644
--- a/vendor/github.com/mgechev/revive/rule/enforce_repeated_arg_type_style.go
+++ b/vendor/github.com/mgechev/revive/rule/enforce_repeated_arg_type_style.go
@@ -69,8 +69,8 @@ func (r *EnforceRepeatedArgTypeStyleRule) Configure(arguments lint.Arguments) er
r.funcRetValStyle = valstyle
case map[string]any: // expecting map[string]string
for k, v := range funcArgStyle {
- switch k {
- case "funcArgStyle":
+ switch {
+ case isRuleOption(k, "funcArgStyle"):
val, ok := v.(string)
if !ok {
return fmt.Errorf("invalid map value type for 'enforce-repeated-arg-type-style' rule. Expecting string, got %T", v)
@@ -80,7 +80,7 @@ func (r *EnforceRepeatedArgTypeStyleRule) Configure(arguments lint.Arguments) er
return err
}
r.funcArgStyle = valstyle
- case "funcRetValStyle":
+ case isRuleOption(k, "funcRetValStyle"):
val, ok := v.(string)
if !ok {
return fmt.Errorf("invalid map value '%v' for 'enforce-repeated-arg-type-style' rule. Expecting string, got %T", v, v)
diff --git a/vendor/github.com/mgechev/revive/rule/error_strings.go b/vendor/github.com/mgechev/revive/rule/error_strings.go
index 839a613a..ea295f8d 100644
--- a/vendor/github.com/mgechev/revive/rule/error_strings.go
+++ b/vendor/github.com/mgechev/revive/rule/error_strings.go
@@ -37,14 +37,19 @@ func (r *ErrorStringsRule) Configure(arguments lint.Arguments) error {
var invalidCustomFunctions []string
for _, argument := range arguments {
- if functionName, ok := argument.(string); ok {
- fields := strings.Split(strings.TrimSpace(functionName), ".")
- if len(fields) != 2 || len(fields[0]) == 0 || len(fields[1]) == 0 {
- invalidCustomFunctions = append(invalidCustomFunctions, functionName)
- continue
- }
- r.errorFunctions[fields[0]] = map[string]struct{}{fields[1]: {}}
+ pkgFunction, ok := argument.(string)
+ if !ok {
+ continue
}
+ pkg, function, ok := strings.Cut(strings.TrimSpace(pkgFunction), ".")
+ if !ok || pkg == "" || function == "" {
+ invalidCustomFunctions = append(invalidCustomFunctions, pkgFunction)
+ continue
+ }
+ if _, ok := r.errorFunctions[pkg]; !ok {
+ r.errorFunctions[pkg] = map[string]struct{}{}
+ }
+ r.errorFunctions[pkg][function] = struct{}{}
}
if len(invalidCustomFunctions) != 0 {
return fmt.Errorf("found invalid custom function: %s", strings.Join(invalidCustomFunctions, ","))
@@ -173,21 +178,29 @@ func (lintErrorStrings) checkArg(expr *ast.CallExpr, arg int) (s *ast.BasicLit,
func lintErrorString(s string) (isClean bool, conf float64) {
const basicConfidence = 0.8
const capConfidence = basicConfidence - 0.2
- first, firstN := utf8.DecodeRuneInString(s)
+
last, _ := utf8.DecodeLastRuneInString(s)
if last == '.' || last == ':' || last == '!' || last == '\n' {
return false, basicConfidence
}
- if unicode.IsUpper(first) {
- // People use proper nouns and exported Go identifiers in error strings,
- // so decrease the confidence of warnings for capitalization.
- if len(s) <= firstN {
- return false, capConfidence
+
+ first, firstN := utf8.DecodeRuneInString(s)
+ if !unicode.IsUpper(first) {
+ return true, 0
+ }
+
+ // People use proper nouns and exported Go identifiers in error strings,
+ // so decrease the confidence of warnings for capitalization.
+ for _, r := range s[firstN:] {
+ if unicode.IsSpace(r) {
+ break
}
- // Flag strings starting with something that doesn't look like an initialism.
- if second, _ := utf8.DecodeRuneInString(s[firstN:]); !unicode.IsUpper(second) {
- return false, capConfidence
+
+ if unicode.IsUpper(r) || unicode.IsDigit(r) {
+ return true, 0 // accept words with more than 2 capital letters or digits (e.g. GitHub, URLs, I2000)
}
}
- return true, 0
+
+ // Flag strings starting with something that doesn't look like an initialism.
+ return false, capConfidence
}
diff --git a/vendor/github.com/mgechev/revive/rule/exported.go b/vendor/github.com/mgechev/revive/rule/exported.go
index 7d59c4de..2bcc458a 100644
--- a/vendor/github.com/mgechev/revive/rule/exported.go
+++ b/vendor/github.com/mgechev/revive/rule/exported.go
@@ -19,7 +19,7 @@ type disabledChecks struct {
Method bool
PrivateReceivers bool
PublicInterfaces bool
- Stuttering bool
+ RepetitiveNames bool
Type bool
Var bool
}
@@ -46,7 +46,7 @@ func (dc *disabledChecks) isDisabled(checkName string) bool {
case checkNamePublicInterfaces:
return dc.PublicInterfaces
case checkNameStuttering:
- return dc.Stuttering
+ return dc.RepetitiveNames
case "type":
return dc.Type
default:
@@ -65,37 +65,37 @@ var commonMethods = map[string]bool{
// ExportedRule lints naming and commenting conventions on exported symbols.
type ExportedRule struct {
- stuttersMsg string
- disabledChecks disabledChecks
+ isRepetitiveMsg string
+ disabledChecks disabledChecks
}
// Configure validates the rule configuration, and configures the rule accordingly.
//
-// Configuration implements the [lint.ConfigurableRule] interface.
+// Configure makes the rule implement the [lint.ConfigurableRule] interface.
func (r *ExportedRule) Configure(arguments lint.Arguments) error {
r.disabledChecks = disabledChecks{PrivateReceivers: true, PublicInterfaces: true}
- r.stuttersMsg = "stutters"
+ r.isRepetitiveMsg = "stutters"
for _, flag := range arguments {
switch flag := flag.(type) {
case string:
- switch flag {
- case "checkPrivateReceivers":
+ switch {
+ case isRuleOption(flag, "checkPrivateReceivers"):
r.disabledChecks.PrivateReceivers = false
- case "disableStutteringCheck":
- r.disabledChecks.Stuttering = true
- case "sayRepetitiveInsteadOfStutters":
- r.stuttersMsg = "is repetitive"
- case "checkPublicInterface":
+ case isRuleOption(flag, "disableStutteringCheck"):
+ r.disabledChecks.RepetitiveNames = true
+ case isRuleOption(flag, "sayRepetitiveInsteadOfStutters"):
+ r.isRepetitiveMsg = "is repetitive"
+ case isRuleOption(flag, "checkPublicInterface"):
r.disabledChecks.PublicInterfaces = false
- case "disableChecksOnConstants":
+ case isRuleOption(flag, "disableChecksOnConstants"):
r.disabledChecks.Const = true
- case "disableChecksOnFunctions":
+ case isRuleOption(flag, "disableChecksOnFunctions"):
r.disabledChecks.Function = true
- case "disableChecksOnMethods":
+ case isRuleOption(flag, "disableChecksOnMethods"):
r.disabledChecks.Method = true
- case "disableChecksOnTypes":
+ case isRuleOption(flag, "disableChecksOnTypes"):
r.disabledChecks.Type = true
- case "disableChecksOnVariables":
+ case isRuleOption(flag, "disableChecksOnVariables"):
r.disabledChecks.Var = true
default:
return fmt.Errorf("unknown configuration flag %s for %s rule", flag, r.Name())
@@ -115,20 +115,17 @@ func (r *ExportedRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
return failures
}
- fileAst := file.AST
-
walker := lintExported{
- file: file,
- fileAst: fileAst,
+ file: file,
onFailure: func(failure lint.Failure) {
failures = append(failures, failure)
},
genDeclMissingComments: map[*ast.GenDecl]bool{},
- stuttersMsg: r.stuttersMsg,
+ isRepetitiveMsg: r.isRepetitiveMsg,
disabledChecks: r.disabledChecks,
}
- ast.Walk(&walker, fileAst)
+ ast.Walk(&walker, file.AST)
return failures
}
@@ -140,11 +137,10 @@ func (*ExportedRule) Name() string {
type lintExported struct {
file *lint.File
- fileAst *ast.File
- lastGen *ast.GenDecl
+ lastGenDecl *ast.GenDecl // the last visited general declaration in the AST
genDeclMissingComments map[*ast.GenDecl]bool
onFailure func(lint.Failure)
- stuttersMsg string
+ isRepetitiveMsg string
disabledChecks disabledChecks
}
@@ -155,26 +151,13 @@ func (w *lintExported) lintFuncDoc(fn *ast.FuncDecl) {
kind := "function"
name := fn.Name.Name
- isMethod := fn.Recv != nil && len(fn.Recv.List) > 0
- if isMethod {
- kind = "method"
- recv := typeparams.ReceiverType(fn)
-
- if !ast.IsExported(recv) && w.disabledChecks.PrivateReceivers {
- return
- }
-
- if commonMethods[name] {
+ if isMethod := fn.Recv != nil && len(fn.Recv.List) > 0; isMethod {
+ if !w.mustCheckMethod(fn) {
return
}
- switch name {
- case "Len", "Less", "Swap":
- sortables := w.file.Pkg.Sortable()
- if sortables[recv] {
- return
- }
- }
+ kind = "method"
+ recv := typeparams.ReceiverType(fn)
name = recv + "." + name
}
@@ -182,42 +165,37 @@ func (w *lintExported) lintFuncDoc(fn *ast.FuncDecl) {
return
}
- if !hasTextComment(fn.Doc) {
- w.onFailure(lint.Failure{
- Node: fn,
- Confidence: 1,
- Category: lint.FailureCategoryComments,
- Failure: fmt.Sprintf("exported %s %s should have comment or be unexported", kind, name),
- })
+ firstCommentLine := firstCommentLine(fn.Doc)
+
+ if firstCommentLine == "" {
+ w.addFailuref(fn, 1, lint.FailureCategoryComments,
+ "exported %s %s should have comment or be unexported", kind, name,
+ )
return
}
- s := normalizeText(fn.Doc.Text())
prefix := fn.Name.Name + " "
- if !strings.HasPrefix(s, prefix) {
- w.onFailure(lint.Failure{
- Node: fn.Doc,
- Confidence: 0.8,
- Category: lint.FailureCategoryComments,
- Failure: fmt.Sprintf(`comment on exported %s %s should be of the form "%s..."`, kind, name, prefix),
- })
+ if !strings.HasPrefix(firstCommentLine, prefix) {
+ w.addFailuref(fn.Doc, 0.8, lint.FailureCategoryComments,
+ `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix,
+ )
}
}
-func (w *lintExported) checkStutter(id *ast.Ident, thing string) {
- if w.disabledChecks.Stuttering {
+func (w *lintExported) checkRepetitiveNames(id *ast.Ident, thing string) {
+ if w.disabledChecks.RepetitiveNames {
return
}
- pkg, name := w.fileAst.Name.Name, id.Name
+ pkg, name := w.file.AST.Name.Name, id.Name
if !ast.IsExported(name) {
// unexported name
return
}
- // A name stutters if the package name is a strict prefix
+ // A name is repetitive if the package name is a strict prefix
// and the next character of the name starts a new word.
if len(name) <= len(pkg) {
- // name is too short to stutter.
+ // name is too short to be a repetition.
// This permits the name to be the same as the package name.
return
}
@@ -226,63 +204,74 @@ func (w *lintExported) checkStutter(id *ast.Ident, thing string) {
}
// We can assume the name is well-formed UTF-8.
// If the next rune after the package name is uppercase or an underscore
- // the it's starting a new word and thus this name stutters.
+ // the it's starting a new word and thus this name is repetitive.
rem := name[len(pkg):]
if next, _ := utf8.DecodeRuneInString(rem); next == '_' || unicode.IsUpper(next) {
- w.onFailure(lint.Failure{
- Node: id,
- Confidence: 0.8,
- Category: lint.FailureCategoryNaming,
- Failure: fmt.Sprintf("%s name will be used as %s.%s by other packages, and that %s; consider calling this %s", thing, pkg, name, w.stuttersMsg, rem),
- })
+ w.addFailuref(id, 0.8, lint.FailureCategoryNaming,
+ "%s name will be used as %s.%s by other packages, and that %s; consider calling this %s", thing, pkg, name, w.isRepetitiveMsg, rem,
+ )
}
}
-func (w *lintExported) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup) {
+var articles = [...]string{"A", "An", "The", "This"}
+
+func (w *lintExported) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup, firstCommentLine string) {
if w.disabledChecks.isDisabled("type") {
return
}
- if !ast.IsExported(t.Name.Name) {
+ typeName := t.Name.Name
+
+ if !ast.IsExported(typeName) {
return
}
- if !hasTextComment(doc) {
- w.onFailure(lint.Failure{
- Node: t,
- Confidence: 1,
- Category: lint.FailureCategoryComments,
- Failure: fmt.Sprintf("exported type %v should have comment or be unexported", t.Name),
- })
+ if firstCommentLine == "" {
+ w.addFailuref(t, 1, lint.FailureCategoryComments,
+ "exported type %v should have comment or be unexported", t.Name,
+ )
return
}
- s := normalizeText(doc.Text())
- articles := [...]string{"A", "An", "The", "This"}
for _, a := range articles {
- if t.Name.Name == a {
+ if typeName == a {
continue
}
var found bool
- if s, found = strings.CutPrefix(s, a+" "); found {
+ if firstCommentLine, found = strings.CutPrefix(firstCommentLine, a+" "); found {
break
}
}
// if comment starts with name of type and has some text after - it's ok
- expectedPrefix := t.Name.Name + " "
- if strings.HasPrefix(s, expectedPrefix) {
+ expectedPrefix := typeName + " "
+ if strings.HasPrefix(firstCommentLine, expectedPrefix) {
return
}
- w.onFailure(lint.Failure{
- Node: doc,
- Confidence: 1,
- Category: lint.FailureCategoryComments,
- Failure: fmt.Sprintf(`comment on exported type %v should be of the form "%s..." (with optional leading article)`, t.Name, expectedPrefix),
- })
+ w.addFailuref(doc, 1, lint.FailureCategoryComments,
+ `comment on exported type %v should be of the form "%s..." (with optional leading article)`, t.Name, expectedPrefix,
+ )
}
+// checkValueNames returns true if names check, false otherwise
+func (w *lintExported) checkValueNames(names []*ast.Ident, nodeToBlame ast.Node, kind string) bool {
+ // Check that none are exported except for the first.
+ if len(names) < 2 {
+ return true // nothing to check
+ }
+
+ for _, n := range names[1:] {
+ if ast.IsExported(n.Name) {
+ w.addFailuref(nodeToBlame, 1, lint.FailureCategoryComments,
+ "exported %s %s should have its own declaration", kind, n.Name,
+ )
+ return false
+ }
+ }
+
+ return true
+}
func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) {
kind := "var"
if gd.Tok == token.CONST {
@@ -293,19 +282,8 @@ func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genD
return
}
- if len(vs.Names) > 1 {
- // Check that none are exported except for the first.
- for _, n := range vs.Names[1:] {
- if ast.IsExported(n.Name) {
- w.onFailure(lint.Failure{
- Category: lint.FailureCategoryComments,
- Confidence: 1,
- Failure: fmt.Sprintf("exported %s %s should have its own declaration", kind, n.Name),
- Node: vs,
- })
- return
- }
- }
+ if !w.checkValueNames(vs.Names, vs, kind) {
+ return
}
// Only one name.
@@ -314,7 +292,9 @@ func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genD
return
}
- if !hasTextComment(vs.Doc) && !hasTextComment(gd.Doc) {
+ vsFirstCommentLine := firstCommentLine(vs.Doc)
+ gdFirstCommentLine := firstCommentLine(gd.Doc)
+ if vsFirstCommentLine == "" && gdFirstCommentLine == "" {
if genDeclMissingComments[gd] {
return
}
@@ -322,90 +302,95 @@ func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genD
if kind == "const" && gd.Lparen.IsValid() {
block = " (or a comment on this block)"
}
- w.onFailure(lint.Failure{
- Confidence: 1,
- Node: vs,
- Category: lint.FailureCategoryComments,
- Failure: fmt.Sprintf("exported %s %s should have comment%s or be unexported", kind, name, block),
- })
+ w.addFailuref(vs, 1, lint.FailureCategoryComments,
+ "exported %s %s should have comment%s or be unexported", kind, name, block,
+ )
genDeclMissingComments[gd] = true
return
}
+
// If this GenDecl has parens and a comment, we don't check its comment form.
- if hasTextComment(gd.Doc) && gd.Lparen.IsValid() {
+ if gdFirstCommentLine != "" && gd.Lparen.IsValid() {
return
}
+
// The relevant text to check will be on either vs.Doc or gd.Doc.
// Use vs.Doc preferentially.
var doc *ast.CommentGroup
switch {
- case hasTextComment(vs.Doc):
+ case vsFirstCommentLine != "":
doc = vs.Doc
- case hasTextComment(vs.Comment) && !hasTextComment(gd.Doc):
+ case vsFirstCommentLine != "" && gdFirstCommentLine == "":
doc = vs.Comment
default:
doc = gd.Doc
}
prefix := name + " "
- s := normalizeText(doc.Text())
- if !strings.HasPrefix(s, prefix) {
- w.onFailure(lint.Failure{
- Confidence: 1,
- Node: doc,
- Category: lint.FailureCategoryComments,
- Failure: fmt.Sprintf(`comment on exported %s %s should be of the form "%s..."`, kind, name, prefix),
- })
+ if !strings.HasPrefix(firstCommentLine(doc), prefix) {
+ w.addFailuref(doc, 1, lint.FailureCategoryComments,
+ `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix,
+ )
}
}
-// hasTextComment returns true if the comment contains a text comment
-// e.g. //go:embed foo.txt a directive comment, not a text comment
-// e.g. //nolint:whatever is a directive comment, not a text comment
-func hasTextComment(comment *ast.CommentGroup) bool {
+// firstCommentLine yields the first line of interest in comment group or "" if there is nothing of interest.
+// An "interesting line" is a comment line that is neither a directive (e.g. //go:...) or a deprecation comment
+// (lines from the first line with a prefix // Deprecated: to the end of the comment group)
+// Empty or spaces-only lines are discarded.
+func firstCommentLine(comment *ast.CommentGroup) (result string) {
if comment == nil {
- return false
+ return ""
}
- // a comment could be directive and not a text comment
- text := comment.Text()
- return text != ""
-}
+ commentWithoutDirectives := comment.Text() // removes directives from the comment block
+ lines := strings.Split(commentWithoutDirectives, "\n")
+ for _, line := range lines {
+ line := strings.TrimSpace(line)
+ if line == "" {
+ continue // ignore empty lines
+ }
+ if strings.HasPrefix(line, "Deprecated: ") {
+ break // ignore deprecation comment line and the subsequent lines of the original comment
+ }
-// normalizeText is a helper function that normalizes comment strings by:
-// * removing one leading space
-//
-// This function is needed because ast.CommentGroup.Text() does not handle //-style and /*-style comments uniformly
-func normalizeText(t string) string {
- return strings.TrimSpace(t)
+ result = line
+ break // first non-directive/non-empty/non-deprecation comment line found
+ }
+
+ return result
}
func (w *lintExported) Visit(n ast.Node) ast.Visitor {
switch v := n.(type) {
case *ast.GenDecl:
- if v.Tok == token.IMPORT {
+ switch v.Tok {
+ case token.IMPORT:
return nil
+ case token.CONST, token.TYPE, token.VAR:
+ w.lastGenDecl = v
}
- // token.CONST, token.TYPE or token.VAR
- w.lastGen = v
return w
case *ast.FuncDecl:
w.lintFuncDoc(v)
if v.Recv == nil {
- // Only check for stutter on functions, not methods.
+ // Only check for repetitive names on functions, not methods.
// Method names are not used package-qualified.
- w.checkStutter(v.Name, "func")
+ w.checkRepetitiveNames(v.Name, "func")
}
// Don't proceed inside funcs.
return nil
case *ast.TypeSpec:
// inside a GenDecl, which usually has the doc
doc := v.Doc
- if !hasTextComment(doc) {
- doc = w.lastGen.Doc
+
+ fcl := firstCommentLine(doc)
+ if fcl == "" {
+ doc = w.lastGenDecl.Doc
+ fcl = firstCommentLine(doc)
}
- w.lintTypeDoc(v, doc)
- w.checkStutter(v.Name, "type")
+ w.lintTypeDoc(v, doc, fcl)
+ w.checkRepetitiveNames(v.Name, "type")
if !w.disabledChecks.PublicInterfaces {
if iface, ok := v.Type.(*ast.InterfaceType); ok {
@@ -417,7 +402,7 @@ func (w *lintExported) Visit(n ast.Node) ast.Visitor {
return nil
case *ast.ValueSpec:
- w.lintValueSpecDoc(v, w.lastGen, w.genDeclMissingComments)
+ w.lintValueSpecDoc(v, w.lastGenDecl, w.genDeclMissingComments)
return nil
}
return w
@@ -437,23 +422,51 @@ func (w *lintExported) lintInterfaceMethod(typeName string, m *ast.Field) {
return
}
name := m.Names[0].Name
- if !hasTextComment(m.Doc) {
- w.onFailure(lint.Failure{
- Node: m,
- Confidence: 1,
- Category: lint.FailureCategoryComments,
- Failure: fmt.Sprintf("public interface method %s.%s should be commented", typeName, name),
- })
+ firstCommentLine := firstCommentLine(m.Doc)
+ if firstCommentLine == "" {
+ w.addFailuref(m, 1, lint.FailureCategoryComments,
+ "public interface method %s.%s should be commented", typeName, name,
+ )
return
}
- s := normalizeText(m.Doc.Text())
+
expectedPrefix := m.Names[0].Name + " "
- if !strings.HasPrefix(s, expectedPrefix) {
- w.onFailure(lint.Failure{
- Node: m.Doc,
- Confidence: 0.8,
- Category: lint.FailureCategoryComments,
- Failure: fmt.Sprintf(`comment on exported interface method %s.%s should be of the form "%s..."`, typeName, name, expectedPrefix),
- })
+ if !strings.HasPrefix(firstCommentLine, expectedPrefix) {
+ w.addFailuref(m.Doc, 0.8, lint.FailureCategoryComments,
+ `comment on exported interface method %s.%s should be of the form "%s..."`, typeName, name, expectedPrefix,
+ )
+ }
+}
+
+// mustCheckMethod returns true if the method must be checked by this rule, false otherwise
+func (w *lintExported) mustCheckMethod(fn *ast.FuncDecl) bool {
+ recv := typeparams.ReceiverType(fn)
+
+ if !ast.IsExported(recv) && w.disabledChecks.PrivateReceivers {
+ return false
}
+
+ name := fn.Name.Name
+ if commonMethods[name] {
+ return false
+ }
+
+ switch name {
+ case "Len", "Less", "Swap":
+ sortables := w.file.Pkg.Sortable()
+ if sortables[recv] {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (w *lintExported) addFailuref(node ast.Node, confidence float64, category lint.FailureCategory, message string, args ...any) {
+ w.onFailure(lint.Failure{
+ Node: node,
+ Confidence: confidence,
+ Category: category,
+ Failure: fmt.Sprintf(message, args...),
+ })
}
diff --git a/vendor/github.com/mgechev/revive/rule/file_length_limit.go b/vendor/github.com/mgechev/revive/rule/file_length_limit.go
index 8a3b3712..a9b4e8da 100644
--- a/vendor/github.com/mgechev/revive/rule/file_length_limit.go
+++ b/vendor/github.com/mgechev/revive/rule/file_length_limit.go
@@ -83,23 +83,23 @@ func (r *FileLengthLimitRule) Configure(arguments lint.Arguments) error {
return fmt.Errorf(`invalid argument to the "file-length-limit" rule. Expecting a k,v map, got %T`, arguments[0])
}
for k, v := range argKV {
- switch k {
- case "max":
+ switch {
+ case isRuleOption(k, "max"):
maxLines, ok := v.(int64)
if !ok || maxLines < 0 {
- return fmt.Errorf(`invalid configuration value for max lines in "file-length-limit" rule; need positive int64 but got %T`, arguments[0])
+ return fmt.Errorf(`invalid configuration value for max lines in "file-length-limit" rule; need positive int64 but got %T`, v)
}
r.max = int(maxLines)
- case "skipComments":
+ case isRuleOption(k, "skipComments"):
skipComments, ok := v.(bool)
if !ok {
- return fmt.Errorf(`invalid configuration value for skip comments in "file-length-limit" rule; need bool but got %T`, arguments[1])
+ return fmt.Errorf(`invalid configuration value for skip comments in "file-length-limit" rule; need bool but got %T`, v)
}
r.skipComments = skipComments
- case "skipBlankLines":
+ case isRuleOption(k, "skipBlankLines"):
skipBlankLines, ok := v.(bool)
if !ok {
- return fmt.Errorf(`invalid configuration value for skip blank lines in "file-length-limit" rule; need bool but got %T`, arguments[2])
+ return fmt.Errorf(`invalid configuration value for skip blank lines in "file-length-limit" rule; need bool but got %T`, v)
}
r.skipBlankLines = skipBlankLines
}
diff --git a/vendor/github.com/mgechev/revive/rule/if_return.go b/vendor/github.com/mgechev/revive/rule/if_return.go
index f9e5ef23..d0f581f8 100644
--- a/vendor/github.com/mgechev/revive/rule/if_return.go
+++ b/vendor/github.com/mgechev/revive/rule/if_return.go
@@ -38,7 +38,7 @@ type lintElseError struct {
func (w *lintElseError) Visit(node ast.Node) ast.Visitor {
switch v := node.(type) {
case *ast.BlockStmt:
- for i := 0; i < len(v.List)-1; i++ {
+ for i := range len(v.List) - 1 {
// if var := whatever; var != nil { return var }
s, ok := v.List[i].(*ast.IfStmt)
if !ok || s.Body == nil || len(s.Body.List) != 1 || s.Else != nil {
diff --git a/vendor/github.com/mgechev/revive/rule/import_alias_naming.go b/vendor/github.com/mgechev/revive/rule/import_alias_naming.go
index 0859150a..94cea78c 100644
--- a/vendor/github.com/mgechev/revive/rule/import_alias_naming.go
+++ b/vendor/github.com/mgechev/revive/rule/import_alias_naming.go
@@ -34,13 +34,13 @@ func (r *ImportAliasNamingRule) Configure(arguments lint.Arguments) error {
}
case map[string]any: // expecting map[string]string
for k, v := range namingRule {
- switch k {
- case "allowRegex":
+ switch {
+ case isRuleOption(k, "allowRegex"):
err := r.setAllowRule(v)
if err != nil {
return err
}
- case "denyRegex":
+ case isRuleOption(k, "denyRegex"):
err := r.setDenyRule(v)
if err != nil {
return err
diff --git a/vendor/github.com/mgechev/revive/rule/indent_error_flow.go b/vendor/github.com/mgechev/revive/rule/indent_error_flow.go
index 4dda64c1..be4734ba 100644
--- a/vendor/github.com/mgechev/revive/rule/indent_error_flow.go
+++ b/vendor/github.com/mgechev/revive/rule/indent_error_flow.go
@@ -6,11 +6,33 @@ import (
)
// IndentErrorFlowRule prevents redundant else statements.
-type IndentErrorFlowRule struct{}
+type IndentErrorFlowRule struct {
+ // preserveScope prevents suggestions that would enlarge variable scope.
+ preserveScope bool
+}
+
+// Configure validates the rule configuration, and configures the rule accordingly.
+//
+// Configuration implements the [lint.ConfigurableRule] interface.
+func (e *IndentErrorFlowRule) Configure(arguments lint.Arguments) error {
+ for _, arg := range arguments {
+ sarg, ok := arg.(string)
+ if !ok {
+ continue
+ }
+ if isRuleOption(sarg, "preserveScope") {
+ e.preserveScope = true
+ }
+ }
+ return nil
+}
// Apply applies the rule to given file.
-func (e *IndentErrorFlowRule) Apply(file *lint.File, args lint.Arguments) []lint.Failure {
- return ifelse.Apply(e.checkIfElse, file.AST, ifelse.TargetElse, args)
+func (e *IndentErrorFlowRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ return ifelse.Apply(e.checkIfElse, file.AST, ifelse.TargetElse, ifelse.Args{
+ PreserveScope: e.preserveScope,
+ // AllowJump is not used by this rule
+ })
}
// Name returns the rule name.
@@ -18,7 +40,7 @@ func (*IndentErrorFlowRule) Name() string {
return "indent-error-flow"
}
-func (*IndentErrorFlowRule) checkIfElse(chain ifelse.Chain, args ifelse.Args) (string, bool) {
+func (e *IndentErrorFlowRule) checkIfElse(chain ifelse.Chain) (string, bool) {
if !chain.HasElse {
return "", false
}
@@ -39,7 +61,7 @@ func (*IndentErrorFlowRule) checkIfElse(chain ifelse.Chain, args ifelse.Args) (s
return "", false
}
- if args.PreserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.Else.HasDecls()) {
+ if e.preserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.Else.HasDecls()) {
// avoid increasing variable scope
return "", false
}
diff --git a/vendor/github.com/mgechev/revive/rule/optimize_operands_order.go b/vendor/github.com/mgechev/revive/rule/optimize_operands_order.go
index c9297d2d..6b3143cb 100644
--- a/vendor/github.com/mgechev/revive/rule/optimize_operands_order.go
+++ b/vendor/github.com/mgechev/revive/rule/optimize_operands_order.go
@@ -18,7 +18,7 @@ func (*OptimizeOperandsOrderRule) Apply(file *lint.File, _ lint.Arguments) []lin
onFailure := func(failure lint.Failure) {
failures = append(failures, failure)
}
- w := lintOptimizeOperandsOrderlExpr{
+ w := lintOptimizeOperandsOrderExpr{
onFailure: onFailure,
}
ast.Walk(w, file.AST)
@@ -30,13 +30,13 @@ func (*OptimizeOperandsOrderRule) Name() string {
return "optimize-operands-order"
}
-type lintOptimizeOperandsOrderlExpr struct {
+type lintOptimizeOperandsOrderExpr struct {
onFailure func(failure lint.Failure)
}
// Visit checks boolean AND and OR expressions to determine
// if swapping their operands may result in an execution speedup.
-func (w lintOptimizeOperandsOrderlExpr) Visit(node ast.Node) ast.Visitor {
+func (w lintOptimizeOperandsOrderExpr) Visit(node ast.Node) ast.Visitor {
binExpr, ok := node.(*ast.BinaryExpr)
if !ok {
return w
diff --git a/vendor/github.com/mgechev/revive/rule/range_val_address.go b/vendor/github.com/mgechev/revive/rule/range_val_address.go
index 239175c6..66980717 100644
--- a/vendor/github.com/mgechev/revive/rule/range_val_address.go
+++ b/vendor/github.com/mgechev/revive/rule/range_val_address.go
@@ -16,7 +16,7 @@ type RangeValAddress struct{}
func (*RangeValAddress) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
var failures []lint.Failure
- if file.Pkg.IsAtLeastGo122() {
+ if file.Pkg.IsAtLeastGoVersion(lint.Go122) {
return failures
}
diff --git a/vendor/github.com/mgechev/revive/rule/range_val_in_closure.go b/vendor/github.com/mgechev/revive/rule/range_val_in_closure.go
index 92078288..a99376fb 100644
--- a/vendor/github.com/mgechev/revive/rule/range_val_in_closure.go
+++ b/vendor/github.com/mgechev/revive/rule/range_val_in_closure.go
@@ -14,7 +14,7 @@ type RangeValInClosureRule struct{}
func (*RangeValInClosureRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
var failures []lint.Failure
- if file.Pkg.IsAtLeastGo122() {
+ if file.Pkg.IsAtLeastGoVersion(lint.Go122) {
return failures
}
diff --git a/vendor/github.com/mgechev/revive/rule/receiver_naming.go b/vendor/github.com/mgechev/revive/rule/receiver_naming.go
index 0327feed..e2737ed8 100644
--- a/vendor/github.com/mgechev/revive/rule/receiver_naming.go
+++ b/vendor/github.com/mgechev/revive/rule/receiver_naming.go
@@ -29,16 +29,14 @@ func (r *ReceiverNamingRule) Configure(arguments lint.Arguments) error {
}
for k, v := range args {
- switch k {
- case "maxLength":
- value, ok := v.(int64)
- if !ok {
- return fmt.Errorf("invalid value %v for argument %s of rule %s, expected integer value got %T", v, k, r.Name(), v)
- }
- r.receiverNameMaxLength = int(value)
- default:
+ if !isRuleOption(k, "maxLength") {
return fmt.Errorf("unknown argument %s for %s rule", k, r.Name())
}
+ value, ok := v.(int64)
+ if !ok {
+ return fmt.Errorf("invalid value %v for argument %s of rule %s, expected integer value got %T", v, k, r.Name(), v)
+ }
+ r.receiverNameMaxLength = int(value)
}
return nil
}
diff --git a/vendor/github.com/mgechev/revive/rule/redefines_builtin_id.go b/vendor/github.com/mgechev/revive/rule/redefines_builtin_id.go
index 62f8d7a2..52c679f1 100644
--- a/vendor/github.com/mgechev/revive/rule/redefines_builtin_id.go
+++ b/vendor/github.com/mgechev/revive/rule/redefines_builtin_id.go
@@ -78,7 +78,7 @@ func (*RedefinesBuiltinIDRule) Apply(file *lint.File, _ lint.Arguments) []lint.F
astFile := file.AST
builtFuncs := maps.Clone(builtFunctions)
- if file.Pkg.IsAtLeastGo121() {
+ if file.Pkg.IsAtLeastGoVersion(lint.Go121) {
maps.Copy(builtFuncs, builtFunctionsAfterGo121)
}
w := &lintRedefinesBuiltinID{
diff --git a/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go b/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go
index d456aa21..01a90a47 100644
--- a/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go
+++ b/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go
@@ -14,7 +14,7 @@ type RedundantTestMainExitRule struct{}
func (*RedundantTestMainExitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
var failures []lint.Failure
- if !file.IsTest() || !file.Pkg.IsAtLeastGo115() {
+ if !file.IsTest() || !file.Pkg.IsAtLeastGoVersion(lint.Go115) {
// skip analysis for non-test files or for Go versions before 1.15
return failures
}
diff --git a/vendor/github.com/mgechev/revive/rule/string_format.go b/vendor/github.com/mgechev/revive/rule/string_format.go
index a3beac43..d539577e 100644
--- a/vendor/github.com/mgechev/revive/rule/string_format.go
+++ b/vendor/github.com/mgechev/revive/rule/string_format.go
@@ -12,20 +12,24 @@ import (
)
// StringFormatRule lints strings and/or comments according to a set of regular expressions given as Arguments
-type StringFormatRule struct{}
+type StringFormatRule struct {
+ rules []stringFormatSubrule
+}
// Apply applies the rule to the given file.
-func (*StringFormatRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
+func (r *StringFormatRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
var failures []lint.Failure
onFailure := func(failure lint.Failure) {
failures = append(failures, failure)
}
- w := &lintStringFormatRule{onFailure: onFailure}
- err := w.parseArguments(arguments)
- if err != nil {
- return newInternalFailureError(err)
+ for i := range r.rules {
+ r.rules[i].onFailure = onFailure
+ }
+
+ w := &lintStringFormatRule{
+ rules: r.rules,
}
ast.Walk(w, file.AST)
@@ -38,32 +42,31 @@ func (*StringFormatRule) Name() string {
return "string-format"
}
-// ParseArgumentsTest is a public wrapper around w.parseArguments used for testing. Returns the error message provided to panic, or nil if no error was encountered
-func (*StringFormatRule) ParseArgumentsTest(arguments lint.Arguments) *string {
- w := lintStringFormatRule{}
- c := make(chan any)
- // Parse the arguments in a goroutine, defer a recover() call, return the error encountered (or nil if there was no error)
- go func() {
- defer func() {
- err := w.parseArguments(arguments)
- c <- err
- }()
- }()
- err := <-c
- if err != nil {
- e := fmt.Sprintf("%s", err)
- return &e
+// Configure validates the rule configuration, and configures the rule accordingly.
+//
+// Configuration implements the [lint.ConfigurableRule] interface.
+func (r *StringFormatRule) Configure(arguments lint.Arguments) error {
+ for i, argument := range arguments {
+ scopes, regex, negated, errorMessage, err := r.parseArgument(argument, i)
+ if err != nil {
+ return err
+ }
+ r.rules = append(r.rules, stringFormatSubrule{
+ scopes: scopes,
+ regexp: regex,
+ negated: negated,
+ errorMessage: errorMessage,
+ })
}
return nil
}
type lintStringFormatRule struct {
- onFailure func(lint.Failure)
- rules []stringFormatSubrule
+ rules []stringFormatSubrule
}
type stringFormatSubrule struct {
- parent *lintStringFormatRule
+ onFailure func(lint.Failure)
scopes stringFormatSubruleScopes
regexp *regexp.Regexp
negated bool
@@ -84,45 +87,28 @@ const identRegex = "[_A-Za-z][_A-Za-z0-9]*"
var parseStringFormatScope = regexp.MustCompile(
fmt.Sprintf("^(%s(?:\\.%s)?)(?:\\[([0-9]+)\\](?:\\.(%s))?)?$", identRegex, identRegex, identRegex))
-func (w *lintStringFormatRule) parseArguments(arguments lint.Arguments) error {
- for i, argument := range arguments {
- scopes, regex, negated, errorMessage, err := w.parseArgument(argument, i)
- if err != nil {
- return err
- }
- w.rules = append(w.rules, stringFormatSubrule{
- parent: w,
- scopes: scopes,
- regexp: regex,
- negated: negated,
- errorMessage: errorMessage,
- })
- }
- return nil
-}
-
-func (w *lintStringFormatRule) parseArgument(argument any, ruleNum int) (scopes stringFormatSubruleScopes, regex *regexp.Regexp, negated bool, errorMessage string, err error) {
+func (r *StringFormatRule) parseArgument(argument any, ruleNum int) (scopes stringFormatSubruleScopes, regex *regexp.Regexp, negated bool, errorMessage string, err error) {
g, ok := argument.([]any) // Cast to generic slice first
if !ok {
- return stringFormatSubruleScopes{}, regex, false, "", w.configError("argument is not a slice", ruleNum, 0)
+ return stringFormatSubruleScopes{}, regex, false, "", r.configError("argument is not a slice", ruleNum, 0)
}
if len(g) < 2 {
- return stringFormatSubruleScopes{}, regex, false, "", w.configError("less than two slices found in argument, scope and regex are required", ruleNum, len(g)-1)
+ return stringFormatSubruleScopes{}, regex, false, "", r.configError("less than two slices found in argument, scope and regex are required", ruleNum, len(g)-1)
}
rule := make([]string, len(g))
for i, obj := range g {
val, ok := obj.(string)
if !ok {
- return stringFormatSubruleScopes{}, regex, false, "", w.configError("unexpected value, string was expected", ruleNum, i)
+ return stringFormatSubruleScopes{}, regex, false, "", r.configError("unexpected value, string was expected", ruleNum, i)
}
rule[i] = val
}
// Validate scope and regex length
if rule[0] == "" {
- return stringFormatSubruleScopes{}, regex, false, "", w.configError("empty scope provided", ruleNum, 0)
+ return stringFormatSubruleScopes{}, regex, false, "", r.configError("empty scope provided", ruleNum, 0)
} else if len(rule[1]) < 2 {
- return stringFormatSubruleScopes{}, regex, false, "", w.configError("regex is too small (regexes should begin and end with '/')", ruleNum, 1)
+ return stringFormatSubruleScopes{}, regex, false, "", r.configError("regex is too small (regexes should begin and end with '/')", ruleNum, 1)
}
// Parse rule scopes
@@ -133,25 +119,25 @@ func (w *lintStringFormatRule) parseArgument(argument any, ruleNum int) (scopes
rawScope = strings.TrimSpace(rawScope)
if len(rawScope) == 0 {
- return stringFormatSubruleScopes{}, regex, false, "", w.parseScopeError("empty scope in rule scopes:", ruleNum, 0, scopeNum)
+ return stringFormatSubruleScopes{}, regex, false, "", r.parseScopeError("empty scope in rule scopes:", ruleNum, 0, scopeNum)
}
scope := stringFormatSubruleScope{}
matches := parseStringFormatScope.FindStringSubmatch(rawScope)
if matches == nil {
// The rule's scope didn't match the parsing regex at all, probably a configuration error
- return stringFormatSubruleScopes{}, regex, false, "", w.parseScopeError("unable to parse rule scope", ruleNum, 0, scopeNum)
+ return stringFormatSubruleScopes{}, regex, false, "", r.parseScopeError("unable to parse rule scope", ruleNum, 0, scopeNum)
} else if len(matches) != 4 {
// The rule's scope matched the parsing regex, but an unexpected number of submatches was returned, probably a bug
return stringFormatSubruleScopes{}, regex, false, "",
- w.parseScopeError(fmt.Sprintf("unexpected number of submatches when parsing scope: %d, expected 4", len(matches)), ruleNum, 0, scopeNum)
+ r.parseScopeError(fmt.Sprintf("unexpected number of submatches when parsing scope: %d, expected 4", len(matches)), ruleNum, 0, scopeNum)
}
scope.funcName = matches[1]
if len(matches[2]) > 0 {
var err error
scope.argument, err = strconv.Atoi(matches[2])
if err != nil {
- return stringFormatSubruleScopes{}, regex, false, "", w.parseScopeError("unable to parse argument number in rule scope", ruleNum, 0, scopeNum)
+ return stringFormatSubruleScopes{}, regex, false, "", r.parseScopeError("unable to parse argument number in rule scope", ruleNum, 0, scopeNum)
}
}
if len(matches[3]) > 0 {
@@ -169,7 +155,7 @@ func (w *lintStringFormatRule) parseArgument(argument any, ruleNum int) (scopes
}
regex, errr := regexp.Compile(rule[1][offset : len(rule[1])-1])
if errr != nil {
- return stringFormatSubruleScopes{}, regex, false, "", w.parseError(fmt.Sprintf("unable to compile %s as regexp", rule[1]), ruleNum, 1)
+ return stringFormatSubruleScopes{}, regex, false, "", r.parseError(fmt.Sprintf("unable to compile %s as regexp", rule[1]), ruleNum, 1)
}
// Use custom error message if provided
@@ -180,17 +166,17 @@ func (w *lintStringFormatRule) parseArgument(argument any, ruleNum int) (scopes
}
// Report an invalid config, this is specifically the user's fault
-func (*lintStringFormatRule) configError(msg string, ruleNum, option int) error {
+func (*StringFormatRule) configError(msg string, ruleNum, option int) error {
return fmt.Errorf("invalid configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option)
}
// Report a general config parsing failure, this may be the user's fault, but it isn't known for certain
-func (*lintStringFormatRule) parseError(msg string, ruleNum, option int) error {
+func (*StringFormatRule) parseError(msg string, ruleNum, option int) error {
return fmt.Errorf("failed to parse configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option)
}
// Report a general scope config parsing failure, this may be the user's fault, but it isn't known for certain
-func (*lintStringFormatRule) parseScopeError(msg string, ruleNum, option, scopeNum int) error {
+func (*StringFormatRule) parseScopeError(msg string, ruleNum, option, scopeNum int) error {
return fmt.Errorf("failed to parse configuration for string-format: %s [argument %d, option %d, scope index %d]", msg, ruleNum, option, scopeNum)
}
@@ -314,7 +300,7 @@ func (r *stringFormatSubrule) generateFailure(node ast.Node) {
failure = fmt.Sprintf("string literal doesn't match user defined regex /%s/", r.regexp.String())
}
- r.parent.onFailure(lint.Failure{
+ r.onFailure(lint.Failure{
Confidence: 1,
Failure: failure,
Node: node,
diff --git a/vendor/github.com/mgechev/revive/rule/struct_tag.go b/vendor/github.com/mgechev/revive/rule/struct_tag.go
index 00a2b964..5cfa31c8 100644
--- a/vendor/github.com/mgechev/revive/rule/struct_tag.go
+++ b/vendor/github.com/mgechev/revive/rule/struct_tag.go
@@ -3,6 +3,7 @@ package rule
import (
"fmt"
"go/ast"
+ "slices"
"strconv"
"strings"
@@ -12,7 +13,62 @@ import (
// StructTagRule lints struct tags.
type StructTagRule struct {
- userDefined map[string][]string // map: key -> []option
+ userDefined map[tagKey][]string // map: key -> []option
+}
+
+type tagKey string
+
+const (
+ keyASN1 tagKey = "asn1"
+ keyBSON tagKey = "bson"
+ keyDatastore tagKey = "datastore"
+ keyDefault tagKey = "default"
+ keyJSON tagKey = "json"
+ keyMapstructure tagKey = "mapstructure"
+ keyProperties tagKey = "properties"
+ keyProtobuf tagKey = "protobuf"
+ keyRequired tagKey = "required"
+ keyTOML tagKey = "toml"
+ keyURL tagKey = "url"
+ keyValidate tagKey = "validate"
+ keyXML tagKey = "xml"
+ keyYAML tagKey = "yaml"
+)
+
+type tagChecker func(checkCtx *checkContext, tag *structtag.Tag, fieldType ast.Expr) (message string, succeeded bool)
+
+// populate tag checkers map
+var tagCheckers = map[tagKey]tagChecker{
+ keyASN1: checkASN1Tag,
+ keyBSON: checkBSONTag,
+ keyDatastore: checkDatastoreTag,
+ keyDefault: checkDefaultTag,
+ keyJSON: checkJSONTag,
+ keyMapstructure: checkMapstructureTag,
+ keyProperties: checkPropertiesTag,
+ keyProtobuf: checkProtobufTag,
+ keyRequired: checkRequiredTag,
+ keyTOML: checkTOMLTag,
+ keyURL: checkURLTag,
+ keyValidate: checkValidateTag,
+ keyXML: checkXMLTag,
+ keyYAML: checkYAMLTag,
+}
+
+type checkContext struct {
+ userDefined map[tagKey][]string // map: key -> []option
+ usedTagNbr map[int]bool // list of used tag numbers
+ usedTagName map[string]bool // list of used tag keys
+ isAtLeastGo124 bool
+}
+
+func (checkCtx checkContext) isUserDefined(key tagKey, opt string) bool {
+ if checkCtx.userDefined == nil {
+ return false
+ }
+
+ options := checkCtx.userDefined[key]
+ return slices.Contains(options, opt)
}
// Configure validates the rule configuration, and configures the rule accordingly.
@@ -27,7 +83,8 @@ func (r *StructTagRule) Configure(arguments lint.Arguments) error {
if err != nil {
return err
}
- r.userDefined = make(map[string][]string, len(arguments))
+
+ r.userDefined = make(map[tagKey][]string, len(arguments))
for _, arg := range arguments {
item, ok := arg.(string)
if !ok {
@@ -37,12 +94,13 @@ func (r *StructTagRule) Configure(arguments lint.Arguments) error {
if len(parts) < 2 {
return fmt.Errorf("invalid argument to the %s rule. Expecting a string of the form key[,option]+, got %s", r.Name(), item)
}
- key := strings.TrimSpace(parts[0])
+ key := tagKey(strings.TrimSpace(parts[0]))
for i := 1; i < len(parts); i++ {
option := strings.TrimSpace(parts[i])
r.userDefined[key] = append(r.userDefined[key], option)
}
}
+
return nil
}
@@ -56,7 +114,8 @@ func (r *StructTagRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure
w := lintStructTagRule{
onFailure: onFailure,
userDefined: r.userDefined,
- isAtLeastGo124: file.Pkg.IsAtLeastGo124(),
+ isAtLeastGo124: file.Pkg.IsAtLeastGoVersion(lint.Go124),
+ tagCheckers: tagCheckers,
}
ast.Walk(w, file.AST)
@@ -71,10 +130,9 @@ func (*StructTagRule) Name() string {
type lintStructTagRule struct {
onFailure func(lint.Failure)
- userDefined map[string][]string // map: key -> []option
- usedTagNbr map[int]bool // list of used tag numbers
- usedTagName map[string]bool // list of used tag keys
+ userDefined map[tagKey][]string // map: key -> []option
isAtLeastGo124 bool
+ tagCheckers map[tagKey]tagChecker
}
func (w lintStructTagRule) Visit(node ast.Node) ast.Visitor {
@@ -85,11 +143,16 @@ func (w lintStructTagRule) Visit(node ast.Node) ast.Visitor {
return nil // skip empty structs
}
- w.usedTagNbr = map[int]bool{}
- w.usedTagName = map[string]bool{}
+ checkCtx := &checkContext{
+ userDefined: w.userDefined,
+ usedTagNbr: map[int]bool{},
+ usedTagName: map[string]bool{},
+ isAtLeastGo124: w.isAtLeastGo124,
+ }
+
for _, f := range n.Fields.List {
if f.Tag != nil {
- w.checkTaggedField(f)
+ w.checkTaggedField(checkCtx, f)
}
}
}
@@ -97,24 +160,44 @@ func (w lintStructTagRule) Visit(node ast.Node) ast.Visitor {
return w
}
-const (
- keyASN1 = "asn1"
- keyBSON = "bson"
- keyDefault = "default"
- keyJSON = "json"
- keyProtobuf = "protobuf"
- keyRequired = "required"
- keyXML = "xml"
- keyYAML = "yaml"
-)
+// checkTaggedField checks the tag of the given field.
+// precondition: the field has a tag
+func (w lintStructTagRule) checkTaggedField(checkCtx *checkContext, f *ast.Field) {
+ if len(f.Names) > 0 && !f.Names[0].IsExported() {
+ w.addFailuref(f, "tag on not-exported field %s", f.Names[0].Name)
+ }
+
+ tags, err := structtag.Parse(strings.Trim(f.Tag.Value, "`"))
+ if err != nil || tags == nil {
+ w.addFailuref(f.Tag, "malformed tag")
+ return
+ }
-func (w lintStructTagRule) checkTagNameIfNeed(tag *structtag.Tag) (string, bool) {
+ for _, tag := range tags.Tags() {
+ if msg, ok := w.checkTagNameIfNeed(checkCtx, tag); !ok {
+ w.addFailureWithTagKey(f.Tag, msg, tag.Key)
+ }
+
+ checker, ok := w.tagCheckers[tagKey(tag.Key)]
+ if !ok {
+ continue // we don't have a checker for the tag
+ }
+
+ msg, ok := checker(checkCtx, tag, f.Type)
+ if !ok {
+ w.addFailureWithTagKey(f.Tag, msg, tag.Key)
+ }
+ }
+}
+
+func (w lintStructTagRule) checkTagNameIfNeed(checkCtx *checkContext, tag *structtag.Tag) (message string, succeeded bool) {
isUnnamedTag := tag.Name == "" || tag.Name == "-"
if isUnnamedTag {
return "", true
}
- switch tag.Key {
+ key := tagKey(tag.Key)
+ switch key {
case keyBSON, keyJSON, keyXML, keyYAML, keyProtobuf:
default:
return "", true
@@ -127,22 +210,23 @@ func (w lintStructTagRule) checkTagNameIfNeed(tag *structtag.Tag) (string, bool)
// We concat the key and name as the mapping key here
// to allow the same tag name in different tag type.
- key := tag.Key + ":" + tagName
- if _, ok := w.usedTagName[key]; ok {
- return fmt.Sprintf("duplicate tag name: '%s'", tagName), false
+ mapKey := tag.Key + ":" + tagName
+ if _, ok := checkCtx.usedTagName[mapKey]; ok {
+ return fmt.Sprintf("duplicated tag name %q", tagName), false
}
- w.usedTagName[key] = true
+ checkCtx.usedTagName[mapKey] = true
return "", true
}
func (lintStructTagRule) getTagName(tag *structtag.Tag) string {
- switch tag.Key {
+ key := tagKey(tag.Key)
+ switch key {
case keyProtobuf:
for _, option := range tag.Options {
- if tagName, found := strings.CutPrefix(option, "name="); found {
- return tagName
+ if tagKey, found := strings.CutPrefix(option, "name="); found {
+ return tagKey
}
}
return "" // protobuf tag lacks 'name' option
@@ -151,185 +235,353 @@ func (lintStructTagRule) getTagName(tag *structtag.Tag) string {
}
}
-// checkTaggedField checks the tag of the given field.
-// precondition: the field has a tag
-func (w lintStructTagRule) checkTaggedField(f *ast.Field) {
- if len(f.Names) > 0 && !f.Names[0].IsExported() {
- w.addFailure(f, "tag on not-exported field "+f.Names[0].Name)
+func checkASN1Tag(checkCtx *checkContext, tag *structtag.Tag, fieldType ast.Expr) (message string, succeeded bool) {
+ checkList := append(tag.Options, tag.Name)
+ for _, opt := range checkList {
+ switch opt {
+ case "application", "explicit", "generalized", "ia5", "omitempty", "optional", "set", "utf8":
+ // do nothing
+ default:
+ msg, ok := checkCompoundANS1Option(checkCtx, opt, fieldType)
+ if !ok {
+ return msg, false
+ }
+ }
}
- tags, err := structtag.Parse(strings.Trim(f.Tag.Value, "`"))
- if err != nil || tags == nil {
- w.addFailure(f.Tag, "malformed tag")
- return
- }
+ return "", true
+}
- for _, tag := range tags.Tags() {
- if msg, ok := w.checkTagNameIfNeed(tag); !ok {
- w.addFailure(f.Tag, msg)
+func checkCompoundANS1Option(checkCtx *checkContext, opt string, fieldType ast.Expr) (message string, succeeded bool) {
+ key, value, _ := strings.Cut(opt, ":")
+ switch key {
+ case "tag":
+ number, err := strconv.Atoi(value)
+ if err != nil {
+ return fmt.Sprintf("tag must be a number but is %q", value), false
+ }
+ if checkCtx.usedTagNbr[number] {
+ return fmt.Sprintf(msgDuplicatedTagNumber, number), false
+ }
+ checkCtx.usedTagNbr[number] = true
+ case "default":
+ if !typeValueMatch(fieldType, value) {
+ return msgTypeMismatch, false
+ }
+ default:
+ if !checkCtx.isUserDefined(keyASN1, opt) {
+ return fmt.Sprintf(msgUnknownOption, opt), false
}
+ }
+ return "", true
+}
- switch key := tag.Key; key {
- case keyASN1:
- msg, ok := w.checkASN1Tag(f.Type, tag)
- if !ok {
- w.addFailure(f.Tag, msg)
- }
- case keyBSON:
- msg, ok := w.checkBSONTag(tag.Options)
- if !ok {
- w.addFailure(f.Tag, msg)
- }
- case keyDefault:
- if !w.typeValueMatch(f.Type, tag.Name) {
- w.addFailure(f.Tag, "field's type and default value's type mismatch")
- }
- case keyJSON:
- msg, ok := w.checkJSONTag(tag.Name, tag.Options)
- if !ok {
- w.addFailure(f.Tag, msg)
- }
- case keyProtobuf:
- msg, ok := w.checkProtobufTag(tag)
- if !ok {
- w.addFailure(f.Tag, msg)
+func checkDatastoreTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ for _, opt := range tag.Options {
+ switch opt {
+ case "flatten", "noindex", "omitempty":
+ default:
+ if checkCtx.isUserDefined(keyDatastore, opt) {
+ continue
}
- case keyRequired:
- if tag.Name != "true" && tag.Name != "false" {
- w.addFailure(f.Tag, "required should be 'true' or 'false'")
+ return fmt.Sprintf(msgUnknownOption, opt), false
+ }
+ }
+
+ return "", true
+}
+
+func checkDefaultTag(_ *checkContext, tag *structtag.Tag, fieldType ast.Expr) (message string, succeeded bool) {
+ if !typeValueMatch(fieldType, tag.Name) {
+ return msgTypeMismatch, false
+ }
+
+ return "", true
+}
+
+func checkBSONTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ for _, opt := range tag.Options {
+ switch opt {
+ case "inline", "minsize", "omitempty":
+ default:
+ if checkCtx.isUserDefined(keyBSON, opt) {
+ continue
}
- case keyXML:
- msg, ok := w.checkXMLTag(tag.Options)
- if !ok {
- w.addFailure(f.Tag, msg)
+ return fmt.Sprintf(msgUnknownOption, opt), false
+ }
+ }
+
+ return "", true
+}
+
+func checkJSONTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ for _, opt := range tag.Options {
+ switch opt {
+ case "omitempty", "string":
+ case "":
+ // special case for JSON key "-"
+ if tag.Name != "-" {
+ return "option can not be empty", false
}
- case keyYAML:
- msg, ok := w.checkYAMLTag(tag.Options)
- if !ok {
- w.addFailure(f.Tag, msg)
+ case "omitzero":
+ if checkCtx.isAtLeastGo124 {
+ continue
}
+ return `prior Go 1.24, option "omitzero" is unsupported`, false
default:
- // unknown key
+ if checkCtx.isUserDefined(keyJSON, opt) {
+ continue
+ }
+ return fmt.Sprintf(msgUnknownOption, opt), false
}
}
+
+ return "", true
}
-func (w lintStructTagRule) checkASN1Tag(t ast.Expr, tag *structtag.Tag) (string, bool) {
- checkList := append(tag.Options, tag.Name)
- for _, opt := range checkList {
+func checkMapstructureTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ for _, opt := range tag.Options {
switch opt {
- case "application", "explicit", "generalized", "ia5", "omitempty", "optional", "set", "utf8":
-
+ case "omitempty", "reminder", "squash":
default:
- if strings.HasPrefix(opt, "tag:") {
- parts := strings.Split(opt, ":")
- tagNumber := parts[1]
- number, err := strconv.Atoi(tagNumber)
- if err != nil {
- return fmt.Sprintf("ASN1 tag must be a number, got '%s'", tagNumber), false
- }
- if w.usedTagNbr[number] {
- return fmt.Sprintf("duplicated tag number %v", number), false
- }
- w.usedTagNbr[number] = true
-
+ if checkCtx.isUserDefined(keyMapstructure, opt) {
continue
}
+ return fmt.Sprintf(msgUnknownOption, opt), false
+ }
+ }
- if strings.HasPrefix(opt, "default:") {
- parts := strings.Split(opt, ":")
- if len(parts) < 2 {
- return "malformed default for ASN1 tag", false
- }
- if !w.typeValueMatch(t, parts[1]) {
- return "field's type and default value's type mismatch", false
- }
+ return "", true
+}
- continue
+func checkPropertiesTag(_ *checkContext, tag *structtag.Tag, fieldType ast.Expr) (message string, succeeded bool) {
+ options := tag.Options
+ if len(options) == 0 {
+ return "", true
+ }
+
+ seenOptions := map[string]bool{}
+ for _, opt := range options {
+ msg, ok := fmt.Sprintf("unknown or malformed option %q", opt), false
+ if key, value, found := strings.Cut(opt, "="); found {
+ msg, ok = checkCompoundPropertiesOption(key, value, fieldType, seenOptions)
+ }
+
+ if !ok {
+ return msg, false
+ }
+ }
+
+ return "", true
+}
+
+func checkCompoundPropertiesOption(key, value string, fieldType ast.Expr, seenOptions map[string]bool) (message string, succeeded bool) {
+ if _, ok := seenOptions[key]; ok {
+ return fmt.Sprintf(msgDuplicatedOption, key), false
+ }
+ seenOptions[key] = true
+
+ if strings.TrimSpace(value) == "" {
+ return fmt.Sprintf("option %q not of the form %s=value", key, key), false
+ }
+
+ switch key {
+ case "default":
+ if !typeValueMatch(fieldType, value) {
+ return msgTypeMismatch, false
+ }
+ case "layout":
+ if gofmt(fieldType) != "time.Time" {
+ return "layout option is only applicable to fields of type time.Time", false
+ }
+ }
+
+ return "", true
+}
+
+func checkProtobufTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ // check name
+ switch tag.Name {
+ case "bytes", "fixed32", "fixed64", "group", "varint", "zigzag32", "zigzag64":
+ // do nothing
+ default:
+ return fmt.Sprintf("invalid tag name %q", tag.Name), false
+ }
+
+ return checkProtobufOptions(checkCtx, tag.Options)
+}
+
+func checkProtobufOptions(checkCtx *checkContext, options []string) (message string, succeeded bool) {
+ seenOptions := map[string]bool{}
+ hasName := false
+ for _, opt := range options {
+ opt := strings.Split(opt, "=")[0]
+
+ if number, err := strconv.Atoi(opt); err == nil {
+ _, alreadySeen := checkCtx.usedTagNbr[number]
+ if alreadySeen {
+ return fmt.Sprintf(msgDuplicatedTagNumber, number), false
}
+ checkCtx.usedTagNbr[number] = true
+ continue // option is an integer
+ }
- if w.isUserDefined(keyASN1, opt) {
+ switch opt {
+ case "json", "opt", "proto3", "rep", "req":
+ // do nothing
+ case "name":
+ hasName = true
+ default:
+ if checkCtx.isUserDefined(keyProtobuf, opt) {
continue
}
+ return fmt.Sprintf(msgUnknownOption, opt), false
+ }
- return fmt.Sprintf("unknown option '%s' in ASN1 tag", opt), false
+ _, alreadySeen := seenOptions[opt]
+ if alreadySeen {
+ return fmt.Sprintf(msgDuplicatedOption, opt), false
}
+ seenOptions[opt] = true
+ }
+
+ if !hasName {
+ return `mandatory option "name" not found`, false
}
return "", true
}
-func (w lintStructTagRule) checkBSONTag(options []string) (string, bool) {
- for _, opt := range options {
+func checkRequiredTag(_ *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ switch tag.Name {
+ case "true", "false":
+ return "", true
+ default:
+ return `required should be "true" or "false"`, false
+ }
+}
+
+func checkTOMLTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ for _, opt := range tag.Options {
switch opt {
- case "inline", "minsize", "omitempty":
+ case "omitempty":
default:
- if w.isUserDefined(keyBSON, opt) {
+ if checkCtx.isUserDefined(keyTOML, opt) {
continue
}
- return fmt.Sprintf("unknown option '%s' in BSON tag", opt), false
+ return fmt.Sprintf(msgUnknownOption, opt), false
}
}
return "", true
}
-func (w lintStructTagRule) checkJSONTag(name string, options []string) (string, bool) {
- for _, opt := range options {
+func checkURLTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ var delimiter = ""
+ for _, opt := range tag.Options {
switch opt {
- case "omitempty", "string":
- case "":
- // special case for JSON key "-"
- if name != "-" {
- return "option can not be empty in JSON tag", false
- }
- case "omitzero":
- if w.isAtLeastGo124 {
+ case "int", "omitempty", "numbered", "brackets":
+ case "unix", "unixmilli", "unixnano": // TODO : check that the field is of type time.Time
+ case "comma", "semicolon", "space":
+ if delimiter == "" {
+ delimiter = opt
continue
}
- fallthrough
+ return fmt.Sprintf("can not set both %q and %q as delimiters", opt, delimiter), false
default:
- if w.isUserDefined(keyJSON, opt) {
+ if checkCtx.isUserDefined(keyURL, opt) {
continue
}
- return fmt.Sprintf("unknown option '%s' in JSON tag", opt), false
+ return fmt.Sprintf(msgUnknownOption, opt), false
}
}
return "", true
}
-func (w lintStructTagRule) checkXMLTag(options []string) (string, bool) {
+func checkValidateTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ previousOption := ""
+ seenKeysOption := false
+ options := append([]string{tag.Name}, tag.Options...)
for _, opt := range options {
+ switch opt {
+ case "keys":
+ if previousOption != "dive" {
+ return `option "keys" must follow a "dive" option`, false
+ }
+ seenKeysOption = true
+ case "endkeys":
+ if !seenKeysOption {
+ return `option "endkeys" without a previous "keys" option`, false
+ }
+ seenKeysOption = false
+ default:
+ parts := strings.Split(opt, "|")
+ errMsg, ok := checkValidateOptionsAlternatives(checkCtx, parts)
+ if !ok {
+ return errMsg, false
+ }
+ }
+ previousOption = opt
+ }
+
+ return "", true
+}
+
+func checkXMLTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ for _, opt := range tag.Options {
switch opt {
case "any", "attr", "cdata", "chardata", "comment", "innerxml", "omitempty", "typeattr":
default:
- if w.isUserDefined(keyXML, opt) {
+ if checkCtx.isUserDefined(keyXML, opt) {
continue
}
- return fmt.Sprintf("unknown option '%s' in XML tag", opt), false
+ return fmt.Sprintf(msgUnknownOption, opt), false
}
}
return "", true
}
-func (w lintStructTagRule) checkYAMLTag(options []string) (string, bool) {
- for _, opt := range options {
+func checkYAMLTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
+ for _, opt := range tag.Options {
switch opt {
case "flow", "inline", "omitempty":
default:
- if w.isUserDefined(keyYAML, opt) {
+ if checkCtx.isUserDefined(keyYAML, opt) {
continue
}
- return fmt.Sprintf("unknown option '%s' in YAML tag", opt), false
+ return fmt.Sprintf(msgUnknownOption, opt), false
}
}
return "", true
}
-func (lintStructTagRule) typeValueMatch(t ast.Expr, val string) bool {
+func checkValidateOptionsAlternatives(checkCtx *checkContext, alternatives []string) (message string, succeeded bool) {
+ for _, alternative := range alternatives {
+ alternative := strings.TrimSpace(alternative)
+ lhs, _, found := strings.Cut(alternative, "=")
+ if found {
+ _, ok := validateLHS[lhs]
+ if ok || checkCtx.isUserDefined(keyValidate, lhs) {
+ continue
+ }
+ return fmt.Sprintf(msgUnknownOption, lhs), false
+ }
+
+ badOpt, ok := areValidateOpts(alternative)
+ if ok || checkCtx.isUserDefined(keyValidate, badOpt) {
+ continue
+ }
+
+ return fmt.Sprintf(msgUnknownOption, badOpt), false
+ }
+
+ return "", true
+}
+
+func typeValueMatch(t ast.Expr, val string) bool {
tID, ok := t.(*ast.Ident)
if !ok {
return true
@@ -354,78 +606,172 @@ func (lintStructTagRule) typeValueMatch(t ast.Expr, val string) bool {
return typeMatches
}
-func (w lintStructTagRule) checkProtobufTag(tag *structtag.Tag) (string, bool) {
- // check name
- switch tag.Name {
- case "bytes", "fixed32", "fixed64", "group", "varint", "zigzag32", "zigzag64":
- // do nothing
- default:
- return fmt.Sprintf("invalid protobuf tag name '%s'", tag.Name), false
- }
-
- // check options
- seenOptions := map[string]bool{}
- for _, opt := range tag.Options {
- if number, err := strconv.Atoi(opt); err == nil {
- _, alreadySeen := w.usedTagNbr[number]
- if alreadySeen {
- return fmt.Sprintf("duplicated tag number %v", number), false
- }
- w.usedTagNbr[number] = true
- continue // option is an integer
- }
-
- switch {
- case opt == "opt" || opt == "proto3" || opt == "rep" || opt == "req":
- // do nothing
- case strings.Contains(opt, "="):
- o := strings.Split(opt, "=")[0]
- _, alreadySeen := seenOptions[o]
- if alreadySeen {
- return fmt.Sprintf("protobuf tag has duplicated option '%s'", o), false
- }
- seenOptions[o] = true
- continue
- }
- }
- _, hasName := seenOptions["name"]
- if !hasName {
- return "protobuf tag lacks mandatory option 'name'", false
- }
-
- for k := range seenOptions {
- switch k {
- case "name", "json":
- // do nothing
- default:
- if w.isUserDefined(keyProtobuf, k) {
- continue
- }
- return fmt.Sprintf("unknown option '%s' in protobuf tag", k), false
- }
- }
-
- return "", true
+func (w lintStructTagRule) addFailureWithTagKey(n ast.Node, msg string, tagKey string) {
+ w.addFailuref(n, "%s in %s tag", msg, tagKey)
}
-func (w lintStructTagRule) addFailure(n ast.Node, msg string) {
+func (w lintStructTagRule) addFailuref(n ast.Node, msg string, args ...any) {
w.onFailure(lint.Failure{
Node: n,
- Failure: msg,
+ Failure: fmt.Sprintf(msg, args...),
Confidence: 1,
})
}
-func (w lintStructTagRule) isUserDefined(key, opt string) bool {
- if w.userDefined == nil {
- return false
- }
-
- options := w.userDefined[key]
- for _, o := range options {
- if opt == o {
- return true
+func areValidateOpts(opts string) (string, bool) {
+ parts := strings.Split(opts, "|")
+ for _, opt := range parts {
+ _, ok := validateSingleOptions[opt]
+ if !ok {
+ return opt, false
}
}
- return false
+
+ return "", true
+}
+
+const (
+ msgDuplicatedOption = "duplicated option %q"
+ msgDuplicatedTagNumber = "duplicated tag number %v"
+ msgUnknownOption = "unknown option %q"
+ msgTypeMismatch = "type mismatch between field type and default value type"
+)
+
+var validateSingleOptions = map[string]struct{}{
+ "alpha": {},
+ "alphanum": {},
+ "alphanumunicode": {},
+ "alphaunicode": {},
+ "ascii": {},
+ "base32": {},
+ "base64": {},
+ "base64url": {},
+ "bcp47_language_tag": {},
+ "boolean": {},
+ "bic": {},
+ "btc_addr": {},
+ "btc_addr_bech32": {},
+ "cidr": {},
+ "cidrv4": {},
+ "cidrv6": {},
+ "country_code": {},
+ "credit_card": {},
+ "cron": {},
+ "cve": {},
+ "datauri": {},
+ "dir": {},
+ "dirpath": {},
+ "dive": {},
+ "dns_rfc1035_label": {},
+ "e164": {},
+ "email": {},
+ "eth_addr": {},
+ "file": {},
+ "filepath": {},
+ "fqdn": {},
+ "hexadecimal": {},
+ "hexcolor": {},
+ "hostname": {},
+ "hostname_port": {},
+ "hostname_rfc1123": {},
+ "hsl": {},
+ "hsla": {},
+ "html": {},
+ "html_encoded": {},
+ "image": {},
+ "ip": {},
+ "ip4_addr": {},
+ "ip6_addr": {},
+ "ip_addr": {},
+ "ipv4": {},
+ "ipv6": {},
+ "isbn": {},
+ "isbn10": {},
+ "isbn13": {},
+ "isdefault": {},
+ "iso3166_1_alpha2": {},
+ "iso3166_1_alpha3": {},
+ "iscolor": {},
+ "json": {},
+ "jwt": {},
+ "latitude": {},
+ "longitude": {},
+ "lowercase": {},
+ "luhn_checksum": {},
+ "mac": {},
+ "mongodb": {},
+ "mongodb_connection_string": {},
+ "multibyte": {},
+ "nostructlevel": {},
+ "number": {},
+ "numeric": {},
+ "omitempty": {},
+ "printascii": {},
+ "required": {},
+ "rgb": {},
+ "rgba": {},
+ "semver": {},
+ "ssn": {},
+ "structonly": {},
+ "tcp_addr": {},
+ "tcp4_addr": {},
+ "tcp6_addr": {},
+ "timezone": {},
+ "udp4_addr": {},
+ "udp6_addr": {},
+ "ulid": {},
+ "unique": {},
+ "unix_addr": {},
+ "uppercase": {},
+ "uri": {},
+ "url": {},
+ "url_encoded": {},
+ "urn_rfc2141": {},
+ "uuid": {},
+ "uuid3": {},
+ "uuid4": {},
+ "uuid5": {},
+}
+
+var validateLHS = map[string]struct{}{
+ "contains": {},
+ "containsany": {},
+ "containsfield": {},
+ "containsrune": {},
+ "datetime": {},
+ "endsnotwith": {},
+ "endswith": {},
+ "eq": {},
+ "eqfield": {},
+ "eqcsfield": {},
+ "excluded_if": {},
+ "excluded_unless": {},
+ "excludes": {},
+ "excludesall": {},
+ "excludesfield": {},
+ "excludesrune": {},
+ "gt": {},
+ "gtcsfield": {},
+ "gtecsfield": {},
+ "len": {},
+ "lt": {},
+ "lte": {},
+ "ltcsfield": {},
+ "ltecsfield": {},
+ "max": {},
+ "min": {},
+ "ne": {},
+ "necsfield": {},
+ "oneof": {},
+ "oneofci": {},
+ "required_if": {},
+ "required_unless": {},
+ "required_with": {},
+ "required_with_all": {},
+ "required_without": {},
+ "required_without_all": {},
+ "spicedb": {},
+ "startsnotwith": {},
+ "startswith": {},
+ "unique": {},
}
diff --git a/vendor/github.com/mgechev/revive/rule/superfluous_else.go b/vendor/github.com/mgechev/revive/rule/superfluous_else.go
index c9474d9c..dfa8a2fa 100644
--- a/vendor/github.com/mgechev/revive/rule/superfluous_else.go
+++ b/vendor/github.com/mgechev/revive/rule/superfluous_else.go
@@ -8,11 +8,33 @@ import (
)
// SuperfluousElseRule lints given else constructs.
-type SuperfluousElseRule struct{}
+type SuperfluousElseRule struct {
+ // preserveScope prevents suggestions that would enlarge variable scope.
+ preserveScope bool
+}
+
+// Configure validates the rule configuration, and configures the rule accordingly.
+//
+// Configuration implements the [lint.ConfigurableRule] interface.
+func (e *SuperfluousElseRule) Configure(arguments lint.Arguments) error {
+ for _, arg := range arguments {
+ sarg, ok := arg.(string)
+ if !ok {
+ continue
+ }
+ if isRuleOption(sarg, "preserveScope") {
+ e.preserveScope = true
+ }
+ }
+ return nil
+}
// Apply applies the rule to given file.
-func (e *SuperfluousElseRule) Apply(file *lint.File, args lint.Arguments) []lint.Failure {
- return ifelse.Apply(e.checkIfElse, file.AST, ifelse.TargetElse, args)
+func (e *SuperfluousElseRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ return ifelse.Apply(e.checkIfElse, file.AST, ifelse.TargetElse, ifelse.Args{
+ PreserveScope: e.preserveScope,
+ // AllowJump is not used by this rule
+ })
}
// Name returns the rule name.
@@ -20,7 +42,7 @@ func (*SuperfluousElseRule) Name() string {
return "superfluous-else"
}
-func (*SuperfluousElseRule) checkIfElse(chain ifelse.Chain, args ifelse.Args) (string, bool) {
+func (e *SuperfluousElseRule) checkIfElse(chain ifelse.Chain) (string, bool) {
if !chain.HasElse {
return "", false
}
@@ -41,7 +63,7 @@ func (*SuperfluousElseRule) checkIfElse(chain ifelse.Chain, args ifelse.Args) (s
return "", false
}
- if args.PreserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.Else.HasDecls()) {
+ if e.preserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.Else.HasDecls()) {
// avoid increasing variable scope
return "", false
}
diff --git a/vendor/github.com/mgechev/revive/rule/unchecked_type_assertion.go b/vendor/github.com/mgechev/revive/rule/unchecked_type_assertion.go
index a272724d..eb0ba4fe 100644
--- a/vendor/github.com/mgechev/revive/rule/unchecked_type_assertion.go
+++ b/vendor/github.com/mgechev/revive/rule/unchecked_type_assertion.go
@@ -32,15 +32,13 @@ func (r *UncheckedTypeAssertionRule) Configure(arguments lint.Arguments) error {
}
for k, v := range args {
- switch k {
- case "acceptIgnoredAssertionResult":
- r.acceptIgnoredAssertionResult, ok = v.(bool)
- if !ok {
- return fmt.Errorf("unable to parse argument '%s'. Expected boolean", k)
- }
- default:
+ if !isRuleOption(k, "acceptIgnoredAssertionResult") {
return fmt.Errorf("unknown argument: %s", k)
}
+ r.acceptIgnoredAssertionResult, ok = v.(bool)
+ if !ok {
+ return fmt.Errorf("unable to parse argument '%s'. Expected boolean", k)
+ }
}
return nil
}
diff --git a/vendor/github.com/mgechev/revive/rule/unexported_return.go b/vendor/github.com/mgechev/revive/rule/unexported_return.go
index 0d88a957..ab619a77 100644
--- a/vendor/github.com/mgechev/revive/rule/unexported_return.go
+++ b/vendor/github.com/mgechev/revive/rule/unexported_return.go
@@ -16,6 +16,8 @@ type UnexportedReturnRule struct{}
func (*UnexportedReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
var failures []lint.Failure
+ file.Pkg.TypeCheck()
+
for _, decl := range file.AST.Decls {
fn, ok := decl.(*ast.FuncDecl)
if !ok {
@@ -70,7 +72,7 @@ func (*UnexportedReturnRule) Name() string {
// It is imprecise, and will err on the side of returning true,
// such as for composite types.
func exportedType(typ types.Type) bool {
- switch t := typ.(type) {
+ switch t := types.Unalias(typ).(type) {
case *types.Named:
obj := t.Obj()
switch {
diff --git a/vendor/github.com/mgechev/revive/rule/unhandled_error.go b/vendor/github.com/mgechev/revive/rule/unhandled_error.go
index 6ae919bc..6e2fb2d9 100644
--- a/vendor/github.com/mgechev/revive/rule/unhandled_error.go
+++ b/vendor/github.com/mgechev/revive/rule/unhandled_error.go
@@ -151,7 +151,7 @@ func (*lintUnhandledErrors) isTypeError(t *types.Named) bool {
}
func (w *lintUnhandledErrors) returnsAnError(tt *types.Tuple) bool {
- for i := 0; i < tt.Len(); i++ {
+ for i := range tt.Len() {
nt, ok := tt.At(i).Type().(*types.Named)
if ok && w.isTypeError(nt) {
return true
diff --git a/vendor/github.com/mgechev/revive/rule/unused_param.go b/vendor/github.com/mgechev/revive/rule/unused_param.go
index f57c59b0..826eca16 100644
--- a/vendor/github.com/mgechev/revive/rule/unused_param.go
+++ b/vendor/github.com/mgechev/revive/rule/unused_param.go
@@ -28,24 +28,28 @@ func (r *UnusedParamRule) Configure(args lint.Arguments) error {
if len(args) == 0 {
return nil
}
- // Arguments = [{}]
- options := args[0].(map[string]any)
- allowRegexParam, ok := options["allowRegex"]
+ options, ok := args[0].(map[string]any)
if !ok {
+ // Arguments = [{}]
return nil
}
- // Arguments = [{allowRegex="^_"}]
- allowRegexStr, ok := allowRegexParam.(string)
- if !ok {
- panic(fmt.Errorf("error configuring %s rule: allowRegex is not string but [%T]", r.Name(), allowRegexParam))
- }
- var err error
- r.allowRegex, err = regexp.Compile(allowRegexStr)
- if err != nil {
- return fmt.Errorf("error configuring %s rule: allowRegex is not valid regex [%s]: %w", r.Name(), allowRegexStr, err)
+ for k, v := range options {
+ if !isRuleOption(k, "allowRegex") {
+ return nil
+ }
+ // Arguments = [{allowRegex="_"}]
+ allowRegexStr, ok := v.(string)
+ if !ok {
+ return fmt.Errorf("error configuring %s rule: allowRegex is not string but [%T]", r.Name(), v)
+ }
+ var err error
+ r.allowRegex, err = regexp.Compile(allowRegexStr)
+ if err != nil {
+ return fmt.Errorf("error configuring %s rule: allowRegex is not valid regex [%s]: %w", r.Name(), allowRegexStr, err)
+ }
+ r.failureMsg = "parameter '%s' seems to be unused, consider removing or renaming it to match " + r.allowRegex.String()
}
- r.failureMsg = "parameter '%s' seems to be unused, consider removing or renaming it to match " + r.allowRegex.String()
return nil
}
diff --git a/vendor/github.com/mgechev/revive/rule/unused_receiver.go b/vendor/github.com/mgechev/revive/rule/unused_receiver.go
index 13ca39df..2b39296c 100644
--- a/vendor/github.com/mgechev/revive/rule/unused_receiver.go
+++ b/vendor/github.com/mgechev/revive/rule/unused_receiver.go
@@ -27,23 +27,27 @@ func (r *UnusedReceiverRule) Configure(args lint.Arguments) error {
return nil
}
// Arguments = [{}]
- options := args[0].(map[string]any)
-
- allowRegexParam, ok := options["allowRegex"]
+ options, ok := args[0].(map[string]any)
if !ok {
return nil
}
- // Arguments = [{allowRegex="^_"}]
- allowRegexStr, ok := allowRegexParam.(string)
- if !ok {
- panic(fmt.Errorf("error configuring [unused-receiver] rule: allowRegex is not string but [%T]", allowRegexParam))
- }
- var err error
- r.allowRegex, err = regexp.Compile(allowRegexStr)
- if err != nil {
- return fmt.Errorf("error configuring [unused-receiver] rule: allowRegex is not valid regex [%s]: %w", allowRegexStr, err)
+
+ for k, v := range options {
+ if !isRuleOption(k, "allowRegex") {
+ return nil
+ }
+ // Arguments = [{allowRegex="^_"}]
+ allowRegexStr, ok := v.(string)
+ if !ok {
+ return fmt.Errorf("error configuring [unused-receiver] rule: allowRegex is not string but [%T]", v)
+ }
+ var err error
+ r.allowRegex, err = regexp.Compile(allowRegexStr)
+ if err != nil {
+ return fmt.Errorf("error configuring [unused-receiver] rule: allowRegex is not valid regex [%s]: %w", allowRegexStr, err)
+ }
+ r.failureMsg = "method receiver '%s' is not referenced in method's body, consider removing or renaming it to match " + r.allowRegex.String()
}
- r.failureMsg = "method receiver '%s' is not referenced in method's body, consider removing or renaming it to match " + r.allowRegex.String()
return nil
}
diff --git a/vendor/github.com/mgechev/revive/rule/useless_break.go b/vendor/github.com/mgechev/revive/rule/useless_break.go
index 8db20c9b..b99cc81e 100644
--- a/vendor/github.com/mgechev/revive/rule/useless_break.go
+++ b/vendor/github.com/mgechev/revive/rule/useless_break.go
@@ -47,36 +47,39 @@ func (w *lintUselessBreak) Visit(node ast.Node) ast.Visitor {
w.inLoopBody = false
return nil
case *ast.CommClause:
- for _, n := range v.Body {
- w.inspectCaseStatement(n)
- }
+ w.inspectCaseStatement(v.Body)
return nil
case *ast.CaseClause:
- for _, n := range v.Body {
- w.inspectCaseStatement(n)
- }
+ w.inspectCaseStatement(v.Body)
return nil
}
return w
}
-func (w *lintUselessBreak) inspectCaseStatement(n ast.Stmt) {
- switch s := n.(type) {
- case *ast.BranchStmt:
- if s.Tok != token.BREAK {
- return // not a break statement
- }
- if s.Label != nil {
- return // labeled break statement, usually affects a nesting loop
- }
- msg := "useless break in case clause"
- if w.inLoopBody {
- msg += " (WARN: this break statement affects this switch or select statement and not the loop enclosing it)"
- }
- w.onFailure(lint.Failure{
- Confidence: 1,
- Node: s,
- Failure: msg,
- })
+func (w *lintUselessBreak) inspectCaseStatement(body []ast.Stmt) {
+ l := len(body)
+ if l == 0 {
+ return // empty body, nothing to do
}
+
+ s := body[l-1] // pick the last statement
+ if !isUnlabelledBreak(s) {
+ return
+ }
+
+ msg := "useless break in case clause"
+ if w.inLoopBody {
+ msg += " (WARN: this break statement affects this switch or select statement and not the loop enclosing it)"
+ }
+
+ w.onFailure(lint.Failure{
+ Confidence: 1,
+ Node: s,
+ Failure: msg,
+ })
+}
+
+func isUnlabelledBreak(stmt ast.Stmt) bool {
+ s, ok := stmt.(*ast.BranchStmt)
+ return ok && s.Tok == token.BREAK && s.Label == nil
}
diff --git a/vendor/github.com/mgechev/revive/rule/utils.go b/vendor/github.com/mgechev/revive/rule/utils.go
index 5075c782..05f4c041 100644
--- a/vendor/github.com/mgechev/revive/rule/utils.go
+++ b/vendor/github.com/mgechev/revive/rule/utils.go
@@ -7,6 +7,7 @@ import (
"go/printer"
"go/token"
"regexp"
+ "strings"
"github.com/mgechev/revive/lint"
)
@@ -112,6 +113,18 @@ func checkNumberOfArguments(expected int, args lint.Arguments, ruleName string)
return nil
}
+// isRuleOption returns true if arg and name are the same after normalization.
+func isRuleOption(arg, name string) bool {
+ return normalizeRuleOption(arg) == normalizeRuleOption(name)
+}
+
+// normalizeRuleOption returns an option name from the argument. It is lowercased and without hyphens.
+//
+// Example: normalizeRuleOption("allowTypesBefore"), normalizeRuleOption("allow-types-before") -> "allowtypesbefore"
+func normalizeRuleOption(arg string) string {
+ return strings.ToLower(strings.ReplaceAll(arg, "-", ""))
+}
+
var directiveCommentRE = regexp.MustCompile("^//(line |extern |export |[a-z0-9]+:[a-z0-9])") // see https://go-review.googlesource.com/c/website/+/442516/1..2/_content/doc/comment.md#494
func isDirectiveComment(line string) bool {
diff --git a/vendor/github.com/mgechev/revive/rule/var_naming.go b/vendor/github.com/mgechev/revive/rule/var_naming.go
index bffcbb27..2248d350 100644
--- a/vendor/github.com/mgechev/revive/rule/var_naming.go
+++ b/vendor/github.com/mgechev/revive/rule/var_naming.go
@@ -64,8 +64,14 @@ func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
if !ok {
return fmt.Errorf("invalid third argument to the var-naming rule. Expecting a %s of type slice, of len==1, with map, but %T", "options", asSlice[0])
}
- r.allowUpperCaseConst = fmt.Sprint(args["upperCaseConst"]) == "true"
- r.skipPackageNameChecks = fmt.Sprint(args["skipPackageNameChecks"]) == "true"
+ for k, v := range args {
+ switch {
+ case isRuleOption(k, "upperCaseConst"):
+ r.allowUpperCaseConst = fmt.Sprint(v) == "true"
+ case isRuleOption(k, "skipPackageNameChecks"):
+ r.skipPackageNameChecks = fmt.Sprint(v) == "true"
+ }
+ }
}
return nil
}
@@ -279,7 +285,7 @@ func getList(arg any, argName string) ([]string, error) {
for _, v := range args {
val, ok := v.(string)
if !ok {
- return nil, fmt.Errorf("invalid %s values of the var-naming rule. Expecting slice of strings but got element of type %T", val, arg)
+ return nil, fmt.Errorf("invalid %v values of the var-naming rule. Expecting slice of strings but got element of type %T", v, arg)
}
list = append(list, val)
}
diff --git a/vendor/github.com/sivchari/tenv/.gitignore b/vendor/github.com/muesli/termenv/.gitignore
similarity index 97%
rename from vendor/github.com/sivchari/tenv/.gitignore
rename to vendor/github.com/muesli/termenv/.gitignore
index 83470100..66fd13c9 100644
--- a/vendor/github.com/sivchari/tenv/.gitignore
+++ b/vendor/github.com/muesli/termenv/.gitignore
@@ -11,7 +11,5 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
-.idea
-
# Dependency directories (remove the comment below to include it)
# vendor/
diff --git a/vendor/github.com/muesli/termenv/.golangci-soft.yml b/vendor/github.com/muesli/termenv/.golangci-soft.yml
new file mode 100644
index 00000000..84e3d41d
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/.golangci-soft.yml
@@ -0,0 +1,43 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ # - dupl
+ - exhaustive
+ # - exhaustivestruct
+ - goconst
+ - godot
+ - godox
+ - mnd
+ - gomoddirectives
+ - goprintffuncname
+ # - lll
+ - misspell
+ - nakedret
+ - nestif
+ - noctx
+ - nolintlint
+ - prealloc
+ - wrapcheck
+
+ # disable default linters, they are already enabled in .golangci.yml
+ disable:
+ - errcheck
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - typecheck
+ - unused
diff --git a/vendor/github.com/muesli/termenv/.golangci.yml b/vendor/github.com/muesli/termenv/.golangci.yml
new file mode 100644
index 00000000..684d54bf
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/.golangci.yml
@@ -0,0 +1,28 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - goimports
+ - gosec
+ - nilerr
+ - predeclared
+ - revive
+ - rowserrcheck
+ - sqlclosecheck
+ - tparallel
+ - unconvert
+ - unparam
+ - whitespace
diff --git a/vendor/github.com/muesli/termenv/LICENSE b/vendor/github.com/muesli/termenv/LICENSE
new file mode 100644
index 00000000..8532c45c
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Christian Muehlhaeuser
+
+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.
diff --git a/vendor/github.com/muesli/termenv/README.md b/vendor/github.com/muesli/termenv/README.md
new file mode 100644
index 00000000..fa7929d4
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/README.md
@@ -0,0 +1,431 @@
+
+
+`termenv` lets you safely use advanced styling options on the terminal. It
+gathers information about the terminal environment in terms of its ANSI & color
+support and offers you convenient methods to colorize and style your output,
+without you having to deal with all kinds of weird ANSI escape sequences and
+color conversions.
+
+## Features
+
+- RGB/TrueColor support
+- Detects the supported color range of your terminal
+- Automatically converts colors to the best matching, available colors
+- Terminal theme (light/dark) detection
+- Chainable syntax
+- Nested styles
+
+## Installation
+
+```bash
+go get github.com/muesli/termenv
+```
+
+## Usage
+
+```go
+output := termenv.NewOutput(os.Stdout)
+```
+
+`termenv` queries the terminal's capabilities it is running in, so you can
+safely use advanced features, like RGB colors or ANSI styles. `output.Profile`
+returns the supported profile:
+
+- `termenv.Ascii` - no ANSI support detected, ASCII only
+- `termenv.ANSI` - 16 color ANSI support
+- `termenv.ANSI256` - Extended 256 color ANSI support
+- `termenv.TrueColor` - RGB/TrueColor support
+
+Alternatively, you can use `termenv.EnvColorProfile` which evaluates the
+terminal like `ColorProfile`, but also respects the `NO_COLOR` and
+`CLICOLOR_FORCE` environment variables.
+
+You can also query the terminal for its color scheme, so you know whether your
+app is running in a light- or dark-themed environment:
+
+```go
+// Returns terminal's foreground color
+color := output.ForegroundColor()
+
+// Returns terminal's background color
+color := output.BackgroundColor()
+
+// Returns whether terminal uses a dark-ish background
+darkTheme := output.HasDarkBackground()
+```
+
+### Manual Profile Selection
+
+If you don't want to rely on the automatic detection, you can manually select
+the profile you want to use:
+
+```go
+output := termenv.NewOutput(os.Stdout, termenv.WithProfile(termenv.TrueColor))
+```
+
+## Colors
+
+`termenv` supports multiple color profiles: Ascii (black & white only),
+ANSI (16 colors), ANSI Extended (256 colors), and TrueColor (24-bit RGB). Colors
+will automatically be degraded to the best matching available color in the
+desired profile:
+
+`TrueColor` => `ANSI 256 Colors` => `ANSI 16 Colors` => `Ascii`
+
+```go
+s := output.String("Hello World")
+
+// Supports hex values
+// Will automatically degrade colors on terminals not supporting RGB
+s.Foreground(output.Color("#abcdef"))
+// but also supports ANSI colors (0-255)
+s.Background(output.Color("69"))
+// ...or the color.Color interface
+s.Foreground(output.FromColor(color.RGBA{255, 128, 0, 255}))
+
+// Combine fore- & background colors
+s.Foreground(output.Color("#ffffff")).Background(output.Color("#0000ff"))
+
+// Supports the fmt.Stringer interface
+fmt.Println(s)
+```
+
+## Styles
+
+You can use a chainable syntax to compose your own styles:
+
+```go
+s := output.String("foobar")
+
+// Text styles
+s.Bold()
+s.Faint()
+s.Italic()
+s.CrossOut()
+s.Underline()
+s.Overline()
+
+// Reverse swaps current fore- & background colors
+s.Reverse()
+
+// Blinking text
+s.Blink()
+
+// Combine multiple options
+s.Bold().Underline()
+```
+
+## Template Helpers
+
+`termenv` provides a set of helper functions to style your Go templates:
+
+```go
+// load template helpers
+f := output.TemplateFuncs()
+tpl := template.New("tpl").Funcs(f)
+
+// apply bold style in a template
+bold := `{{ Bold "Hello World" }}`
+
+// examples for colorized templates
+col := `{{ Color "#ff0000" "#0000ff" "Red on Blue" }}`
+fg := `{{ Foreground "#ff0000" "Red Foreground" }}`
+bg := `{{ Background "#0000ff" "Blue Background" }}`
+
+// wrap styles
+wrap := `{{ Bold (Underline "Hello World") }}`
+
+// parse and render
+tpl, err = tpl.Parse(bold)
+
+var buf bytes.Buffer
+tpl.Execute(&buf, nil)
+fmt.Println(&buf)
+```
+
+Other available helper functions are: `Faint`, `Italic`, `CrossOut`,
+`Underline`, `Overline`, `Reverse`, and `Blink`.
+
+## Positioning
+
+```go
+// Move the cursor to a given position
+output.MoveCursor(row, column)
+
+// Save the cursor position
+output.SaveCursorPosition()
+
+// Restore a saved cursor position
+output.RestoreCursorPosition()
+
+// Move the cursor up a given number of lines
+output.CursorUp(n)
+
+// Move the cursor down a given number of lines
+output.CursorDown(n)
+
+// Move the cursor up a given number of lines
+output.CursorForward(n)
+
+// Move the cursor backwards a given number of cells
+output.CursorBack(n)
+
+// Move the cursor down a given number of lines and place it at the beginning
+// of the line
+output.CursorNextLine(n)
+
+// Move the cursor up a given number of lines and place it at the beginning of
+// the line
+output.CursorPrevLine(n)
+```
+
+## Screen
+
+```go
+// Reset the terminal to its default style, removing any active styles
+output.Reset()
+
+// RestoreScreen restores a previously saved screen state
+output.RestoreScreen()
+
+// SaveScreen saves the screen state
+output.SaveScreen()
+
+// Switch to the altscreen. The former view can be restored with ExitAltScreen()
+output.AltScreen()
+
+// Exit the altscreen and return to the former terminal view
+output.ExitAltScreen()
+
+// Clear the visible portion of the terminal
+output.ClearScreen()
+
+// Clear the current line
+output.ClearLine()
+
+// Clear a given number of lines
+output.ClearLines(n)
+
+// Set the scrolling region of the terminal
+output.ChangeScrollingRegion(top, bottom)
+
+// Insert the given number of lines at the top of the scrollable region, pushing
+// lines below down
+output.InsertLines(n)
+
+// Delete the given number of lines, pulling any lines in the scrollable region
+// below up
+output.DeleteLines(n)
+```
+
+## Session
+
+```go
+// SetWindowTitle sets the terminal window title
+output.SetWindowTitle(title)
+
+// SetForegroundColor sets the default foreground color
+output.SetForegroundColor(color)
+
+// SetBackgroundColor sets the default background color
+output.SetBackgroundColor(color)
+
+// SetCursorColor sets the cursor color
+output.SetCursorColor(color)
+
+// Hide the cursor
+output.HideCursor()
+
+// Show the cursor
+output.ShowCursor()
+
+// Copy to clipboard
+output.Copy(message)
+
+// Copy to primary clipboard (X11)
+output.CopyPrimary(message)
+
+// Trigger notification
+output.Notify(title, body)
+```
+
+## Mouse
+
+```go
+// Enable X10 mouse mode, only button press events are sent
+output.EnableMousePress()
+
+// Disable X10 mouse mode
+output.DisableMousePress()
+
+// Enable Mouse Tracking mode
+output.EnableMouse()
+
+// Disable Mouse Tracking mode
+output.DisableMouse()
+
+// Enable Hilite Mouse Tracking mode
+output.EnableMouseHilite()
+
+// Disable Hilite Mouse Tracking mode
+output.DisableMouseHilite()
+
+// Enable Cell Motion Mouse Tracking mode
+output.EnableMouseCellMotion()
+
+// Disable Cell Motion Mouse Tracking mode
+output.DisableMouseCellMotion()
+
+// Enable All Motion Mouse mode
+output.EnableMouseAllMotion()
+
+// Disable All Motion Mouse mode
+output.DisableMouseAllMotion()
+```
+
+## Bracketed Paste
+
+```go
+// Enables bracketed paste mode
+termenv.EnableBracketedPaste()
+
+// Disables bracketed paste mode
+termenv.DisableBracketedPaste()
+```
+
+## Terminal Feature Support
+
+### Color Support
+
+- 24-bit (RGB): alacritty, foot, iTerm, kitty, Konsole, st, tmux, vte-based, wezterm, Ghostty, Windows Terminal
+- 8-bit (256): rxvt, screen, xterm, Apple Terminal
+- 4-bit (16): Linux Console
+
+### Control Sequences
+
+
+Click to show feature matrix
+
+| Terminal | Query Color Scheme | Query Cursor Position | Set Window Title | Change Cursor Color | Change Default Foreground Setting | Change Default Background Setting | Bracketed Paste | Extended Mouse (SGR) | Pixels Mouse (SGR-Pixels) |
+| ---------------- | :----------------: | :-------------------: | :--------------: | :-----------------: | :-------------------------------: | :-------------------------------: | :-------------: | :------------------: | :-----------------------: |
+| alacritty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| foot | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| kitty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| Konsole | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| rxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
+| urxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| screen | ⛔[^mux] | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
+| st | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| tmux | ⛔[^mux] | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| vte-based[^vte] | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
+| wezterm | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| xterm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
+| Linux Console | ❌ | ✅ | ⛔ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
+| Apple Terminal | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
+| iTerm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
+| Windows cmd | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
+| Windows Terminal | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
+
+[^vte]: This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal.
+[^mux]: Unavailable as multiplexers (like tmux or screen) can be connected to multiple terminals (with different color settings) at the same time.
+
+You can help improve this list! Check out [how to](ansi_compat.md) and open an issue or pull request.
+
+
+
+### System Commands
+
+
+Click to show feature matrix
+
+| Terminal | Copy to Clipboard (OSC52) | Hyperlinks (OSC8) | Notifications (OSC777) |
+| ---------------- | :-----------------------: | :---------------: | :--------------------: |
+| alacritty | ✅ | ✅[^alacritty] | ❌ |
+| foot | ✅ | ✅ | ✅ |
+| kitty | ✅ | ✅ | ✅ |
+| Konsole | ❌[^konsole] | ✅ | ❌ |
+| rxvt | ❌ | ❌ | ❌ |
+| urxvt | ✅[^urxvt] | ❌ | ✅ |
+| screen | ✅ | ❌[^screen] | ❌ |
+| st | ✅ | ❌ | ❌ |
+| tmux | ✅ | ❌[^tmux] | ❌ |
+| vte-based[^vte] | ❌[^vte] | ✅ | ❌ |
+| wezterm | ✅ | ✅ | ❌ |
+| xterm | ✅ | ❌ | ❌ |
+| Linux Console | ⛔ | ⛔ | ❌ |
+| Apple Terminal | ✅[^apple] | ❌ | ❌ |
+| iTerm | ✅ | ✅ | ❌ |
+| Windows cmd | ❌ | ❌ | ❌ |
+| Windows Terminal | ✅ | ✅ | ❌ |
+
+[^vte]: This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal. OSC52 is not supported, see [issue#2495](https://gitlab.gnome.org/GNOME/vte/-/issues/2495).
+[^urxvt]: Workaround for urxvt not supporting OSC52. See [this](https://unix.stackexchange.com/a/629485) for more information.
+[^konsole]: OSC52 is not supported, for more info see [bug#372116](https://bugs.kde.org/show_bug.cgi?id=372116).
+[^apple]: OSC52 works with a [workaround](https://github.com/roy2220/osc52pty).
+[^tmux]: OSC8 is not supported, for more info see [issue#911](https://github.com/tmux/tmux/issues/911).
+[^screen]: OSC8 is not supported, for more info see [bug#50952](https://savannah.gnu.org/bugs/index.php?50952).
+[^alacritty]: OSC8 is supported since [v0.11.0](https://github.com/alacritty/alacritty/releases/tag/v0.11.0)
+
+
+
+## Platform Support
+
+`termenv` works on Unix systems (like Linux, macOS, or BSD) and Windows. While
+terminal applications on Unix support ANSI styling out-of-the-box, on Windows
+you need to enable ANSI processing in your application first:
+
+```go
+ restoreConsole, err := termenv.EnableVirtualTerminalProcessing(termenv.DefaultOutput())
+ if err != nil {
+ panic(err)
+ }
+ defer restoreConsole()
+```
+
+The above code is safe to include on non-Windows systems or when os.Stdout does
+not refer to a terminal (e.g. in tests).
+
+## Color Chart
+
+
+
+You can find the source code used to create this chart in `termenv`'s examples.
+
+## Related Projects
+
+- [reflow](https://github.com/muesli/reflow) - ANSI-aware text operations
+- [Lip Gloss](https://github.com/charmbracelet/lipgloss) - style definitions for nice terminal layouts 👄
+- [ansi](https://github.com/muesli/ansi) - ANSI sequence helpers
+
+## termenv in the Wild
+
+Need some inspiration or just want to see how others are using `termenv`? Check
+out these projects:
+
+- [Bubble Tea](https://github.com/charmbracelet/bubbletea) - a powerful little TUI framework 🏗
+- [Glamour](https://github.com/charmbracelet/glamour) - stylesheet-based markdown rendering for your CLI apps 💇🏻♀️
+- [Glow](https://github.com/charmbracelet/glow) - a markdown renderer for the command-line 💅🏻
+- [duf](https://github.com/muesli/duf) - Disk Usage/Free Utility - a better 'df' alternative
+- [gitty](https://github.com/muesli/gitty) - contextual information about your git projects
+- [slides](https://github.com/maaslalani/slides) - terminal-based presentation tool
+
+## Feedback
+
+Got some feedback or suggestions? Please open an issue or drop me a note!
+
+- [Twitter](https://twitter.com/mueslix)
+- [The Fediverse](https://mastodon.social/@fribbledom)
+
+## License
+
+[MIT](https://github.com/muesli/termenv/raw/master/LICENSE)
diff --git a/vendor/github.com/muesli/termenv/ansi_compat.md b/vendor/github.com/muesli/termenv/ansi_compat.md
new file mode 100644
index 00000000..6b68a3a9
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/ansi_compat.md
@@ -0,0 +1,65 @@
+## Change Foreground Color
+
+This command should enable a blue foreground color:
+
+```bash
+echo -ne "\033]10;#0000ff\007"
+```
+
+## Change Background Color
+
+This command should enable a green background color:
+
+```bash
+echo -ne "\033]11;#00ff00\007"
+```
+
+## Change Cursor Color
+
+This command should enable a red cursor color:
+
+```bash
+echo -ne "\033]12;#ff0000\007"
+```
+
+## Query Color Scheme
+
+These two commands should print out the currently active color scheme:
+
+```bash
+echo -ne "\033]10;?\033\\"
+echo -ne "\033]11;?\033\\"
+```
+
+## Query Cursor Position
+
+This command should print out the current cursor position:
+
+```bash
+echo -ne "\033[6n"
+```
+
+## Set Window Title
+
+This command should set the window title to "Test":
+
+```bash
+echo -ne "\033]2;Test\007" && sleep 10
+```
+
+## Bracketed paste
+
+Enter this command, then paste a word from the clipboard. The text
+displayed on the terminal should contain the codes `200~` and `201~`:
+
+```bash
+echo -ne "\033[?2004h" && sleep 10
+```
+
+## Trigger Notification
+
+This command should trigger a notification:
+
+```bash
+echo -ne "\033]777;notify;Title;Body\033\\"
+```
diff --git a/vendor/github.com/muesli/termenv/ansicolors.go b/vendor/github.com/muesli/termenv/ansicolors.go
new file mode 100644
index 00000000..1a301b0f
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/ansicolors.go
@@ -0,0 +1,281 @@
+package termenv
+
+// ANSI color codes.
+const (
+ ANSIBlack ANSIColor = iota
+ ANSIRed
+ ANSIGreen
+ ANSIYellow
+ ANSIBlue
+ ANSIMagenta
+ ANSICyan
+ ANSIWhite
+ ANSIBrightBlack
+ ANSIBrightRed
+ ANSIBrightGreen
+ ANSIBrightYellow
+ ANSIBrightBlue
+ ANSIBrightMagenta
+ ANSIBrightCyan
+ ANSIBrightWhite
+)
+
+// RGB values of ANSI colors (0-255).
+var ansiHex = []string{
+ "#000000",
+ "#800000",
+ "#008000",
+ "#808000",
+ "#000080",
+ "#800080",
+ "#008080",
+ "#c0c0c0",
+ "#808080",
+ "#ff0000",
+ "#00ff00",
+ "#ffff00",
+ "#0000ff",
+ "#ff00ff",
+ "#00ffff",
+ "#ffffff",
+ "#000000",
+ "#00005f",
+ "#000087",
+ "#0000af",
+ "#0000d7",
+ "#0000ff",
+ "#005f00",
+ "#005f5f",
+ "#005f87",
+ "#005faf",
+ "#005fd7",
+ "#005fff",
+ "#008700",
+ "#00875f",
+ "#008787",
+ "#0087af",
+ "#0087d7",
+ "#0087ff",
+ "#00af00",
+ "#00af5f",
+ "#00af87",
+ "#00afaf",
+ "#00afd7",
+ "#00afff",
+ "#00d700",
+ "#00d75f",
+ "#00d787",
+ "#00d7af",
+ "#00d7d7",
+ "#00d7ff",
+ "#00ff00",
+ "#00ff5f",
+ "#00ff87",
+ "#00ffaf",
+ "#00ffd7",
+ "#00ffff",
+ "#5f0000",
+ "#5f005f",
+ "#5f0087",
+ "#5f00af",
+ "#5f00d7",
+ "#5f00ff",
+ "#5f5f00",
+ "#5f5f5f",
+ "#5f5f87",
+ "#5f5faf",
+ "#5f5fd7",
+ "#5f5fff",
+ "#5f8700",
+ "#5f875f",
+ "#5f8787",
+ "#5f87af",
+ "#5f87d7",
+ "#5f87ff",
+ "#5faf00",
+ "#5faf5f",
+ "#5faf87",
+ "#5fafaf",
+ "#5fafd7",
+ "#5fafff",
+ "#5fd700",
+ "#5fd75f",
+ "#5fd787",
+ "#5fd7af",
+ "#5fd7d7",
+ "#5fd7ff",
+ "#5fff00",
+ "#5fff5f",
+ "#5fff87",
+ "#5fffaf",
+ "#5fffd7",
+ "#5fffff",
+ "#870000",
+ "#87005f",
+ "#870087",
+ "#8700af",
+ "#8700d7",
+ "#8700ff",
+ "#875f00",
+ "#875f5f",
+ "#875f87",
+ "#875faf",
+ "#875fd7",
+ "#875fff",
+ "#878700",
+ "#87875f",
+ "#878787",
+ "#8787af",
+ "#8787d7",
+ "#8787ff",
+ "#87af00",
+ "#87af5f",
+ "#87af87",
+ "#87afaf",
+ "#87afd7",
+ "#87afff",
+ "#87d700",
+ "#87d75f",
+ "#87d787",
+ "#87d7af",
+ "#87d7d7",
+ "#87d7ff",
+ "#87ff00",
+ "#87ff5f",
+ "#87ff87",
+ "#87ffaf",
+ "#87ffd7",
+ "#87ffff",
+ "#af0000",
+ "#af005f",
+ "#af0087",
+ "#af00af",
+ "#af00d7",
+ "#af00ff",
+ "#af5f00",
+ "#af5f5f",
+ "#af5f87",
+ "#af5faf",
+ "#af5fd7",
+ "#af5fff",
+ "#af8700",
+ "#af875f",
+ "#af8787",
+ "#af87af",
+ "#af87d7",
+ "#af87ff",
+ "#afaf00",
+ "#afaf5f",
+ "#afaf87",
+ "#afafaf",
+ "#afafd7",
+ "#afafff",
+ "#afd700",
+ "#afd75f",
+ "#afd787",
+ "#afd7af",
+ "#afd7d7",
+ "#afd7ff",
+ "#afff00",
+ "#afff5f",
+ "#afff87",
+ "#afffaf",
+ "#afffd7",
+ "#afffff",
+ "#d70000",
+ "#d7005f",
+ "#d70087",
+ "#d700af",
+ "#d700d7",
+ "#d700ff",
+ "#d75f00",
+ "#d75f5f",
+ "#d75f87",
+ "#d75faf",
+ "#d75fd7",
+ "#d75fff",
+ "#d78700",
+ "#d7875f",
+ "#d78787",
+ "#d787af",
+ "#d787d7",
+ "#d787ff",
+ "#d7af00",
+ "#d7af5f",
+ "#d7af87",
+ "#d7afaf",
+ "#d7afd7",
+ "#d7afff",
+ "#d7d700",
+ "#d7d75f",
+ "#d7d787",
+ "#d7d7af",
+ "#d7d7d7",
+ "#d7d7ff",
+ "#d7ff00",
+ "#d7ff5f",
+ "#d7ff87",
+ "#d7ffaf",
+ "#d7ffd7",
+ "#d7ffff",
+ "#ff0000",
+ "#ff005f",
+ "#ff0087",
+ "#ff00af",
+ "#ff00d7",
+ "#ff00ff",
+ "#ff5f00",
+ "#ff5f5f",
+ "#ff5f87",
+ "#ff5faf",
+ "#ff5fd7",
+ "#ff5fff",
+ "#ff8700",
+ "#ff875f",
+ "#ff8787",
+ "#ff87af",
+ "#ff87d7",
+ "#ff87ff",
+ "#ffaf00",
+ "#ffaf5f",
+ "#ffaf87",
+ "#ffafaf",
+ "#ffafd7",
+ "#ffafff",
+ "#ffd700",
+ "#ffd75f",
+ "#ffd787",
+ "#ffd7af",
+ "#ffd7d7",
+ "#ffd7ff",
+ "#ffff00",
+ "#ffff5f",
+ "#ffff87",
+ "#ffffaf",
+ "#ffffd7",
+ "#ffffff",
+ "#080808",
+ "#121212",
+ "#1c1c1c",
+ "#262626",
+ "#303030",
+ "#3a3a3a",
+ "#444444",
+ "#4e4e4e",
+ "#585858",
+ "#626262",
+ "#6c6c6c",
+ "#767676",
+ "#808080",
+ "#8a8a8a",
+ "#949494",
+ "#9e9e9e",
+ "#a8a8a8",
+ "#b2b2b2",
+ "#bcbcbc",
+ "#c6c6c6",
+ "#d0d0d0",
+ "#dadada",
+ "#e4e4e4",
+ "#eeeeee",
+}
diff --git a/vendor/github.com/muesli/termenv/color.go b/vendor/github.com/muesli/termenv/color.go
new file mode 100644
index 00000000..59e639b1
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/color.go
@@ -0,0 +1,205 @@
+package termenv
+
+import (
+ "errors"
+ "fmt"
+ "math"
+ "strings"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+// ErrInvalidColor gets returned when a color is invalid.
+var ErrInvalidColor = errors.New("invalid color")
+
+// Foreground and Background sequence codes.
+const (
+ Foreground = "38"
+ Background = "48"
+)
+
+// Color is an interface implemented by all colors that can be converted to an
+// ANSI sequence.
+type Color interface {
+ // Sequence returns the ANSI Sequence for the color.
+ Sequence(bg bool) string
+}
+
+// NoColor is a nop for terminals that don't support colors.
+type NoColor struct{}
+
+func (c NoColor) String() string {
+ return ""
+}
+
+// ANSIColor is a color (0-15) as defined by the ANSI Standard.
+type ANSIColor int
+
+func (c ANSIColor) String() string {
+ return ansiHex[c]
+}
+
+// ANSI256Color is a color (16-255) as defined by the ANSI Standard.
+type ANSI256Color int
+
+func (c ANSI256Color) String() string {
+ return ansiHex[c]
+}
+
+// RGBColor is a hex-encoded color, e.g. "#abcdef".
+type RGBColor string
+
+// ConvertToRGB converts a Color to a colorful.Color.
+func ConvertToRGB(c Color) colorful.Color {
+ var hex string
+ switch v := c.(type) {
+ case RGBColor:
+ hex = string(v)
+ case ANSIColor:
+ hex = ansiHex[v]
+ case ANSI256Color:
+ hex = ansiHex[v]
+ }
+
+ ch, _ := colorful.Hex(hex)
+ return ch
+}
+
+// Sequence returns the ANSI Sequence for the color.
+func (c NoColor) Sequence(_ bool) string {
+ return ""
+}
+
+// Sequence returns the ANSI Sequence for the color.
+//
+//nolint:mnd
+func (c ANSIColor) Sequence(bg bool) string {
+ col := int(c)
+ bgMod := func(c int) int {
+ if bg {
+ return c + 10
+ }
+ return c
+ }
+
+ if col < 8 {
+ return fmt.Sprintf("%d", bgMod(col)+30) //nolint:mnd
+ }
+ return fmt.Sprintf("%d", bgMod(col-8)+90) //nolint:mnd
+}
+
+// Sequence returns the ANSI Sequence for the color.
+func (c ANSI256Color) Sequence(bg bool) string {
+ prefix := Foreground
+ if bg {
+ prefix = Background
+ }
+ return fmt.Sprintf("%s;5;%d", prefix, c)
+}
+
+// Sequence returns the ANSI Sequence for the color.
+func (c RGBColor) Sequence(bg bool) string {
+ f, err := colorful.Hex(string(c))
+ if err != nil {
+ return ""
+ }
+
+ prefix := Foreground
+ if bg {
+ prefix = Background
+ }
+ return fmt.Sprintf("%s;2;%d;%d;%d", prefix, uint8(f.R*255), uint8(f.G*255), uint8(f.B*255)) //nolint:mnd
+}
+
+func xTermColor(s string) (RGBColor, error) {
+ if len(s) < 24 || len(s) > 25 {
+ return RGBColor(""), ErrInvalidColor
+ }
+
+ switch {
+ case strings.HasSuffix(s, string(BEL)):
+ s = strings.TrimSuffix(s, string(BEL))
+ case strings.HasSuffix(s, string(ESC)):
+ s = strings.TrimSuffix(s, string(ESC))
+ case strings.HasSuffix(s, ST):
+ s = strings.TrimSuffix(s, ST)
+ default:
+ return RGBColor(""), ErrInvalidColor
+ }
+
+ s = s[4:]
+
+ prefix := ";rgb:"
+ if !strings.HasPrefix(s, prefix) {
+ return RGBColor(""), ErrInvalidColor
+ }
+ s = strings.TrimPrefix(s, prefix)
+
+ h := strings.Split(s, "/")
+ hex := fmt.Sprintf("#%s%s%s", h[0][:2], h[1][:2], h[2][:2])
+ return RGBColor(hex), nil
+}
+
+func ansi256ToANSIColor(c ANSI256Color) ANSIColor {
+ var r int
+ md := math.MaxFloat64
+
+ h, _ := colorful.Hex(ansiHex[c])
+ for i := 0; i <= 15; i++ {
+ hb, _ := colorful.Hex(ansiHex[i])
+ d := h.DistanceHSLuv(hb)
+
+ if d < md {
+ md = d
+ r = i
+ }
+ }
+
+ return ANSIColor(r)
+}
+
+//nolint:mnd
+func hexToANSI256Color(c colorful.Color) ANSI256Color {
+ v2ci := func(v float64) int {
+ if v < 48 {
+ return 0
+ }
+ if v < 115 {
+ return 1
+ }
+ return int((v - 35) / 40)
+ }
+
+ // Calculate the nearest 0-based color index at 16..231
+ r := v2ci(c.R * 255.0) // 0..5 each
+ g := v2ci(c.G * 255.0)
+ b := v2ci(c.B * 255.0)
+ ci := 36*r + 6*g + b /* 0..215 */
+
+ // Calculate the represented colors back from the index
+ i2cv := [6]int{0, 0x5f, 0x87, 0xaf, 0xd7, 0xff}
+ cr := i2cv[r] // r/g/b, 0..255 each
+ cg := i2cv[g]
+ cb := i2cv[b]
+
+ // Calculate the nearest 0-based gray index at 232..255
+ var grayIdx int
+ average := (r + g + b) / 3
+ if average > 238 {
+ grayIdx = 23
+ } else {
+ grayIdx = (average - 3) / 10 // 0..23
+ }
+ gv := 8 + 10*grayIdx // same value for r/g/b, 0..255
+
+ // Return the one which is nearer to the original input rgb value
+ c2 := colorful.Color{R: float64(cr) / 255.0, G: float64(cg) / 255.0, B: float64(cb) / 255.0}
+ g2 := colorful.Color{R: float64(gv) / 255.0, G: float64(gv) / 255.0, B: float64(gv) / 255.0}
+ colorDist := c.DistanceHSLuv(c2)
+ grayDist := c.DistanceHSLuv(g2)
+
+ if colorDist <= grayDist {
+ return ANSI256Color(16 + ci)
+ }
+ return ANSI256Color(232 + grayIdx)
+}
diff --git a/vendor/github.com/muesli/termenv/constants_linux.go b/vendor/github.com/muesli/termenv/constants_linux.go
new file mode 100644
index 00000000..4262f03b
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/constants_linux.go
@@ -0,0 +1,8 @@
+package termenv
+
+import "golang.org/x/sys/unix"
+
+const (
+ tcgetattr = unix.TCGETS
+ tcsetattr = unix.TCSETS
+)
diff --git a/vendor/github.com/muesli/termenv/constants_solaris.go b/vendor/github.com/muesli/termenv/constants_solaris.go
new file mode 100644
index 00000000..4262f03b
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/constants_solaris.go
@@ -0,0 +1,8 @@
+package termenv
+
+import "golang.org/x/sys/unix"
+
+const (
+ tcgetattr = unix.TCGETS
+ tcsetattr = unix.TCSETS
+)
diff --git a/vendor/github.com/muesli/termenv/constants_unix.go b/vendor/github.com/muesli/termenv/constants_unix.go
new file mode 100644
index 00000000..5d664245
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/constants_unix.go
@@ -0,0 +1,13 @@
+//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && !solaris && !illumos
+// +build darwin dragonfly freebsd netbsd openbsd
+// +build !solaris
+// +build !illumos
+
+package termenv
+
+import "golang.org/x/sys/unix"
+
+const (
+ tcgetattr = unix.TIOCGETA
+ tcsetattr = unix.TIOCSETA
+)
diff --git a/vendor/github.com/muesli/termenv/constants_zos.go b/vendor/github.com/muesli/termenv/constants_zos.go
new file mode 100644
index 00000000..4262f03b
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/constants_zos.go
@@ -0,0 +1,8 @@
+package termenv
+
+import "golang.org/x/sys/unix"
+
+const (
+ tcgetattr = unix.TCGETS
+ tcsetattr = unix.TCSETS
+)
diff --git a/vendor/github.com/muesli/termenv/copy.go b/vendor/github.com/muesli/termenv/copy.go
new file mode 100644
index 00000000..4bf5c9fe
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/copy.go
@@ -0,0 +1,37 @@
+package termenv
+
+import (
+ "strings"
+
+ "github.com/aymanbagabas/go-osc52/v2"
+)
+
+// Copy copies text to clipboard using OSC 52 escape sequence.
+func (o Output) Copy(str string) {
+ s := osc52.New(str)
+ if strings.HasPrefix(o.environ.Getenv("TERM"), "screen") {
+ s = s.Screen()
+ }
+ _, _ = s.WriteTo(o)
+}
+
+// CopyPrimary copies text to primary clipboard (X11) using OSC 52 escape
+// sequence.
+func (o Output) CopyPrimary(str string) {
+ s := osc52.New(str).Primary()
+ if strings.HasPrefix(o.environ.Getenv("TERM"), "screen") {
+ s = s.Screen()
+ }
+ _, _ = s.WriteTo(o)
+}
+
+// Copy copies text to clipboard using OSC 52 escape sequence.
+func Copy(str string) {
+ output.Copy(str)
+}
+
+// CopyPrimary copies text to primary clipboard (X11) using OSC 52 escape
+// sequence.
+func CopyPrimary(str string) {
+ output.CopyPrimary(str)
+}
diff --git a/vendor/github.com/muesli/termenv/hyperlink.go b/vendor/github.com/muesli/termenv/hyperlink.go
new file mode 100644
index 00000000..97e760a3
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/hyperlink.go
@@ -0,0 +1,11 @@
+package termenv
+
+// Hyperlink creates a hyperlink using OSC8.
+func Hyperlink(link, name string) string {
+ return output.Hyperlink(link, name)
+}
+
+// Hyperlink creates a hyperlink using OSC8.
+func (o *Output) Hyperlink(link, name string) string {
+ return OSC + "8;;" + link + ST + name + OSC + "8;;" + ST
+}
diff --git a/vendor/github.com/muesli/termenv/notification.go b/vendor/github.com/muesli/termenv/notification.go
new file mode 100644
index 00000000..2a8cf06a
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/notification.go
@@ -0,0 +1,11 @@
+package termenv
+
+// Notify triggers a notification using OSC777.
+func Notify(title, body string) {
+ output.Notify(title, body)
+}
+
+// Notify triggers a notification using OSC777.
+func (o *Output) Notify(title, body string) {
+ _, _ = o.WriteString(OSC + "777;notify;" + title + ";" + body + ST)
+}
diff --git a/vendor/github.com/muesli/termenv/output.go b/vendor/github.com/muesli/termenv/output.go
new file mode 100644
index 00000000..e4434de0
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/output.go
@@ -0,0 +1,205 @@
+package termenv
+
+import (
+ "io"
+ "os"
+ "sync"
+)
+
+// output is the default global output.
+var output = NewOutput(os.Stdout)
+
+// File represents a file descriptor.
+//
+// Deprecated: Use *os.File instead.
+type File interface {
+ io.ReadWriter
+ Fd() uintptr
+}
+
+// OutputOption sets an option on Output.
+type OutputOption = func(*Output)
+
+// Output is a terminal output.
+type Output struct {
+ Profile
+ w io.Writer
+ environ Environ
+
+ assumeTTY bool
+ unsafe bool
+ cache bool
+ fgSync *sync.Once
+ fgColor Color
+ bgSync *sync.Once
+ bgColor Color
+}
+
+// Environ is an interface for getting environment variables.
+type Environ interface {
+ Environ() []string
+ Getenv(string) string
+}
+
+type osEnviron struct{}
+
+func (oe *osEnviron) Environ() []string {
+ return os.Environ()
+}
+
+func (oe *osEnviron) Getenv(key string) string {
+ return os.Getenv(key)
+}
+
+// DefaultOutput returns the default global output.
+func DefaultOutput() *Output {
+ return output
+}
+
+// SetDefaultOutput sets the default global output.
+func SetDefaultOutput(o *Output) {
+ output = o
+}
+
+// NewOutput returns a new Output for the given writer.
+func NewOutput(w io.Writer, opts ...OutputOption) *Output {
+ o := &Output{
+ w: w,
+ environ: &osEnviron{},
+ Profile: -1,
+ fgSync: &sync.Once{},
+ fgColor: NoColor{},
+ bgSync: &sync.Once{},
+ bgColor: NoColor{},
+ }
+
+ if o.w == nil {
+ o.w = os.Stdout
+ }
+ for _, opt := range opts {
+ opt(o)
+ }
+ if o.Profile < 0 {
+ o.Profile = o.EnvColorProfile()
+ }
+
+ return o
+}
+
+// WithEnvironment returns a new OutputOption for the given environment.
+func WithEnvironment(environ Environ) OutputOption {
+ return func(o *Output) {
+ o.environ = environ
+ }
+}
+
+// WithProfile returns a new OutputOption for the given profile.
+func WithProfile(profile Profile) OutputOption {
+ return func(o *Output) {
+ o.Profile = profile
+ }
+}
+
+// WithColorCache returns a new OutputOption with fore- and background color values
+// pre-fetched and cached.
+func WithColorCache(v bool) OutputOption {
+ return func(o *Output) {
+ o.cache = v
+
+ // cache the values now
+ _ = o.ForegroundColor()
+ _ = o.BackgroundColor()
+ }
+}
+
+// WithTTY returns a new OutputOption to assume whether or not the output is a TTY.
+// This is useful when mocking console output.
+func WithTTY(v bool) OutputOption {
+ return func(o *Output) {
+ o.assumeTTY = v
+ }
+}
+
+// WithUnsafe returns a new OutputOption with unsafe mode enabled. Unsafe mode doesn't
+// check whether or not the terminal is a TTY.
+//
+// This option supersedes WithTTY.
+//
+// This is useful when mocking console output and enforcing ANSI escape output
+// e.g. on SSH sessions.
+func WithUnsafe() OutputOption {
+ return func(o *Output) {
+ o.unsafe = true
+ }
+}
+
+// ForegroundColor returns the terminal's default foreground color.
+func (o *Output) ForegroundColor() Color {
+ f := func() {
+ if !o.isTTY() {
+ return
+ }
+
+ o.fgColor = o.foregroundColor()
+ }
+
+ if o.cache {
+ o.fgSync.Do(f)
+ } else {
+ f()
+ }
+
+ return o.fgColor
+}
+
+// BackgroundColor returns the terminal's default background color.
+func (o *Output) BackgroundColor() Color {
+ f := func() {
+ if !o.isTTY() {
+ return
+ }
+
+ o.bgColor = o.backgroundColor()
+ }
+
+ if o.cache {
+ o.bgSync.Do(f)
+ } else {
+ f()
+ }
+
+ return o.bgColor
+}
+
+// HasDarkBackground returns whether terminal uses a dark-ish background.
+func (o *Output) HasDarkBackground() bool {
+ c := ConvertToRGB(o.BackgroundColor())
+ _, _, l := c.Hsl()
+ return l < 0.5 //nolint:mnd
+}
+
+// TTY returns the terminal's file descriptor. This may be nil if the output is
+// not a terminal.
+//
+// Deprecated: Use Writer() instead.
+func (o Output) TTY() File {
+ if f, ok := o.w.(File); ok {
+ return f
+ }
+ return nil
+}
+
+// Writer returns the underlying writer. This may be of type io.Writer,
+// io.ReadWriter, or *os.File.
+func (o Output) Writer() io.Writer {
+ return o.w
+}
+
+func (o Output) Write(p []byte) (int, error) {
+ return o.w.Write(p) //nolint:wrapcheck
+}
+
+// WriteString writes the given string to the output.
+func (o Output) WriteString(s string) (int, error) {
+ return o.Write([]byte(s))
+}
diff --git a/vendor/github.com/muesli/termenv/profile.go b/vendor/github.com/muesli/termenv/profile.go
new file mode 100644
index 00000000..7d38f5fb
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/profile.go
@@ -0,0 +1,112 @@
+package termenv
+
+import (
+ "image/color"
+ "strconv"
+ "strings"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+// Profile is a color profile: Ascii, ANSI, ANSI256, or TrueColor.
+type Profile int
+
+const (
+ // TrueColor, 24-bit color profile.
+ TrueColor = Profile(iota)
+ // ANSI256, 8-bit color profile.
+ ANSI256
+ // ANSI, 4-bit color profile.
+ ANSI
+ // Ascii, uncolored profile.
+ Ascii //nolint:revive
+)
+
+// Name returns the profile name as a string.
+func (p Profile) Name() string {
+ switch p {
+ case Ascii:
+ return "Ascii"
+ case ANSI:
+ return "ANSI"
+ case ANSI256:
+ return "ANSI256"
+ case TrueColor:
+ return "TrueColor"
+ }
+ return "Unknown"
+}
+
+// String returns a new Style.
+func (p Profile) String(s ...string) Style {
+ return Style{
+ profile: p,
+ string: strings.Join(s, " "),
+ }
+}
+
+// Convert transforms a given Color to a Color supported within the Profile.
+func (p Profile) Convert(c Color) Color {
+ if p == Ascii {
+ return NoColor{}
+ }
+
+ switch v := c.(type) {
+ case ANSIColor:
+ return v
+
+ case ANSI256Color:
+ if p == ANSI {
+ return ansi256ToANSIColor(v)
+ }
+ return v
+
+ case RGBColor:
+ h, err := colorful.Hex(string(v))
+ if err != nil {
+ return nil
+ }
+ if p != TrueColor {
+ ac := hexToANSI256Color(h)
+ if p == ANSI {
+ return ansi256ToANSIColor(ac)
+ }
+ return ac
+ }
+ return v
+ }
+
+ return c
+}
+
+// Color creates a Color from a string. Valid inputs are hex colors, as well as
+// ANSI color codes (0-15, 16-255).
+func (p Profile) Color(s string) Color {
+ if len(s) == 0 {
+ return nil
+ }
+
+ var c Color
+ if strings.HasPrefix(s, "#") {
+ c = RGBColor(s)
+ } else {
+ i, err := strconv.Atoi(s)
+ if err != nil {
+ return nil
+ }
+
+ if i < 16 { //nolint:mnd
+ c = ANSIColor(i)
+ } else {
+ c = ANSI256Color(i)
+ }
+ }
+
+ return p.Convert(c)
+}
+
+// FromColor creates a Color from a color.Color.
+func (p Profile) FromColor(c color.Color) Color {
+ col, _ := colorful.MakeColor(c)
+ return p.Color(col.Hex())
+}
diff --git a/vendor/github.com/muesli/termenv/screen.go b/vendor/github.com/muesli/termenv/screen.go
new file mode 100644
index 00000000..75c11d01
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/screen.go
@@ -0,0 +1,590 @@
+package termenv
+
+import (
+ "fmt"
+ "strings"
+)
+
+// Sequence definitions.
+const (
+ // Cursor positioning.
+ CursorUpSeq = "%dA"
+ CursorDownSeq = "%dB"
+ CursorForwardSeq = "%dC"
+ CursorBackSeq = "%dD"
+ CursorNextLineSeq = "%dE"
+ CursorPreviousLineSeq = "%dF"
+ CursorHorizontalSeq = "%dG"
+ CursorPositionSeq = "%d;%dH"
+ EraseDisplaySeq = "%dJ"
+ EraseLineSeq = "%dK"
+ ScrollUpSeq = "%dS"
+ ScrollDownSeq = "%dT"
+ SaveCursorPositionSeq = "s"
+ RestoreCursorPositionSeq = "u"
+ ChangeScrollingRegionSeq = "%d;%dr"
+ InsertLineSeq = "%dL"
+ DeleteLineSeq = "%dM"
+
+ // Explicit values for EraseLineSeq.
+ EraseLineRightSeq = "0K"
+ EraseLineLeftSeq = "1K"
+ EraseEntireLineSeq = "2K"
+
+ // Mouse.
+ EnableMousePressSeq = "?9h" // press only (X10)
+ DisableMousePressSeq = "?9l"
+ EnableMouseSeq = "?1000h" // press, release, wheel
+ DisableMouseSeq = "?1000l"
+ EnableMouseHiliteSeq = "?1001h" // highlight
+ DisableMouseHiliteSeq = "?1001l"
+ EnableMouseCellMotionSeq = "?1002h" // press, release, move on pressed, wheel
+ DisableMouseCellMotionSeq = "?1002l"
+ EnableMouseAllMotionSeq = "?1003h" // press, release, move, wheel
+ DisableMouseAllMotionSeq = "?1003l"
+ EnableMouseExtendedModeSeq = "?1006h" // press, release, move, wheel, extended coordinates
+ DisableMouseExtendedModeSeq = "?1006l"
+ EnableMousePixelsModeSeq = "?1016h" // press, release, move, wheel, extended pixel coordinates
+ DisableMousePixelsModeSeq = "?1016l"
+
+ // Screen.
+ RestoreScreenSeq = "?47l"
+ SaveScreenSeq = "?47h"
+ AltScreenSeq = "?1049h"
+ ExitAltScreenSeq = "?1049l"
+
+ // Bracketed paste.
+ // https://en.wikipedia.org/wiki/Bracketed-paste
+ EnableBracketedPasteSeq = "?2004h"
+ DisableBracketedPasteSeq = "?2004l"
+ StartBracketedPasteSeq = "200~"
+ EndBracketedPasteSeq = "201~"
+
+ // Session.
+ SetWindowTitleSeq = "2;%s" + string(BEL)
+ SetForegroundColorSeq = "10;%s" + string(BEL)
+ SetBackgroundColorSeq = "11;%s" + string(BEL)
+ SetCursorColorSeq = "12;%s" + string(BEL)
+ ShowCursorSeq = "?25h"
+ HideCursorSeq = "?25l"
+)
+
+// Reset the terminal to its default style, removing any active styles.
+func (o Output) Reset() {
+ fmt.Fprint(o.w, CSI+ResetSeq+"m") //nolint:errcheck
+}
+
+// SetForegroundColor sets the default foreground color.
+func (o Output) SetForegroundColor(color Color) {
+ fmt.Fprintf(o.w, OSC+SetForegroundColorSeq, color) //nolint:errcheck
+}
+
+// SetBackgroundColor sets the default background color.
+func (o Output) SetBackgroundColor(color Color) {
+ fmt.Fprintf(o.w, OSC+SetBackgroundColorSeq, color) //nolint:errcheck
+}
+
+// SetCursorColor sets the cursor color.
+func (o Output) SetCursorColor(color Color) {
+ fmt.Fprintf(o.w, OSC+SetCursorColorSeq, color) //nolint:errcheck
+}
+
+// RestoreScreen restores a previously saved screen state.
+func (o Output) RestoreScreen() {
+ fmt.Fprint(o.w, CSI+RestoreScreenSeq) //nolint:errcheck
+}
+
+// SaveScreen saves the screen state.
+func (o Output) SaveScreen() {
+ fmt.Fprint(o.w, CSI+SaveScreenSeq) //nolint:errcheck
+}
+
+// AltScreen switches to the alternate screen buffer. The former view can be
+// restored with ExitAltScreen().
+func (o Output) AltScreen() {
+ fmt.Fprint(o.w, CSI+AltScreenSeq) //nolint:errcheck
+}
+
+// ExitAltScreen exits the alternate screen buffer and returns to the former
+// terminal view.
+func (o Output) ExitAltScreen() {
+ fmt.Fprint(o.w, CSI+ExitAltScreenSeq) //nolint:errcheck
+}
+
+// ClearScreen clears the visible portion of the terminal.
+func (o Output) ClearScreen() {
+ fmt.Fprintf(o.w, CSI+EraseDisplaySeq, 2) //nolint:errcheck,mnd
+ o.MoveCursor(1, 1)
+}
+
+// MoveCursor moves the cursor to a given position.
+func (o Output) MoveCursor(row int, column int) {
+ fmt.Fprintf(o.w, CSI+CursorPositionSeq, row, column) //nolint:errcheck
+}
+
+// HideCursor hides the cursor.
+func (o Output) HideCursor() {
+ fmt.Fprint(o.w, CSI+HideCursorSeq) //nolint:errcheck
+}
+
+// ShowCursor shows the cursor.
+func (o Output) ShowCursor() {
+ fmt.Fprint(o.w, CSI+ShowCursorSeq) //nolint:errcheck
+}
+
+// SaveCursorPosition saves the cursor position.
+func (o Output) SaveCursorPosition() {
+ fmt.Fprint(o.w, CSI+SaveCursorPositionSeq) //nolint:errcheck
+}
+
+// RestoreCursorPosition restores a saved cursor position.
+func (o Output) RestoreCursorPosition() {
+ fmt.Fprint(o.w, CSI+RestoreCursorPositionSeq) //nolint:errcheck
+}
+
+// CursorUp moves the cursor up a given number of lines.
+func (o Output) CursorUp(n int) {
+ fmt.Fprintf(o.w, CSI+CursorUpSeq, n) //nolint:errcheck
+}
+
+// CursorDown moves the cursor down a given number of lines.
+func (o Output) CursorDown(n int) {
+ fmt.Fprintf(o.w, CSI+CursorDownSeq, n) //nolint:errcheck
+}
+
+// CursorForward moves the cursor up a given number of lines.
+func (o Output) CursorForward(n int) {
+ fmt.Fprintf(o.w, CSI+CursorForwardSeq, n) //nolint:errcheck
+}
+
+// CursorBack moves the cursor backwards a given number of cells.
+func (o Output) CursorBack(n int) {
+ fmt.Fprintf(o.w, CSI+CursorBackSeq, n) //nolint:errcheck
+}
+
+// CursorNextLine moves the cursor down a given number of lines and places it at
+// the beginning of the line.
+func (o Output) CursorNextLine(n int) {
+ fmt.Fprintf(o.w, CSI+CursorNextLineSeq, n) //nolint:errcheck
+}
+
+// CursorPrevLine moves the cursor up a given number of lines and places it at
+// the beginning of the line.
+func (o Output) CursorPrevLine(n int) {
+ fmt.Fprintf(o.w, CSI+CursorPreviousLineSeq, n) //nolint:errcheck
+}
+
+// ClearLine clears the current line.
+func (o Output) ClearLine() {
+ fmt.Fprint(o.w, CSI+EraseEntireLineSeq) //nolint:errcheck
+}
+
+// ClearLineLeft clears the line to the left of the cursor.
+func (o Output) ClearLineLeft() {
+ fmt.Fprint(o.w, CSI+EraseLineLeftSeq) //nolint:errcheck
+}
+
+// ClearLineRight clears the line to the right of the cursor.
+func (o Output) ClearLineRight() {
+ fmt.Fprint(o.w, CSI+EraseLineRightSeq) //nolint:errcheck
+}
+
+// ClearLines clears a given number of lines.
+func (o Output) ClearLines(n int) {
+ clearLine := fmt.Sprintf(CSI+EraseLineSeq, 2) //nolint:mnd
+ cursorUp := fmt.Sprintf(CSI+CursorUpSeq, 1)
+ fmt.Fprint(o.w, clearLine+strings.Repeat(cursorUp+clearLine, n)) //nolint:errcheck
+}
+
+// ChangeScrollingRegion sets the scrolling region of the terminal.
+func (o Output) ChangeScrollingRegion(top, bottom int) {
+ fmt.Fprintf(o.w, CSI+ChangeScrollingRegionSeq, top, bottom) //nolint:errcheck
+}
+
+// InsertLines inserts the given number of lines at the top of the scrollable
+// region, pushing lines below down.
+func (o Output) InsertLines(n int) {
+ fmt.Fprintf(o.w, CSI+InsertLineSeq, n) //nolint:errcheck
+}
+
+// DeleteLines deletes the given number of lines, pulling any lines in
+// the scrollable region below up.
+func (o Output) DeleteLines(n int) {
+ fmt.Fprintf(o.w, CSI+DeleteLineSeq, n) //nolint:errcheck
+}
+
+// EnableMousePress enables X10 mouse mode. Button press events are sent only.
+func (o Output) EnableMousePress() {
+ fmt.Fprint(o.w, CSI+EnableMousePressSeq) //nolint:errcheck
+}
+
+// DisableMousePress disables X10 mouse mode.
+func (o Output) DisableMousePress() {
+ fmt.Fprint(o.w, CSI+DisableMousePressSeq) //nolint:errcheck
+}
+
+// EnableMouse enables Mouse Tracking mode.
+func (o Output) EnableMouse() {
+ fmt.Fprint(o.w, CSI+EnableMouseSeq) //nolint:errcheck
+}
+
+// DisableMouse disables Mouse Tracking mode.
+func (o Output) DisableMouse() {
+ fmt.Fprint(o.w, CSI+DisableMouseSeq) //nolint:errcheck
+}
+
+// EnableMouseHilite enables Hilite Mouse Tracking mode.
+func (o Output) EnableMouseHilite() {
+ fmt.Fprint(o.w, CSI+EnableMouseHiliteSeq) //nolint:errcheck
+}
+
+// DisableMouseHilite disables Hilite Mouse Tracking mode.
+func (o Output) DisableMouseHilite() {
+ fmt.Fprint(o.w, CSI+DisableMouseHiliteSeq) //nolint:errcheck
+}
+
+// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode.
+func (o Output) EnableMouseCellMotion() {
+ fmt.Fprint(o.w, CSI+EnableMouseCellMotionSeq) //nolint:errcheck
+}
+
+// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode.
+func (o Output) DisableMouseCellMotion() {
+ fmt.Fprint(o.w, CSI+DisableMouseCellMotionSeq) //nolint:errcheck
+}
+
+// EnableMouseAllMotion enables All Motion Mouse mode.
+func (o Output) EnableMouseAllMotion() {
+ fmt.Fprint(o.w, CSI+EnableMouseAllMotionSeq) //nolint:errcheck
+}
+
+// DisableMouseAllMotion disables All Motion Mouse mode.
+func (o Output) DisableMouseAllMotion() {
+ fmt.Fprint(o.w, CSI+DisableMouseAllMotionSeq) //nolint:errcheck
+}
+
+// EnableMouseExtendedMotion enables Extended Mouse mode (SGR). This should be
+// enabled in conjunction with EnableMouseCellMotion, and EnableMouseAllMotion.
+func (o Output) EnableMouseExtendedMode() {
+ fmt.Fprint(o.w, CSI+EnableMouseExtendedModeSeq) //nolint:errcheck
+}
+
+// DisableMouseExtendedMotion disables Extended Mouse mode (SGR).
+func (o Output) DisableMouseExtendedMode() {
+ fmt.Fprint(o.w, CSI+DisableMouseExtendedModeSeq) //nolint:errcheck
+}
+
+// EnableMousePixelsMotion enables Pixel Motion Mouse mode (SGR-Pixels). This
+// should be enabled in conjunction with EnableMouseCellMotion, and
+// EnableMouseAllMotion.
+func (o Output) EnableMousePixelsMode() {
+ fmt.Fprint(o.w, CSI+EnableMousePixelsModeSeq) //nolint:errcheck
+}
+
+// DisableMousePixelsMotion disables Pixel Motion Mouse mode (SGR-Pixels).
+func (o Output) DisableMousePixelsMode() {
+ fmt.Fprint(o.w, CSI+DisableMousePixelsModeSeq) //nolint:errcheck
+}
+
+// SetWindowTitle sets the terminal window title.
+func (o Output) SetWindowTitle(title string) {
+ fmt.Fprintf(o.w, OSC+SetWindowTitleSeq, title) //nolint:errcheck
+}
+
+// EnableBracketedPaste enables bracketed paste.
+func (o Output) EnableBracketedPaste() {
+ fmt.Fprintf(o.w, CSI+EnableBracketedPasteSeq) //nolint:errcheck
+}
+
+// DisableBracketedPaste disables bracketed paste.
+func (o Output) DisableBracketedPaste() {
+ fmt.Fprintf(o.w, CSI+DisableBracketedPasteSeq) //nolint:errcheck
+}
+
+// Legacy functions.
+
+// Reset the terminal to its default style, removing any active styles.
+//
+// Deprecated: please use termenv.Output instead.
+func Reset() {
+ output.Reset()
+}
+
+// SetForegroundColor sets the default foreground color.
+//
+// Deprecated: please use termenv.Output instead.
+func SetForegroundColor(color Color) {
+ output.SetForegroundColor(color)
+}
+
+// SetBackgroundColor sets the default background color.
+//
+// Deprecated: please use termenv.Output instead.
+func SetBackgroundColor(color Color) {
+ output.SetBackgroundColor(color)
+}
+
+// SetCursorColor sets the cursor color.
+//
+// Deprecated: please use termenv.Output instead.
+func SetCursorColor(color Color) {
+ output.SetCursorColor(color)
+}
+
+// RestoreScreen restores a previously saved screen state.
+//
+// Deprecated: please use termenv.Output instead.
+func RestoreScreen() {
+ output.RestoreScreen()
+}
+
+// SaveScreen saves the screen state.
+//
+// Deprecated: please use termenv.Output instead.
+func SaveScreen() {
+ output.SaveScreen()
+}
+
+// AltScreen switches to the alternate screen buffer. The former view can be
+// restored with ExitAltScreen().
+//
+// Deprecated: please use termenv.Output instead.
+func AltScreen() {
+ output.AltScreen()
+}
+
+// ExitAltScreen exits the alternate screen buffer and returns to the former
+// terminal view.
+//
+// Deprecated: please use termenv.Output instead.
+func ExitAltScreen() {
+ output.ExitAltScreen()
+}
+
+// ClearScreen clears the visible portion of the terminal.
+//
+// Deprecated: please use termenv.Output instead.
+func ClearScreen() {
+ output.ClearScreen()
+}
+
+// MoveCursor moves the cursor to a given position.
+//
+// Deprecated: please use termenv.Output instead.
+func MoveCursor(row int, column int) {
+ output.MoveCursor(row, column)
+}
+
+// HideCursor hides the cursor.
+//
+// Deprecated: please use termenv.Output instead.
+func HideCursor() {
+ output.HideCursor()
+}
+
+// ShowCursor shows the cursor.
+//
+// Deprecated: please use termenv.Output instead.
+func ShowCursor() {
+ output.ShowCursor()
+}
+
+// SaveCursorPosition saves the cursor position.
+//
+// Deprecated: please use termenv.Output instead.
+func SaveCursorPosition() {
+ output.SaveCursorPosition()
+}
+
+// RestoreCursorPosition restores a saved cursor position.
+//
+// Deprecated: please use termenv.Output instead.
+func RestoreCursorPosition() {
+ output.RestoreCursorPosition()
+}
+
+// CursorUp moves the cursor up a given number of lines.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorUp(n int) {
+ output.CursorUp(n)
+}
+
+// CursorDown moves the cursor down a given number of lines.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorDown(n int) {
+ output.CursorDown(n)
+}
+
+// CursorForward moves the cursor up a given number of lines.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorForward(n int) {
+ output.CursorForward(n)
+}
+
+// CursorBack moves the cursor backwards a given number of cells.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorBack(n int) {
+ output.CursorBack(n)
+}
+
+// CursorNextLine moves the cursor down a given number of lines and places it at
+// the beginning of the line.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorNextLine(n int) {
+ output.CursorNextLine(n)
+}
+
+// CursorPrevLine moves the cursor up a given number of lines and places it at
+// the beginning of the line.
+//
+// Deprecated: please use termenv.Output instead.
+func CursorPrevLine(n int) {
+ output.CursorPrevLine(n)
+}
+
+// ClearLine clears the current line.
+//
+// Deprecated: please use termenv.Output instead.
+func ClearLine() {
+ output.ClearLine()
+}
+
+// ClearLineLeft clears the line to the left of the cursor.
+//
+// Deprecated: please use termenv.Output instead.
+func ClearLineLeft() {
+ output.ClearLineLeft()
+}
+
+// ClearLineRight clears the line to the right of the cursor.
+//
+// Deprecated: please use termenv.Output instead.
+func ClearLineRight() {
+ output.ClearLineRight()
+}
+
+// ClearLines clears a given number of lines.
+//
+// Deprecated: please use termenv.Output instead.
+func ClearLines(n int) {
+ output.ClearLines(n)
+}
+
+// ChangeScrollingRegion sets the scrolling region of the terminal.
+//
+// Deprecated: please use termenv.Output instead.
+func ChangeScrollingRegion(top, bottom int) {
+ output.ChangeScrollingRegion(top, bottom)
+}
+
+// InsertLines inserts the given number of lines at the top of the scrollable
+// region, pushing lines below down.
+//
+// Deprecated: please use termenv.Output instead.
+func InsertLines(n int) {
+ output.InsertLines(n)
+}
+
+// DeleteLines deletes the given number of lines, pulling any lines in
+// the scrollable region below up.
+//
+// Deprecated: please use termenv.Output instead.
+func DeleteLines(n int) {
+ output.DeleteLines(n)
+}
+
+// EnableMousePress enables X10 mouse mode. Button press events are sent only.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableMousePress() {
+ output.EnableMousePress()
+}
+
+// DisableMousePress disables X10 mouse mode.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableMousePress() {
+ output.DisableMousePress()
+}
+
+// EnableMouse enables Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableMouse() {
+ output.EnableMouse()
+}
+
+// DisableMouse disables Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableMouse() {
+ output.DisableMouse()
+}
+
+// EnableMouseHilite enables Hilite Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableMouseHilite() {
+ output.EnableMouseHilite()
+}
+
+// DisableMouseHilite disables Hilite Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableMouseHilite() {
+ output.DisableMouseHilite()
+}
+
+// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableMouseCellMotion() {
+ output.EnableMouseCellMotion()
+}
+
+// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableMouseCellMotion() {
+ output.DisableMouseCellMotion()
+}
+
+// EnableMouseAllMotion enables All Motion Mouse mode.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableMouseAllMotion() {
+ output.EnableMouseAllMotion()
+}
+
+// DisableMouseAllMotion disables All Motion Mouse mode.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableMouseAllMotion() {
+ output.DisableMouseAllMotion()
+}
+
+// SetWindowTitle sets the terminal window title.
+//
+// Deprecated: please use termenv.Output instead.
+func SetWindowTitle(title string) {
+ output.SetWindowTitle(title)
+}
+
+// EnableBracketedPaste enables bracketed paste.
+//
+// Deprecated: please use termenv.Output instead.
+func EnableBracketedPaste() {
+ output.EnableBracketedPaste()
+}
+
+// DisableBracketedPaste disables bracketed paste.
+//
+// Deprecated: please use termenv.Output instead.
+func DisableBracketedPaste() {
+ output.DisableBracketedPaste()
+}
diff --git a/vendor/github.com/muesli/termenv/style.go b/vendor/github.com/muesli/termenv/style.go
new file mode 100644
index 00000000..dedc1f9f
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/style.go
@@ -0,0 +1,126 @@
+package termenv
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/rivo/uniseg"
+)
+
+// Sequence definitions.
+const (
+ ResetSeq = "0"
+ BoldSeq = "1"
+ FaintSeq = "2"
+ ItalicSeq = "3"
+ UnderlineSeq = "4"
+ BlinkSeq = "5"
+ ReverseSeq = "7"
+ CrossOutSeq = "9"
+ OverlineSeq = "53"
+)
+
+// Style is a string that various rendering styles can be applied to.
+type Style struct {
+ profile Profile
+ string
+ styles []string
+}
+
+// String returns a new Style.
+func String(s ...string) Style {
+ return Style{
+ profile: ANSI,
+ string: strings.Join(s, " "),
+ }
+}
+
+func (t Style) String() string {
+ return t.Styled(t.string)
+}
+
+// Styled renders s with all applied styles.
+func (t Style) Styled(s string) string {
+ if t.profile == Ascii {
+ return s
+ }
+ if len(t.styles) == 0 {
+ return s
+ }
+
+ seq := strings.Join(t.styles, ";")
+ if seq == "" {
+ return s
+ }
+
+ return fmt.Sprintf("%s%sm%s%sm", CSI, seq, s, CSI+ResetSeq)
+}
+
+// Foreground sets a foreground color.
+func (t Style) Foreground(c Color) Style {
+ if c != nil {
+ t.styles = append(t.styles, c.Sequence(false))
+ }
+ return t
+}
+
+// Background sets a background color.
+func (t Style) Background(c Color) Style {
+ if c != nil {
+ t.styles = append(t.styles, c.Sequence(true))
+ }
+ return t
+}
+
+// Bold enables bold rendering.
+func (t Style) Bold() Style {
+ t.styles = append(t.styles, BoldSeq)
+ return t
+}
+
+// Faint enables faint rendering.
+func (t Style) Faint() Style {
+ t.styles = append(t.styles, FaintSeq)
+ return t
+}
+
+// Italic enables italic rendering.
+func (t Style) Italic() Style {
+ t.styles = append(t.styles, ItalicSeq)
+ return t
+}
+
+// Underline enables underline rendering.
+func (t Style) Underline() Style {
+ t.styles = append(t.styles, UnderlineSeq)
+ return t
+}
+
+// Overline enables overline rendering.
+func (t Style) Overline() Style {
+ t.styles = append(t.styles, OverlineSeq)
+ return t
+}
+
+// Blink enables blink mode.
+func (t Style) Blink() Style {
+ t.styles = append(t.styles, BlinkSeq)
+ return t
+}
+
+// Reverse enables reverse color mode.
+func (t Style) Reverse() Style {
+ t.styles = append(t.styles, ReverseSeq)
+ return t
+}
+
+// CrossOut enables crossed-out rendering.
+func (t Style) CrossOut() Style {
+ t.styles = append(t.styles, CrossOutSeq)
+ return t
+}
+
+// Width returns the width required to print all runes in Style.
+func (t Style) Width() int {
+ return uniseg.StringWidth(t.string)
+}
diff --git a/vendor/github.com/muesli/termenv/templatehelper.go b/vendor/github.com/muesli/termenv/templatehelper.go
new file mode 100644
index 00000000..4c7c80f5
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/templatehelper.go
@@ -0,0 +1,88 @@
+package termenv
+
+import (
+ "text/template"
+)
+
+// TemplateFuncs returns template helpers for the given output.
+func (o Output) TemplateFuncs() template.FuncMap {
+ return TemplateFuncs(o.Profile)
+}
+
+// TemplateFuncs contains a few useful template helpers.
+//
+//nolint:mnd
+func TemplateFuncs(p Profile) template.FuncMap {
+ if p == Ascii {
+ return noopTemplateFuncs
+ }
+
+ return template.FuncMap{
+ "Color": func(values ...interface{}) string {
+ s := p.String(values[len(values)-1].(string))
+ switch len(values) {
+ case 2:
+ s = s.Foreground(p.Color(values[0].(string)))
+ case 3:
+ s = s.
+ Foreground(p.Color(values[0].(string))).
+ Background(p.Color(values[1].(string)))
+ }
+
+ return s.String()
+ },
+ "Foreground": func(values ...interface{}) string {
+ s := p.String(values[len(values)-1].(string))
+ if len(values) == 2 {
+ s = s.Foreground(p.Color(values[0].(string)))
+ }
+
+ return s.String()
+ },
+ "Background": func(values ...interface{}) string {
+ s := p.String(values[len(values)-1].(string))
+ if len(values) == 2 {
+ s = s.Background(p.Color(values[0].(string)))
+ }
+
+ return s.String()
+ },
+ "Bold": styleFunc(p, Style.Bold),
+ "Faint": styleFunc(p, Style.Faint),
+ "Italic": styleFunc(p, Style.Italic),
+ "Underline": styleFunc(p, Style.Underline),
+ "Overline": styleFunc(p, Style.Overline),
+ "Blink": styleFunc(p, Style.Blink),
+ "Reverse": styleFunc(p, Style.Reverse),
+ "CrossOut": styleFunc(p, Style.CrossOut),
+ }
+}
+
+func styleFunc(p Profile, f func(Style) Style) func(...interface{}) string {
+ return func(values ...interface{}) string {
+ s := p.String(values[0].(string))
+ return f(s).String()
+ }
+}
+
+var noopTemplateFuncs = template.FuncMap{
+ "Color": noColorFunc,
+ "Foreground": noColorFunc,
+ "Background": noColorFunc,
+ "Bold": noStyleFunc,
+ "Faint": noStyleFunc,
+ "Italic": noStyleFunc,
+ "Underline": noStyleFunc,
+ "Overline": noStyleFunc,
+ "Blink": noStyleFunc,
+ "Reverse": noStyleFunc,
+ "CrossOut": noStyleFunc,
+}
+
+func noColorFunc(values ...interface{}) string {
+ return values[len(values)-1].(string)
+}
+
+func noStyleFunc(values ...interface{}) string {
+ return values[0].(string)
+}
diff --git a/vendor/github.com/muesli/termenv/termenv.go b/vendor/github.com/muesli/termenv/termenv.go
new file mode 100644
index 00000000..d702cd55
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv.go
@@ -0,0 +1,115 @@
+package termenv
+
+import (
+ "errors"
+ "os"
+
+ "github.com/mattn/go-isatty"
+)
+
+var (
+ // ErrStatusReport gets returned when the terminal can't be queried.
+ ErrStatusReport = errors.New("unable to retrieve status report")
+)
+
+const (
+ // Escape character.
+ ESC = '\x1b'
+ // Bell.
+ BEL = '\a'
+ // Control Sequence Introducer.
+ CSI = string(ESC) + "["
+ // Operating System Command.
+ OSC = string(ESC) + "]"
+ // String Terminator.
+ ST = string(ESC) + `\`
+)
+
+func (o *Output) isTTY() bool {
+ if o.assumeTTY || o.unsafe {
+ return true
+ }
+ if len(o.environ.Getenv("CI")) > 0 {
+ return false
+ }
+ if f, ok := o.Writer().(*os.File); ok {
+ return isatty.IsTerminal(f.Fd())
+ }
+
+ return false
+}
+
+// ColorProfile returns the supported color profile:
+// Ascii, ANSI, ANSI256, or TrueColor.
+func ColorProfile() Profile {
+ return output.ColorProfile()
+}
+
+// ForegroundColor returns the terminal's default foreground color.
+func ForegroundColor() Color {
+ return output.ForegroundColor()
+}
+
+// BackgroundColor returns the terminal's default background color.
+func BackgroundColor() Color {
+ return output.BackgroundColor()
+}
+
+// HasDarkBackground returns whether terminal uses a dark-ish background.
+func HasDarkBackground() bool {
+ return output.HasDarkBackground()
+}
+
+// EnvNoColor returns true if the environment variables explicitly disable color output
+// by setting NO_COLOR (https://no-color.org/)
+// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
+// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
+// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
+func (o *Output) EnvNoColor() bool {
+ return o.environ.Getenv("NO_COLOR") != "" || (o.environ.Getenv("CLICOLOR") == "0" && !o.cliColorForced())
+}
+
+// EnvNoColor returns true if the environment variables explicitly disable color output
+// by setting NO_COLOR (https://no-color.org/)
+// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
+// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
+// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
+func EnvNoColor() bool {
+ return output.EnvNoColor()
+}
+
+// EnvColorProfile returns the color profile based on environment variables set
+// Supports NO_COLOR (https://no-color.org/)
+// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
+// If none of these environment variables are set, this behaves the same as ColorProfile()
+// It will return the Ascii color profile if EnvNoColor() returns true
+// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
+// then the ANSI color profile will be returned.
+func EnvColorProfile() Profile {
+ return output.EnvColorProfile()
+}
+
+// EnvColorProfile returns the color profile based on environment variables set
+// Supports NO_COLOR (https://no-color.org/)
+// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
+// If none of these environment variables are set, this behaves the same as ColorProfile()
+// It will return the Ascii color profile if EnvNoColor() returns true
+// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
+// then the ANSI color profile will be returned.
+func (o *Output) EnvColorProfile() Profile {
+ if o.EnvNoColor() {
+ return Ascii
+ }
+ p := o.ColorProfile()
+ if o.cliColorForced() && p == Ascii {
+ return ANSI
+ }
+ return p
+}
+
+func (o *Output) cliColorForced() bool {
+ if forced := o.environ.Getenv("CLICOLOR_FORCE"); forced != "" {
+ return forced != "0"
+ }
+ return false
+}
diff --git a/vendor/github.com/muesli/termenv/termenv_other.go b/vendor/github.com/muesli/termenv/termenv_other.go
new file mode 100644
index 00000000..93a43b6a
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_other.go
@@ -0,0 +1,30 @@
+//go:build js || plan9 || aix
+// +build js plan9 aix
+
+package termenv
+
+import "io"
+
+// ColorProfile returns the supported color profile:
+// ANSI256
+func (o Output) ColorProfile() Profile {
+ return ANSI256
+}
+
+func (o Output) foregroundColor() Color {
+ // default gray
+ return ANSIColor(7)
+}
+
+func (o Output) backgroundColor() Color {
+ // default black
+ return ANSIColor(0)
+}
+
+// EnableVirtualTerminalProcessing enables virtual terminal processing on
+// Windows for w and returns a function that restores w to its previous state.
+// On non-Windows platforms, or if w does not refer to a terminal, then it
+// returns a non-nil no-op function and no error.
+func EnableVirtualTerminalProcessing(w io.Writer) (func() error, error) {
+ return func() error { return nil }, nil
+}
diff --git a/vendor/github.com/muesli/termenv/termenv_posix.go b/vendor/github.com/muesli/termenv/termenv_posix.go
new file mode 100644
index 00000000..c971dd99
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_posix.go
@@ -0,0 +1,17 @@
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos
+// +build darwin dragonfly freebsd linux netbsd openbsd zos
+
+package termenv
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+func isForeground(fd int) bool {
+ pgrp, err := unix.IoctlGetInt(fd, unix.TIOCGPGRP)
+ if err != nil {
+ return false
+ }
+
+ return pgrp == unix.Getpgrp()
+}
diff --git a/vendor/github.com/muesli/termenv/termenv_solaris.go b/vendor/github.com/muesli/termenv/termenv_solaris.go
new file mode 100644
index 00000000..27a95a93
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_solaris.go
@@ -0,0 +1,22 @@
+//go:build solaris || illumos
+// +build solaris illumos
+
+package termenv
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+func isForeground(fd int) bool {
+ pgrp, err := unix.IoctlGetInt(fd, unix.TIOCGPGRP)
+ if err != nil {
+ return false
+ }
+
+ g, err := unix.Getpgrp()
+ if err != nil {
+ return false
+ }
+
+ return pgrp == g
+}
diff --git a/vendor/github.com/muesli/termenv/termenv_unix.go b/vendor/github.com/muesli/termenv/termenv_unix.go
new file mode 100644
index 00000000..bef49ca3
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_unix.go
@@ -0,0 +1,301 @@
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package termenv
+
+import (
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+ "time"
+
+ "golang.org/x/sys/unix"
+)
+
+const (
+ // timeout for OSC queries.
+ OSCTimeout = 5 * time.Second
+)
+
+// ColorProfile returns the supported color profile:
+// Ascii, ANSI, ANSI256, or TrueColor.
+func (o *Output) ColorProfile() Profile {
+ if !o.isTTY() {
+ return Ascii
+ }
+
+ if o.environ.Getenv("GOOGLE_CLOUD_SHELL") == "true" {
+ return TrueColor
+ }
+
+ term := o.environ.Getenv("TERM")
+ colorTerm := o.environ.Getenv("COLORTERM")
+
+ switch strings.ToLower(colorTerm) {
+ case "24bit":
+ fallthrough
+ case "truecolor":
+ if strings.HasPrefix(term, "screen") {
+ // tmux supports TrueColor, screen only ANSI256
+ if o.environ.Getenv("TERM_PROGRAM") != "tmux" {
+ return ANSI256
+ }
+ }
+ return TrueColor
+ case "yes":
+ fallthrough
+ case "true":
+ return ANSI256
+ }
+
+ switch term {
+ case
+ "alacritty",
+ "contour",
+ "rio",
+ "wezterm",
+ "xterm-ghostty",
+ "xterm-kitty":
+ return TrueColor
+ case "linux", "xterm":
+ return ANSI
+ }
+
+ if strings.Contains(term, "256color") {
+ return ANSI256
+ }
+ if strings.Contains(term, "color") {
+ return ANSI
+ }
+ if strings.Contains(term, "ansi") {
+ return ANSI
+ }
+
+ return Ascii
+}
+
+//nolint:mnd
+func (o Output) foregroundColor() Color {
+ s, err := o.termStatusReport(10)
+ if err == nil {
+ c, err := xTermColor(s)
+ if err == nil {
+ return c
+ }
+ }
+
+ colorFGBG := o.environ.Getenv("COLORFGBG")
+ if strings.Contains(colorFGBG, ";") {
+ c := strings.Split(colorFGBG, ";")
+ i, err := strconv.Atoi(c[0])
+ if err == nil {
+ return ANSIColor(i)
+ }
+ }
+
+ // default gray
+ return ANSIColor(7)
+}
+
+//nolint:mnd
+func (o Output) backgroundColor() Color {
+ s, err := o.termStatusReport(11)
+ if err == nil {
+ c, err := xTermColor(s)
+ if err == nil {
+ return c
+ }
+ }
+
+ colorFGBG := o.environ.Getenv("COLORFGBG")
+ if strings.Contains(colorFGBG, ";") {
+ c := strings.Split(colorFGBG, ";")
+ i, err := strconv.Atoi(c[len(c)-1])
+ if err == nil {
+ return ANSIColor(i)
+ }
+ }
+
+ // default black
+ return ANSIColor(0)
+}
+
+func (o *Output) waitForData(timeout time.Duration) error {
+ fd := o.TTY().Fd()
+ tv := unix.NsecToTimeval(int64(timeout))
+ var readfds unix.FdSet
+ readfds.Set(int(fd)) //nolint:gosec
+
+ for {
+ n, err := unix.Select(int(fd)+1, &readfds, nil, nil, &tv) //nolint:gosec
+ if err == unix.EINTR {
+ continue
+ }
+ if err != nil {
+ return err //nolint:wrapcheck
+ }
+ if n == 0 {
+ return fmt.Errorf("timeout")
+ }
+
+ break
+ }
+
+ return nil
+}
+
+func (o *Output) readNextByte() (byte, error) {
+ if !o.unsafe {
+ if err := o.waitForData(OSCTimeout); err != nil {
+ return 0, err
+ }
+ }
+
+ var b [1]byte
+ n, err := o.TTY().Read(b[:])
+ if err != nil {
+ return 0, err //nolint:wrapcheck
+ }
+
+ if n == 0 {
+ panic("read returned no data")
+ }
+
+ return b[0], nil
+}
+
+// readNextResponse reads either an OSC response or a cursor position response:
+// - OSC response: "\x1b]11;rgb:1111/1111/1111\x1b\\"
+// - cursor position response: "\x1b[42;1R"
+func (o *Output) readNextResponse() (response string, isOSC bool, err error) {
+ start, err := o.readNextByte()
+ if err != nil {
+ return "", false, err
+ }
+
+ // first byte must be ESC
+ for start != ESC {
+ start, err = o.readNextByte()
+ if err != nil {
+ return "", false, err
+ }
+ }
+
+ response += string(start)
+
+ // next byte is either '[' (cursor position response) or ']' (OSC response)
+ tpe, err := o.readNextByte()
+ if err != nil {
+ return "", false, err
+ }
+
+ response += string(tpe)
+
+ var oscResponse bool
+ switch tpe {
+ case '[':
+ oscResponse = false
+ case ']':
+ oscResponse = true
+ default:
+ return "", false, ErrStatusReport
+ }
+
+ for {
+ b, err := o.readNextByte()
+ if err != nil {
+ return "", false, err
+ }
+
+ response += string(b)
+
+ if oscResponse {
+ // OSC can be terminated by BEL (\a) or ST (ESC)
+ if b == BEL || strings.HasSuffix(response, string(ESC)) {
+ return response, true, nil
+ }
+ } else {
+ // cursor position response is terminated by 'R'
+ if b == 'R' {
+ return response, false, nil
+ }
+ }
+
+ // both responses have less than 25 bytes, so if we read more, that's an error
+ if len(response) > 25 { //nolint:mnd
+ break
+ }
+ }
+
+ return "", false, ErrStatusReport
+}
+
+func (o Output) termStatusReport(sequence int) (string, error) {
+ // screen/tmux can't support OSC, because they can be connected to multiple
+ // terminals concurrently.
+ term := o.environ.Getenv("TERM")
+ if strings.HasPrefix(term, "screen") || strings.HasPrefix(term, "tmux") || strings.HasPrefix(term, "dumb") {
+ return "", ErrStatusReport
+ }
+
+ tty := o.TTY()
+ if tty == nil {
+ return "", ErrStatusReport
+ }
+
+ if !o.unsafe {
+ fd := int(tty.Fd()) //nolint:gosec
+ // if in background, we can't control the terminal
+ if !isForeground(fd) {
+ return "", ErrStatusReport
+ }
+
+ t, err := unix.IoctlGetTermios(fd, tcgetattr)
+ if err != nil {
+ return "", fmt.Errorf("%s: %s", ErrStatusReport, err)
+ }
+ defer unix.IoctlSetTermios(fd, tcsetattr, t) //nolint:errcheck
+
+ noecho := *t
+ noecho.Lflag = noecho.Lflag &^ unix.ECHO
+ noecho.Lflag = noecho.Lflag &^ unix.ICANON
+ if err := unix.IoctlSetTermios(fd, tcsetattr, &noecho); err != nil {
+ return "", fmt.Errorf("%s: %s", ErrStatusReport, err)
+ }
+ }
+
+ // first, send OSC query, which is ignored by terminal which do not support it
+ fmt.Fprintf(tty, OSC+"%d;?"+ST, sequence) //nolint:errcheck
+
+ // then, query cursor position, should be supported by all terminals
+ fmt.Fprintf(tty, CSI+"6n") //nolint:errcheck
+
+ // read the next response
+ res, isOSC, err := o.readNextResponse()
+ if err != nil {
+ return "", fmt.Errorf("%s: %s", ErrStatusReport, err)
+ }
+
+ // if this is not OSC response, then the terminal does not support it
+ if !isOSC {
+ return "", ErrStatusReport
+ }
+
+ // read the cursor query response next and discard the result
+ _, _, err = o.readNextResponse()
+ if err != nil {
+ return "", err
+ }
+
+ // fmt.Println("Rcvd", res[1:])
+ return res, nil
+}
+
+// EnableVirtualTerminalProcessing enables virtual terminal processing on
+// Windows for w and returns a function that restores w to its previous state.
+// On non-Windows platforms, or if w does not refer to a terminal, then it
+// returns a non-nil no-op function and no error.
+func EnableVirtualTerminalProcessing(_ io.Writer) (func() error, error) {
+ return func() error { return nil }, nil
+}
diff --git a/vendor/github.com/muesli/termenv/termenv_windows.go b/vendor/github.com/muesli/termenv/termenv_windows.go
new file mode 100644
index 00000000..f9b1def0
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_windows.go
@@ -0,0 +1,140 @@
+//go:build windows
+// +build windows
+
+package termenv
+
+import (
+ "fmt"
+ "os"
+ "strconv"
+
+ "golang.org/x/sys/windows"
+)
+
+func (o *Output) ColorProfile() Profile {
+ if !o.isTTY() {
+ return Ascii
+ }
+
+ if o.environ.Getenv("ConEmuANSI") == "ON" {
+ return TrueColor
+ }
+
+ winVersion, _, buildNumber := windows.RtlGetNtVersionNumbers()
+ if buildNumber < 10586 || winVersion < 10 {
+ // No ANSI support before Windows 10 build 10586.
+ if o.environ.Getenv("ANSICON") != "" {
+ conVersion := o.environ.Getenv("ANSICON_VER")
+ cv, err := strconv.ParseInt(conVersion, 10, 64)
+ if err != nil || cv < 181 {
+ // No 8 bit color support before v1.81 release.
+ return ANSI
+ }
+
+ return ANSI256
+ }
+
+ return Ascii
+ }
+ if buildNumber < 14931 {
+ // No true color support before build 14931.
+ return ANSI256
+ }
+
+ return TrueColor
+}
+
+func (o Output) foregroundColor() Color {
+ // default gray
+ return ANSIColor(7)
+}
+
+func (o Output) backgroundColor() Color {
+ // default black
+ return ANSIColor(0)
+}
+
+// EnableWindowsANSIConsole enables virtual terminal processing on Windows
+// platforms. This allows the use of ANSI escape sequences in Windows console
+// applications. Ensure this gets called before anything gets rendered with
+// termenv.
+//
+// Returns the original console mode and an error if one occurred.
+func EnableWindowsANSIConsole() (uint32, error) {
+ handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE)
+ if err != nil {
+ return 0, err
+ }
+
+ var mode uint32
+ err = windows.GetConsoleMode(handle, &mode)
+ if err != nil {
+ return 0, err
+ }
+
+ // See https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
+ if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING {
+ vtpmode := mode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
+ if err := windows.SetConsoleMode(handle, vtpmode); err != nil {
+ return 0, err
+ }
+ }
+
+ return mode, nil
+}
+
+// RestoreWindowsConsole restores the console mode to a previous state.
+func RestoreWindowsConsole(mode uint32) error {
+ handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE)
+ if err != nil {
+ return err
+ }
+
+ return windows.SetConsoleMode(handle, mode)
+}
+
+// EnableVirtualTerminalProcessing enables virtual terminal processing on
+// Windows for o and returns a function that restores o to its previous state.
+// On non-Windows platforms, or if o does not refer to a terminal, then it
+// returns a non-nil no-op function and no error.
+func EnableVirtualTerminalProcessing(o *Output) (restoreFunc func() error, err error) {
+ // There is nothing to restore until we set the console mode.
+ restoreFunc = func() error {
+ return nil
+ }
+
+ // If o is not a tty, then there is nothing to do.
+ tty, ok := o.Writer().(*os.File)
+ if tty == nil || !ok {
+ return
+ }
+
+ // Get the current console mode. If there is an error, assume that o is not
+ // a terminal, discard the error, and return.
+ var mode uint32
+ if err2 := windows.GetConsoleMode(windows.Handle(tty.Fd()), &mode); err2 != nil {
+ return
+ }
+
+ // If virtual terminal processing is already set, then there is nothing to
+ // do and nothing to restore.
+ if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING == windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING {
+ return
+ }
+
+ // Enable virtual terminal processing. See
+ // https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
+ if err2 := windows.SetConsoleMode(windows.Handle(tty.Fd()), mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err2 != nil {
+ err = fmt.Errorf("windows.SetConsoleMode: %w", err2)
+ return
+ }
+
+ // Set the restore function. We maintain a reference to the tty in the
+ // closure (rather than just its handle) to ensure that the tty is not
+ // closed by a finalizer.
+ restoreFunc = func() error {
+ return windows.SetConsoleMode(windows.Handle(tty.Fd()), mode)
+ }
+
+ return
+}
diff --git a/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml b/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml
index ec52857a..47f0f591 100644
--- a/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml
+++ b/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml
@@ -113,7 +113,7 @@ dockers:
checksum:
name_template: 'sha256sums.txt'
snapshot:
- name_template: "{{ incpatch .Version }}-next"
+ version_template: "{{ incpatch .Version }}-next"
release:
github:
owner: pelletier
diff --git a/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go b/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
index c3df8bee..189be525 100644
--- a/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
+++ b/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
@@ -59,7 +59,7 @@ func (d *Decoder) DisallowUnknownFields() *Decoder {
//
// With this feature enabled, types implementing the unstable/Unmarshaler
// interface can be decoded from any structure of the document. It allows types
-// that don't have a straightfoward TOML representation to provide their own
+// that don't have a straightforward TOML representation to provide their own
// decoding logic.
//
// Currently, types can only decode from a single value. Tables and array tables
diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go
index 84ebd6cf..a26067bb 100644
--- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go
+++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go
@@ -17,7 +17,7 @@ func NewAnalyzer(opts ...Option) *analysis.Analyzer {
a := &analysis.Analyzer{
Name: "errorlint",
- Doc: "Source code linter for Go software that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.",
+ Doc: "Linter for error wrapping issues.",
Run: run,
}
diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go
index ed3dd0dc..9ef6d585 100644
--- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go
+++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go
@@ -1,11 +1,14 @@
package errorlint
import (
+ "bytes"
"fmt"
"go/ast"
"go/constant"
+ "go/printer"
"go/token"
"go/types"
+ "strings"
"golang.org/x/tools/go/analysis"
)
@@ -14,7 +17,6 @@ type ByPosition []analysis.Diagnostic
func (l ByPosition) Len() int { return len(l) }
func (l ByPosition) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
-
func (l ByPosition) Less(i, j int) bool {
return l[i].Pos < l[j].Pos
}
@@ -100,8 +102,12 @@ func LintFmtErrorfCalls(fset *token.FileSet, info types.Info, multipleWraps bool
Pos: arg.Pos(),
}
}
+ fixMessage := "Use `%w` to format errors"
+ if len(lint.SuggestedFixes) > 0 {
+ fixMessage += fmt.Sprintf(" (%d)", len(lint.SuggestedFixes)+1)
+ }
lint.SuggestedFixes = append(lint.SuggestedFixes, analysis.SuggestedFix{
- Message: "Use `%w` to format errors",
+ Message: fixMessage,
TextEdits: []analysis.TextEdit{{
Pos: strStart + token.Pos(verb.formatOffset) + 1,
End: strStart + token.Pos(verb.formatOffset) + 2,
@@ -162,6 +168,7 @@ func isFmtErrorfCallExpr(info types.Info, expr ast.Expr) (*ast.CallExpr, bool) {
func LintErrorComparisons(info *TypesInfoExt) []analysis.Diagnostic {
var lints []analysis.Diagnostic
+ // Check for error comparisons.
for expr := range info.TypesInfo.Types {
// Find == and != operations.
binExpr, ok := expr.(*ast.BinaryExpr)
@@ -188,12 +195,45 @@ func LintErrorComparisons(info *TypesInfoExt) []analysis.Diagnostic {
continue
}
- lints = append(lints, analysis.Diagnostic{
+ diagnostic := analysis.Diagnostic{
Message: fmt.Sprintf("comparing with %s will fail on wrapped errors. Use errors.Is to check for a specific error", binExpr.Op),
Pos: binExpr.Pos(),
- })
+ }
+
+ // Add suggested fix.
+ var errVar, targetErr ast.Expr
+ // Identify which side is the error variable and which is the sentinel error.
+ if isErrorType(info.TypesInfo, binExpr.Y) && !isErrorType(info.TypesInfo, binExpr.X) {
+ // Y is error, X is not
+ errVar = binExpr.Y
+ targetErr = binExpr.X
+ } else {
+ // X is error (or both are errors)
+ errVar = binExpr.X
+ targetErr = binExpr.Y
+ }
+
+ negated := binExpr.Op == token.NEQ
+
+ // Build the suggested fix - preserve the original order of parameters.
+ replacement := fmt.Sprintf("errors.Is(%s, %s)", exprToString(errVar), exprToString(targetErr))
+ if negated {
+ replacement = "!" + replacement
+ }
+
+ diagnostic.SuggestedFixes = []analysis.SuggestedFix{{
+ Message: "Use errors.Is() to compare errors",
+ TextEdits: []analysis.TextEdit{{
+ Pos: binExpr.Pos(),
+ End: binExpr.End(),
+ NewText: []byte(replacement),
+ }},
+ }}
+
+ lints = append(lints, diagnostic)
}
+ // Check for error comparisons in switch statements.
for scope := range info.TypesInfo.Scopes {
// Find value switch blocks.
switchStmt, ok := scope.(*ast.SwitchStmt)
@@ -223,22 +263,130 @@ func LintErrorComparisons(info *TypesInfoExt) []analysis.Diagnostic {
if problematicCaseClause == nil {
continue
}
+
// Comparisons that happen in `func (type) Is(error) bool` are okay.
if isNodeInErrorIsFunc(info, switchStmt) {
continue
}
if switchComparesNonNil(switchStmt) {
- lints = append(lints, analysis.Diagnostic{
+ diagnostic := analysis.Diagnostic{
Message: "switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors",
Pos: problematicCaseClause.Pos(),
- })
+ }
+
+ // Create a simpler version of the fix for switch statements
+ // We'll transform: switch err { case ErrX: ... }
+ // To: switch { case errors.Is(err, ErrX): ... }
+
+ // Create a new switch statement with an empty tag
+ newSwitchStmt := &ast.SwitchStmt{
+ Init: switchStmt.Init,
+ Tag: nil, // Empty tag for the switch.
+ Body: &ast.BlockStmt{
+ List: make([]ast.Stmt, len(switchStmt.Body.List)),
+ },
+ }
+
+ // Convert each case to use errors.Is.
+ switchTagExpr := switchStmt.Tag // The error variable being checked.
+ for i, stmt := range switchStmt.Body.List {
+ origCaseClause := stmt.(*ast.CaseClause)
+
+ // Create a new case clause.
+ newCaseClause := &ast.CaseClause{
+ Body: origCaseClause.Body,
+ }
+
+ // If this is a default case (no expressions), keep it as-is.
+ if len(origCaseClause.List) == 0 {
+ newCaseClause.List = nil // Default case.
+ newSwitchStmt.Body.List[i] = newCaseClause
+ continue
+ }
+
+ newCaseClause.List = make([]ast.Expr, 0, len(origCaseClause.List))
+
+ // Convert each case expression.
+ for _, caseExpr := range origCaseClause.List {
+ if isNil(caseExpr) {
+ // Keep nil checks as is: case err == nil:
+ newCaseClause.List = append(newCaseClause.List,
+ &ast.BinaryExpr{
+ X: switchTagExpr,
+ Op: token.EQL,
+ Y: caseExpr,
+ })
+ continue
+ }
+ // Replace err == ErrX with errors.Is(err, ErrX).
+ newCaseClause.List = append(newCaseClause.List,
+ &ast.CallExpr{
+ Fun: &ast.SelectorExpr{
+ X: ast.NewIdent("errors"),
+ Sel: ast.NewIdent("Is"),
+ },
+ Args: []ast.Expr{switchTagExpr, caseExpr},
+ })
+ }
+
+ newSwitchStmt.Body.List[i] = newCaseClause
+ }
+
+ // Print the modified AST to get the fix text.
+ var buf bytes.Buffer
+ printer.Fprint(&buf, token.NewFileSet(), newSwitchStmt)
+ fixText := buf.String()
+
+ diagnostic.SuggestedFixes = []analysis.SuggestedFix{{
+ Message: "Convert to errors.Is() for error comparisons",
+ TextEdits: []analysis.TextEdit{{
+ Pos: switchStmt.Pos(),
+ End: switchStmt.End(),
+ NewText: []byte(fixText),
+ }},
+ }}
+
+ lints = append(lints, diagnostic)
}
}
return lints
}
+// exprToString converts an expression to its string representation.
+func exprToString(expr ast.Expr) string {
+ switch e := expr.(type) {
+ case *ast.Ident:
+ return e.Name
+ case *ast.SelectorExpr:
+ return exprToString(e.X) + "." + e.Sel.Name
+ case *ast.StarExpr:
+ return "*" + exprToString(e.X)
+ case *ast.UnaryExpr:
+ return e.Op.String() + exprToString(e.X)
+ case *ast.BinaryExpr:
+ return exprToString(e.X) + " " + e.Op.String() + " " + exprToString(e.Y)
+ case *ast.CallExpr:
+ var args []string
+ for _, arg := range e.Args {
+ args = append(args, exprToString(arg))
+ }
+ return exprToString(e.Fun) + "(" + strings.Join(args, ", ") + ")"
+ case *ast.ParenExpr:
+ return "(" + exprToString(e.X) + ")"
+ case *ast.IndexExpr:
+ return exprToString(e.X) + "[" + exprToString(e.Index) + "]"
+ case *ast.BasicLit:
+ return e.Value
+ case *ast.TypeAssertExpr:
+ return exprToString(e.X) + ".(" + exprToString(e.Type) + ")"
+ default:
+ // If we can't handle the expression type, return a placeholder.
+ return "/* complex expression */"
+ }
+}
+
func isNil(ex ast.Expr) bool {
ident, ok := ex.(*ast.Ident)
return ok && ident.Name == "nil"
@@ -254,22 +402,22 @@ func isNodeInErrorIsFunc(info *TypesInfoExt, node ast.Node) bool {
if funcDecl == nil {
return false
}
-
+ // Check if the function name is Is.
if funcDecl.Name.Name != "Is" {
return false
}
+ // Check if the function has a receiver.
if funcDecl.Recv == nil {
return false
}
// There should be 1 argument of type error.
- if ii := funcDecl.Type.Params.List; len(ii) != 1 || info.TypesInfo.Types[ii[0].Type].Type.String() != "error" {
+ if params := funcDecl.Type.Params.List; len(params) != 1 || info.TypesInfo.Types[params[0].Type].Type.String() != "error" {
return false
}
// The return type should be bool.
- if ii := funcDecl.Type.Results.List; len(ii) != 1 || info.TypesInfo.Types[ii[0].Type].Type.String() != "bool" {
+ if params := funcDecl.Type.Results.List; len(params) != 1 || info.TypesInfo.Types[params[0].Type].Type.String() != "bool" {
return false
}
-
return true
}
@@ -283,15 +431,15 @@ func switchComparesNonNil(switchStmt *ast.SwitchStmt) bool {
for _, clause := range caseClause.List {
switch clause := clause.(type) {
case nil:
- // default label is safe
+ // default label is safe.
continue
case *ast.Ident:
- // `case nil` is safe
+ // `case nil` is safe.
if clause.Name == "nil" {
continue
}
}
- // anything else (including an Ident other than nil) isn't safe
+ // anything else (including an Ident other than nil) isn't safe.
return true
}
}
@@ -322,10 +470,143 @@ func LintErrorTypeAssertions(fset *token.FileSet, info *TypesInfoExt) []analysis
continue
}
- lints = append(lints, analysis.Diagnostic{
+ diagnostic := analysis.Diagnostic{
Message: "type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors",
Pos: typeAssert.Pos(),
- })
+ }
+
+ // Create suggested fix for type assertion
+ targetType := exprToString(typeAssert.Type)
+ errExpr := exprToString(typeAssert.X)
+
+ // Check if the type is a pointer type
+ baseType, isPointerType := strings.CutPrefix(targetType, "*")
+
+ parent := info.NodeParent[typeAssert]
+
+ // For assignment statements like: targetErr, ok := err.(*SomeError)
+ if assign, ok := parent.(*ast.AssignStmt); ok && len(assign.Lhs) == 2 {
+ if id, ok := assign.Lhs[0].(*ast.Ident); ok {
+ // Generate a suitable variable name, handling underscore case
+ // Example: _, ok := err.(*MyError) -> myError := &MyError{}; ok := errors.As(err, &myError)
+ varName := generateErrorVarName(id.Name, baseType)
+
+ // If this is part of an if statement initialization
+ ifParent, isIfInit := info.NodeParent[assign].(*ast.IfStmt)
+ if isIfInit && ifParent.Init == assign {
+ // Handle special case for if statements
+ // Replace: if targetErr, ok := err.(*SomeError); ok {
+ // With: targetErr := &SomeError{}
+ // if errors.As(err, &targetErr) {
+ var varDecl string
+ if isPointerType {
+ varDecl = fmt.Sprintf("%s := &%s{}", varName, baseType)
+ } else {
+ varDecl = fmt.Sprintf("var %s %s", varName, baseType)
+ }
+ condition := fmt.Sprintf("if errors.As(%s, &%s)", errExpr, varName)
+
+ replacement := fmt.Sprintf("%s\n%s",
+ varDecl, condition)
+
+ diagnostic.SuggestedFixes = []analysis.SuggestedFix{{
+ Message: "Use errors.As() for type assertions on errors",
+ TextEdits: []analysis.TextEdit{{
+ // Replace both the if statement's initialization and condition
+ Pos: ifParent.Pos(),
+ End: ifParent.Body.Pos(),
+ NewText: []byte(replacement),
+ }},
+ }}
+ lints = append(lints, diagnostic)
+ continue
+ }
+
+ // Regular assignment outside of if statement.
+ // Replace: targetErr, ok := err.(*SomeError) or err.(SomeError)
+ // With: targetErr := &SomeError{} or var targetErr SomeError
+ // ok := errors.As(err, &targetErr)
+ var varDecl string
+ if isPointerType {
+ varDecl = fmt.Sprintf("%s := &%s{}", varName, baseType)
+ } else {
+ varDecl = fmt.Sprintf("var %s %s", varName, baseType)
+ }
+
+ // Preserve the original name of the "ok" variable
+ // Example: myErr, wasFound := err.(*MyError)
+ // Should use "wasFound" in the transformed code, not just "ok"
+ okName := "ok" // Default
+ if len(assign.Lhs) > 1 {
+ if okIdent, okOk := assign.Lhs[1].(*ast.Ident); okOk && okIdent.Name != "_" {
+ okName = okIdent.Name
+ }
+ }
+
+ // Align with golden file format
+ replacement := fmt.Sprintf("%s\n%s := errors.As(%s, &%s)",
+ varDecl, okName, errExpr, varName)
+
+ diagnostic.SuggestedFixes = []analysis.SuggestedFix{{
+ Message: "Use errors.As() for type assertions on errors",
+ TextEdits: []analysis.TextEdit{{
+ Pos: assign.Pos(),
+ End: assign.End(),
+ NewText: []byte(replacement),
+ }},
+ }}
+ lints = append(lints, diagnostic)
+ continue
+ }
+ }
+
+ if _, ok := parent.(*ast.IfStmt); ok {
+ // For if statements without initialization but with direct type assertion in condition
+ varName := generateErrorVarName("target", baseType)
+ var varDecl string
+ if isPointerType {
+ varDecl = fmt.Sprintf("%s := &%s{}", varName, baseType)
+ } else {
+ varDecl = fmt.Sprintf("var %s %s", varName, baseType)
+ }
+ replacement := fmt.Sprintf("%s\nif errors.As(%s, &%s)",
+ varDecl, errExpr, varName)
+
+ diagnostic.SuggestedFixes = []analysis.SuggestedFix{{
+ Message: "Use errors.As() for type assertions on errors",
+ TextEdits: []analysis.TextEdit{{
+ Pos: typeAssert.Pos(),
+ End: typeAssert.End(),
+ NewText: []byte(replacement),
+ }},
+ }}
+ lints = append(lints, diagnostic)
+ continue
+ }
+
+ // Handle standalone type assertions without assignment
+ // Example: _ = err.(*MyError)
+ // Transforms to: _ = func() *MyError { var target *MyError; _ = errors.As(err, &target); return target }()
+ varName := generateErrorVarName("target", baseType)
+ var targetDecl string
+ if isPointerType {
+ targetDecl = fmt.Sprintf("%s := &%s{}", varName, baseType)
+ } else {
+ targetDecl = fmt.Sprintf("var %s %s", varName, baseType)
+ }
+
+ replacement := fmt.Sprintf("func() %s {\n\t%s\n\t_ = errors.As(%s, &%s)\n\treturn %s\n}()",
+ targetType, targetDecl, errExpr, varName, varName)
+
+ diagnostic.SuggestedFixes = []analysis.SuggestedFix{{
+ Message: "Use errors.As() for type assertions on errors",
+ TextEdits: []analysis.TextEdit{{
+ Pos: typeAssert.Pos(),
+ End: typeAssert.End(),
+ NewText: []byte(replacement),
+ }},
+ }}
+ lints = append(lints, diagnostic)
}
for scope := range info.TypesInfo.Scopes {
@@ -353,10 +634,189 @@ func LintErrorTypeAssertions(fset *token.FileSet, info *TypesInfoExt) []analysis
continue
}
- lints = append(lints, analysis.Diagnostic{
+ diagnostic := analysis.Diagnostic{
Message: "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors",
Pos: typeAssert.Pos(),
- })
+ }
+
+ // Transform type switch into a switch statement with errors.As in each case
+ // e.g., switch err.(type) { case *MyError: ... } becomes:
+ // var myError *MyError; switch { case errors.As(err, &myError): ... }
+
+ // Get the error variable being type-switched on
+ errExpr := typeAssert.X
+
+ // Determine if this is a type switch with assignment (switch e := err.(type))
+ var assignIdent *ast.Ident
+ var useShadowVar bool
+ if assignStmt, ok := typeSwitch.Assign.(*ast.AssignStmt); ok {
+ // This is a type switch with assignment like: switch e := err.(type)
+ if len(assignStmt.Lhs) == 1 {
+ if id, ok := assignStmt.Lhs[0].(*ast.Ident); ok {
+ assignIdent = id
+ useShadowVar = true
+ }
+ }
+ }
+
+ // Create variable declarations for each type
+ varDecls := []ast.Stmt{}
+
+ // Create a map of type expressions to variable names
+ typeToVar := make(map[ast.Expr]string)
+
+ // First collect all unique types from cases
+ caseTypes := []ast.Expr{}
+ for _, stmt := range typeSwitch.Body.List {
+ caseClause := stmt.(*ast.CaseClause)
+ for _, typeExpr := range caseClause.List {
+ // Skip default case (empty list)
+ if typeExpr != nil {
+ caseTypes = append(caseTypes, typeExpr)
+ }
+ }
+ }
+
+ // Create variable declarations for each type.
+ for i, typeExpr := range caseTypes {
+ // Create variable declarations for each type.
+ // generate a default and unique name
+ varName := fmt.Sprintf("errCase%d", i)
+
+ // then try to find a better one.
+ if useShadowVar || (assignIdent != nil && i == 0) {
+ // If we have an assignment identifier, use it for all variables in a switch with assignment.
+ // Otherwise, if we have an assignment but not shadowing, use it for the first variable.
+ varName = assignIdent.Name
+ }
+
+ // Ensure we don't create duplicate variables with the same name.
+ var duplicate bool
+ for j := 0; j < i; j++ {
+ if typeToVar[caseTypes[j]] == varName {
+ duplicate = true
+ break
+ }
+ }
+
+ if duplicate {
+ // Use a different name to avoid duplicate variable declarations.
+ varName = fmt.Sprintf("%s%d", varName, i)
+ }
+
+ typeToVar[typeExpr] = varName
+
+ // Create a variable declaration.
+ varDecl := &ast.DeclStmt{
+ Decl: &ast.GenDecl{
+ Tok: token.VAR,
+ Specs: []ast.Spec{
+ &ast.ValueSpec{
+ Names: []*ast.Ident{ast.NewIdent(varName)},
+ Type: typeExpr,
+ },
+ },
+ },
+ }
+
+ varDecls = append(varDecls, varDecl)
+ }
+
+ // Create a new switch statement with empty tag.
+ newSwitchStmt := &ast.SwitchStmt{
+ Body: &ast.BlockStmt{
+ List: make([]ast.Stmt, len(typeSwitch.Body.List)),
+ },
+ }
+
+ // Create a block statement to hold both variable declarations and the switch.
+ blockStmt := &ast.BlockStmt{
+ List: append(varDecls, newSwitchStmt),
+ }
+
+ // Process each case.
+ for i, stmt := range typeSwitch.Body.List {
+ caseClause := stmt.(*ast.CaseClause)
+
+ // Create a new case clause.
+ newCaseClause := &ast.CaseClause{
+ Body: caseClause.Body,
+ }
+
+ // If this is a default case, keep it as-is.
+ if len(caseClause.List) == 0 {
+ // This is the default case.
+ newCaseClause.List = nil
+ newSwitchStmt.Body.List[i] = newCaseClause
+ continue
+ }
+
+ // For other cases, create errors.As calls for each type.
+ newCaseClause.List = make([]ast.Expr, len(caseClause.List))
+
+ for j, typeExpr := range caseClause.List {
+ // Get the previously declared variable for this type.
+ varName := typeToVar[typeExpr]
+
+ // Create errors.As(err, &varName) call.
+ newCaseClause.List[j] = &ast.CallExpr{
+ Fun: &ast.SelectorExpr{
+ X: ast.NewIdent("errors"),
+ Sel: ast.NewIdent("As"),
+ },
+ Args: []ast.Expr{
+ errExpr,
+ &ast.UnaryExpr{
+ Op: token.AND,
+ X: ast.NewIdent(varName),
+ },
+ },
+ }
+ }
+
+ // If this is a switch with assignment, we need to update the variable
+ // names used in the body of each case to match our renamed variables.
+ if assignIdent != nil && len(caseClause.List) > 0 {
+ typeExpr := caseClause.List[0]
+ oldVarName := assignIdent.Name
+ newVarName := typeToVar[typeExpr]
+
+ if oldVarName != newVarName {
+ // Create a visitor to replace all mentions of the original variable
+ // with our renamed variable in this case's body.
+ visitor := func(n ast.Node) bool {
+ if ident, ok := n.(*ast.Ident); ok && ident.Name == oldVarName {
+ ident.Name = newVarName
+ }
+ return true
+ }
+
+ // Apply the visitor to the case body
+ for _, bodyStmt := range newCaseClause.Body {
+ ast.Inspect(bodyStmt, visitor)
+ }
+ }
+ }
+
+ // Add this case to the switch.
+ newSwitchStmt.Body.List[i] = newCaseClause
+ }
+
+ // Print the resulting block to get the fix text.
+ var buf bytes.Buffer
+ printer.Fprint(&buf, token.NewFileSet(), blockStmt)
+ fixText := buf.String()
+
+ diagnostic.SuggestedFixes = []analysis.SuggestedFix{{
+ Message: "Convert type switch to use errors.As",
+ TextEdits: []analysis.TextEdit{{
+ Pos: typeSwitch.Pos(),
+ End: typeSwitch.End(),
+ NewText: []byte(fixText),
+ }},
+ }}
+
+ lints = append(lints, diagnostic)
}
return lints
@@ -383,3 +843,40 @@ func implementsError(t types.Type) bool {
return false
}
+
+// generateErrorVarName creates an appropriate variable name for error type assertions.
+// If originalName is "_" or a generic placeholder, it generates a more meaningful name
+// based on the error type, following Go naming conventions:
+//
+// Examples:
+// - originalName="_", typeName="MyError" → "myError" (camelCase conversion)
+// - originalName="_", typeName="pkg.CustomError" → "customError" (package prefix removed)
+// - originalName="existingName" → "existingName" (original name preserved)
+// - originalName="_", typeName="" → "myErr" (fallback for unknown types)
+//
+// This helps ensure code readability when converting type assertions to errors.As calls,
+// particularly when dealing with underscore identifiers that can't be referenced.
+func generateErrorVarName(originalName, typeName string) string {
+ // If the original name is not an underscore, use it
+ if originalName != "_" {
+ return originalName
+ }
+
+ // Handle underscore case by generating a name based on the type
+ // Strip any package prefix like "pkg."
+ if lastDot := strings.LastIndex(typeName, "."); lastDot >= 0 {
+ typeName = typeName[lastDot+1:]
+ }
+
+ // Convert first letter to lowercase for camelCase
+ if len(typeName) > 0 {
+ firstChar := strings.ToLower(typeName[:1])
+ if len(typeName) > 1 {
+ return firstChar + typeName[1:]
+ }
+ return firstChar
+ }
+
+ // If we couldn't determine a good name, use default.
+ return "anErr"
+}
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio.go b/vendor/github.com/rogpeppe/go-internal/robustio/robustio.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio.go
rename to vendor/github.com/rogpeppe/go-internal/robustio/robustio.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio_darwin.go b/vendor/github.com/rogpeppe/go-internal/robustio/robustio_darwin.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio_darwin.go
rename to vendor/github.com/rogpeppe/go-internal/robustio/robustio_darwin.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio_flaky.go b/vendor/github.com/rogpeppe/go-internal/robustio/robustio_flaky.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio_flaky.go
rename to vendor/github.com/rogpeppe/go-internal/robustio/robustio_flaky.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio_other.go b/vendor/github.com/rogpeppe/go-internal/robustio/robustio_other.go
similarity index 100%
rename from vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio_other.go
rename to vendor/github.com/rogpeppe/go-internal/robustio/robustio_other.go
diff --git a/vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio_windows.go b/vendor/github.com/rogpeppe/go-internal/robustio/robustio_windows.go
similarity index 70%
rename from vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio_windows.go
rename to vendor/github.com/rogpeppe/go-internal/robustio/robustio_windows.go
index fe172895..961de4ef 100644
--- a/vendor/github.com/golangci/golangci-lint/internal/go/robustio/robustio_windows.go
+++ b/vendor/github.com/rogpeppe/go-internal/robustio/robustio_windows.go
@@ -7,14 +7,12 @@ package robustio
import (
"errors"
"syscall"
+
+ "github.com/rogpeppe/go-internal/internal/syscall/windows"
)
const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND
-// ERROR_SHARING_VIOLATION (ldez) extract from go1.19.1/src/internal/syscall/windows/syscall_windows.go.
-// This is the only modification of this file.
-const ERROR_SHARING_VIOLATION syscall.Errno = 32
-
// isEphemeralError returns true if err may be resolved by waiting.
func isEphemeralError(err error) bool {
var errno syscall.Errno
@@ -22,7 +20,7 @@ func isEphemeralError(err error) bool {
switch errno {
case syscall.ERROR_ACCESS_DENIED,
syscall.ERROR_FILE_NOT_FOUND,
- ERROR_SHARING_VIOLATION:
+ windows.ERROR_SHARING_VIOLATION:
return true
}
}
diff --git a/vendor/github.com/ryancurrah/gomodguard/.golangci.yml b/vendor/github.com/ryancurrah/gomodguard/.golangci.yml
index 5be8aa48..b4d72b7e 100644
--- a/vendor/github.com/ryancurrah/gomodguard/.golangci.yml
+++ b/vendor/github.com/ryancurrah/gomodguard/.golangci.yml
@@ -2,13 +2,13 @@
linters:
enable-all: true
disable:
+ - tenv
- lll
- gomodguard
- gochecknoglobals
- paralleltest
- varnamelen
- exhaustruct
- - gomnd
- depguard
- forbidigo
- funlen
diff --git a/vendor/github.com/ryancurrah/gomodguard/README.md b/vendor/github.com/ryancurrah/gomodguard/README.md
index 68dc8604..e06efaa1 100644
--- a/vendor/github.com/ryancurrah/gomodguard/README.md
+++ b/vendor/github.com/ryancurrah/gomodguard/README.md
@@ -37,7 +37,7 @@ Results can be exported to different report formats. Which can be imported into
```yaml
allowed:
modules: # List of allowed modules
- - gopkg.in/yaml.v2
+ - gopkg.in/yaml.v3
- github.com/go-xmlfmt/xmlfmt
- github.com/phayes/checkstyle
- github.com/mitchellh/go-homedir
@@ -88,7 +88,7 @@ Flags:
```
╰─ ./gomodguard -r checkstyle -f gomodguard-checkstyle.xml ./...
-info: allowed modules, [gopkg.in/yaml.v2 github.com/go-xmlfmt/xmlfmt github.com/phayes/checkstyle github.com/mitchellh/go-homedir]
+info: allowed modules, [gopkg.in/yaml.v3 github.com/go-xmlfmt/xmlfmt github.com/phayes/checkstyle github.com/mitchellh/go-homedir]
info: allowed module domains, [golang.org]
info: blocked modules, [github.com/uudashr/go-module]
info: found `2` blocked modules in the go.mod file, [github.com/gofrs/uuid github.com/uudashr/go-module]
diff --git a/vendor/github.com/ryancurrah/gomodguard/processor.go b/vendor/github.com/ryancurrah/gomodguard/processor.go
index f3f42a5b..4d2fac48 100644
--- a/vendor/github.com/ryancurrah/gomodguard/processor.go
+++ b/vendor/github.com/ryancurrah/gomodguard/processor.go
@@ -146,10 +146,6 @@ func (p *Processor) SetBlockedModules() { //nolint:funlen
replacedModules := p.Modfile.Replace
for i := range lintedModules {
- if lintedModules[i].Indirect {
- continue // Do not lint indirect modules.
- }
-
lintedModuleName := strings.TrimSpace(lintedModules[i].Mod.Path)
lintedModuleVersion := strings.TrimSpace(lintedModules[i].Mod.Version)
diff --git a/vendor/github.com/securego/gosec/v2/README.md b/vendor/github.com/securego/gosec/v2/README.md
index 5e68182c..cbd614b2 100644
--- a/vendor/github.com/securego/gosec/v2/README.md
+++ b/vendor/github.com/securego/gosec/v2/README.md
@@ -138,7 +138,6 @@ directory you can supply `./...` as the input argument.
- G110: Potential DoS vulnerability via decompression bomb
- G111: Potential directory traversal
- G112: Potential slowloris attack
-- G113: Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772)
- G114: Use of net/http serve function that has no support for setting timeouts
- G115: Potential integer overflow when converting between integer types
- G201: SQL query construction using format string
@@ -172,6 +171,7 @@ directory you can supply `./...` as the input argument.
### Retired rules
- G105: Audit the use of math/big.Int.Exp - [CVE is fixed](https://github.com/golang/go/issues/15184)
+- G113: Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772). This affected Go <1.16.14 and Go <1.17.7, which are no longer supported by gosec.
- G307: Deferring a method which returns an error - causing more inconvenience than fixing a security issue, despite the details from this [blog post](https://www.joeshaw.org/dont-defer-close-on-writable-files/)
### Selecting rules
@@ -304,7 +304,13 @@ You could put the description or justification text for the annotation. The
justification should be after the rule(s) to suppress and start with two or
more dashes, e.g: `//#nosec G101 G102 -- This is a false positive`
-In some cases you may also want to revisit places where `#nosec` annotations
+Alternatively, gosec also supports the `//gosec:disable` directive, which functions similar to `#nosec`:
+
+```go
+//gosec:disable G101 -- This is a false positive
+```
+
+In some cases you may also want to revisit places where `#nosec` or `//gosec:disable` annotations
have been used. To run the scanner and ignore any `#nosec` annotations you
can do the following:
diff --git a/vendor/github.com/securego/gosec/v2/USERS.md b/vendor/github.com/securego/gosec/v2/USERS.md
index 9b6e4eee..7fc9c3e3 100644
--- a/vendor/github.com/securego/gosec/v2/USERS.md
+++ b/vendor/github.com/securego/gosec/v2/USERS.md
@@ -16,6 +16,7 @@ This is a list of gosec's users. Please send a pull request with your organisati
10. [Checkmarx](https://www.checkmarx.com/)
11. [SeatGeek](https://www.seatgeek.com/)
12. [reMarkable](https://remarkable.com)
+13. [SSOJet](https://ssojet.com)
## Projects
diff --git a/vendor/github.com/securego/gosec/v2/analyzer.go b/vendor/github.com/securego/gosec/v2/analyzer.go
index 186cc3c2..34ac82b5 100644
--- a/vendor/github.com/securego/gosec/v2/analyzer.go
+++ b/vendor/github.com/securego/gosec/v2/analyzer.go
@@ -57,6 +57,8 @@ const externalSuppressionJustification = "Globally suppressed."
const aliasOfAllRules = "*"
+var directiveRegexp = regexp.MustCompile("^//gosec:disable(?: (.+))?$")
+
type ignore struct {
start int
end int
@@ -582,53 +584,77 @@ func (gosec *Analyzer) ignore(n ast.Node) map[string]issue.SuppressionInfo {
}
for _, group := range groups {
- comment := strings.TrimSpace(group.Text())
- foundDefaultTag := strings.HasPrefix(comment, noSecDefaultTag) || regexp.MustCompile("\n *"+noSecDefaultTag).MatchString(comment)
- foundAlternativeTag := strings.HasPrefix(comment, noSecAlternativeTag) || regexp.MustCompile("\n *"+noSecAlternativeTag).MatchString(comment)
-
- if foundDefaultTag || foundAlternativeTag {
- gosec.stats.NumNosec++
-
- // Discard what's in front of the nosec tag.
- if foundDefaultTag {
- comment = strings.SplitN(comment, noSecDefaultTag, 2)[1]
- } else {
- comment = strings.SplitN(comment, noSecAlternativeTag, 2)[1]
- }
+ found, args := findNoSecDirective(group, noSecDefaultTag, noSecAlternativeTag)
+ if !found {
+ continue
+ }
- // Extract the directive and the justification.
- justification := ""
- commentParts := regexp.MustCompile(`-{2,}`).Split(comment, 2)
- directive := commentParts[0]
- if len(commentParts) > 1 {
- justification = strings.TrimSpace(strings.TrimRight(commentParts[1], "\n"))
- }
+ gosec.stats.NumNosec++
- // Pull out the specific rules that are listed to be ignored.
- re := regexp.MustCompile(`(G\d{3})`)
- matches := re.FindAllStringSubmatch(directive, -1)
+ // Extract the directive and the justification.
+ justification := ""
+ commentParts := regexp.MustCompile(`-{2,}`).Split(args, 2)
+ directive := commentParts[0]
+ if len(commentParts) > 1 {
+ justification = strings.TrimSpace(strings.TrimRight(commentParts[1], "\n"))
+ }
- suppression := issue.SuppressionInfo{
- Kind: "inSource",
- Justification: justification,
- }
+ // Pull out the specific rules that are listed to be ignored.
+ re := regexp.MustCompile(`(G\d{3})`)
+ matches := re.FindAllStringSubmatch(directive, -1)
- // Find the rule IDs to ignore.
- ignores := make(map[string]issue.SuppressionInfo)
- for _, v := range matches {
- ignores[v[1]] = suppression
- }
+ suppression := issue.SuppressionInfo{
+ Kind: "inSource",
+ Justification: justification,
+ }
- // If no specific rules were given, ignore everything.
- if len(matches) == 0 {
- ignores[aliasOfAllRules] = suppression
- }
- return ignores
+ // Find the rule IDs to ignore.
+ ignores := make(map[string]issue.SuppressionInfo)
+ for _, v := range matches {
+ ignores[v[1]] = suppression
}
+
+ // If no specific rules were given, ignore everything.
+ if len(matches) == 0 {
+ ignores[aliasOfAllRules] = suppression
+ }
+ return ignores
}
return nil
}
+// findNoSecDirective checks if the comment group contains `#nosec` or `//gosec:disable` directive.
+// If found, it returns true and the directive's arguments.
+func findNoSecDirective(group *ast.CommentGroup, noSecDefaultTag, noSecAlternativeTag string) (bool, string) {
+ // Check if the comment grounp has a nosec comment.
+ for _, tag := range []string{noSecDefaultTag, noSecAlternativeTag} {
+ if found, args := findNoSecTag(group, tag); found {
+ return true, args
+ }
+ }
+
+ // Check if the comment group has a directive comment.
+ for _, c := range group.List {
+ match := directiveRegexp.FindStringSubmatch(c.Text)
+ if len(match) > 0 {
+ return true, match[0]
+ }
+ }
+
+ return false, ""
+}
+
+func findNoSecTag(group *ast.CommentGroup, tag string) (bool, string) {
+ comment := strings.TrimSpace(group.Text())
+
+ if strings.HasPrefix(comment, tag) || regexp.MustCompile("\n *"+tag).MatchString(comment) {
+ // Discard what's in front of the nosec tag.
+ return true, strings.SplitN(comment, tag, 2)[1]
+ }
+
+ return false, ""
+}
+
// Visit runs the gosec visitor logic over an AST created by parsing go code.
// Rule methods added with AddRule will be invoked as necessary.
func (gosec *Analyzer) Visit(n ast.Node) ast.Visitor {
diff --git a/vendor/github.com/securego/gosec/v2/issue/issue.go b/vendor/github.com/securego/gosec/v2/issue/issue.go
index 6227db67..b7c804e4 100644
--- a/vendor/github.com/securego/gosec/v2/issue/issue.go
+++ b/vendor/github.com/securego/gosec/v2/issue/issue.go
@@ -65,7 +65,6 @@ var ruleToCWE = map[string]string{
"G110": "409",
"G111": "22",
"G112": "400",
- "G113": "190",
"G114": "676",
"G115": "190",
"G201": "89",
diff --git a/vendor/github.com/securego/gosec/v2/rules/math_big_rat.go b/vendor/github.com/securego/gosec/v2/rules/math_big_rat.go
deleted file mode 100644
index 1aac1fa2..00000000
--- a/vendor/github.com/securego/gosec/v2/rules/math_big_rat.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package rules
-
-import (
- "go/ast"
-
- "github.com/securego/gosec/v2"
- "github.com/securego/gosec/v2/issue"
-)
-
-type usingOldMathBig struct {
- issue.MetaData
- calls gosec.CallList
-}
-
-func (r *usingOldMathBig) ID() string {
- return r.MetaData.ID
-}
-
-func (r *usingOldMathBig) Match(node ast.Node, ctx *gosec.Context) (gi *issue.Issue, err error) {
- if callExpr := r.calls.ContainsPkgCallExpr(node, ctx, false); callExpr == nil {
- return nil, nil
- }
-
- confidence := issue.Low
- major, minor, build := gosec.GoVersion()
- if major == 1 && (minor == 16 && build < 14 || minor == 17 && build < 7) {
- confidence = issue.Medium
- }
-
- return ctx.NewIssue(node, r.ID(), r.What, r.Severity, confidence), nil
-}
-
-// NewUsingOldMathBig rule detects the use of Rat.SetString from math/big.
-func NewUsingOldMathBig(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := gosec.NewCallList()
- calls.Add("math/big.Rat", "SetString")
- return &usingOldMathBig{
- calls: calls,
- MetaData: issue.MetaData{
- ID: id,
- What: "Potential uncontrolled memory consumption in Rat.SetString (CVE-2022-23772)",
- Severity: issue.High,
- },
- }, []ast.Node{(*ast.CallExpr)(nil)}
-}
diff --git a/vendor/github.com/securego/gosec/v2/rules/rulelist.go b/vendor/github.com/securego/gosec/v2/rules/rulelist.go
index 13f29f71..3f859800 100644
--- a/vendor/github.com/securego/gosec/v2/rules/rulelist.go
+++ b/vendor/github.com/securego/gosec/v2/rules/rulelist.go
@@ -75,7 +75,6 @@ func Generate(trackSuppressions bool, filters ...RuleFilter) RuleList {
{"G110", "Detect io.Copy instead of io.CopyN when decompression", NewDecompressionBombCheck},
{"G111", "Detect http.Dir('/') as a potential risk", NewDirectoryTraversal},
{"G112", "Detect ReadHeaderTimeout not configured as a potential risk", NewSlowloris},
- {"G113", "Usage of Rat.SetString in math/big with an overflow", NewUsingOldMathBig},
{"G114", "Use of net/http serve function that has no support for setting timeouts", NewHTTPServeWithoutTimeouts},
// injection
diff --git a/vendor/github.com/sivchari/tenv/.golangci.yml b/vendor/github.com/sivchari/tenv/.golangci.yml
deleted file mode 100644
index f687df83..00000000
--- a/vendor/github.com/sivchari/tenv/.golangci.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-run:
- timeout: 5m
- skip-files: []
-
-linters-settings:
- govet:
- enable-all: true
- disable:
- - fieldalignment
- gocyclo:
- min-complexity: 12
- misspell:
- locale: US
- godox:
- keywords:
- - FIXME
- gofumpt:
- extra-rules: true
-
-linters:
- disable-all: true
- enable:
- - govet
- - revive
- - goimports
- - staticcheck
- - gosimple
- - unused
- - godox
- - gofumpt
- - misspell
- - gocyclo
-
-issues:
- exclude-use-default: true
- max-per-linter: 0
- max-same-issues: 0
- exclude: []
diff --git a/vendor/github.com/sivchari/tenv/README.md b/vendor/github.com/sivchari/tenv/README.md
deleted file mode 100644
index 56389e2d..00000000
--- a/vendor/github.com/sivchari/tenv/README.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# tenv
-
-
-
-
-[](https://github.com/sivchari/tenv/actions/workflows/workflows.yml)
-
-tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17
-
-## Instruction
-
-```sh
-go install github.com/sivchari/tenv/cmd/tenv@latest
-```
-
-## Usage
-
-```go
-package main
-
-import (
- "fmt"
- "os"
- "testing"
-)
-
-func TestMain(t *testing.T) {
- fmt.Println(os.Getenv("GO"))
- os.Setenv("GO", "HACKING GOPHER")
-}
-
-func TestMain2(t *testing.T) {
- fmt.Println(os.Getenv("GO"))
-}
-
-func helper() {
- os.Setenv("GO", "HACKING GOPHER")
-}
-```
-
-```console
-go vet -vettool=$(which tenv) ./...
-
-# a
-./main_test.go:11:2: os.Setenv() can be replaced by `t.Setenv()` in TestMain
-```
-
-### option
-
-The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.
-
-By default, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.
-
-```go
-package main
-
-import (
- "fmt"
- "os"
- "testing"
-)
-
-func TestMain(t *testing.T) {
- fmt.Println(os.Getenv("GO"))
- os.Setenv("GO", "HACKING GOPHER")
-}
-
-func TestMain2(t *testing.T) {
- fmt.Println(os.Getenv("GO"))
-}
-
-func helper() {
- os.Setenv("GO", "HACKING GOPHER")
-}
-```
-
-```console
-go vet -vettool=$(which tenv) -tenv.all ./...
-
-# a
-./main_test.go:11:2: os.Setenv() can be replaced by `t.Setenv()` in TestMain
-./main_test.go:19:2: os.Setenv() can be replaced by `testing.Setenv()` in helper
-```
-
-## CI
-
-### CircleCI
-
-```yaml
-- run:
- name: install tenv
- command: go install github.com/sivchari/tenv@latest
-
-- run:
- name: run tenv
- command: go vet -vettool=`which tenv` ./...
-```
-
-### GitHub Actions
-
-```yaml
-- name: install tenv
- run: go install github.com/sivchari/tenv@latest
-
-- name: run tenv
- run: go vet -vettool=`which tenv` ./...
-```
diff --git a/vendor/github.com/sivchari/tenv/goreleaser.yaml b/vendor/github.com/sivchari/tenv/goreleaser.yaml
deleted file mode 100644
index 56db218d..00000000
--- a/vendor/github.com/sivchari/tenv/goreleaser.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-project_name: tenv
-
-env:
- - GO111MODULE=on
-
-builds:
- - id: tenv
- main: ./cmd/tenv/main.go
- binary: tenv
- env:
- - CGO_ENABLED=0
- goos:
- - linux
- - darwin
- goarch:
- - amd64
- - arm64
-
-archives:
- - id: tenv
- builds:
- - tenv
- name_template: '{{ .Binary }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
- format_overrides:
- - goos: windows
- format: zip
diff --git a/vendor/github.com/sivchari/tenv/tenv.go b/vendor/github.com/sivchari/tenv/tenv.go
deleted file mode 100644
index 657e60e4..00000000
--- a/vendor/github.com/sivchari/tenv/tenv.go
+++ /dev/null
@@ -1,223 +0,0 @@
-package tenv
-
-import (
- "go/ast"
- "go/token"
- "go/types"
- "strings"
-
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
- "golang.org/x/tools/go/ast/inspector"
-)
-
-const doc = "tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17"
-
-// Analyzer is tenv analyzer
-var Analyzer = &analysis.Analyzer{
- Name: "tenv",
- Doc: doc,
- Run: run,
- Requires: []*analysis.Analyzer{
- inspect.Analyzer,
- },
-}
-
-var (
- A = "all"
- aflag bool
-)
-
-func init() {
- Analyzer.Flags.BoolVar(&aflag, A, false, "the all option will run against all method in test file")
-}
-
-func run(pass *analysis.Pass) (interface{}, error) {
- inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
-
- nodeFilter := []ast.Node{
- (*ast.FuncDecl)(nil),
- (*ast.FuncLit)(nil),
- }
-
- inspect.Preorder(nodeFilter, func(n ast.Node) {
- switch n := n.(type) {
- case *ast.FuncDecl:
- checkFuncDecl(pass, n, pass.Fset.File(n.Pos()).Name())
- case *ast.FuncLit:
- checkFuncLit(pass, n, pass.Fset.File(n.Pos()).Name())
- }
- })
-
- return nil, nil
-}
-
-func checkFuncDecl(pass *analysis.Pass, f *ast.FuncDecl, fileName string) {
- argName, ok := targetRunner(pass, f.Type.Params.List, fileName)
- if !ok {
- return
- }
- checkStmts(pass, f.Body.List, f.Name.Name, argName)
-}
-
-func checkFuncLit(pass *analysis.Pass, f *ast.FuncLit, fileName string) {
- argName, ok := targetRunner(pass, f.Type.Params.List, fileName)
- if !ok {
- return
- }
- checkStmts(pass, f.Body.List, "anonymous function", argName)
-}
-
-func checkStmts(pass *analysis.Pass, stmts []ast.Stmt, funcName, argName string) {
- for _, stmt := range stmts {
- switch stmt := stmt.(type) {
- case *ast.ExprStmt:
- checkExprStmt(pass, stmt, funcName, argName)
- case *ast.IfStmt:
- checkIfStmt(pass, stmt, funcName, argName)
- case *ast.AssignStmt:
- checkAssignStmt(pass, stmt, funcName, argName)
- case *ast.ForStmt:
- checkForStmt(pass, stmt, funcName, argName)
- }
- }
-}
-
-func checkExprStmt(pass *analysis.Pass, stmt *ast.ExprStmt, funcName, argName string) {
- callExpr, ok := stmt.X.(*ast.CallExpr)
- if !ok {
- return
- }
- checkArgs(pass, callExpr.Args, funcName, argName)
- ident, ok := callExpr.Fun.(*ast.Ident)
- if ok {
- obj := pass.TypesInfo.ObjectOf(ident)
- checkObj(pass, obj, stmt.Pos(), funcName, argName)
- }
- fun, ok := callExpr.Fun.(*ast.SelectorExpr)
- if ok {
- obj := pass.TypesInfo.ObjectOf(fun.Sel)
- checkObj(pass, obj, stmt.Pos(), funcName, argName)
- }
-}
-
-func checkArgs(pass *analysis.Pass, args []ast.Expr, funcName, argName string) {
- for _, arg := range args {
- callExpr, ok := arg.(*ast.CallExpr)
- if !ok {
- continue
- }
- ident, ok := callExpr.Fun.(*ast.Ident)
- if ok {
- obj := pass.TypesInfo.ObjectOf(ident)
- checkObj(pass, obj, arg.Pos(), funcName, argName)
- }
- fun, ok := callExpr.Fun.(*ast.SelectorExpr)
- if ok {
- obj := pass.TypesInfo.ObjectOf(fun.Sel)
- checkObj(pass, obj, arg.Pos(), funcName, argName)
- }
- }
-}
-
-func checkIfStmt(pass *analysis.Pass, stmt *ast.IfStmt, funcName, argName string) {
- assignStmt, ok := stmt.Init.(*ast.AssignStmt)
- if !ok {
- return
- }
- rhs, ok := assignStmt.Rhs[0].(*ast.CallExpr)
- if !ok {
- return
- }
- ident, ok := rhs.Fun.(*ast.Ident)
- if ok {
- obj := pass.TypesInfo.ObjectOf(ident)
- checkObj(pass, obj, stmt.Pos(), funcName, argName)
- }
- fun, ok := rhs.Fun.(*ast.SelectorExpr)
- if ok {
- obj := pass.TypesInfo.ObjectOf(fun.Sel)
- checkObj(pass, obj, stmt.Pos(), funcName, argName)
- }
-}
-
-func checkAssignStmt(pass *analysis.Pass, stmt *ast.AssignStmt, funcName, argName string) {
- rhs, ok := stmt.Rhs[0].(*ast.CallExpr)
- if !ok {
- return
- }
- ident, ok := rhs.Fun.(*ast.Ident)
- if ok {
- obj := pass.TypesInfo.ObjectOf(ident)
- checkObj(pass, obj, stmt.Pos(), funcName, argName)
- }
- fun, ok := rhs.Fun.(*ast.SelectorExpr)
- if ok {
- obj := pass.TypesInfo.ObjectOf(fun.Sel)
- checkObj(pass, obj, stmt.Pos(), funcName, argName)
- }
-}
-
-func checkObj(pass *analysis.Pass, obj types.Object, pos token.Pos, funcName, argName string) {
- // For built-in objects, obj.Pkg() returns nil.
- var pkgPrefix string
- if pkg := obj.Pkg(); pkg != nil {
- pkgPrefix = pkg.Name() + "."
- }
-
- targetName := pkgPrefix + obj.Name()
- if targetName == "os.Setenv" {
- if argName == "" {
- argName = "testing"
- }
- pass.Reportf(pos, "os.Setenv() can be replaced by `%s.Setenv()` in %s", argName, funcName)
- }
-}
-
-func checkForStmt(pass *analysis.Pass, stmt *ast.ForStmt, funcName, argName string) {
- checkStmts(pass, stmt.Body.List, funcName, argName)
-}
-
-func targetRunner(pass *analysis.Pass, params []*ast.Field, fileName string) (string, bool) {
- for _, p := range params {
- switch typ := p.Type.(type) {
- case *ast.StarExpr:
- if checkStarExprTarget(pass, typ) {
- if len(p.Names) == 0 {
- return "", false
- }
- argName := p.Names[0].Name
- return argName, true
- }
- case *ast.SelectorExpr:
- if checkSelectorExprTarget(pass, typ) {
- if len(p.Names) == 0 {
- return "", false
- }
- argName := p.Names[0].Name
- return argName, true
- }
- }
- }
- if aflag && strings.HasSuffix(fileName, "_test.go") {
- return "", true
- }
- return "", false
-}
-
-func checkStarExprTarget(pass *analysis.Pass, typ *ast.StarExpr) bool {
- selector, ok := typ.X.(*ast.SelectorExpr)
- if !ok {
- return false
- }
- switch pass.TypesInfo.TypeOf(selector).String() {
- case "testing.T", "testing.B":
- return true
- default:
- return false
- }
-}
-
-func checkSelectorExprTarget(pass *analysis.Pass, typ *ast.SelectorExpr) bool {
- return pass.TypesInfo.TypeOf(typ).String() == "testing.TB"
-}
diff --git a/vendor/github.com/sivchari/tenv/tenv.png b/vendor/github.com/sivchari/tenv/tenv.png
deleted file mode 100644
index 96dc967e..00000000
Binary files a/vendor/github.com/sivchari/tenv/tenv.png and /dev/null differ
diff --git a/vendor/github.com/spf13/afero/README.md b/vendor/github.com/spf13/afero/README.md
index 619af574..86f15455 100644
--- a/vendor/github.com/spf13/afero/README.md
+++ b/vendor/github.com/spf13/afero/README.md
@@ -2,7 +2,11 @@
A FileSystem Abstraction System for Go
-[](https://github.com/spf13/afero/actions/workflows/test.yml) [](https://godoc.org/github.com/spf13/afero) [](https://gitter.im/spf13/afero?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[](https://github.com/spf13/afero/actions?query=workflow%3ACI)
+[](https://gitter.im/spf13/afero?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[](https://goreportcard.com/report/github.com/spf13/afero)
+
+[](https://pkg.go.dev/mod/github.com/spf13/afero)
# Overview
@@ -427,6 +431,39 @@ See the [Releases Page](https://github.com/spf13/afero/releases).
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
+## Releasing
+
+As of version 1.14.0, Afero moved implementations with third-party libraries to
+their own submodules.
+
+Releasing a new version now requires a few steps:
+
+```
+VERSION=X.Y.Z
+git tag -a v$VERSION -m "Release $VERSION"
+git push origin v$VERSION
+
+cd gcsfs
+go get github.com/spf13/afero@v$VERSION
+go mod tidy
+git commit -am "Update afero to v$VERSION"
+git tag -a gcsfs/v$VERSION -m "Release gcsfs $VERSION"
+git push origin gcsfs/v$VERSION
+cd ..
+
+cd sftpfs
+go get github.com/spf13/afero@v$VERSION
+go mod tidy
+git commit -am "Update afero to v$VERSION"
+git tag -a sftpfs/v$VERSION -m "Release sftpfs $VERSION"
+git push origin sftpfs/v$VERSION
+cd ..
+
+git push
+```
+
+TODO: move these instructions to a Makefile or something
+
## Contributors
Names in no particular order:
diff --git a/vendor/github.com/tetafro/godot/.golangci.yml b/vendor/github.com/tetafro/godot/.golangci.yml
index b9e44358..2b626186 100644
--- a/vendor/github.com/tetafro/godot/.golangci.yml
+++ b/vendor/github.com/tetafro/godot/.golangci.yml
@@ -7,6 +7,7 @@ linters:
enable:
- asciicheck
- bodyclose
+ - copyloopvar
- cyclop
- dogsled
- durationcheck
@@ -15,8 +16,6 @@ linters:
- errname
- errorlint
- exhaustive
- - exportloopref
- - exportloopref
- gochecknoinits
- gocognit
- goconst
diff --git a/vendor/github.com/tetafro/godot/checks.go b/vendor/github.com/tetafro/godot/checks.go
index d3076635..b9a78e2b 100644
--- a/vendor/github.com/tetafro/godot/checks.go
+++ b/vendor/github.com/tetafro/godot/checks.go
@@ -92,10 +92,18 @@ func checkPeriod(c comment) *Issue {
strings.Split(c.text, "\n")[pos.line-1],
)
+ // Get the offset of the first symbol in the last line of the comment.
+ // This value is used only in golangci-lint to point to the problem, and
+ // to replace the problem when running in auto-fix mode.
+ offset := c.start.Offset
+ for i := 0; i < pos.line-1; i++ {
+ offset += len(c.lines[i]) + 1
+ }
+
iss := Issue{
Pos: token.Position{
Filename: c.start.Filename,
- Offset: c.start.Offset,
+ Offset: offset,
Line: pos.line + c.start.Line - 1,
Column: pos.column,
},
diff --git a/vendor/github.com/tetafro/godot/getters.go b/vendor/github.com/tetafro/godot/getters.go
index fda0619f..8e282ba3 100644
--- a/vendor/github.com/tetafro/godot/getters.go
+++ b/vendor/github.com/tetafro/godot/getters.go
@@ -17,7 +17,7 @@ var (
)
// specialReplacer is a replacer for some types of special lines in comments,
-// which shouldn't be checked. For example, if comment ends with a block of
+// which shouldn't be checked. For example, if a comment ends with a block of
// code it should not necessarily have a period at the end.
const specialReplacer = ""
@@ -68,7 +68,7 @@ func (pf *parsedFile) getComments(scope Scope, exclude []*regexp.Regexp) []comme
comments = pf.getAllComments(exclude)
case NoInlineScope:
// All except inline comments
- comments = pf.getNoInline(exclude)
+ comments = pf.getNoInlineComments(exclude)
case TopLevelScope:
// All top level comments and comments from the inside
// of top level blocks
@@ -176,8 +176,8 @@ func (pf *parsedFile) getDeclarationComments(exclude []*regexp.Regexp) []comment
return comments
}
-// getNoInline gets all except inline comments.
-func (pf *parsedFile) getNoInline(exclude []*regexp.Regexp) []comment {
+// getNoInlineComments gets all except inline comments.
+func (pf *parsedFile) getNoInlineComments(exclude []*regexp.Regexp) []comment {
var comments []comment //nolint:prealloc
for _, c := range pf.file.Comments {
if c == nil || len(c.List) == 0 {
diff --git a/vendor/github.com/timonwong/loggercheck/.golangci.yml b/vendor/github.com/timonwong/loggercheck/.golangci.yml
index 6d5e17be..7c82dc77 100644
--- a/vendor/github.com/timonwong/loggercheck/.golangci.yml
+++ b/vendor/github.com/timonwong/loggercheck/.golangci.yml
@@ -1,94 +1,102 @@
-linters-settings:
- dupl:
- threshold: 100
- funlen:
- lines: 100
- statements: 50
- goconst:
- min-len: 2
- min-occurrences: 3
- gocritic:
- enabled-tags:
- - diagnostic
- - experimental
- - opinionated
- - performance
- - style
- disabled-checks:
- - whyNoLint
- gocyclo:
- min-complexity: 15
- goimports:
- local-prefixes: github.com/timonwong/loggercheck
- mnd:
- # don't include the "operation" and "assign"
- checks:
- - argument
- - case
- - condition
- - return
- ignored-numbers:
- - '0'
- - '1'
- - '2'
- - '3'
- ignored-functions:
- - strings.SplitN
- - strconv.ParseInt
- govet:
- shadow: true
- lll:
- line-length: 140
- misspell:
- locale: US
- nolintlint:
- allow-unused: false # report any unused nolint directives
- require-explanation: false # don't require an explanation for nolint directives
- require-specific: false # don't require nolint directives to be specific about which linter is being skipped
+version: "2"
+
+formatters:
+ enable:
+ - gofumpt
+ - goimports
+ settings:
+ goimports:
+ local-prefixes:
+ - github.com/timonwong/loggercheck
+
linters:
- disable-all: true
+ default: none
enable:
- bodyclose
+ - copyloopvar
- dogsled
- dupl
- errcheck
- - copyloopvar
- funlen
- gochecknoinits
- goconst
- gocritic
- gocyclo
- - gofumpt
- - goimports
- - mnd
- goprintffuncname
- gosec
- - gosimple
- govet
- ineffassign
- lll
- misspell
+ - mnd
- nakedret
- noctx
- nolintlint
- revive
- staticcheck
- - stylecheck
- - typecheck
- unconvert
- unparam
- unused
- whitespace
-issues:
- # Excluding configuration per-path, per-linter, per-text and per-source
- exclude-rules:
- - path: _test\.go
- linters:
- - mnd
- exclude-dirs:
- - testdata
+ settings:
+ dupl:
+ threshold: 100
+ funlen:
+ lines: 100
+ statements: 50
+ goconst:
+ min-len: 2
+ min-occurrences: 3
+ gocritic:
+ disabled-checks:
+ - whyNoLint
+ enabled-tags:
+ - diagnostic
+ - experimental
+ - opinionated
+ - performance
+ - style
+ gocyclo:
+ min-complexity: 15
+ govet:
+ enable:
+ - shadow
+ lll:
+ line-length: 140
+ misspell:
+ locale: US
+ mnd:
+ # don't include the "operation" and "assign"
+ checks:
+ - argument
+ - case
+ - condition
+ - return
+ ignored-numbers:
+ - "0"
+ - "1"
+ - "2"
+ - "3"
+ ignored-functions:
+ - strings.SplitN
+ - strconv.ParseInt
+ nolintlint:
+ require-explanation: false # don't require an explanation for nolint directives
+ require-specific: false # don't require nolint directives to be specific about which linter is being skipped
+ allow-unused: false # report any unused nolint directives
-run:
- timeout: 5m
- go: '1.23'
\ No newline at end of file
+ exclusions:
+ presets:
+ - comments
+ - common-false-positives
+ - legacy
+ - std-error-handling
+ # Excluding configuration per-path, per-linter, per-text and per-source
+ rules:
+ - linters:
+ - mnd
+ path: _test\.go
+ - linters:
+ - gocritic
+ path: internal/checkers/printf/printf.go
diff --git a/vendor/github.com/timonwong/loggercheck/README.md b/vendor/github.com/timonwong/loggercheck/README.md
index d8f86fc4..d38885aa 100644
--- a/vendor/github.com/timonwong/loggercheck/README.md
+++ b/vendor/github.com/timonwong/loggercheck/README.md
@@ -6,8 +6,8 @@ A linter checks the odd number of key and value pairs for common logger librarie
- [kitlog](https://github.com/go-kit/log)
- [klog](https://github.com/kubernetes/klog)
- [logr](https://github.com/go-logr/logr)
-- [zap](https://github.com/uber-go/zap)
- [log/slog](https://pkg.go.dev/log/slog)
+- [zap](https://github.com/uber-go/zap)
It's recommended to use loggercheck with [golangci-lint](https://golangci-lint.run/usage/linters/#loggercheck).
@@ -27,7 +27,7 @@ go install github.com/timonwong/loggercheck/cmd/loggercheck
## Usage
```
-loggercheck: Checks key value pairs for common logger libraries (kitlog,logr,klog,zap).
+loggercheck: Checks key value pairs for common logger libraries (kitlog,klog,logr,slog,zap).
Usage: loggercheck [-flag] [package]
@@ -43,7 +43,7 @@ Flags:
-debug string
debug flags, any subset of "fpstv"
-disable value
- comma-separated list of disabled logger checker (kitlog,klog,logr,zap) (default kitlog)
+ comma-separated list of disabled logger checker (kitlog,klog,logr,slog,zap) (default kitlog)
-fix
apply all suggested fixes
-flags
diff --git a/vendor/github.com/timonwong/loggercheck/internal/checkers/printf/printf.go b/vendor/github.com/timonwong/loggercheck/internal/checkers/printf/printf.go
index 926b57e0..a558633f 100644
--- a/vendor/github.com/timonwong/loggercheck/internal/checkers/printf/printf.go
+++ b/vendor/github.com/timonwong/loggercheck/internal/checkers/printf/printf.go
@@ -90,14 +90,6 @@ func (s *formatState) scanNum() {
}
}
-func stringIndexAt(s, substr string, start int) int {
- idx := strings.Index(s[start:], substr)
- if idx < 0 {
- return idx
- }
- return idx + start
-}
-
// parseIndex scans an index expression. It returns false if there is a syntax error.
func (s *formatState) parseIndex() bool {
if s.nbytes == len(s.format) || s.format[s.nbytes] != '[' {
@@ -109,11 +101,12 @@ func (s *formatState) parseIndex() bool {
s.scanNum()
ok := true
if s.nbytes == len(s.format) || s.nbytes == start || s.format[s.nbytes] != ']' {
- ok = false
- s.nbytes = stringIndexAt(s.format, "]", start)
+ ok = false // syntax error is either missing "]" or invalid index.
+ s.nbytes = strings.Index(s.format[start:], "]")
if s.nbytes < 0 {
return false
}
+ s.nbytes = s.nbytes + start
}
arg32, err := strconv.ParseInt(s.format[start:s.nbytes], 10, 32)
if err != nil || !ok || arg32 <= 0 {
diff --git a/vendor/github.com/timonwong/loggercheck/internal/rules/rules.go b/vendor/github.com/timonwong/loggercheck/internal/rules/rules.go
index 3ed69b5b..8f1ba838 100644
--- a/vendor/github.com/timonwong/loggercheck/internal/rules/rules.go
+++ b/vendor/github.com/timonwong/loggercheck/internal/rules/rules.go
@@ -7,6 +7,8 @@ import (
"go/types"
"io"
"strings"
+
+ "golang.org/x/tools/go/types/typeutil"
)
var ErrInvalidRule = errors.New("invalid rule format")
@@ -41,9 +43,19 @@ func (rs *Ruleset) Match(fn *types.Func) bool {
return false
}
-func receiverTypeOf(recvType types.Type) string {
- buf := &strings.Builder{}
+var receiverTypeCache = typeutil.Map{}
+
+func receiverTypeOf(recvType types.Type) (repr string) {
+ if val := receiverTypeCache.At(recvType); val != nil {
+ repr, _ = val.(string)
+ return repr
+ }
+
+ defer func() {
+ receiverTypeCache.Set(recvType, repr)
+ }()
+ buf := &strings.Builder{}
var recvNamed *types.Named
switch recvType := recvType.(type) {
case *types.Pointer:
diff --git a/vendor/github.com/timonwong/loggercheck/loggercheck.go b/vendor/github.com/timonwong/loggercheck/loggercheck.go
index d418c762..adc38e9e 100644
--- a/vendor/github.com/timonwong/loggercheck/loggercheck.go
+++ b/vendor/github.com/timonwong/loggercheck/loggercheck.go
@@ -7,6 +7,7 @@ import (
"go/types"
"os"
"strings"
+ "sync"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
@@ -18,7 +19,7 @@ import (
"github.com/timonwong/loggercheck/internal/sets"
)
-const Doc = `Checks key value pairs for common logger libraries (kitlog,klog,logr,zap).`
+const Doc = `Checks key value pairs for common logger libraries (kitlog,klog,logr,slog,zap).`
func NewAnalyzer(opts ...Option) *analysis.Analyzer {
l := newLoggerCheck(opts...)
@@ -40,9 +41,11 @@ type loggercheck struct {
requireStringKey bool // flag -requirestringkey
noPrintfLike bool // flag -noprintflike
- rules []string // used for external integration, for example golangci-lint
- rulesetList []rules.Ruleset // populate at runtime
- rulesetIndicesByImport map[string][]int // ruleset index, populate at runtime
+ rules []string // used for external integration, for example golangci-lint
+ rulesetList []rules.Ruleset // populate at runtime
+
+ rulesetIndicesByImportMu sync.Mutex
+ rulesetIndicesByImport map[string][]int // ruleset index, populate at runtime
}
func newLoggerCheck(opts ...Option) *loggercheck {
@@ -54,7 +57,7 @@ func newLoggerCheck(opts ...Option) *loggercheck {
}
fs.StringVar(&l.ruleFile, "rulefile", "", "path to a file contains a list of rules")
- fs.Var(&l.disable, "disable", "comma-separated list of disabled logger checker (kitlog,klog,logr,zap,slog)")
+ fs.Var(&l.disable, "disable", "comma-separated list of disabled logger checker (kitlog,klog,logr,slog,zap)")
fs.BoolVar(&l.requireStringKey, "requirestringkey", false, "require all logging keys to be inlined constant strings")
fs.BoolVar(&l.noPrintfLike, "noprintflike", false, "require printf-like format specifier not present in args")
@@ -85,7 +88,10 @@ func (l *loggercheck) getCheckerForFunc(fn *types.Func) checkers.Checker {
}
pkgPath := vendorLessPath(pkg.Path())
+
+ l.rulesetIndicesByImportMu.Lock()
indices := l.rulesetIndicesByImport[pkgPath]
+ l.rulesetIndicesByImportMu.Unlock()
for _, idx := range indices {
rs := &l.rulesetList[idx]
@@ -165,7 +171,10 @@ func (l *loggercheck) processConfig() error {
for i, rs := range l.rulesetList {
indices[rs.PackageImport] = append(indices[rs.PackageImport], i)
}
+
+ l.rulesetIndicesByImportMu.Lock()
l.rulesetIndicesByImport = indices
+ l.rulesetIndicesByImportMu.Unlock()
return nil
}
diff --git a/vendor/github.com/tomarrell/wrapcheck/v2/wrapcheck/wrapcheck.go b/vendor/github.com/tomarrell/wrapcheck/v2/wrapcheck/wrapcheck.go
index 127f7efd..12cd156c 100644
--- a/vendor/github.com/tomarrell/wrapcheck/v2/wrapcheck/wrapcheck.go
+++ b/vendor/github.com/tomarrell/wrapcheck/v2/wrapcheck/wrapcheck.go
@@ -83,6 +83,10 @@ type WrapcheckConfig struct {
// returned from any function whose call is defined on a interface named 'Transactor'
// or 'Transaction' due to the name matching the regular expression `Transac(tor|tion)`.
IgnoreInterfaceRegexps []string `mapstructure:"ignoreInterfaceRegexps" yaml:"ignoreInterfaceRegexps"`
+
+ // ReportInternalErrors determines whether wrapcheck should report errors returned
+ // from inside the package.
+ ReportInternalErrors bool `mapstructure:"reportInternalErrors" yaml:"reportInternalErrors"`
}
func NewDefaultConfig() WrapcheckConfig {
@@ -273,16 +277,31 @@ func reportUnwrapped(
pkgGlobs []glob.Glob,
) {
+ if cfg.ReportInternalErrors {
+ // Check if the call is package-internal function
+ fnIdent, ok := call.Fun.(*ast.Ident)
+ if ok {
+ fnSig := pass.TypesInfo.ObjectOf(fnIdent).String()
+
+ // Check for ignored signatures
+ if checkSignature(cfg, regexpsSig, fnSig) {
+ return
+ }
+
+ pass.Reportf(tokenPos, "package-internal error should be wrapped: sig: %s", fnSig)
+ return
+ }
+ }
+
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return
}
- // Check for ignored signatures
fnSig := pass.TypesInfo.ObjectOf(sel.Sel).String()
- if contains(cfg.IgnoreSigs, fnSig) || contains(cfg.ExtraIgnoreSigs, fnSig) {
- return
- } else if containsMatch(regexpsSig, fnSig) {
+
+ // Check for ignored signatures
+ if checkSignature(cfg, regexpsSig, fnSig) {
return
}
@@ -305,6 +324,17 @@ func reportUnwrapped(
pass.Reportf(tokenPos, "error returned from external package is unwrapped: sig: %s", fnSig)
return
}
+
+ // If `ReportInternalErrors` is true, report package-internal errors
+ if cfg.ReportInternalErrors {
+ pass.Reportf(tokenPos, "package-internal error should be wrapped: sig: %s", fnSig)
+ return
+ }
+}
+
+// checkSignature returns whether the function should be ignored.
+func checkSignature(cfg WrapcheckConfig, regexpsSig []*regexp.Regexp, fnSig string) bool {
+ return contains(cfg.IgnoreSigs, fnSig) || contains(cfg.ExtraIgnoreSigs, fnSig) || containsMatch(regexpsSig, fnSig)
}
// isInterface returns whether the function call is one defined on an interface.
diff --git a/vendor/github.com/xen0n/gosmopolitan/.golangci.yml b/vendor/github.com/xen0n/gosmopolitan/.golangci.yml
index 0bce1250..0f58fc52 100644
--- a/vendor/github.com/xen0n/gosmopolitan/.golangci.yml
+++ b/vendor/github.com/xen0n/gosmopolitan/.golangci.yml
@@ -1,5 +1,5 @@
run:
- go: '1.19'
+ go: '1.24'
modules-download-mode: readonly
linters:
@@ -20,12 +20,8 @@ linters-settings:
SPDX-License-Identifier: GPL-3.0-or-later
goimports:
local-prefixes: github.com/xen0n/gosmopolitan
- gosimple:
- go: '1.19'
lll:
line-length: 120
tab-width: 4
nakedret:
max-func-lines: 1
- stylecheck:
- go: '1.19'
diff --git a/vendor/github.com/xo/terminfo/.gitignore b/vendor/github.com/xo/terminfo/.gitignore
new file mode 100644
index 00000000..368e0c06
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/.gitignore
@@ -0,0 +1,9 @@
+/.cache/
+
+/cmd/infocmp/infocmp
+/cmd/infocmp/.out/
+
+/infocmp
+/.out/
+
+*.txt
diff --git a/vendor/github.com/xo/terminfo/LICENSE b/vendor/github.com/xo/terminfo/LICENSE
new file mode 100644
index 00000000..197dadb1
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Anmol Sethi
+
+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.
diff --git a/vendor/github.com/xo/terminfo/README.md b/vendor/github.com/xo/terminfo/README.md
new file mode 100644
index 00000000..e5002d23
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/README.md
@@ -0,0 +1,139 @@
+# About terminfo [![GoDoc][1]][2]
+
+Package `terminfo` provides a pure-Go implementation of reading information
+from the terminfo database.
+
+`terminfo` is meant as a replacement for `ncurses` in simple Go programs.
+
+## Installing
+
+Install in the usual Go way:
+
+```sh
+$ go get -u github.com/xo/terminfo
+```
+
+## Using
+
+Please see the [GoDoc API listing][2] for more information on using `terminfo`.
+
+```go
+// _examples/simple/main.go
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+ "os"
+ "os/signal"
+ "strings"
+ "sync"
+ "syscall"
+
+ "github.com/xo/terminfo"
+)
+
+func main() {
+ //r := rand.New(nil)
+
+ // load terminfo
+ ti, err := terminfo.LoadFromEnv()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // cleanup
+ defer func() {
+ err := recover()
+ termreset(ti)
+ if err != nil {
+ log.Fatal(err)
+ }
+ }()
+
+ terminit(ti)
+ termtitle(ti, "simple example!")
+ termputs(ti, 3, 3, "Ctrl-C to exit")
+ maxColors := termcolors(ti)
+ if maxColors > 256 {
+ maxColors = 256
+ }
+ for i := 0; i < maxColors; i++ {
+ termputs(ti, 5+i/16, 5+i%16, ti.Colorf(i, 0, "█"))
+ }
+
+ // wait for signal
+ sigs := make(chan os.Signal, 1)
+ signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
+ <-sigs
+}
+
+// terminit initializes the special CA mode on the terminal, and makes the
+// cursor invisible.
+func terminit(ti *terminfo.Terminfo) {
+ buf := new(bytes.Buffer)
+ // set the cursor invisible
+ ti.Fprintf(buf, terminfo.CursorInvisible)
+ // enter special mode
+ ti.Fprintf(buf, terminfo.EnterCaMode)
+ // clear the screen
+ ti.Fprintf(buf, terminfo.ClearScreen)
+ os.Stdout.Write(buf.Bytes())
+}
+
+// termreset is the inverse of terminit.
+func termreset(ti *terminfo.Terminfo) {
+ buf := new(bytes.Buffer)
+ ti.Fprintf(buf, terminfo.ExitCaMode)
+ ti.Fprintf(buf, terminfo.CursorNormal)
+ os.Stdout.Write(buf.Bytes())
+}
+
+// termputs puts a string at row, col, interpolating v.
+func termputs(ti *terminfo.Terminfo, row, col int, s string, v ...interface{}) {
+ buf := new(bytes.Buffer)
+ ti.Fprintf(buf, terminfo.CursorAddress, row, col)
+ fmt.Fprintf(buf, s, v...)
+ os.Stdout.Write(buf.Bytes())
+}
+
+// sl is the status line terminfo.
+var sl *terminfo.Terminfo
+
+// termtitle sets the window title.
+func termtitle(ti *terminfo.Terminfo, s string) {
+ var once sync.Once
+ once.Do(func() {
+ if ti.Has(terminfo.HasStatusLine) {
+ return
+ }
+ // load the sl xterm if terminal is an xterm or has COLORTERM
+ if strings.Contains(strings.ToLower(os.Getenv("TERM")), "xterm") || os.Getenv("COLORTERM") == "truecolor" {
+ sl, _ = terminfo.Load("xterm+sl")
+ }
+ })
+ if sl != nil {
+ ti = sl
+ }
+ if !ti.Has(terminfo.HasStatusLine) {
+ return
+ }
+ buf := new(bytes.Buffer)
+ ti.Fprintf(buf, terminfo.ToStatusLine)
+ fmt.Fprint(buf, s)
+ ti.Fprintf(buf, terminfo.FromStatusLine)
+ os.Stdout.Write(buf.Bytes())
+}
+
+// termcolors returns the maximum colors available for the terminal.
+func termcolors(ti *terminfo.Terminfo) int {
+ if colors := ti.Num(terminfo.MaxColors); colors > 0 {
+ return colors
+ }
+ return int(terminfo.ColorLevelBasic)
+}
+```
+
+[1]: https://godoc.org/github.com/xo/terminfo?status.svg
+[2]: https://godoc.org/github.com/xo/terminfo
diff --git a/vendor/github.com/xo/terminfo/caps.go b/vendor/github.com/xo/terminfo/caps.go
new file mode 100644
index 00000000..e5e1d41f
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/caps.go
@@ -0,0 +1,31 @@
+package terminfo
+
+// BoolCapName returns the bool capability name.
+func BoolCapName(i int) string {
+ return boolCapNames[2*i]
+}
+
+// BoolCapNameShort returns the short bool capability name.
+func BoolCapNameShort(i int) string {
+ return boolCapNames[2*i+1]
+}
+
+// NumCapName returns the num capability name.
+func NumCapName(i int) string {
+ return numCapNames[2*i]
+}
+
+// NumCapNameShort returns the short num capability name.
+func NumCapNameShort(i int) string {
+ return numCapNames[2*i+1]
+}
+
+// StringCapName returns the string capability name.
+func StringCapName(i int) string {
+ return stringCapNames[2*i]
+}
+
+// StringCapNameShort returns the short string capability name.
+func StringCapNameShort(i int) string {
+ return stringCapNames[2*i+1]
+}
diff --git a/vendor/github.com/xo/terminfo/capvals.go b/vendor/github.com/xo/terminfo/capvals.go
new file mode 100644
index 00000000..0c2274e3
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/capvals.go
@@ -0,0 +1,1525 @@
+package terminfo
+
+// Code generated by gen.go. DO NOT EDIT.
+// Bool capabilities.
+const (
+ // The AutoLeftMargin [auto_left_margin, bw] bool capability indicates cub1 wraps from column 0 to last column.
+ AutoLeftMargin = iota
+ // The AutoRightMargin [auto_right_margin, am] bool capability indicates terminal has automatic margins.
+ AutoRightMargin
+ // The NoEscCtlc [no_esc_ctlc, xsb] bool capability indicates beehive (f1=escape, f2=ctrl C).
+ NoEscCtlc
+ // The CeolStandoutGlitch [ceol_standout_glitch, xhp] bool capability indicates standout not erased by overwriting (hp).
+ CeolStandoutGlitch
+ // The EatNewlineGlitch [eat_newline_glitch, xenl] bool capability indicates newline ignored after 80 cols (concept).
+ EatNewlineGlitch
+ // The EraseOverstrike [erase_overstrike, eo] bool capability indicates can erase overstrikes with a blank.
+ EraseOverstrike
+ // The GenericType [generic_type, gn] bool capability indicates generic line type.
+ GenericType
+ // The HardCopy [hard_copy, hc] bool capability indicates hardcopy terminal.
+ HardCopy
+ // The HasMetaKey [has_meta_key, km] bool capability indicates Has a meta key (i.e., sets 8th-bit).
+ HasMetaKey
+ // The HasStatusLine [has_status_line, hs] bool capability indicates has extra status line.
+ HasStatusLine
+ // The InsertNullGlitch [insert_null_glitch, in] bool capability indicates insert mode distinguishes nulls.
+ InsertNullGlitch
+ // The MemoryAbove [memory_above, da] bool capability indicates display may be retained above the screen.
+ MemoryAbove
+ // The MemoryBelow [memory_below, db] bool capability indicates display may be retained below the screen.
+ MemoryBelow
+ // The MoveInsertMode [move_insert_mode, mir] bool capability indicates safe to move while in insert mode.
+ MoveInsertMode
+ // The MoveStandoutMode [move_standout_mode, msgr] bool capability indicates safe to move while in standout mode.
+ MoveStandoutMode
+ // The OverStrike [over_strike, os] bool capability indicates terminal can overstrike.
+ OverStrike
+ // The StatusLineEscOk [status_line_esc_ok, eslok] bool capability indicates escape can be used on the status line.
+ StatusLineEscOk
+ // The DestTabsMagicSmso [dest_tabs_magic_smso, xt] bool capability indicates tabs destructive, magic so char (t1061).
+ DestTabsMagicSmso
+ // The TildeGlitch [tilde_glitch, hz] bool capability indicates cannot print ~'s (Hazeltine).
+ TildeGlitch
+ // The TransparentUnderline [transparent_underline, ul] bool capability indicates underline character overstrikes.
+ TransparentUnderline
+ // The XonXoff [xon_xoff, xon] bool capability indicates terminal uses xon/xoff handshaking.
+ XonXoff
+ // The NeedsXonXoff [needs_xon_xoff, nxon] bool capability indicates padding will not work, xon/xoff required.
+ NeedsXonXoff
+ // The PrtrSilent [prtr_silent, mc5i] bool capability indicates printer will not echo on screen.
+ PrtrSilent
+ // The HardCursor [hard_cursor, chts] bool capability indicates cursor is hard to see.
+ HardCursor
+ // The NonRevRmcup [non_rev_rmcup, nrrmc] bool capability indicates smcup does not reverse rmcup.
+ NonRevRmcup
+ // The NoPadChar [no_pad_char, npc] bool capability indicates pad character does not exist.
+ NoPadChar
+ // The NonDestScrollRegion [non_dest_scroll_region, ndscr] bool capability indicates scrolling region is non-destructive.
+ NonDestScrollRegion
+ // The CanChange [can_change, ccc] bool capability indicates terminal can re-define existing colors.
+ CanChange
+ // The BackColorErase [back_color_erase, bce] bool capability indicates screen erased with background color.
+ BackColorErase
+ // The HueLightnessSaturation [hue_lightness_saturation, hls] bool capability indicates terminal uses only HLS color notation (Tektronix).
+ HueLightnessSaturation
+ // The ColAddrGlitch [col_addr_glitch, xhpa] bool capability indicates only positive motion for hpa/mhpa caps.
+ ColAddrGlitch
+ // The CrCancelsMicroMode [cr_cancels_micro_mode, crxm] bool capability indicates using cr turns off micro mode.
+ CrCancelsMicroMode
+ // The HasPrintWheel [has_print_wheel, daisy] bool capability indicates printer needs operator to change character set.
+ HasPrintWheel
+ // The RowAddrGlitch [row_addr_glitch, xvpa] bool capability indicates only positive motion for vpa/mvpa caps.
+ RowAddrGlitch
+ // The SemiAutoRightMargin [semi_auto_right_margin, sam] bool capability indicates printing in last column causes cr.
+ SemiAutoRightMargin
+ // The CpiChangesRes [cpi_changes_res, cpix] bool capability indicates changing character pitch changes resolution.
+ CpiChangesRes
+ // The LpiChangesRes [lpi_changes_res, lpix] bool capability indicates changing line pitch changes resolution.
+ LpiChangesRes
+ // The BackspacesWithBs [backspaces_with_bs, OTbs] bool capability indicates uses ^H to move left.
+ BackspacesWithBs
+ // The CrtNoScrolling [crt_no_scrolling, OTns] bool capability indicates crt cannot scroll.
+ CrtNoScrolling
+ // The NoCorrectlyWorkingCr [no_correctly_working_cr, OTnc] bool capability indicates no way to go to start of line.
+ NoCorrectlyWorkingCr
+ // The GnuHasMetaKey [gnu_has_meta_key, OTMT] bool capability indicates has meta key.
+ GnuHasMetaKey
+ // The LinefeedIsNewline [linefeed_is_newline, OTNL] bool capability indicates move down with \n.
+ LinefeedIsNewline
+ // The HasHardwareTabs [has_hardware_tabs, OTpt] bool capability indicates has 8-char tabs invoked with ^I.
+ HasHardwareTabs
+ // The ReturnDoesClrEol [return_does_clr_eol, OTxr] bool capability indicates return clears the line.
+ ReturnDoesClrEol
+)
+
+// Num capabilities.
+const (
+ // The Columns [columns, cols] num capability is number of columns in a line.
+ Columns = iota
+ // The InitTabs [init_tabs, it] num capability is tabs initially every # spaces.
+ InitTabs
+ // The Lines [lines, lines] num capability is number of lines on screen or page.
+ Lines
+ // The LinesOfMemory [lines_of_memory, lm] num capability is lines of memory if > line. 0 means varies.
+ LinesOfMemory
+ // The MagicCookieGlitch [magic_cookie_glitch, xmc] num capability is number of blank characters left by smso or rmso.
+ MagicCookieGlitch
+ // The PaddingBaudRate [padding_baud_rate, pb] num capability is lowest baud rate where padding needed.
+ PaddingBaudRate
+ // The VirtualTerminal [virtual_terminal, vt] num capability is virtual terminal number (CB/unix).
+ VirtualTerminal
+ // The WidthStatusLine [width_status_line, wsl] num capability is number of columns in status line.
+ WidthStatusLine
+ // The NumLabels [num_labels, nlab] num capability is number of labels on screen.
+ NumLabels
+ // The LabelHeight [label_height, lh] num capability is rows in each label.
+ LabelHeight
+ // The LabelWidth [label_width, lw] num capability is columns in each label.
+ LabelWidth
+ // The MaxAttributes [max_attributes, ma] num capability is maximum combined attributes terminal can handle.
+ MaxAttributes
+ // The MaximumWindows [maximum_windows, wnum] num capability is maximum number of definable windows.
+ MaximumWindows
+ // The MaxColors [max_colors, colors] num capability is maximum number of colors on screen.
+ MaxColors
+ // The MaxPairs [max_pairs, pairs] num capability is maximum number of color-pairs on the screen.
+ MaxPairs
+ // The NoColorVideo [no_color_video, ncv] num capability is video attributes that cannot be used with colors.
+ NoColorVideo
+ // The BufferCapacity [buffer_capacity, bufsz] num capability is numbers of bytes buffered before printing.
+ BufferCapacity
+ // The DotVertSpacing [dot_vert_spacing, spinv] num capability is spacing of pins vertically in pins per inch.
+ DotVertSpacing
+ // The DotHorzSpacing [dot_horz_spacing, spinh] num capability is spacing of dots horizontally in dots per inch.
+ DotHorzSpacing
+ // The MaxMicroAddress [max_micro_address, maddr] num capability is maximum value in micro_..._address.
+ MaxMicroAddress
+ // The MaxMicroJump [max_micro_jump, mjump] num capability is maximum value in parm_..._micro.
+ MaxMicroJump
+ // The MicroColSize [micro_col_size, mcs] num capability is character step size when in micro mode.
+ MicroColSize
+ // The MicroLineSize [micro_line_size, mls] num capability is line step size when in micro mode.
+ MicroLineSize
+ // The NumberOfPins [number_of_pins, npins] num capability is numbers of pins in print-head.
+ NumberOfPins
+ // The OutputResChar [output_res_char, orc] num capability is horizontal resolution in units per line.
+ OutputResChar
+ // The OutputResLine [output_res_line, orl] num capability is vertical resolution in units per line.
+ OutputResLine
+ // The OutputResHorzInch [output_res_horz_inch, orhi] num capability is horizontal resolution in units per inch.
+ OutputResHorzInch
+ // The OutputResVertInch [output_res_vert_inch, orvi] num capability is vertical resolution in units per inch.
+ OutputResVertInch
+ // The PrintRate [print_rate, cps] num capability is print rate in characters per second.
+ PrintRate
+ // The WideCharSize [wide_char_size, widcs] num capability is character step size when in double wide mode.
+ WideCharSize
+ // The Buttons [buttons, btns] num capability is number of buttons on mouse.
+ Buttons
+ // The BitImageEntwining [bit_image_entwining, bitwin] num capability is number of passes for each bit-image row.
+ BitImageEntwining
+ // The BitImageType [bit_image_type, bitype] num capability is type of bit-image device.
+ BitImageType
+ // The MagicCookieGlitchUl [magic_cookie_glitch_ul, OTug] num capability is number of blanks left by ul.
+ MagicCookieGlitchUl
+ // The CarriageReturnDelay [carriage_return_delay, OTdC] num capability is pad needed for CR.
+ CarriageReturnDelay
+ // The NewLineDelay [new_line_delay, OTdN] num capability is pad needed for LF.
+ NewLineDelay
+ // The BackspaceDelay [backspace_delay, OTdB] num capability is padding required for ^H.
+ BackspaceDelay
+ // The HorizontalTabDelay [horizontal_tab_delay, OTdT] num capability is padding required for ^I.
+ HorizontalTabDelay
+ // The NumberOfFunctionKeys [number_of_function_keys, OTkn] num capability is count of function keys.
+ NumberOfFunctionKeys
+)
+
+// String capabilities.
+const (
+ // The BackTab [back_tab, cbt] string capability is the back tab (P).
+ BackTab = iota
+ // The Bell [bell, bel] string capability is the audible signal (bell) (P).
+ Bell
+ // The CarriageReturn [carriage_return, cr] string capability is the carriage return (P*) (P*).
+ CarriageReturn
+ // The ChangeScrollRegion [change_scroll_region, csr] string capability is the change region to line #1 to line #2 (P).
+ ChangeScrollRegion
+ // The ClearAllTabs [clear_all_tabs, tbc] string capability is the clear all tab stops (P).
+ ClearAllTabs
+ // The ClearScreen [clear_screen, clear] string capability is the clear screen and home cursor (P*).
+ ClearScreen
+ // The ClrEol [clr_eol, el] string capability is the clear to end of line (P).
+ ClrEol
+ // The ClrEos [clr_eos, ed] string capability is the clear to end of screen (P*).
+ ClrEos
+ // The ColumnAddress [column_address, hpa] string capability is the horizontal position #1, absolute (P).
+ ColumnAddress
+ // The CommandCharacter [command_character, cmdch] string capability is the terminal settable cmd character in prototype !?.
+ CommandCharacter
+ // The CursorAddress [cursor_address, cup] string capability is the move to row #1 columns #2.
+ CursorAddress
+ // The CursorDown [cursor_down, cud1] string capability is the down one line.
+ CursorDown
+ // The CursorHome [cursor_home, home] string capability is the home cursor (if no cup).
+ CursorHome
+ // The CursorInvisible [cursor_invisible, civis] string capability is the make cursor invisible.
+ CursorInvisible
+ // The CursorLeft [cursor_left, cub1] string capability is the move left one space.
+ CursorLeft
+ // The CursorMemAddress [cursor_mem_address, mrcup] string capability is the memory relative cursor addressing, move to row #1 columns #2.
+ CursorMemAddress
+ // The CursorNormal [cursor_normal, cnorm] string capability is the make cursor appear normal (undo civis/cvvis).
+ CursorNormal
+ // The CursorRight [cursor_right, cuf1] string capability is the non-destructive space (move right one space).
+ CursorRight
+ // The CursorToLl [cursor_to_ll, ll] string capability is the last line, first column (if no cup).
+ CursorToLl
+ // The CursorUp [cursor_up, cuu1] string capability is the up one line.
+ CursorUp
+ // The CursorVisible [cursor_visible, cvvis] string capability is the make cursor very visible.
+ CursorVisible
+ // The DeleteCharacter [delete_character, dch1] string capability is the delete character (P*).
+ DeleteCharacter
+ // The DeleteLine [delete_line, dl1] string capability is the delete line (P*).
+ DeleteLine
+ // The DisStatusLine [dis_status_line, dsl] string capability is the disable status line.
+ DisStatusLine
+ // The DownHalfLine [down_half_line, hd] string capability is the half a line down.
+ DownHalfLine
+ // The EnterAltCharsetMode [enter_alt_charset_mode, smacs] string capability is the start alternate character set (P).
+ EnterAltCharsetMode
+ // The EnterBlinkMode [enter_blink_mode, blink] string capability is the turn on blinking.
+ EnterBlinkMode
+ // The EnterBoldMode [enter_bold_mode, bold] string capability is the turn on bold (extra bright) mode.
+ EnterBoldMode
+ // The EnterCaMode [enter_ca_mode, smcup] string capability is the string to start programs using cup.
+ EnterCaMode
+ // The EnterDeleteMode [enter_delete_mode, smdc] string capability is the enter delete mode.
+ EnterDeleteMode
+ // The EnterDimMode [enter_dim_mode, dim] string capability is the turn on half-bright mode.
+ EnterDimMode
+ // The EnterInsertMode [enter_insert_mode, smir] string capability is the enter insert mode.
+ EnterInsertMode
+ // The EnterSecureMode [enter_secure_mode, invis] string capability is the turn on blank mode (characters invisible).
+ EnterSecureMode
+ // The EnterProtectedMode [enter_protected_mode, prot] string capability is the turn on protected mode.
+ EnterProtectedMode
+ // The EnterReverseMode [enter_reverse_mode, rev] string capability is the turn on reverse video mode.
+ EnterReverseMode
+ // The EnterStandoutMode [enter_standout_mode, smso] string capability is the begin standout mode.
+ EnterStandoutMode
+ // The EnterUnderlineMode [enter_underline_mode, smul] string capability is the begin underline mode.
+ EnterUnderlineMode
+ // The EraseChars [erase_chars, ech] string capability is the erase #1 characters (P).
+ EraseChars
+ // The ExitAltCharsetMode [exit_alt_charset_mode, rmacs] string capability is the end alternate character set (P).
+ ExitAltCharsetMode
+ // The ExitAttributeMode [exit_attribute_mode, sgr0] string capability is the turn off all attributes.
+ ExitAttributeMode
+ // The ExitCaMode [exit_ca_mode, rmcup] string capability is the strings to end programs using cup.
+ ExitCaMode
+ // The ExitDeleteMode [exit_delete_mode, rmdc] string capability is the end delete mode.
+ ExitDeleteMode
+ // The ExitInsertMode [exit_insert_mode, rmir] string capability is the exit insert mode.
+ ExitInsertMode
+ // The ExitStandoutMode [exit_standout_mode, rmso] string capability is the exit standout mode.
+ ExitStandoutMode
+ // The ExitUnderlineMode [exit_underline_mode, rmul] string capability is the exit underline mode.
+ ExitUnderlineMode
+ // The FlashScreen [flash_screen, flash] string capability is the visible bell (may not move cursor).
+ FlashScreen
+ // The FormFeed [form_feed, ff] string capability is the hardcopy terminal page eject (P*).
+ FormFeed
+ // The FromStatusLine [from_status_line, fsl] string capability is the return from status line.
+ FromStatusLine
+ // The Init1string [init_1string, is1] string capability is the initialization string.
+ Init1string
+ // The Init2string [init_2string, is2] string capability is the initialization string.
+ Init2string
+ // The Init3string [init_3string, is3] string capability is the initialization string.
+ Init3string
+ // The InitFile [init_file, if] string capability is the name of initialization file.
+ InitFile
+ // The InsertCharacter [insert_character, ich1] string capability is the insert character (P).
+ InsertCharacter
+ // The InsertLine [insert_line, il1] string capability is the insert line (P*).
+ InsertLine
+ // The InsertPadding [insert_padding, ip] string capability is the insert padding after inserted character.
+ InsertPadding
+ // The KeyBackspace [key_backspace, kbs] string capability is the backspace key.
+ KeyBackspace
+ // The KeyCatab [key_catab, ktbc] string capability is the clear-all-tabs key.
+ KeyCatab
+ // The KeyClear [key_clear, kclr] string capability is the clear-screen or erase key.
+ KeyClear
+ // The KeyCtab [key_ctab, kctab] string capability is the clear-tab key.
+ KeyCtab
+ // The KeyDc [key_dc, kdch1] string capability is the delete-character key.
+ KeyDc
+ // The KeyDl [key_dl, kdl1] string capability is the delete-line key.
+ KeyDl
+ // The KeyDown [key_down, kcud1] string capability is the down-arrow key.
+ KeyDown
+ // The KeyEic [key_eic, krmir] string capability is the sent by rmir or smir in insert mode.
+ KeyEic
+ // The KeyEol [key_eol, kel] string capability is the clear-to-end-of-line key.
+ KeyEol
+ // The KeyEos [key_eos, ked] string capability is the clear-to-end-of-screen key.
+ KeyEos
+ // The KeyF0 [key_f0, kf0] string capability is the F0 function key.
+ KeyF0
+ // The KeyF1 [key_f1, kf1] string capability is the F1 function key.
+ KeyF1
+ // The KeyF10 [key_f10, kf10] string capability is the F10 function key.
+ KeyF10
+ // The KeyF2 [key_f2, kf2] string capability is the F2 function key.
+ KeyF2
+ // The KeyF3 [key_f3, kf3] string capability is the F3 function key.
+ KeyF3
+ // The KeyF4 [key_f4, kf4] string capability is the F4 function key.
+ KeyF4
+ // The KeyF5 [key_f5, kf5] string capability is the F5 function key.
+ KeyF5
+ // The KeyF6 [key_f6, kf6] string capability is the F6 function key.
+ KeyF6
+ // The KeyF7 [key_f7, kf7] string capability is the F7 function key.
+ KeyF7
+ // The KeyF8 [key_f8, kf8] string capability is the F8 function key.
+ KeyF8
+ // The KeyF9 [key_f9, kf9] string capability is the F9 function key.
+ KeyF9
+ // The KeyHome [key_home, khome] string capability is the home key.
+ KeyHome
+ // The KeyIc [key_ic, kich1] string capability is the insert-character key.
+ KeyIc
+ // The KeyIl [key_il, kil1] string capability is the insert-line key.
+ KeyIl
+ // The KeyLeft [key_left, kcub1] string capability is the left-arrow key.
+ KeyLeft
+ // The KeyLl [key_ll, kll] string capability is the lower-left key (home down).
+ KeyLl
+ // The KeyNpage [key_npage, knp] string capability is the next-page key.
+ KeyNpage
+ // The KeyPpage [key_ppage, kpp] string capability is the previous-page key.
+ KeyPpage
+ // The KeyRight [key_right, kcuf1] string capability is the right-arrow key.
+ KeyRight
+ // The KeySf [key_sf, kind] string capability is the scroll-forward key.
+ KeySf
+ // The KeySr [key_sr, kri] string capability is the scroll-backward key.
+ KeySr
+ // The KeyStab [key_stab, khts] string capability is the set-tab key.
+ KeyStab
+ // The KeyUp [key_up, kcuu1] string capability is the up-arrow key.
+ KeyUp
+ // The KeypadLocal [keypad_local, rmkx] string capability is the leave 'keyboard_transmit' mode.
+ KeypadLocal
+ // The KeypadXmit [keypad_xmit, smkx] string capability is the enter 'keyboard_transmit' mode.
+ KeypadXmit
+ // The LabF0 [lab_f0, lf0] string capability is the label on function key f0 if not f0.
+ LabF0
+ // The LabF1 [lab_f1, lf1] string capability is the label on function key f1 if not f1.
+ LabF1
+ // The LabF10 [lab_f10, lf10] string capability is the label on function key f10 if not f10.
+ LabF10
+ // The LabF2 [lab_f2, lf2] string capability is the label on function key f2 if not f2.
+ LabF2
+ // The LabF3 [lab_f3, lf3] string capability is the label on function key f3 if not f3.
+ LabF3
+ // The LabF4 [lab_f4, lf4] string capability is the label on function key f4 if not f4.
+ LabF4
+ // The LabF5 [lab_f5, lf5] string capability is the label on function key f5 if not f5.
+ LabF5
+ // The LabF6 [lab_f6, lf6] string capability is the label on function key f6 if not f6.
+ LabF6
+ // The LabF7 [lab_f7, lf7] string capability is the label on function key f7 if not f7.
+ LabF7
+ // The LabF8 [lab_f8, lf8] string capability is the label on function key f8 if not f8.
+ LabF8
+ // The LabF9 [lab_f9, lf9] string capability is the label on function key f9 if not f9.
+ LabF9
+ // The MetaOff [meta_off, rmm] string capability is the turn off meta mode.
+ MetaOff
+ // The MetaOn [meta_on, smm] string capability is the turn on meta mode (8th-bit on).
+ MetaOn
+ // The Newline [newline, nel] string capability is the newline (behave like cr followed by lf).
+ Newline
+ // The PadChar [pad_char, pad] string capability is the padding char (instead of null).
+ PadChar
+ // The ParmDch [parm_dch, dch] string capability is the delete #1 characters (P*).
+ ParmDch
+ // The ParmDeleteLine [parm_delete_line, dl] string capability is the delete #1 lines (P*).
+ ParmDeleteLine
+ // The ParmDownCursor [parm_down_cursor, cud] string capability is the down #1 lines (P*).
+ ParmDownCursor
+ // The ParmIch [parm_ich, ich] string capability is the insert #1 characters (P*).
+ ParmIch
+ // The ParmIndex [parm_index, indn] string capability is the scroll forward #1 lines (P).
+ ParmIndex
+ // The ParmInsertLine [parm_insert_line, il] string capability is the insert #1 lines (P*).
+ ParmInsertLine
+ // The ParmLeftCursor [parm_left_cursor, cub] string capability is the move #1 characters to the left (P).
+ ParmLeftCursor
+ // The ParmRightCursor [parm_right_cursor, cuf] string capability is the move #1 characters to the right (P*).
+ ParmRightCursor
+ // The ParmRindex [parm_rindex, rin] string capability is the scroll back #1 lines (P).
+ ParmRindex
+ // The ParmUpCursor [parm_up_cursor, cuu] string capability is the up #1 lines (P*).
+ ParmUpCursor
+ // The PkeyKey [pkey_key, pfkey] string capability is the program function key #1 to type string #2.
+ PkeyKey
+ // The PkeyLocal [pkey_local, pfloc] string capability is the program function key #1 to execute string #2.
+ PkeyLocal
+ // The PkeyXmit [pkey_xmit, pfx] string capability is the program function key #1 to transmit string #2.
+ PkeyXmit
+ // The PrintScreen [print_screen, mc0] string capability is the print contents of screen.
+ PrintScreen
+ // The PrtrOff [prtr_off, mc4] string capability is the turn off printer.
+ PrtrOff
+ // The PrtrOn [prtr_on, mc5] string capability is the turn on printer.
+ PrtrOn
+ // The RepeatChar [repeat_char, rep] string capability is the repeat char #1 #2 times (P*).
+ RepeatChar
+ // The Reset1string [reset_1string, rs1] string capability is the reset string.
+ Reset1string
+ // The Reset2string [reset_2string, rs2] string capability is the reset string.
+ Reset2string
+ // The Reset3string [reset_3string, rs3] string capability is the reset string.
+ Reset3string
+ // The ResetFile [reset_file, rf] string capability is the name of reset file.
+ ResetFile
+ // The RestoreCursor [restore_cursor, rc] string capability is the restore cursor to position of last save_cursor.
+ RestoreCursor
+ // The RowAddress [row_address, vpa] string capability is the vertical position #1 absolute (P).
+ RowAddress
+ // The SaveCursor [save_cursor, sc] string capability is the save current cursor position (P).
+ SaveCursor
+ // The ScrollForward [scroll_forward, ind] string capability is the scroll text up (P).
+ ScrollForward
+ // The ScrollReverse [scroll_reverse, ri] string capability is the scroll text down (P).
+ ScrollReverse
+ // The SetAttributes [set_attributes, sgr] string capability is the define video attributes #1-#9 (PG9).
+ SetAttributes
+ // The SetTab [set_tab, hts] string capability is the set a tab in every row, current columns.
+ SetTab
+ // The SetWindow [set_window, wind] string capability is the current window is lines #1-#2 cols #3-#4.
+ SetWindow
+ // The Tab [tab, ht] string capability is the tab to next 8-space hardware tab stop.
+ Tab
+ // The ToStatusLine [to_status_line, tsl] string capability is the move to status line, column #1.
+ ToStatusLine
+ // The UnderlineChar [underline_char, uc] string capability is the underline char and move past it.
+ UnderlineChar
+ // The UpHalfLine [up_half_line, hu] string capability is the half a line up.
+ UpHalfLine
+ // The InitProg [init_prog, iprog] string capability is the path name of program for initialization.
+ InitProg
+ // The KeyA1 [key_a1, ka1] string capability is the upper left of keypad.
+ KeyA1
+ // The KeyA3 [key_a3, ka3] string capability is the upper right of keypad.
+ KeyA3
+ // The KeyB2 [key_b2, kb2] string capability is the center of keypad.
+ KeyB2
+ // The KeyC1 [key_c1, kc1] string capability is the lower left of keypad.
+ KeyC1
+ // The KeyC3 [key_c3, kc3] string capability is the lower right of keypad.
+ KeyC3
+ // The PrtrNon [prtr_non, mc5p] string capability is the turn on printer for #1 bytes.
+ PrtrNon
+ // The CharPadding [char_padding, rmp] string capability is the like ip but when in insert mode.
+ CharPadding
+ // The AcsChars [acs_chars, acsc] string capability is the graphics charset pairs, based on vt100.
+ AcsChars
+ // The PlabNorm [plab_norm, pln] string capability is the program label #1 to show string #2.
+ PlabNorm
+ // The KeyBtab [key_btab, kcbt] string capability is the back-tab key.
+ KeyBtab
+ // The EnterXonMode [enter_xon_mode, smxon] string capability is the turn on xon/xoff handshaking.
+ EnterXonMode
+ // The ExitXonMode [exit_xon_mode, rmxon] string capability is the turn off xon/xoff handshaking.
+ ExitXonMode
+ // The EnterAmMode [enter_am_mode, smam] string capability is the turn on automatic margins.
+ EnterAmMode
+ // The ExitAmMode [exit_am_mode, rmam] string capability is the turn off automatic margins.
+ ExitAmMode
+ // The XonCharacter [xon_character, xonc] string capability is the XON character.
+ XonCharacter
+ // The XoffCharacter [xoff_character, xoffc] string capability is the XOFF character.
+ XoffCharacter
+ // The EnaAcs [ena_acs, enacs] string capability is the enable alternate char set.
+ EnaAcs
+ // The LabelOn [label_on, smln] string capability is the turn on soft labels.
+ LabelOn
+ // The LabelOff [label_off, rmln] string capability is the turn off soft labels.
+ LabelOff
+ // The KeyBeg [key_beg, kbeg] string capability is the begin key.
+ KeyBeg
+ // The KeyCancel [key_cancel, kcan] string capability is the cancel key.
+ KeyCancel
+ // The KeyClose [key_close, kclo] string capability is the close key.
+ KeyClose
+ // The KeyCommand [key_command, kcmd] string capability is the command key.
+ KeyCommand
+ // The KeyCopy [key_copy, kcpy] string capability is the copy key.
+ KeyCopy
+ // The KeyCreate [key_create, kcrt] string capability is the create key.
+ KeyCreate
+ // The KeyEnd [key_end, kend] string capability is the end key.
+ KeyEnd
+ // The KeyEnter [key_enter, kent] string capability is the enter/send key.
+ KeyEnter
+ // The KeyExit [key_exit, kext] string capability is the exit key.
+ KeyExit
+ // The KeyFind [key_find, kfnd] string capability is the find key.
+ KeyFind
+ // The KeyHelp [key_help, khlp] string capability is the help key.
+ KeyHelp
+ // The KeyMark [key_mark, kmrk] string capability is the mark key.
+ KeyMark
+ // The KeyMessage [key_message, kmsg] string capability is the message key.
+ KeyMessage
+ // The KeyMove [key_move, kmov] string capability is the move key.
+ KeyMove
+ // The KeyNext [key_next, knxt] string capability is the next key.
+ KeyNext
+ // The KeyOpen [key_open, kopn] string capability is the open key.
+ KeyOpen
+ // The KeyOptions [key_options, kopt] string capability is the options key.
+ KeyOptions
+ // The KeyPrevious [key_previous, kprv] string capability is the previous key.
+ KeyPrevious
+ // The KeyPrint [key_print, kprt] string capability is the print key.
+ KeyPrint
+ // The KeyRedo [key_redo, krdo] string capability is the redo key.
+ KeyRedo
+ // The KeyReference [key_reference, kref] string capability is the reference key.
+ KeyReference
+ // The KeyRefresh [key_refresh, krfr] string capability is the refresh key.
+ KeyRefresh
+ // The KeyReplace [key_replace, krpl] string capability is the replace key.
+ KeyReplace
+ // The KeyRestart [key_restart, krst] string capability is the restart key.
+ KeyRestart
+ // The KeyResume [key_resume, kres] string capability is the resume key.
+ KeyResume
+ // The KeySave [key_save, ksav] string capability is the save key.
+ KeySave
+ // The KeySuspend [key_suspend, kspd] string capability is the suspend key.
+ KeySuspend
+ // The KeyUndo [key_undo, kund] string capability is the undo key.
+ KeyUndo
+ // The KeySbeg [key_sbeg, kBEG] string capability is the shifted begin key.
+ KeySbeg
+ // The KeyScancel [key_scancel, kCAN] string capability is the shifted cancel key.
+ KeyScancel
+ // The KeyScommand [key_scommand, kCMD] string capability is the shifted command key.
+ KeyScommand
+ // The KeyScopy [key_scopy, kCPY] string capability is the shifted copy key.
+ KeyScopy
+ // The KeyScreate [key_screate, kCRT] string capability is the shifted create key.
+ KeyScreate
+ // The KeySdc [key_sdc, kDC] string capability is the shifted delete-character key.
+ KeySdc
+ // The KeySdl [key_sdl, kDL] string capability is the shifted delete-line key.
+ KeySdl
+ // The KeySelect [key_select, kslt] string capability is the select key.
+ KeySelect
+ // The KeySend [key_send, kEND] string capability is the shifted end key.
+ KeySend
+ // The KeySeol [key_seol, kEOL] string capability is the shifted clear-to-end-of-line key.
+ KeySeol
+ // The KeySexit [key_sexit, kEXT] string capability is the shifted exit key.
+ KeySexit
+ // The KeySfind [key_sfind, kFND] string capability is the shifted find key.
+ KeySfind
+ // The KeyShelp [key_shelp, kHLP] string capability is the shifted help key.
+ KeyShelp
+ // The KeyShome [key_shome, kHOM] string capability is the shifted home key.
+ KeyShome
+ // The KeySic [key_sic, kIC] string capability is the shifted insert-character key.
+ KeySic
+ // The KeySleft [key_sleft, kLFT] string capability is the shifted left-arrow key.
+ KeySleft
+ // The KeySmessage [key_smessage, kMSG] string capability is the shifted message key.
+ KeySmessage
+ // The KeySmove [key_smove, kMOV] string capability is the shifted move key.
+ KeySmove
+ // The KeySnext [key_snext, kNXT] string capability is the shifted next key.
+ KeySnext
+ // The KeySoptions [key_soptions, kOPT] string capability is the shifted options key.
+ KeySoptions
+ // The KeySprevious [key_sprevious, kPRV] string capability is the shifted previous key.
+ KeySprevious
+ // The KeySprint [key_sprint, kPRT] string capability is the shifted print key.
+ KeySprint
+ // The KeySredo [key_sredo, kRDO] string capability is the shifted redo key.
+ KeySredo
+ // The KeySreplace [key_sreplace, kRPL] string capability is the shifted replace key.
+ KeySreplace
+ // The KeySright [key_sright, kRIT] string capability is the shifted right-arrow key.
+ KeySright
+ // The KeySrsume [key_srsume, kRES] string capability is the shifted resume key.
+ KeySrsume
+ // The KeySsave [key_ssave, kSAV] string capability is the shifted save key.
+ KeySsave
+ // The KeySsuspend [key_ssuspend, kSPD] string capability is the shifted suspend key.
+ KeySsuspend
+ // The KeySundo [key_sundo, kUND] string capability is the shifted undo key.
+ KeySundo
+ // The ReqForInput [req_for_input, rfi] string capability is the send next input char (for ptys).
+ ReqForInput
+ // The KeyF11 [key_f11, kf11] string capability is the F11 function key.
+ KeyF11
+ // The KeyF12 [key_f12, kf12] string capability is the F12 function key.
+ KeyF12
+ // The KeyF13 [key_f13, kf13] string capability is the F13 function key.
+ KeyF13
+ // The KeyF14 [key_f14, kf14] string capability is the F14 function key.
+ KeyF14
+ // The KeyF15 [key_f15, kf15] string capability is the F15 function key.
+ KeyF15
+ // The KeyF16 [key_f16, kf16] string capability is the F16 function key.
+ KeyF16
+ // The KeyF17 [key_f17, kf17] string capability is the F17 function key.
+ KeyF17
+ // The KeyF18 [key_f18, kf18] string capability is the F18 function key.
+ KeyF18
+ // The KeyF19 [key_f19, kf19] string capability is the F19 function key.
+ KeyF19
+ // The KeyF20 [key_f20, kf20] string capability is the F20 function key.
+ KeyF20
+ // The KeyF21 [key_f21, kf21] string capability is the F21 function key.
+ KeyF21
+ // The KeyF22 [key_f22, kf22] string capability is the F22 function key.
+ KeyF22
+ // The KeyF23 [key_f23, kf23] string capability is the F23 function key.
+ KeyF23
+ // The KeyF24 [key_f24, kf24] string capability is the F24 function key.
+ KeyF24
+ // The KeyF25 [key_f25, kf25] string capability is the F25 function key.
+ KeyF25
+ // The KeyF26 [key_f26, kf26] string capability is the F26 function key.
+ KeyF26
+ // The KeyF27 [key_f27, kf27] string capability is the F27 function key.
+ KeyF27
+ // The KeyF28 [key_f28, kf28] string capability is the F28 function key.
+ KeyF28
+ // The KeyF29 [key_f29, kf29] string capability is the F29 function key.
+ KeyF29
+ // The KeyF30 [key_f30, kf30] string capability is the F30 function key.
+ KeyF30
+ // The KeyF31 [key_f31, kf31] string capability is the F31 function key.
+ KeyF31
+ // The KeyF32 [key_f32, kf32] string capability is the F32 function key.
+ KeyF32
+ // The KeyF33 [key_f33, kf33] string capability is the F33 function key.
+ KeyF33
+ // The KeyF34 [key_f34, kf34] string capability is the F34 function key.
+ KeyF34
+ // The KeyF35 [key_f35, kf35] string capability is the F35 function key.
+ KeyF35
+ // The KeyF36 [key_f36, kf36] string capability is the F36 function key.
+ KeyF36
+ // The KeyF37 [key_f37, kf37] string capability is the F37 function key.
+ KeyF37
+ // The KeyF38 [key_f38, kf38] string capability is the F38 function key.
+ KeyF38
+ // The KeyF39 [key_f39, kf39] string capability is the F39 function key.
+ KeyF39
+ // The KeyF40 [key_f40, kf40] string capability is the F40 function key.
+ KeyF40
+ // The KeyF41 [key_f41, kf41] string capability is the F41 function key.
+ KeyF41
+ // The KeyF42 [key_f42, kf42] string capability is the F42 function key.
+ KeyF42
+ // The KeyF43 [key_f43, kf43] string capability is the F43 function key.
+ KeyF43
+ // The KeyF44 [key_f44, kf44] string capability is the F44 function key.
+ KeyF44
+ // The KeyF45 [key_f45, kf45] string capability is the F45 function key.
+ KeyF45
+ // The KeyF46 [key_f46, kf46] string capability is the F46 function key.
+ KeyF46
+ // The KeyF47 [key_f47, kf47] string capability is the F47 function key.
+ KeyF47
+ // The KeyF48 [key_f48, kf48] string capability is the F48 function key.
+ KeyF48
+ // The KeyF49 [key_f49, kf49] string capability is the F49 function key.
+ KeyF49
+ // The KeyF50 [key_f50, kf50] string capability is the F50 function key.
+ KeyF50
+ // The KeyF51 [key_f51, kf51] string capability is the F51 function key.
+ KeyF51
+ // The KeyF52 [key_f52, kf52] string capability is the F52 function key.
+ KeyF52
+ // The KeyF53 [key_f53, kf53] string capability is the F53 function key.
+ KeyF53
+ // The KeyF54 [key_f54, kf54] string capability is the F54 function key.
+ KeyF54
+ // The KeyF55 [key_f55, kf55] string capability is the F55 function key.
+ KeyF55
+ // The KeyF56 [key_f56, kf56] string capability is the F56 function key.
+ KeyF56
+ // The KeyF57 [key_f57, kf57] string capability is the F57 function key.
+ KeyF57
+ // The KeyF58 [key_f58, kf58] string capability is the F58 function key.
+ KeyF58
+ // The KeyF59 [key_f59, kf59] string capability is the F59 function key.
+ KeyF59
+ // The KeyF60 [key_f60, kf60] string capability is the F60 function key.
+ KeyF60
+ // The KeyF61 [key_f61, kf61] string capability is the F61 function key.
+ KeyF61
+ // The KeyF62 [key_f62, kf62] string capability is the F62 function key.
+ KeyF62
+ // The KeyF63 [key_f63, kf63] string capability is the F63 function key.
+ KeyF63
+ // The ClrBol [clr_bol, el1] string capability is the Clear to beginning of line.
+ ClrBol
+ // The ClearMargins [clear_margins, mgc] string capability is the clear right and left soft margins.
+ ClearMargins
+ // The SetLeftMargin [set_left_margin, smgl] string capability is the set left soft margin at current column. (ML is not in BSD termcap).
+ SetLeftMargin
+ // The SetRightMargin [set_right_margin, smgr] string capability is the set right soft margin at current column.
+ SetRightMargin
+ // The LabelFormat [label_format, fln] string capability is the label format.
+ LabelFormat
+ // The SetClock [set_clock, sclk] string capability is the set clock, #1 hrs #2 mins #3 secs.
+ SetClock
+ // The DisplayClock [display_clock, dclk] string capability is the display clock.
+ DisplayClock
+ // The RemoveClock [remove_clock, rmclk] string capability is the remove clock.
+ RemoveClock
+ // The CreateWindow [create_window, cwin] string capability is the define a window #1 from #2,#3 to #4,#5.
+ CreateWindow
+ // The GotoWindow [goto_window, wingo] string capability is the go to window #1.
+ GotoWindow
+ // The Hangup [hangup, hup] string capability is the hang-up phone.
+ Hangup
+ // The DialPhone [dial_phone, dial] string capability is the dial number #1.
+ DialPhone
+ // The QuickDial [quick_dial, qdial] string capability is the dial number #1 without checking.
+ QuickDial
+ // The Tone [tone, tone] string capability is the select touch tone dialing.
+ Tone
+ // The Pulse [pulse, pulse] string capability is the select pulse dialing.
+ Pulse
+ // The FlashHook [flash_hook, hook] string capability is the flash switch hook.
+ FlashHook
+ // The FixedPause [fixed_pause, pause] string capability is the pause for 2-3 seconds.
+ FixedPause
+ // The WaitTone [wait_tone, wait] string capability is the wait for dial-tone.
+ WaitTone
+ // The User0 [user0, u0] string capability is the User string #0.
+ User0
+ // The User1 [user1, u1] string capability is the User string #1.
+ User1
+ // The User2 [user2, u2] string capability is the User string #2.
+ User2
+ // The User3 [user3, u3] string capability is the User string #3.
+ User3
+ // The User4 [user4, u4] string capability is the User string #4.
+ User4
+ // The User5 [user5, u5] string capability is the User string #5.
+ User5
+ // The User6 [user6, u6] string capability is the User string #6.
+ User6
+ // The User7 [user7, u7] string capability is the User string #7.
+ User7
+ // The User8 [user8, u8] string capability is the User string #8.
+ User8
+ // The User9 [user9, u9] string capability is the User string #9.
+ User9
+ // The OrigPair [orig_pair, op] string capability is the Set default pair to its original value.
+ OrigPair
+ // The OrigColors [orig_colors, oc] string capability is the Set all color pairs to the original ones.
+ OrigColors
+ // The InitializeColor [initialize_color, initc] string capability is the initialize color #1 to (#2,#3,#4).
+ InitializeColor
+ // The InitializePair [initialize_pair, initp] string capability is the Initialize color pair #1 to fg=(#2,#3,#4), bg=(#5,#6,#7).
+ InitializePair
+ // The SetColorPair [set_color_pair, scp] string capability is the Set current color pair to #1.
+ SetColorPair
+ // The SetForeground [set_foreground, setf] string capability is the Set foreground color #1.
+ SetForeground
+ // The SetBackground [set_background, setb] string capability is the Set background color #1.
+ SetBackground
+ // The ChangeCharPitch [change_char_pitch, cpi] string capability is the Change number of characters per inch to #1.
+ ChangeCharPitch
+ // The ChangeLinePitch [change_line_pitch, lpi] string capability is the Change number of lines per inch to #1.
+ ChangeLinePitch
+ // The ChangeResHorz [change_res_horz, chr] string capability is the Change horizontal resolution to #1.
+ ChangeResHorz
+ // The ChangeResVert [change_res_vert, cvr] string capability is the Change vertical resolution to #1.
+ ChangeResVert
+ // The DefineChar [define_char, defc] string capability is the Define a character #1, #2 dots wide, descender #3.
+ DefineChar
+ // The EnterDoublewideMode [enter_doublewide_mode, swidm] string capability is the Enter double-wide mode.
+ EnterDoublewideMode
+ // The EnterDraftQuality [enter_draft_quality, sdrfq] string capability is the Enter draft-quality mode.
+ EnterDraftQuality
+ // The EnterItalicsMode [enter_italics_mode, sitm] string capability is the Enter italic mode.
+ EnterItalicsMode
+ // The EnterLeftwardMode [enter_leftward_mode, slm] string capability is the Start leftward carriage motion.
+ EnterLeftwardMode
+ // The EnterMicroMode [enter_micro_mode, smicm] string capability is the Start micro-motion mode.
+ EnterMicroMode
+ // The EnterNearLetterQuality [enter_near_letter_quality, snlq] string capability is the Enter NLQ mode.
+ EnterNearLetterQuality
+ // The EnterNormalQuality [enter_normal_quality, snrmq] string capability is the Enter normal-quality mode.
+ EnterNormalQuality
+ // The EnterShadowMode [enter_shadow_mode, sshm] string capability is the Enter shadow-print mode.
+ EnterShadowMode
+ // The EnterSubscriptMode [enter_subscript_mode, ssubm] string capability is the Enter subscript mode.
+ EnterSubscriptMode
+ // The EnterSuperscriptMode [enter_superscript_mode, ssupm] string capability is the Enter superscript mode.
+ EnterSuperscriptMode
+ // The EnterUpwardMode [enter_upward_mode, sum] string capability is the Start upward carriage motion.
+ EnterUpwardMode
+ // The ExitDoublewideMode [exit_doublewide_mode, rwidm] string capability is the End double-wide mode.
+ ExitDoublewideMode
+ // The ExitItalicsMode [exit_italics_mode, ritm] string capability is the End italic mode.
+ ExitItalicsMode
+ // The ExitLeftwardMode [exit_leftward_mode, rlm] string capability is the End left-motion mode.
+ ExitLeftwardMode
+ // The ExitMicroMode [exit_micro_mode, rmicm] string capability is the End micro-motion mode.
+ ExitMicroMode
+ // The ExitShadowMode [exit_shadow_mode, rshm] string capability is the End shadow-print mode.
+ ExitShadowMode
+ // The ExitSubscriptMode [exit_subscript_mode, rsubm] string capability is the End subscript mode.
+ ExitSubscriptMode
+ // The ExitSuperscriptMode [exit_superscript_mode, rsupm] string capability is the End superscript mode.
+ ExitSuperscriptMode
+ // The ExitUpwardMode [exit_upward_mode, rum] string capability is the End reverse character motion.
+ ExitUpwardMode
+ // The MicroColumnAddress [micro_column_address, mhpa] string capability is the Like column_address in micro mode.
+ MicroColumnAddress
+ // The MicroDown [micro_down, mcud1] string capability is the Like cursor_down in micro mode.
+ MicroDown
+ // The MicroLeft [micro_left, mcub1] string capability is the Like cursor_left in micro mode.
+ MicroLeft
+ // The MicroRight [micro_right, mcuf1] string capability is the Like cursor_right in micro mode.
+ MicroRight
+ // The MicroRowAddress [micro_row_address, mvpa] string capability is the Like row_address #1 in micro mode.
+ MicroRowAddress
+ // The MicroUp [micro_up, mcuu1] string capability is the Like cursor_up in micro mode.
+ MicroUp
+ // The OrderOfPins [order_of_pins, porder] string capability is the Match software bits to print-head pins.
+ OrderOfPins
+ // The ParmDownMicro [parm_down_micro, mcud] string capability is the Like parm_down_cursor in micro mode.
+ ParmDownMicro
+ // The ParmLeftMicro [parm_left_micro, mcub] string capability is the Like parm_left_cursor in micro mode.
+ ParmLeftMicro
+ // The ParmRightMicro [parm_right_micro, mcuf] string capability is the Like parm_right_cursor in micro mode.
+ ParmRightMicro
+ // The ParmUpMicro [parm_up_micro, mcuu] string capability is the Like parm_up_cursor in micro mode.
+ ParmUpMicro
+ // The SelectCharSet [select_char_set, scs] string capability is the Select character set, #1.
+ SelectCharSet
+ // The SetBottomMargin [set_bottom_margin, smgb] string capability is the Set bottom margin at current line.
+ SetBottomMargin
+ // The SetBottomMarginParm [set_bottom_margin_parm, smgbp] string capability is the Set bottom margin at line #1 or (if smgtp is not given) #2 lines from bottom.
+ SetBottomMarginParm
+ // The SetLeftMarginParm [set_left_margin_parm, smglp] string capability is the Set left (right) margin at column #1.
+ SetLeftMarginParm
+ // The SetRightMarginParm [set_right_margin_parm, smgrp] string capability is the Set right margin at column #1.
+ SetRightMarginParm
+ // The SetTopMargin [set_top_margin, smgt] string capability is the Set top margin at current line.
+ SetTopMargin
+ // The SetTopMarginParm [set_top_margin_parm, smgtp] string capability is the Set top (bottom) margin at row #1.
+ SetTopMarginParm
+ // The StartBitImage [start_bit_image, sbim] string capability is the Start printing bit image graphics.
+ StartBitImage
+ // The StartCharSetDef [start_char_set_def, scsd] string capability is the Start character set definition #1, with #2 characters in the set.
+ StartCharSetDef
+ // The StopBitImage [stop_bit_image, rbim] string capability is the Stop printing bit image graphics.
+ StopBitImage
+ // The StopCharSetDef [stop_char_set_def, rcsd] string capability is the End definition of character set #1.
+ StopCharSetDef
+ // The SubscriptCharacters [subscript_characters, subcs] string capability is the List of subscriptable characters.
+ SubscriptCharacters
+ // The SuperscriptCharacters [superscript_characters, supcs] string capability is the List of superscriptable characters.
+ SuperscriptCharacters
+ // The TheseCauseCr [these_cause_cr, docr] string capability is the Printing any of these characters causes CR.
+ TheseCauseCr
+ // The ZeroMotion [zero_motion, zerom] string capability is the No motion for subsequent character.
+ ZeroMotion
+ // The CharSetNames [char_set_names, csnm] string capability is the Produce #1'th item from list of character set names.
+ CharSetNames
+ // The KeyMouse [key_mouse, kmous] string capability is the Mouse event has occurred.
+ KeyMouse
+ // The MouseInfo [mouse_info, minfo] string capability is the Mouse status information.
+ MouseInfo
+ // The ReqMousePos [req_mouse_pos, reqmp] string capability is the Request mouse position.
+ ReqMousePos
+ // The GetMouse [get_mouse, getm] string capability is the Curses should get button events, parameter #1 not documented.
+ GetMouse
+ // The SetAForeground [set_a_foreground, setaf] string capability is the Set foreground color to #1, using ANSI escape.
+ SetAForeground
+ // The SetABackground [set_a_background, setab] string capability is the Set background color to #1, using ANSI escape.
+ SetABackground
+ // The PkeyPlab [pkey_plab, pfxl] string capability is the Program function key #1 to type string #2 and show string #3.
+ PkeyPlab
+ // The DeviceType [device_type, devt] string capability is the Indicate language/codeset support.
+ DeviceType
+ // The CodeSetInit [code_set_init, csin] string capability is the Init sequence for multiple codesets.
+ CodeSetInit
+ // The Set0DesSeq [set0_des_seq, s0ds] string capability is the Shift to codeset 0 (EUC set 0, ASCII).
+ Set0DesSeq
+ // The Set1DesSeq [set1_des_seq, s1ds] string capability is the Shift to codeset 1.
+ Set1DesSeq
+ // The Set2DesSeq [set2_des_seq, s2ds] string capability is the Shift to codeset 2.
+ Set2DesSeq
+ // The Set3DesSeq [set3_des_seq, s3ds] string capability is the Shift to codeset 3.
+ Set3DesSeq
+ // The SetLrMargin [set_lr_margin, smglr] string capability is the Set both left and right margins to #1, #2. (ML is not in BSD termcap).
+ SetLrMargin
+ // The SetTbMargin [set_tb_margin, smgtb] string capability is the Sets both top and bottom margins to #1, #2.
+ SetTbMargin
+ // The BitImageRepeat [bit_image_repeat, birep] string capability is the Repeat bit image cell #1 #2 times.
+ BitImageRepeat
+ // The BitImageNewline [bit_image_newline, binel] string capability is the Move to next row of the bit image.
+ BitImageNewline
+ // The BitImageCarriageReturn [bit_image_carriage_return, bicr] string capability is the Move to beginning of same row.
+ BitImageCarriageReturn
+ // The ColorNames [color_names, colornm] string capability is the Give name for color #1.
+ ColorNames
+ // The DefineBitImageRegion [define_bit_image_region, defbi] string capability is the Define rectangular bit image region.
+ DefineBitImageRegion
+ // The EndBitImageRegion [end_bit_image_region, endbi] string capability is the End a bit-image region.
+ EndBitImageRegion
+ // The SetColorBand [set_color_band, setcolor] string capability is the Change to ribbon color #1.
+ SetColorBand
+ // The SetPageLength [set_page_length, slines] string capability is the Set page length to #1 lines.
+ SetPageLength
+ // The DisplayPcChar [display_pc_char, dispc] string capability is the Display PC character #1.
+ DisplayPcChar
+ // The EnterPcCharsetMode [enter_pc_charset_mode, smpch] string capability is the Enter PC character display mode.
+ EnterPcCharsetMode
+ // The ExitPcCharsetMode [exit_pc_charset_mode, rmpch] string capability is the Exit PC character display mode.
+ ExitPcCharsetMode
+ // The EnterScancodeMode [enter_scancode_mode, smsc] string capability is the Enter PC scancode mode.
+ EnterScancodeMode
+ // The ExitScancodeMode [exit_scancode_mode, rmsc] string capability is the Exit PC scancode mode.
+ ExitScancodeMode
+ // The PcTermOptions [pc_term_options, pctrm] string capability is the PC terminal options.
+ PcTermOptions
+ // The ScancodeEscape [scancode_escape, scesc] string capability is the Escape for scancode emulation.
+ ScancodeEscape
+ // The AltScancodeEsc [alt_scancode_esc, scesa] string capability is the Alternate escape for scancode emulation.
+ AltScancodeEsc
+ // The EnterHorizontalHlMode [enter_horizontal_hl_mode, ehhlm] string capability is the Enter horizontal highlight mode.
+ EnterHorizontalHlMode
+ // The EnterLeftHlMode [enter_left_hl_mode, elhlm] string capability is the Enter left highlight mode.
+ EnterLeftHlMode
+ // The EnterLowHlMode [enter_low_hl_mode, elohlm] string capability is the Enter low highlight mode.
+ EnterLowHlMode
+ // The EnterRightHlMode [enter_right_hl_mode, erhlm] string capability is the Enter right highlight mode.
+ EnterRightHlMode
+ // The EnterTopHlMode [enter_top_hl_mode, ethlm] string capability is the Enter top highlight mode.
+ EnterTopHlMode
+ // The EnterVerticalHlMode [enter_vertical_hl_mode, evhlm] string capability is the Enter vertical highlight mode.
+ EnterVerticalHlMode
+ // The SetAAttributes [set_a_attributes, sgr1] string capability is the Define second set of video attributes #1-#6.
+ SetAAttributes
+ // The SetPglenInch [set_pglen_inch, slength] string capability is the Set page length to #1 hundredth of an inch (some implementations use sL for termcap).
+ SetPglenInch
+ // The TermcapInit2 [termcap_init2, OTi2] string capability is the secondary initialization string.
+ TermcapInit2
+ // The TermcapReset [termcap_reset, OTrs] string capability is the terminal reset string.
+ TermcapReset
+ // The LinefeedIfNotLf [linefeed_if_not_lf, OTnl] string capability is the use to move down.
+ LinefeedIfNotLf
+ // The BackspaceIfNotBs [backspace_if_not_bs, OTbc] string capability is the move left, if not ^H.
+ BackspaceIfNotBs
+ // The OtherNonFunctionKeys [other_non_function_keys, OTko] string capability is the list of self-mapped keycaps.
+ OtherNonFunctionKeys
+ // The ArrowKeyMap [arrow_key_map, OTma] string capability is the map motion-keys for vi version 2.
+ ArrowKeyMap
+ // The AcsUlcorner [acs_ulcorner, OTG2] string capability is the single upper left.
+ AcsUlcorner
+ // The AcsLlcorner [acs_llcorner, OTG3] string capability is the single lower left.
+ AcsLlcorner
+ // The AcsUrcorner [acs_urcorner, OTG1] string capability is the single upper right.
+ AcsUrcorner
+ // The AcsLrcorner [acs_lrcorner, OTG4] string capability is the single lower right.
+ AcsLrcorner
+ // The AcsLtee [acs_ltee, OTGR] string capability is the tee pointing right.
+ AcsLtee
+ // The AcsRtee [acs_rtee, OTGL] string capability is the tee pointing left.
+ AcsRtee
+ // The AcsBtee [acs_btee, OTGU] string capability is the tee pointing up.
+ AcsBtee
+ // The AcsTtee [acs_ttee, OTGD] string capability is the tee pointing down.
+ AcsTtee
+ // The AcsHline [acs_hline, OTGH] string capability is the single horizontal line.
+ AcsHline
+ // The AcsVline [acs_vline, OTGV] string capability is the single vertical line.
+ AcsVline
+ // The AcsPlus [acs_plus, OTGC] string capability is the single intersection.
+ AcsPlus
+ // The MemoryLock [memory_lock, meml] string capability is the lock memory above cursor.
+ MemoryLock
+ // The MemoryUnlock [memory_unlock, memu] string capability is the unlock memory.
+ MemoryUnlock
+ // The BoxChars1 [box_chars_1, box1] string capability is the box characters primary set.
+ BoxChars1
+)
+const (
+ // CapCountBool is the count of bool capabilities.
+ CapCountBool = ReturnDoesClrEol + 1
+ // CapCountNum is the count of num capabilities.
+ CapCountNum = NumberOfFunctionKeys + 1
+ // CapCountString is the count of string capabilities.
+ CapCountString = BoxChars1 + 1
+)
+
+// boolCapNames are the bool term cap names.
+var boolCapNames = [...]string{
+ "auto_left_margin", "bw",
+ "auto_right_margin", "am",
+ "no_esc_ctlc", "xsb",
+ "ceol_standout_glitch", "xhp",
+ "eat_newline_glitch", "xenl",
+ "erase_overstrike", "eo",
+ "generic_type", "gn",
+ "hard_copy", "hc",
+ "has_meta_key", "km",
+ "has_status_line", "hs",
+ "insert_null_glitch", "in",
+ "memory_above", "da",
+ "memory_below", "db",
+ "move_insert_mode", "mir",
+ "move_standout_mode", "msgr",
+ "over_strike", "os",
+ "status_line_esc_ok", "eslok",
+ "dest_tabs_magic_smso", "xt",
+ "tilde_glitch", "hz",
+ "transparent_underline", "ul",
+ "xon_xoff", "xon",
+ "needs_xon_xoff", "nxon",
+ "prtr_silent", "mc5i",
+ "hard_cursor", "chts",
+ "non_rev_rmcup", "nrrmc",
+ "no_pad_char", "npc",
+ "non_dest_scroll_region", "ndscr",
+ "can_change", "ccc",
+ "back_color_erase", "bce",
+ "hue_lightness_saturation", "hls",
+ "col_addr_glitch", "xhpa",
+ "cr_cancels_micro_mode", "crxm",
+ "has_print_wheel", "daisy",
+ "row_addr_glitch", "xvpa",
+ "semi_auto_right_margin", "sam",
+ "cpi_changes_res", "cpix",
+ "lpi_changes_res", "lpix",
+ "backspaces_with_bs", "OTbs",
+ "crt_no_scrolling", "OTns",
+ "no_correctly_working_cr", "OTnc",
+ "gnu_has_meta_key", "OTMT",
+ "linefeed_is_newline", "OTNL",
+ "has_hardware_tabs", "OTpt",
+ "return_does_clr_eol", "OTxr",
+}
+
+// numCapNames are the num term cap names.
+var numCapNames = [...]string{
+ "columns", "cols",
+ "init_tabs", "it",
+ "lines", "lines",
+ "lines_of_memory", "lm",
+ "magic_cookie_glitch", "xmc",
+ "padding_baud_rate", "pb",
+ "virtual_terminal", "vt",
+ "width_status_line", "wsl",
+ "num_labels", "nlab",
+ "label_height", "lh",
+ "label_width", "lw",
+ "max_attributes", "ma",
+ "maximum_windows", "wnum",
+ "max_colors", "colors",
+ "max_pairs", "pairs",
+ "no_color_video", "ncv",
+ "buffer_capacity", "bufsz",
+ "dot_vert_spacing", "spinv",
+ "dot_horz_spacing", "spinh",
+ "max_micro_address", "maddr",
+ "max_micro_jump", "mjump",
+ "micro_col_size", "mcs",
+ "micro_line_size", "mls",
+ "number_of_pins", "npins",
+ "output_res_char", "orc",
+ "output_res_line", "orl",
+ "output_res_horz_inch", "orhi",
+ "output_res_vert_inch", "orvi",
+ "print_rate", "cps",
+ "wide_char_size", "widcs",
+ "buttons", "btns",
+ "bit_image_entwining", "bitwin",
+ "bit_image_type", "bitype",
+ "magic_cookie_glitch_ul", "OTug",
+ "carriage_return_delay", "OTdC",
+ "new_line_delay", "OTdN",
+ "backspace_delay", "OTdB",
+ "horizontal_tab_delay", "OTdT",
+ "number_of_function_keys", "OTkn",
+}
+
+// stringCapNames are the string term cap names.
+var stringCapNames = [...]string{
+ "back_tab", "cbt",
+ "bell", "bel",
+ "carriage_return", "cr",
+ "change_scroll_region", "csr",
+ "clear_all_tabs", "tbc",
+ "clear_screen", "clear",
+ "clr_eol", "el",
+ "clr_eos", "ed",
+ "column_address", "hpa",
+ "command_character", "cmdch",
+ "cursor_address", "cup",
+ "cursor_down", "cud1",
+ "cursor_home", "home",
+ "cursor_invisible", "civis",
+ "cursor_left", "cub1",
+ "cursor_mem_address", "mrcup",
+ "cursor_normal", "cnorm",
+ "cursor_right", "cuf1",
+ "cursor_to_ll", "ll",
+ "cursor_up", "cuu1",
+ "cursor_visible", "cvvis",
+ "delete_character", "dch1",
+ "delete_line", "dl1",
+ "dis_status_line", "dsl",
+ "down_half_line", "hd",
+ "enter_alt_charset_mode", "smacs",
+ "enter_blink_mode", "blink",
+ "enter_bold_mode", "bold",
+ "enter_ca_mode", "smcup",
+ "enter_delete_mode", "smdc",
+ "enter_dim_mode", "dim",
+ "enter_insert_mode", "smir",
+ "enter_secure_mode", "invis",
+ "enter_protected_mode", "prot",
+ "enter_reverse_mode", "rev",
+ "enter_standout_mode", "smso",
+ "enter_underline_mode", "smul",
+ "erase_chars", "ech",
+ "exit_alt_charset_mode", "rmacs",
+ "exit_attribute_mode", "sgr0",
+ "exit_ca_mode", "rmcup",
+ "exit_delete_mode", "rmdc",
+ "exit_insert_mode", "rmir",
+ "exit_standout_mode", "rmso",
+ "exit_underline_mode", "rmul",
+ "flash_screen", "flash",
+ "form_feed", "ff",
+ "from_status_line", "fsl",
+ "init_1string", "is1",
+ "init_2string", "is2",
+ "init_3string", "is3",
+ "init_file", "if",
+ "insert_character", "ich1",
+ "insert_line", "il1",
+ "insert_padding", "ip",
+ "key_backspace", "kbs",
+ "key_catab", "ktbc",
+ "key_clear", "kclr",
+ "key_ctab", "kctab",
+ "key_dc", "kdch1",
+ "key_dl", "kdl1",
+ "key_down", "kcud1",
+ "key_eic", "krmir",
+ "key_eol", "kel",
+ "key_eos", "ked",
+ "key_f0", "kf0",
+ "key_f1", "kf1",
+ "key_f10", "kf10",
+ "key_f2", "kf2",
+ "key_f3", "kf3",
+ "key_f4", "kf4",
+ "key_f5", "kf5",
+ "key_f6", "kf6",
+ "key_f7", "kf7",
+ "key_f8", "kf8",
+ "key_f9", "kf9",
+ "key_home", "khome",
+ "key_ic", "kich1",
+ "key_il", "kil1",
+ "key_left", "kcub1",
+ "key_ll", "kll",
+ "key_npage", "knp",
+ "key_ppage", "kpp",
+ "key_right", "kcuf1",
+ "key_sf", "kind",
+ "key_sr", "kri",
+ "key_stab", "khts",
+ "key_up", "kcuu1",
+ "keypad_local", "rmkx",
+ "keypad_xmit", "smkx",
+ "lab_f0", "lf0",
+ "lab_f1", "lf1",
+ "lab_f10", "lf10",
+ "lab_f2", "lf2",
+ "lab_f3", "lf3",
+ "lab_f4", "lf4",
+ "lab_f5", "lf5",
+ "lab_f6", "lf6",
+ "lab_f7", "lf7",
+ "lab_f8", "lf8",
+ "lab_f9", "lf9",
+ "meta_off", "rmm",
+ "meta_on", "smm",
+ "newline", "nel",
+ "pad_char", "pad",
+ "parm_dch", "dch",
+ "parm_delete_line", "dl",
+ "parm_down_cursor", "cud",
+ "parm_ich", "ich",
+ "parm_index", "indn",
+ "parm_insert_line", "il",
+ "parm_left_cursor", "cub",
+ "parm_right_cursor", "cuf",
+ "parm_rindex", "rin",
+ "parm_up_cursor", "cuu",
+ "pkey_key", "pfkey",
+ "pkey_local", "pfloc",
+ "pkey_xmit", "pfx",
+ "print_screen", "mc0",
+ "prtr_off", "mc4",
+ "prtr_on", "mc5",
+ "repeat_char", "rep",
+ "reset_1string", "rs1",
+ "reset_2string", "rs2",
+ "reset_3string", "rs3",
+ "reset_file", "rf",
+ "restore_cursor", "rc",
+ "row_address", "vpa",
+ "save_cursor", "sc",
+ "scroll_forward", "ind",
+ "scroll_reverse", "ri",
+ "set_attributes", "sgr",
+ "set_tab", "hts",
+ "set_window", "wind",
+ "tab", "ht",
+ "to_status_line", "tsl",
+ "underline_char", "uc",
+ "up_half_line", "hu",
+ "init_prog", "iprog",
+ "key_a1", "ka1",
+ "key_a3", "ka3",
+ "key_b2", "kb2",
+ "key_c1", "kc1",
+ "key_c3", "kc3",
+ "prtr_non", "mc5p",
+ "char_padding", "rmp",
+ "acs_chars", "acsc",
+ "plab_norm", "pln",
+ "key_btab", "kcbt",
+ "enter_xon_mode", "smxon",
+ "exit_xon_mode", "rmxon",
+ "enter_am_mode", "smam",
+ "exit_am_mode", "rmam",
+ "xon_character", "xonc",
+ "xoff_character", "xoffc",
+ "ena_acs", "enacs",
+ "label_on", "smln",
+ "label_off", "rmln",
+ "key_beg", "kbeg",
+ "key_cancel", "kcan",
+ "key_close", "kclo",
+ "key_command", "kcmd",
+ "key_copy", "kcpy",
+ "key_create", "kcrt",
+ "key_end", "kend",
+ "key_enter", "kent",
+ "key_exit", "kext",
+ "key_find", "kfnd",
+ "key_help", "khlp",
+ "key_mark", "kmrk",
+ "key_message", "kmsg",
+ "key_move", "kmov",
+ "key_next", "knxt",
+ "key_open", "kopn",
+ "key_options", "kopt",
+ "key_previous", "kprv",
+ "key_print", "kprt",
+ "key_redo", "krdo",
+ "key_reference", "kref",
+ "key_refresh", "krfr",
+ "key_replace", "krpl",
+ "key_restart", "krst",
+ "key_resume", "kres",
+ "key_save", "ksav",
+ "key_suspend", "kspd",
+ "key_undo", "kund",
+ "key_sbeg", "kBEG",
+ "key_scancel", "kCAN",
+ "key_scommand", "kCMD",
+ "key_scopy", "kCPY",
+ "key_screate", "kCRT",
+ "key_sdc", "kDC",
+ "key_sdl", "kDL",
+ "key_select", "kslt",
+ "key_send", "kEND",
+ "key_seol", "kEOL",
+ "key_sexit", "kEXT",
+ "key_sfind", "kFND",
+ "key_shelp", "kHLP",
+ "key_shome", "kHOM",
+ "key_sic", "kIC",
+ "key_sleft", "kLFT",
+ "key_smessage", "kMSG",
+ "key_smove", "kMOV",
+ "key_snext", "kNXT",
+ "key_soptions", "kOPT",
+ "key_sprevious", "kPRV",
+ "key_sprint", "kPRT",
+ "key_sredo", "kRDO",
+ "key_sreplace", "kRPL",
+ "key_sright", "kRIT",
+ "key_srsume", "kRES",
+ "key_ssave", "kSAV",
+ "key_ssuspend", "kSPD",
+ "key_sundo", "kUND",
+ "req_for_input", "rfi",
+ "key_f11", "kf11",
+ "key_f12", "kf12",
+ "key_f13", "kf13",
+ "key_f14", "kf14",
+ "key_f15", "kf15",
+ "key_f16", "kf16",
+ "key_f17", "kf17",
+ "key_f18", "kf18",
+ "key_f19", "kf19",
+ "key_f20", "kf20",
+ "key_f21", "kf21",
+ "key_f22", "kf22",
+ "key_f23", "kf23",
+ "key_f24", "kf24",
+ "key_f25", "kf25",
+ "key_f26", "kf26",
+ "key_f27", "kf27",
+ "key_f28", "kf28",
+ "key_f29", "kf29",
+ "key_f30", "kf30",
+ "key_f31", "kf31",
+ "key_f32", "kf32",
+ "key_f33", "kf33",
+ "key_f34", "kf34",
+ "key_f35", "kf35",
+ "key_f36", "kf36",
+ "key_f37", "kf37",
+ "key_f38", "kf38",
+ "key_f39", "kf39",
+ "key_f40", "kf40",
+ "key_f41", "kf41",
+ "key_f42", "kf42",
+ "key_f43", "kf43",
+ "key_f44", "kf44",
+ "key_f45", "kf45",
+ "key_f46", "kf46",
+ "key_f47", "kf47",
+ "key_f48", "kf48",
+ "key_f49", "kf49",
+ "key_f50", "kf50",
+ "key_f51", "kf51",
+ "key_f52", "kf52",
+ "key_f53", "kf53",
+ "key_f54", "kf54",
+ "key_f55", "kf55",
+ "key_f56", "kf56",
+ "key_f57", "kf57",
+ "key_f58", "kf58",
+ "key_f59", "kf59",
+ "key_f60", "kf60",
+ "key_f61", "kf61",
+ "key_f62", "kf62",
+ "key_f63", "kf63",
+ "clr_bol", "el1",
+ "clear_margins", "mgc",
+ "set_left_margin", "smgl",
+ "set_right_margin", "smgr",
+ "label_format", "fln",
+ "set_clock", "sclk",
+ "display_clock", "dclk",
+ "remove_clock", "rmclk",
+ "create_window", "cwin",
+ "goto_window", "wingo",
+ "hangup", "hup",
+ "dial_phone", "dial",
+ "quick_dial", "qdial",
+ "tone", "tone",
+ "pulse", "pulse",
+ "flash_hook", "hook",
+ "fixed_pause", "pause",
+ "wait_tone", "wait",
+ "user0", "u0",
+ "user1", "u1",
+ "user2", "u2",
+ "user3", "u3",
+ "user4", "u4",
+ "user5", "u5",
+ "user6", "u6",
+ "user7", "u7",
+ "user8", "u8",
+ "user9", "u9",
+ "orig_pair", "op",
+ "orig_colors", "oc",
+ "initialize_color", "initc",
+ "initialize_pair", "initp",
+ "set_color_pair", "scp",
+ "set_foreground", "setf",
+ "set_background", "setb",
+ "change_char_pitch", "cpi",
+ "change_line_pitch", "lpi",
+ "change_res_horz", "chr",
+ "change_res_vert", "cvr",
+ "define_char", "defc",
+ "enter_doublewide_mode", "swidm",
+ "enter_draft_quality", "sdrfq",
+ "enter_italics_mode", "sitm",
+ "enter_leftward_mode", "slm",
+ "enter_micro_mode", "smicm",
+ "enter_near_letter_quality", "snlq",
+ "enter_normal_quality", "snrmq",
+ "enter_shadow_mode", "sshm",
+ "enter_subscript_mode", "ssubm",
+ "enter_superscript_mode", "ssupm",
+ "enter_upward_mode", "sum",
+ "exit_doublewide_mode", "rwidm",
+ "exit_italics_mode", "ritm",
+ "exit_leftward_mode", "rlm",
+ "exit_micro_mode", "rmicm",
+ "exit_shadow_mode", "rshm",
+ "exit_subscript_mode", "rsubm",
+ "exit_superscript_mode", "rsupm",
+ "exit_upward_mode", "rum",
+ "micro_column_address", "mhpa",
+ "micro_down", "mcud1",
+ "micro_left", "mcub1",
+ "micro_right", "mcuf1",
+ "micro_row_address", "mvpa",
+ "micro_up", "mcuu1",
+ "order_of_pins", "porder",
+ "parm_down_micro", "mcud",
+ "parm_left_micro", "mcub",
+ "parm_right_micro", "mcuf",
+ "parm_up_micro", "mcuu",
+ "select_char_set", "scs",
+ "set_bottom_margin", "smgb",
+ "set_bottom_margin_parm", "smgbp",
+ "set_left_margin_parm", "smglp",
+ "set_right_margin_parm", "smgrp",
+ "set_top_margin", "smgt",
+ "set_top_margin_parm", "smgtp",
+ "start_bit_image", "sbim",
+ "start_char_set_def", "scsd",
+ "stop_bit_image", "rbim",
+ "stop_char_set_def", "rcsd",
+ "subscript_characters", "subcs",
+ "superscript_characters", "supcs",
+ "these_cause_cr", "docr",
+ "zero_motion", "zerom",
+ "char_set_names", "csnm",
+ "key_mouse", "kmous",
+ "mouse_info", "minfo",
+ "req_mouse_pos", "reqmp",
+ "get_mouse", "getm",
+ "set_a_foreground", "setaf",
+ "set_a_background", "setab",
+ "pkey_plab", "pfxl",
+ "device_type", "devt",
+ "code_set_init", "csin",
+ "set0_des_seq", "s0ds",
+ "set1_des_seq", "s1ds",
+ "set2_des_seq", "s2ds",
+ "set3_des_seq", "s3ds",
+ "set_lr_margin", "smglr",
+ "set_tb_margin", "smgtb",
+ "bit_image_repeat", "birep",
+ "bit_image_newline", "binel",
+ "bit_image_carriage_return", "bicr",
+ "color_names", "colornm",
+ "define_bit_image_region", "defbi",
+ "end_bit_image_region", "endbi",
+ "set_color_band", "setcolor",
+ "set_page_length", "slines",
+ "display_pc_char", "dispc",
+ "enter_pc_charset_mode", "smpch",
+ "exit_pc_charset_mode", "rmpch",
+ "enter_scancode_mode", "smsc",
+ "exit_scancode_mode", "rmsc",
+ "pc_term_options", "pctrm",
+ "scancode_escape", "scesc",
+ "alt_scancode_esc", "scesa",
+ "enter_horizontal_hl_mode", "ehhlm",
+ "enter_left_hl_mode", "elhlm",
+ "enter_low_hl_mode", "elohlm",
+ "enter_right_hl_mode", "erhlm",
+ "enter_top_hl_mode", "ethlm",
+ "enter_vertical_hl_mode", "evhlm",
+ "set_a_attributes", "sgr1",
+ "set_pglen_inch", "slength",
+ "termcap_init2", "OTi2",
+ "termcap_reset", "OTrs",
+ "linefeed_if_not_lf", "OTnl",
+ "backspace_if_not_bs", "OTbc",
+ "other_non_function_keys", "OTko",
+ "arrow_key_map", "OTma",
+ "acs_ulcorner", "OTG2",
+ "acs_llcorner", "OTG3",
+ "acs_urcorner", "OTG1",
+ "acs_lrcorner", "OTG4",
+ "acs_ltee", "OTGR",
+ "acs_rtee", "OTGL",
+ "acs_btee", "OTGU",
+ "acs_ttee", "OTGD",
+ "acs_hline", "OTGH",
+ "acs_vline", "OTGV",
+ "acs_plus", "OTGC",
+ "memory_lock", "meml",
+ "memory_unlock", "memu",
+ "box_chars_1", "box1",
+}
diff --git a/vendor/github.com/xo/terminfo/color.go b/vendor/github.com/xo/terminfo/color.go
new file mode 100644
index 00000000..76c439fc
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/color.go
@@ -0,0 +1,88 @@
+package terminfo
+
+import (
+ "os"
+ "strconv"
+ "strings"
+)
+
+// ColorLevel is the color level supported by a terminal.
+type ColorLevel uint
+
+// ColorLevel values.
+const (
+ ColorLevelNone ColorLevel = iota
+ ColorLevelBasic
+ ColorLevelHundreds
+ ColorLevelMillions
+)
+
+// String satisfies the Stringer interface.
+func (c ColorLevel) String() string {
+ switch c {
+ case ColorLevelBasic:
+ return "basic"
+ case ColorLevelHundreds:
+ return "hundreds"
+ case ColorLevelMillions:
+ return "millions"
+ }
+ return "none"
+}
+
+// ChromaFormatterName returns the github.com/alecthomas/chroma compatible
+// formatter name for the color level.
+func (c ColorLevel) ChromaFormatterName() string {
+ switch c {
+ case ColorLevelBasic:
+ return "terminal"
+ case ColorLevelHundreds:
+ return "terminal256"
+ case ColorLevelMillions:
+ return "terminal16m"
+ }
+ return "noop"
+}
+
+// ColorLevelFromEnv returns the color level COLORTERM, FORCE_COLOR,
+// TERM_PROGRAM, or determined from the TERM environment variable.
+func ColorLevelFromEnv() (ColorLevel, error) {
+ // 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") || termProg == "Hyper":
+ return ColorLevelMillions, nil
+ case colorTerm != "" || forceColor != "":
+ return ColorLevelBasic, nil
+ case termProg == "Apple_Terminal":
+ return ColorLevelHundreds, nil
+ case termProg == "iTerm.app":
+ ver := os.Getenv("TERM_PROGRAM_VERSION")
+ if ver == "" {
+ return ColorLevelHundreds, nil
+ }
+ i, err := strconv.Atoi(strings.Split(ver, ".")[0])
+ if err != nil {
+ return ColorLevelNone, ErrInvalidTermProgramVersion
+ }
+ if i == 3 {
+ return ColorLevelMillions, nil
+ }
+ return ColorLevelHundreds, nil
+ }
+ // otherwise determine from TERM's max_colors capability
+ if term := os.Getenv("TERM"); term != "" {
+ ti, err := Load(term)
+ if err != nil {
+ return ColorLevelNone, err
+ }
+ v, ok := ti.Nums[MaxColors]
+ switch {
+ case !ok || v <= 16:
+ return ColorLevelNone, nil
+ case ok && v >= 256:
+ return ColorLevelHundreds, nil
+ }
+ }
+ return ColorLevelBasic, nil
+}
diff --git a/vendor/github.com/xo/terminfo/dec.go b/vendor/github.com/xo/terminfo/dec.go
new file mode 100644
index 00000000..dacc88e3
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/dec.go
@@ -0,0 +1,245 @@
+package terminfo
+
+import (
+ "sort"
+)
+
+const (
+ // maxFileLength is the max file length.
+ maxFileLength = 4096
+ // magic is the file magic for terminfo files.
+ magic = 0o432
+ // magicExtended is the file magic for terminfo files with the extended
+ // number format.
+ magicExtended = 0o1036
+)
+
+// header fields.
+const (
+ fieldMagic = iota
+ fieldNameSize
+ fieldBoolCount
+ fieldNumCount
+ fieldStringCount
+ fieldTableSize
+)
+
+// header extended fields.
+const (
+ fieldExtBoolCount = iota
+ fieldExtNumCount
+ fieldExtStringCount
+ fieldExtOffsetCount
+ fieldExtTableSize
+)
+
+// hasInvalidCaps determines if the capabilities in h are invalid.
+func hasInvalidCaps(h []int) bool {
+ return h[fieldBoolCount] > CapCountBool ||
+ h[fieldNumCount] > CapCountNum ||
+ h[fieldStringCount] > CapCountString
+}
+
+// capLength returns the total length of the capabilities in bytes.
+func capLength(h []int) int {
+ return h[fieldNameSize] +
+ h[fieldBoolCount] +
+ (h[fieldNameSize]+h[fieldBoolCount])%2 + // account for word align
+ h[fieldNumCount]*2 +
+ h[fieldStringCount]*2 +
+ h[fieldTableSize]
+}
+
+// hasInvalidExtOffset determines if the extended offset field is valid.
+func hasInvalidExtOffset(h []int) bool {
+ return h[fieldExtBoolCount]+
+ h[fieldExtNumCount]+
+ h[fieldExtStringCount]*2 != h[fieldExtOffsetCount]
+}
+
+// extCapLength returns the total length of extended capabilities in bytes.
+func extCapLength(h []int, numWidth int) int {
+ return h[fieldExtBoolCount] +
+ h[fieldExtBoolCount]%2 + // account for word align
+ h[fieldExtNumCount]*(numWidth/8) +
+ h[fieldExtOffsetCount]*2 +
+ h[fieldExtTableSize]
+}
+
+// findNull finds the position of null in buf.
+func findNull(buf []byte, i int) int {
+ for ; i < len(buf); i++ {
+ if buf[i] == 0 {
+ return i
+ }
+ }
+ return -1
+}
+
+// readStrings decodes n strings from string data table buf using the indexes in idx.
+func readStrings(idx []int, buf []byte, n int) (map[int][]byte, int, error) {
+ var last int
+ m := make(map[int][]byte)
+ for i := 0; i < n; i++ {
+ start := idx[i]
+ if start < 0 {
+ continue
+ }
+ if end := findNull(buf, start); end != -1 {
+ m[i], last = buf[start:end], end+1
+ } else {
+ return nil, 0, ErrInvalidStringTable
+ }
+ }
+ return m, last, nil
+}
+
+// decoder holds state info while decoding a terminfo file.
+type decoder struct {
+ buf []byte
+ pos int
+ n int
+}
+
+// readBytes reads the next n bytes of buf, incrementing pos by n.
+func (d *decoder) readBytes(n int) ([]byte, error) {
+ if d.n < d.pos+n {
+ return nil, ErrUnexpectedFileEnd
+ }
+ n, d.pos = d.pos, d.pos+n
+ return d.buf[n:d.pos], nil
+}
+
+// readInts reads n number of ints with width w.
+func (d *decoder) readInts(n, w int) ([]int, error) {
+ w /= 8
+ l := n * w
+ buf, err := d.readBytes(l)
+ if err != nil {
+ return nil, err
+ }
+ // align
+ d.pos += d.pos % 2
+ z := make([]int, n)
+ for i, j := 0, 0; i < l; i, j = i+w, j+1 {
+ switch w {
+ case 1:
+ z[i] = int(buf[i])
+ case 2:
+ z[j] = int(int16(buf[i+1])<<8 | int16(buf[i]))
+ case 4:
+ z[j] = int(buf[i+3])<<24 | int(buf[i+2])<<16 | int(buf[i+1])<<8 | int(buf[i])
+ }
+ }
+ return z, nil
+}
+
+// readBools reads the next n bools.
+func (d *decoder) readBools(n int) (map[int]bool, map[int]bool, error) {
+ buf, err := d.readInts(n, 8)
+ if err != nil {
+ return nil, nil, err
+ }
+ // process
+ bools, boolsM := make(map[int]bool), make(map[int]bool)
+ for i, b := range buf {
+ bools[i] = b == 1
+ if int8(b) == -2 {
+ boolsM[i] = true
+ }
+ }
+ return bools, boolsM, nil
+}
+
+// readNums reads the next n nums.
+func (d *decoder) readNums(n, w int) (map[int]int, map[int]bool, error) {
+ buf, err := d.readInts(n, w)
+ if err != nil {
+ return nil, nil, err
+ }
+ // process
+ nums, numsM := make(map[int]int), make(map[int]bool)
+ for i := 0; i < n; i++ {
+ nums[i] = buf[i]
+ if buf[i] == -2 {
+ numsM[i] = true
+ }
+ }
+ return nums, numsM, nil
+}
+
+// readStringTable reads the string data for n strings and the accompanying data
+// table of length sz.
+func (d *decoder) readStringTable(n, sz int) ([][]byte, []int, error) {
+ buf, err := d.readInts(n, 16)
+ if err != nil {
+ return nil, nil, err
+ }
+ // read string data table
+ data, err := d.readBytes(sz)
+ if err != nil {
+ return nil, nil, err
+ }
+ // align
+ d.pos += d.pos % 2
+ // process
+ s := make([][]byte, n)
+ var m []int
+ for i := 0; i < n; i++ {
+ start := buf[i]
+ if start == -2 {
+ m = append(m, i)
+ } else if start >= 0 {
+ if end := findNull(data, start); end != -1 {
+ s[i] = data[start:end]
+ } else {
+ return nil, nil, ErrInvalidStringTable
+ }
+ }
+ }
+ return s, m, nil
+}
+
+// readStrings reads the next n strings and processes the string data table of
+// length sz.
+func (d *decoder) readStrings(n, sz int) (map[int][]byte, map[int]bool, error) {
+ s, m, err := d.readStringTable(n, sz)
+ if err != nil {
+ return nil, nil, err
+ }
+ strs := make(map[int][]byte)
+ for k, v := range s {
+ if k == AcsChars {
+ v = canonicalizeAscChars(v)
+ }
+ strs[k] = v
+ }
+ strsM := make(map[int]bool, len(m))
+ for _, k := range m {
+ strsM[k] = true
+ }
+ return strs, strsM, nil
+}
+
+// canonicalizeAscChars reorders chars to be unique, in order.
+//
+// see repair_ascc in ncurses-6.3/progs/dump_entry.c
+func canonicalizeAscChars(z []byte) []byte {
+ var c []byte
+ enc := make(map[byte]byte, len(z)/2)
+ for i := 0; i < len(z); i += 2 {
+ if _, ok := enc[z[i]]; !ok {
+ a, b := z[i], z[i+1]
+ // log.Printf(">>> a: %d %c, b: %d %c", a, a, b, b)
+ c, enc[a] = append(c, b), b
+ }
+ }
+ sort.Slice(c, func(i, j int) bool {
+ return c[i] < c[j]
+ })
+ r := make([]byte, 2*len(c))
+ for i := 0; i < len(c); i++ {
+ r[i*2], r[i*2+1] = c[i], enc[c[i]]
+ }
+ return r
+}
diff --git a/vendor/github.com/xo/terminfo/load.go b/vendor/github.com/xo/terminfo/load.go
new file mode 100644
index 00000000..d7cd266c
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/load.go
@@ -0,0 +1,64 @@
+package terminfo
+
+import (
+ "os"
+ "os/user"
+ "path"
+ "strings"
+ "sync"
+)
+
+// termCache is the terminfo cache.
+var termCache = struct {
+ db map[string]*Terminfo
+ sync.RWMutex
+}{
+ db: make(map[string]*Terminfo),
+}
+
+// Load follows the behavior described in terminfo(5) to find correct the
+// terminfo file using the name, reads the file and then returns a Terminfo
+// struct that describes the file.
+func Load(name string) (*Terminfo, error) {
+ if name == "" {
+ return nil, ErrEmptyTermName
+ }
+ termCache.RLock()
+ ti, ok := termCache.db[name]
+ termCache.RUnlock()
+ if ok {
+ return ti, nil
+ }
+ var checkDirs []string
+ // check $TERMINFO
+ if dir := os.Getenv("TERMINFO"); dir != "" {
+ checkDirs = append(checkDirs, dir)
+ }
+ // check $HOME/.terminfo
+ u, err := user.Current()
+ if err != nil {
+ return nil, err
+ }
+ checkDirs = append(checkDirs, path.Join(u.HomeDir, ".terminfo"))
+ // check $TERMINFO_DIRS
+ if dirs := os.Getenv("TERMINFO_DIRS"); dirs != "" {
+ checkDirs = append(checkDirs, strings.Split(dirs, ":")...)
+ }
+ // check fallback directories
+ checkDirs = append(checkDirs, "/etc/terminfo", "/lib/terminfo", "/usr/share/terminfo")
+ for _, dir := range checkDirs {
+ ti, err = Open(dir, name)
+ if err != nil && err != ErrFileNotFound && !os.IsNotExist(err) {
+ return nil, err
+ } else if err == nil {
+ return ti, nil
+ }
+ }
+ return nil, ErrDatabaseDirectoryNotFound
+}
+
+// LoadFromEnv loads the terminal info based on the name contained in
+// environment variable TERM.
+func LoadFromEnv() (*Terminfo, error) {
+ return Load(os.Getenv("TERM"))
+}
diff --git a/vendor/github.com/xo/terminfo/param.go b/vendor/github.com/xo/terminfo/param.go
new file mode 100644
index 00000000..ed4cb86b
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/param.go
@@ -0,0 +1,405 @@
+package terminfo
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+ "sync"
+)
+
+// parametizer represents the a scan state for a parameterized string.
+type parametizer struct {
+ // z is the string to parameterize
+ z []byte
+ // pos is the current position in s.
+ pos int
+ // nest is the current nest level.
+ nest int
+ // s is the variable stack.
+ s stack
+ // skipElse keeps the state of skipping else.
+ skipElse bool
+ // buf is the result buffer.
+ buf *bytes.Buffer
+ // params are the parameters to interpolate.
+ params [9]interface{}
+ // vars are dynamic variables.
+ vars [26]interface{}
+}
+
+// staticVars are the static, global variables.
+var staticVars = struct {
+ vars [26]interface{}
+ sync.Mutex
+}{}
+
+var parametizerPool = sync.Pool{
+ New: func() interface{} {
+ p := new(parametizer)
+ p.buf = bytes.NewBuffer(make([]byte, 0, 45))
+ return p
+ },
+}
+
+// newParametizer returns a new initialized parametizer from the pool.
+func newParametizer(z []byte) *parametizer {
+ p := parametizerPool.Get().(*parametizer)
+ p.z = z
+ return p
+}
+
+// reset resets the parametizer.
+func (p *parametizer) reset() {
+ p.pos, p.nest = 0, 0
+ p.s.reset()
+ p.buf.Reset()
+ p.params, p.vars = [9]interface{}{}, [26]interface{}{}
+ parametizerPool.Put(p)
+}
+
+// stateFn represents the state of the scanner as a function that returns the
+// next state.
+type stateFn func() stateFn
+
+// exec executes the parameterizer, interpolating the supplied parameters.
+func (p *parametizer) exec() string {
+ for state := p.scanTextFn; state != nil; {
+ state = state()
+ }
+ return p.buf.String()
+}
+
+// peek returns the next byte.
+func (p *parametizer) peek() (byte, error) {
+ if p.pos >= len(p.z) {
+ return 0, io.EOF
+ }
+ return p.z[p.pos], nil
+}
+
+// writeFrom writes the characters from ppos to pos to the buffer.
+func (p *parametizer) writeFrom(ppos int) {
+ if p.pos > ppos {
+ // append remaining characters.
+ p.buf.Write(p.z[ppos:p.pos])
+ }
+}
+
+func (p *parametizer) scanTextFn() stateFn {
+ ppos := p.pos
+ for {
+ ch, err := p.peek()
+ if err != nil {
+ p.writeFrom(ppos)
+ return nil
+ }
+ if ch == '%' {
+ p.writeFrom(ppos)
+ p.pos++
+ return p.scanCodeFn
+ }
+ p.pos++
+ }
+}
+
+func (p *parametizer) scanCodeFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ switch ch {
+ case '%':
+ p.buf.WriteByte('%')
+ case ':':
+ // this character is used to avoid interpreting "%-" and "%+" as operators.
+ // the next character is where the format really begins.
+ p.pos++
+ _, err = p.peek()
+ if err != nil {
+ return nil
+ }
+ return p.scanFormatFn
+ case '#', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.':
+ return p.scanFormatFn
+ case 'o':
+ p.buf.WriteString(strconv.FormatInt(int64(p.s.popInt()), 8))
+ case 'd':
+ p.buf.WriteString(strconv.Itoa(p.s.popInt()))
+ case 'x':
+ p.buf.WriteString(strconv.FormatInt(int64(p.s.popInt()), 16))
+ case 'X':
+ p.buf.WriteString(strings.ToUpper(strconv.FormatInt(int64(p.s.popInt()), 16)))
+ case 's':
+ p.buf.WriteString(p.s.popString())
+ case 'c':
+ p.buf.WriteByte(p.s.popByte())
+ case 'p':
+ p.pos++
+ return p.pushParamFn
+ case 'P':
+ p.pos++
+ return p.setDsVarFn
+ case 'g':
+ p.pos++
+ return p.getDsVarFn
+ case '\'':
+ p.pos++
+ ch, err = p.peek()
+ if err != nil {
+ return nil
+ }
+ p.s.push(ch)
+ // skip the '\''
+ p.pos++
+ case '{':
+ p.pos++
+ return p.pushIntfn
+ case 'l':
+ p.s.push(len(p.s.popString()))
+ case '+':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai + bi)
+ case '-':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai - bi)
+ case '*':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai * bi)
+ case '/':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ if bi != 0 {
+ p.s.push(ai / bi)
+ } else {
+ p.s.push(0)
+ }
+ case 'm':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ if bi != 0 {
+ p.s.push(ai % bi)
+ } else {
+ p.s.push(0)
+ }
+ case '&':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai & bi)
+ case '|':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai | bi)
+ case '^':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai ^ bi)
+ case '=':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai == bi)
+ case '>':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai > bi)
+ case '<':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai < bi)
+ case 'A':
+ bi, ai := p.s.popBool(), p.s.popBool()
+ p.s.push(ai && bi)
+ case 'O':
+ bi, ai := p.s.popBool(), p.s.popBool()
+ p.s.push(ai || bi)
+ case '!':
+ p.s.push(!p.s.popBool())
+ case '~':
+ p.s.push(^p.s.popInt())
+ case 'i':
+ for i := range p.params[:2] {
+ if n, ok := p.params[i].(int); ok {
+ p.params[i] = n + 1
+ }
+ }
+ case '?', ';':
+ case 't':
+ return p.scanThenFn
+ case 'e':
+ p.skipElse = true
+ return p.skipTextFn
+ }
+ p.pos++
+ return p.scanTextFn
+}
+
+func (p *parametizer) scanFormatFn() stateFn {
+ // the character was already read, so no need to check the error.
+ ch, _ := p.peek()
+ // 6 should be the maximum length of a format string, for example "%:-9.9d".
+ f := []byte{'%', ch, 0, 0, 0, 0}
+ var err error
+ for {
+ p.pos++
+ ch, err = p.peek()
+ if err != nil {
+ return nil
+ }
+ f = append(f, ch)
+ switch ch {
+ case 'o', 'd', 'x', 'X':
+ fmt.Fprintf(p.buf, string(f), p.s.popInt())
+ break
+ case 's':
+ fmt.Fprintf(p.buf, string(f), p.s.popString())
+ break
+ case 'c':
+ fmt.Fprintf(p.buf, string(f), p.s.popByte())
+ break
+ }
+ }
+ p.pos++
+ return p.scanTextFn
+}
+
+func (p *parametizer) pushParamFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ if ai := int(ch - '1'); ai >= 0 && ai < len(p.params) {
+ p.s.push(p.params[ai])
+ } else {
+ p.s.push(0)
+ }
+ // skip the '}'
+ p.pos++
+ return p.scanTextFn
+}
+
+func (p *parametizer) setDsVarFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ if ch >= 'A' && ch <= 'Z' {
+ staticVars.Lock()
+ staticVars.vars[int(ch-'A')] = p.s.pop()
+ staticVars.Unlock()
+ } else if ch >= 'a' && ch <= 'z' {
+ p.vars[int(ch-'a')] = p.s.pop()
+ }
+ p.pos++
+ return p.scanTextFn
+}
+
+func (p *parametizer) getDsVarFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ var a byte
+ if ch >= 'A' && ch <= 'Z' {
+ a = 'A'
+ } else if ch >= 'a' && ch <= 'z' {
+ a = 'a'
+ }
+ staticVars.Lock()
+ p.s.push(staticVars.vars[int(ch-a)])
+ staticVars.Unlock()
+ p.pos++
+ return p.scanTextFn
+}
+
+func (p *parametizer) pushIntfn() stateFn {
+ var ai int
+ for {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ p.pos++
+ if ch < '0' || ch > '9' {
+ p.s.push(ai)
+ return p.scanTextFn
+ }
+ ai = (ai * 10) + int(ch-'0')
+ }
+}
+
+func (p *parametizer) scanThenFn() stateFn {
+ p.pos++
+ if p.s.popBool() {
+ return p.scanTextFn
+ }
+ p.skipElse = false
+ return p.skipTextFn
+}
+
+func (p *parametizer) skipTextFn() stateFn {
+ for {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ p.pos++
+ if ch == '%' {
+ break
+ }
+ }
+ if p.skipElse {
+ return p.skipElseFn
+ }
+ return p.skipThenFn
+}
+
+func (p *parametizer) skipThenFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ p.pos++
+ switch ch {
+ case ';':
+ if p.nest == 0 {
+ return p.scanTextFn
+ }
+ p.nest--
+ case '?':
+ p.nest++
+ case 'e':
+ if p.nest == 0 {
+ return p.scanTextFn
+ }
+ }
+ return p.skipTextFn
+}
+
+func (p *parametizer) skipElseFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ p.pos++
+ switch ch {
+ case ';':
+ if p.nest == 0 {
+ return p.scanTextFn
+ }
+ p.nest--
+ case '?':
+ p.nest++
+ }
+ return p.skipTextFn
+}
+
+// Printf evaluates a parameterized terminfo value z, interpolating params.
+func Printf(z []byte, params ...interface{}) string {
+ p := newParametizer(z)
+ defer p.reset()
+ // make sure we always have 9 parameters -- makes it easier
+ // later to skip checks and its faster
+ for i := 0; i < len(p.params) && i < len(params); i++ {
+ p.params[i] = params[i]
+ }
+ return p.exec()
+}
+
+// Fprintf evaluates a parameterized terminfo value z, interpolating params and
+// writing to w.
+func Fprintf(w io.Writer, z []byte, params ...interface{}) {
+ w.Write([]byte(Printf(z, params...)))
+}
diff --git a/vendor/github.com/xo/terminfo/stack.go b/vendor/github.com/xo/terminfo/stack.go
new file mode 100644
index 00000000..a6de3950
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/stack.go
@@ -0,0 +1,48 @@
+package terminfo
+
+type stack []interface{}
+
+func (s *stack) push(v interface{}) {
+ *s = append(*s, v)
+}
+
+func (s *stack) pop() interface{} {
+ if len(*s) == 0 {
+ return nil
+ }
+ v := (*s)[len(*s)-1]
+ *s = (*s)[:len(*s)-1]
+ return v
+}
+
+func (s *stack) popInt() int {
+ if i, ok := s.pop().(int); ok {
+ return i
+ }
+ return 0
+}
+
+func (s *stack) popBool() bool {
+ if b, ok := s.pop().(bool); ok {
+ return b
+ }
+ return false
+}
+
+func (s *stack) popByte() byte {
+ if b, ok := s.pop().(byte); ok {
+ return b
+ }
+ return 0
+}
+
+func (s *stack) popString() string {
+ if a, ok := s.pop().(string); ok {
+ return a
+ }
+ return ""
+}
+
+func (s *stack) reset() {
+ *s = (*s)[:0]
+}
diff --git a/vendor/github.com/xo/terminfo/terminfo.go b/vendor/github.com/xo/terminfo/terminfo.go
new file mode 100644
index 00000000..69e3b606
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/terminfo.go
@@ -0,0 +1,479 @@
+// Package terminfo implements reading terminfo files in pure go.
+package terminfo
+
+//go:generate go run gen.go
+
+import (
+ "io"
+ "io/ioutil"
+ "path"
+ "strconv"
+ "strings"
+)
+
+// Error is a terminfo error.
+type Error string
+
+// Error satisfies the error interface.
+func (err Error) Error() string {
+ return string(err)
+}
+
+const (
+ // ErrInvalidFileSize is the invalid file size error.
+ ErrInvalidFileSize Error = "invalid file size"
+ // ErrUnexpectedFileEnd is the unexpected file end error.
+ ErrUnexpectedFileEnd Error = "unexpected file end"
+ // ErrInvalidStringTable is the invalid string table error.
+ ErrInvalidStringTable Error = "invalid string table"
+ // ErrInvalidMagic is the invalid magic error.
+ ErrInvalidMagic Error = "invalid magic"
+ // ErrInvalidHeader is the invalid header error.
+ ErrInvalidHeader Error = "invalid header"
+ // ErrInvalidNames is the invalid names error.
+ ErrInvalidNames Error = "invalid names"
+ // ErrInvalidExtendedHeader is the invalid extended header error.
+ ErrInvalidExtendedHeader Error = "invalid extended header"
+ // ErrEmptyTermName is the empty term name error.
+ ErrEmptyTermName Error = "empty term name"
+ // ErrDatabaseDirectoryNotFound is the database directory not found error.
+ ErrDatabaseDirectoryNotFound Error = "database directory not found"
+ // ErrFileNotFound is the file not found error.
+ ErrFileNotFound Error = "file not found"
+ // ErrInvalidTermProgramVersion is the invalid TERM_PROGRAM_VERSION error.
+ ErrInvalidTermProgramVersion Error = "invalid TERM_PROGRAM_VERSION"
+)
+
+// Terminfo describes a terminal's capabilities.
+type Terminfo struct {
+ // File is the original source file.
+ File string
+ // Names are the provided cap names.
+ Names []string
+ // Bools are the bool capabilities.
+ Bools map[int]bool
+ // BoolsM are the missing bool capabilities.
+ BoolsM map[int]bool
+ // Nums are the num capabilities.
+ Nums map[int]int
+ // NumsM are the missing num capabilities.
+ NumsM map[int]bool
+ // Strings are the string capabilities.
+ Strings map[int][]byte
+ // StringsM are the missing string capabilities.
+ StringsM map[int]bool
+ // ExtBools are the extended bool capabilities.
+ ExtBools map[int]bool
+ // ExtBoolsNames is the map of extended bool capabilities to their index.
+ ExtBoolNames map[int][]byte
+ // ExtNums are the extended num capabilities.
+ ExtNums map[int]int
+ // ExtNumsNames is the map of extended num capabilities to their index.
+ ExtNumNames map[int][]byte
+ // ExtStrings are the extended string capabilities.
+ ExtStrings map[int][]byte
+ // ExtStringsNames is the map of extended string capabilities to their index.
+ ExtStringNames map[int][]byte
+}
+
+// Decode decodes the terminfo data contained in buf.
+func Decode(buf []byte) (*Terminfo, error) {
+ var err error
+ // check max file length
+ if len(buf) >= maxFileLength {
+ return nil, ErrInvalidFileSize
+ }
+ d := &decoder{
+ buf: buf,
+ n: len(buf),
+ }
+ // read header
+ h, err := d.readInts(6, 16)
+ if err != nil {
+ return nil, err
+ }
+ var numWidth int
+ // check magic
+ switch {
+ case h[fieldMagic] == magic:
+ numWidth = 16
+ case h[fieldMagic] == magicExtended:
+ numWidth = 32
+ default:
+ return nil, ErrInvalidMagic
+ }
+ // check header
+ if hasInvalidCaps(h) {
+ return nil, ErrInvalidHeader
+ }
+ // check remaining length
+ if d.n-d.pos < capLength(h) {
+ return nil, ErrUnexpectedFileEnd
+ }
+ // read names
+ names, err := d.readBytes(h[fieldNameSize])
+ if err != nil {
+ return nil, err
+ }
+ // check name is terminated properly
+ i := findNull(names, 0)
+ if i == -1 {
+ return nil, ErrInvalidNames
+ }
+ names = names[:i]
+ // read bool caps
+ bools, boolsM, err := d.readBools(h[fieldBoolCount])
+ if err != nil {
+ return nil, err
+ }
+ // read num caps
+ nums, numsM, err := d.readNums(h[fieldNumCount], numWidth)
+ if err != nil {
+ return nil, err
+ }
+ // read string caps
+ strs, strsM, err := d.readStrings(h[fieldStringCount], h[fieldTableSize])
+ if err != nil {
+ return nil, err
+ }
+ ti := &Terminfo{
+ Names: strings.Split(string(names), "|"),
+ Bools: bools,
+ BoolsM: boolsM,
+ Nums: nums,
+ NumsM: numsM,
+ Strings: strs,
+ StringsM: strsM,
+ }
+ // at the end of file, so no extended caps
+ if d.pos >= d.n {
+ return ti, nil
+ }
+ // decode extended header
+ eh, err := d.readInts(5, 16)
+ if err != nil {
+ return nil, err
+ }
+ // check extended offset field
+ if hasInvalidExtOffset(eh) {
+ return nil, ErrInvalidExtendedHeader
+ }
+ // check extended cap lengths
+ if d.n-d.pos != extCapLength(eh, numWidth) {
+ return nil, ErrInvalidExtendedHeader
+ }
+ // read extended bool caps
+ ti.ExtBools, _, err = d.readBools(eh[fieldExtBoolCount])
+ if err != nil {
+ return nil, err
+ }
+ // read extended num caps
+ ti.ExtNums, _, err = d.readNums(eh[fieldExtNumCount], numWidth)
+ if err != nil {
+ return nil, err
+ }
+ // read extended string data table indexes
+ extIndexes, err := d.readInts(eh[fieldExtOffsetCount], 16)
+ if err != nil {
+ return nil, err
+ }
+ // read string data table
+ extData, err := d.readBytes(eh[fieldExtTableSize])
+ if err != nil {
+ return nil, err
+ }
+ // precautionary check that exactly at end of file
+ if d.pos != d.n {
+ return nil, ErrUnexpectedFileEnd
+ }
+ var last int
+ // read extended string caps
+ ti.ExtStrings, last, err = readStrings(extIndexes, extData, eh[fieldExtStringCount])
+ if err != nil {
+ return nil, err
+ }
+ extIndexes, extData = extIndexes[eh[fieldExtStringCount]:], extData[last:]
+ // read extended bool names
+ ti.ExtBoolNames, _, err = readStrings(extIndexes, extData, eh[fieldExtBoolCount])
+ if err != nil {
+ return nil, err
+ }
+ extIndexes = extIndexes[eh[fieldExtBoolCount]:]
+ // read extended num names
+ ti.ExtNumNames, _, err = readStrings(extIndexes, extData, eh[fieldExtNumCount])
+ if err != nil {
+ return nil, err
+ }
+ extIndexes = extIndexes[eh[fieldExtNumCount]:]
+ // read extended string names
+ ti.ExtStringNames, _, err = readStrings(extIndexes, extData, eh[fieldExtStringCount])
+ if err != nil {
+ return nil, err
+ }
+ // extIndexes = extIndexes[eh[fieldExtStringCount]:]
+ return ti, nil
+}
+
+// Open reads the terminfo file name from the specified directory dir.
+func Open(dir, name string) (*Terminfo, error) {
+ var err error
+ var buf []byte
+ var filename string
+ for _, f := range []string{
+ path.Join(dir, name[0:1], name),
+ path.Join(dir, strconv.FormatUint(uint64(name[0]), 16), name),
+ } {
+ buf, err = ioutil.ReadFile(f)
+ if err == nil {
+ filename = f
+ break
+ }
+ }
+ if buf == nil {
+ return nil, ErrFileNotFound
+ }
+ // decode
+ ti, err := Decode(buf)
+ if err != nil {
+ return nil, err
+ }
+ // save original file name
+ ti.File = filename
+ // add to cache
+ termCache.Lock()
+ for _, n := range ti.Names {
+ termCache.db[n] = ti
+ }
+ termCache.Unlock()
+ return ti, nil
+}
+
+// boolCaps returns all bool and extended capabilities using f to format the
+// index key.
+func (ti *Terminfo) boolCaps(f func(int) string, extended bool) map[string]bool {
+ m := make(map[string]bool, len(ti.Bools)+len(ti.ExtBools))
+ if !extended {
+ for k, v := range ti.Bools {
+ m[f(k)] = v
+ }
+ } else {
+ for k, v := range ti.ExtBools {
+ m[string(ti.ExtBoolNames[k])] = v
+ }
+ }
+ return m
+}
+
+// BoolCaps returns all bool capabilities.
+func (ti *Terminfo) BoolCaps() map[string]bool {
+ return ti.boolCaps(BoolCapName, false)
+}
+
+// BoolCapsShort returns all bool capabilities, using the short name as the
+// index.
+func (ti *Terminfo) BoolCapsShort() map[string]bool {
+ return ti.boolCaps(BoolCapNameShort, false)
+}
+
+// ExtBoolCaps returns all extended bool capabilities.
+func (ti *Terminfo) ExtBoolCaps() map[string]bool {
+ return ti.boolCaps(BoolCapName, true)
+}
+
+// ExtBoolCapsShort returns all extended bool capabilities, using the short
+// name as the index.
+func (ti *Terminfo) ExtBoolCapsShort() map[string]bool {
+ return ti.boolCaps(BoolCapNameShort, true)
+}
+
+// numCaps returns all num and extended capabilities using f to format the
+// index key.
+func (ti *Terminfo) numCaps(f func(int) string, extended bool) map[string]int {
+ m := make(map[string]int, len(ti.Nums)+len(ti.ExtNums))
+ if !extended {
+ for k, v := range ti.Nums {
+ m[f(k)] = v
+ }
+ } else {
+ for k, v := range ti.ExtNums {
+ m[string(ti.ExtNumNames[k])] = v
+ }
+ }
+ return m
+}
+
+// NumCaps returns all num capabilities.
+func (ti *Terminfo) NumCaps() map[string]int {
+ return ti.numCaps(NumCapName, false)
+}
+
+// NumCapsShort returns all num capabilities, using the short name as the
+// index.
+func (ti *Terminfo) NumCapsShort() map[string]int {
+ return ti.numCaps(NumCapNameShort, false)
+}
+
+// ExtNumCaps returns all extended num capabilities.
+func (ti *Terminfo) ExtNumCaps() map[string]int {
+ return ti.numCaps(NumCapName, true)
+}
+
+// ExtNumCapsShort returns all extended num capabilities, using the short
+// name as the index.
+func (ti *Terminfo) ExtNumCapsShort() map[string]int {
+ return ti.numCaps(NumCapNameShort, true)
+}
+
+// stringCaps returns all string and extended capabilities using f to format the
+// index key.
+func (ti *Terminfo) stringCaps(f func(int) string, extended bool) map[string][]byte {
+ m := make(map[string][]byte, len(ti.Strings)+len(ti.ExtStrings))
+ if !extended {
+ for k, v := range ti.Strings {
+ m[f(k)] = v
+ }
+ } else {
+ for k, v := range ti.ExtStrings {
+ m[string(ti.ExtStringNames[k])] = v
+ }
+ }
+ return m
+}
+
+// StringCaps returns all string capabilities.
+func (ti *Terminfo) StringCaps() map[string][]byte {
+ return ti.stringCaps(StringCapName, false)
+}
+
+// StringCapsShort returns all string capabilities, using the short name as the
+// index.
+func (ti *Terminfo) StringCapsShort() map[string][]byte {
+ return ti.stringCaps(StringCapNameShort, false)
+}
+
+// ExtStringCaps returns all extended string capabilities.
+func (ti *Terminfo) ExtStringCaps() map[string][]byte {
+ return ti.stringCaps(StringCapName, true)
+}
+
+// ExtStringCapsShort returns all extended string capabilities, using the short
+// name as the index.
+func (ti *Terminfo) ExtStringCapsShort() map[string][]byte {
+ return ti.stringCaps(StringCapNameShort, true)
+}
+
+// Has determines if the bool cap i is present.
+func (ti *Terminfo) Has(i int) bool {
+ return ti.Bools[i]
+}
+
+// Num returns the num cap i, or -1 if not present.
+func (ti *Terminfo) Num(i int) int {
+ n, ok := ti.Nums[i]
+ if !ok {
+ return -1
+ }
+ return n
+}
+
+// Printf formats the string cap i, interpolating parameters v.
+func (ti *Terminfo) Printf(i int, v ...interface{}) string {
+ return Printf(ti.Strings[i], v...)
+}
+
+// Fprintf prints the string cap i to writer w, interpolating parameters v.
+func (ti *Terminfo) Fprintf(w io.Writer, i int, v ...interface{}) {
+ Fprintf(w, ti.Strings[i], v...)
+}
+
+// Color takes a foreground and background color and returns string that sets
+// them for this terminal.
+func (ti *Terminfo) Colorf(fg, bg int, str string) string {
+ maxColors := int(ti.Nums[MaxColors])
+ // map bright colors to lower versions if the color table only holds 8.
+ if maxColors == 8 {
+ if fg > 7 && fg < 16 {
+ fg -= 8
+ }
+ if bg > 7 && bg < 16 {
+ bg -= 8
+ }
+ }
+ var s string
+ if maxColors > fg && fg >= 0 {
+ s += ti.Printf(SetAForeground, fg)
+ }
+ if maxColors > bg && bg >= 0 {
+ s += ti.Printf(SetABackground, bg)
+ }
+ return s + str + ti.Printf(ExitAttributeMode)
+}
+
+// Goto returns a string suitable for addressing the cursor at the given
+// row and column. The origin 0, 0 is in the upper left corner of the screen.
+func (ti *Terminfo) Goto(row, col int) string {
+ return Printf(ti.Strings[CursorAddress], row, col)
+}
+
+// Puts emits the string to the writer, but expands inline padding indications
+// (of the form $<[delay]> where [delay] is msec) to a suitable number of
+// padding characters (usually null bytes) based upon the supplied baud. At
+// high baud rates, more padding characters will be inserted.
+/*func (ti *Terminfo) Puts(w io.Writer, s string, lines, baud int) (int, error) {
+ var err error
+ for {
+ start := strings.Index(s, "$<")
+ if start == -1 {
+ // most strings don't need padding, which is good news!
+ return io.WriteString(w, s)
+ }
+ end := strings.Index(s, ">")
+ if end == -1 {
+ // unterminated... just emit bytes unadulterated.
+ return io.WriteString(w, "$<"+s)
+ }
+ var c int
+ c, err = io.WriteString(w, s[:start])
+ if err != nil {
+ return n + c, err
+ }
+ n += c
+ s = s[start+2:]
+ val := s[:end]
+ s = s[end+1:]
+ var ms int
+ var dot, mandatory, asterisk bool
+ unit := 1000
+ for _, ch := range val {
+ switch {
+ case ch >= '0' && ch <= '9':
+ ms = (ms * 10) + int(ch-'0')
+ if dot {
+ unit *= 10
+ }
+ case ch == '.' && !dot:
+ dot = true
+ case ch == '*' && !asterisk:
+ ms *= lines
+ asterisk = true
+ case ch == '/':
+ mandatory = true
+ default:
+ break
+ }
+ }
+ z, pad := ((baud/8)/unit)*ms, ti.Strings[PadChar]
+ b := make([]byte, len(pad)*z)
+ for bp := copy(b, pad); bp < len(b); bp *= 2 {
+ copy(b[bp:], b[:bp])
+ }
+ if (!ti.Bools[XonXoff] && baud > int(ti.Nums[PaddingBaudRate])) || mandatory {
+ c, err = w.Write(b)
+ if err != nil {
+ return n + c, err
+ }
+ n += c
+ }
+ }
+ return n, nil
+}*/
diff --git a/vendor/go-simpler.org/musttag/.golangci.yaml b/vendor/go-simpler.org/musttag/.golangci.yaml
new file mode 100644
index 00000000..cbac9150
--- /dev/null
+++ b/vendor/go-simpler.org/musttag/.golangci.yaml
@@ -0,0 +1,18 @@
+# https://golangci-lint.run/usage/configuration
+version: "2"
+
+linters:
+ default: standard
+ enable:
+ - gocritic
+ settings:
+ gocritic:
+ enable-all: true
+ exclusions:
+ presets:
+ - std-error-handling
+
+formatters:
+ enable:
+ - gofumpt
+ - goimports
diff --git a/vendor/go-simpler.org/musttag/.golangci.yml b/vendor/go-simpler.org/musttag/.golangci.yml
deleted file mode 100644
index 641471cc..00000000
--- a/vendor/go-simpler.org/musttag/.golangci.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-linters:
- disable-all: true
- enable:
- # enabled by default:
- - errcheck
- - gosimple
- - govet
- - ineffassign
- - staticcheck
- - typecheck
- - unused
- # disabled by default:
- - gocritic
- - gofumpt
-
-linters-settings:
- gocritic:
- enabled-tags:
- - diagnostic
- - style
- - performance
- - experimental
- - opinionated
diff --git a/vendor/go-simpler.org/musttag/README.md b/vendor/go-simpler.org/musttag/README.md
index 3f3a2533..4faa41a4 100644
--- a/vendor/go-simpler.org/musttag/README.md
+++ b/vendor/go-simpler.org/musttag/README.md
@@ -69,7 +69,7 @@ When using `musttag` standalone, pass the options as flags.
### Custom packages
To report a custom function, you need to add its description to `.golangci.yml`.
-The following is an example of adding support for [`hclsimple.Decode`][11]:
+The following is an example of adding support for [`hclsimple.Decode`][11] and [`validator.Validate.Struct`][12]:
```yaml
linters-settings:
@@ -81,12 +81,17 @@ linters-settings:
tag: hcl
# The position of the argument to check.
arg-pos: 2
+
+ # If the function is a pointer receiver method, use this format:
+ - name: (*github.com/go-playground/validator/v10.Validate).Struct
+ tag: validate
+ arg-pos: 0
```
The same can be done via the `-fn=` flag when using `musttag` standalone:
```shell
-musttag -fn="github.com/hashicorp/hcl/v2/hclsimple.DecodeFile:hcl:2" ./...
+musttag -fn="github.com/hashicorp/hcl/v2/hclsimple.DecodeFile:hcl:2" -fn="(*github.com/go-playground/validator/v10.Validate).Struct:validate:0" ./...
```
[1]: https://github.com/uber-go/guide/blob/master/style.md#use-field-tags-in-marshaled-structs
@@ -100,3 +105,4 @@ musttag -fn="github.com/hashicorp/hcl/v2/hclsimple.DecodeFile:hcl:2" ./...
[9]: https://github.com/go-simpler/musttag/releases
[10]: https://golangci-lint.run/usage/linters/#musttag
[11]: https://pkg.go.dev/github.com/hashicorp/hcl/v2/hclsimple#Decode
+[12]: https://pkg.go.dev/github.com/go-playground/validator/v10#Validate.Struct
diff --git a/vendor/go-simpler.org/musttag/builtins.go b/vendor/go-simpler.org/musttag/builtins.go
index 60fa8941..f0be6fcb 100644
--- a/vendor/go-simpler.org/musttag/builtins.go
+++ b/vendor/go-simpler.org/musttag/builtins.go
@@ -19,10 +19,10 @@ var builtins = []Func{
{"(*encoding/xml.Decoder).DecodeElement", "xml", 0, []string{"encoding/xml.Unmarshaler", "encoding.TextUnmarshaler"}},
// https://pkg.go.dev/gopkg.in/yaml.v3
- {"gopkg.in/yaml.v3.Marshal", "yaml", 0, []string{"gopkg.in/yaml.v3.Marshaler"}},
- {"gopkg.in/yaml.v3.Unmarshal", "yaml", 1, []string{"gopkg.in/yaml.v3.Unmarshaler"}},
- {"(*gopkg.in/yaml.v3.Encoder).Encode", "yaml", 0, []string{"gopkg.in/yaml.v3.Marshaler"}},
- {"(*gopkg.in/yaml.v3.Decoder).Decode", "yaml", 0, []string{"gopkg.in/yaml.v3.Unmarshaler"}},
+ {"gopkg.in/yaml.v3.Marshal", "yaml", 0, []string{"gopkg.in/yaml.v3.Marshaler", "encoding.TextMarshaler"}},
+ {"gopkg.in/yaml.v3.Unmarshal", "yaml", 1, []string{"gopkg.in/yaml.v3.Unmarshaler", "encoding.TextUnmarshaler"}},
+ {"(*gopkg.in/yaml.v3.Encoder).Encode", "yaml", 0, []string{"gopkg.in/yaml.v3.Marshaler", "encoding.TextMarshaler"}},
+ {"(*gopkg.in/yaml.v3.Decoder).Decode", "yaml", 0, []string{"gopkg.in/yaml.v3.Unmarshaler", "encoding.TextUnmarshaler"}},
// https://pkg.go.dev/github.com/BurntSushi/toml
{"github.com/BurntSushi/toml.Unmarshal", "toml", 1, []string{"github.com/BurntSushi/toml.Unmarshaler", "encoding.TextUnmarshaler"}},
diff --git a/vendor/go-simpler.org/musttag/musttag.go b/vendor/go-simpler.org/musttag/musttag.go
index f8c0352d..7c1fe0b2 100644
--- a/vendor/go-simpler.org/musttag/musttag.go
+++ b/vendor/go-simpler.org/musttag/musttag.go
@@ -49,9 +49,15 @@ func New(funcs ...Func) *analysis.Analyzer {
merge(funcs)
merge(flagFuncs)
- mainModule, err := getMainModule()
- if err != nil {
- return nil, err
+ var mainModule string
+ if pass.Module != nil {
+ mainModule = pass.Module.Path
+ } else {
+ var err error
+ mainModule, err = getMainModule()
+ if err != nil {
+ return nil, err
+ }
}
return run(pass, mainModule, allFuncs)
diff --git a/vendor/go-simpler.org/sloglint/.golangci.yaml b/vendor/go-simpler.org/sloglint/.golangci.yaml
new file mode 100644
index 00000000..cbac9150
--- /dev/null
+++ b/vendor/go-simpler.org/sloglint/.golangci.yaml
@@ -0,0 +1,18 @@
+# https://golangci-lint.run/usage/configuration
+version: "2"
+
+linters:
+ default: standard
+ enable:
+ - gocritic
+ settings:
+ gocritic:
+ enable-all: true
+ exclusions:
+ presets:
+ - std-error-handling
+
+formatters:
+ enable:
+ - gofumpt
+ - goimports
diff --git a/vendor/go-simpler.org/sloglint/.golangci.yml b/vendor/go-simpler.org/sloglint/.golangci.yml
deleted file mode 100644
index ef926a05..00000000
--- a/vendor/go-simpler.org/sloglint/.golangci.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-linters:
- disable-all: true
- enable:
- # enabled by default:
- - errcheck
- - gosimple
- - govet
- - ineffassign
- - staticcheck
- - unused
- # disabled by default:
- - gocritic
- - gofumpt
-
-linters-settings:
- gocritic:
- enabled-tags:
- - diagnostic
- - style
- - performance
- - experimental
- - opinionated
diff --git a/vendor/go-simpler.org/sloglint/README.md b/vendor/go-simpler.org/sloglint/README.md
index 0a35818f..e75fd021 100644
--- a/vendor/go-simpler.org/sloglint/README.md
+++ b/vendor/go-simpler.org/sloglint/README.md
@@ -19,9 +19,10 @@ With `sloglint` you can enforce various rules for `log/slog` based on your prefe
* Enforce using either key-value pairs only or attributes only (optional)
* Enforce not using global loggers (optional)
* Enforce using methods that accept a context (optional)
-* Enforce using static log messages (optional)
+* Enforce using static messages (optional)
+* Enforce message style (optional)
* Enforce using constants instead of raw keys (optional)
-* Enforce a single key naming convention (optional)
+* Enforce key naming convention (optional)
* Enforce not using specific keys (optional)
* Enforce putting arguments on separate lines (optional)
@@ -110,6 +111,24 @@ The report can be fixed by moving dynamic values to arguments:
slog.Info("a user has logged in", "user_id", 42)
```
+### Message style
+
+The `msg-style` option causes `sloglint` to check log messages for a particular style.
+
+Possible values are `lowercased` (report messages that begin with an uppercase letter)...
+
+```go
+slog.Info("Msg") // sloglint: message should be lowercased
+```
+
+...and `capitalized` (report messages that begin with a lowercase letter):
+
+```go
+slog.Info("msg") // sloglint: message should be capitalized
+```
+
+Special cases such as acronyms (e.g. `HTTP`, `U.S.`) are ignored.
+
### No raw keys
To prevent typos, you may want to forbid the use of raw keys altogether.
diff --git a/vendor/go-simpler.org/sloglint/sloglint.go b/vendor/go-simpler.org/sloglint/sloglint.go
index 97199b41..b506c357 100644
--- a/vendor/go-simpler.org/sloglint/sloglint.go
+++ b/vendor/go-simpler.org/sloglint/sloglint.go
@@ -8,9 +8,12 @@ import (
"go/ast"
"go/token"
"go/types"
+ "go/version"
+ "iter"
"slices"
"strconv"
"strings"
+ "unicode"
"github.com/ettle/strcase"
"golang.org/x/tools/go/analysis"
@@ -26,11 +29,14 @@ type Options struct {
AttrOnly bool // Enforce using attributes only (overrides NoMixedArgs, incompatible with KVOnly).
NoGlobal string // Enforce not using global loggers ("all" or "default").
ContextOnly string // Enforce using methods that accept a context ("all" or "scope").
- StaticMsg bool // Enforce using static log messages.
+ StaticMsg bool // Enforce using static messages.
+ MsgStyle string // Enforce message style ("lowercased" or "capitalized").
NoRawKeys bool // Enforce using constants instead of raw keys.
- KeyNamingCase string // Enforce a single key naming convention ("snake", "kebab", "camel", or "pascal").
+ KeyNamingCase string // Enforce key naming convention ("snake", "kebab", "camel", or "pascal").
ForbiddenKeys []string // Enforce not using specific keys.
ArgsOnSepLines bool // Enforce putting arguments on separate lines.
+
+ go124 bool
}
// New creates a new sloglint analyzer.
@@ -61,12 +67,22 @@ func New(opts *Options) *analysis.Analyzer {
return nil, fmt.Errorf("sloglint: Options.ContextOnly=%s: %w", opts.ContextOnly, errInvalidValue)
}
+ switch opts.MsgStyle {
+ case "", styleLowercased, styleCapitalized:
+ default:
+ return nil, fmt.Errorf("sloglint: Options.MsgStyle=%s: %w", opts.MsgStyle, errInvalidValue)
+ }
+
switch opts.KeyNamingCase {
case "", snakeCase, kebabCase, camelCase, pascalCase:
default:
return nil, fmt.Errorf("sloglint: Options.KeyNamingCase=%s: %w", opts.KeyNamingCase, errInvalidValue)
}
+ if version.Compare("go"+pass.Module.GoVersion, "go1.24") >= 0 {
+ opts.go124 = true
+ }
+
run(pass, opts)
return nil, nil
},
@@ -101,9 +117,10 @@ func flags(opts *Options) flag.FlagSet {
boolVar(&opts.AttrOnly, "attr-only", "enforce using attributes only (overrides -no-mixed-args, incompatible with -kv-only)")
strVar(&opts.NoGlobal, "no-global", "enforce not using global loggers (all|default)")
strVar(&opts.ContextOnly, "context-only", "enforce using methods that accept a context (all|scope)")
- boolVar(&opts.StaticMsg, "static-msg", "enforce using static log messages")
+ boolVar(&opts.StaticMsg, "static-msg", "enforce using static messages")
+ strVar(&opts.MsgStyle, "msg-style", "enforce message style (lowercased|capitalized)")
boolVar(&opts.NoRawKeys, "no-raw-keys", "enforce using constants instead of raw keys")
- strVar(&opts.KeyNamingCase, "key-naming-case", "enforce a single key naming convention (snake|kebab|camel|pascal)")
+ strVar(&opts.KeyNamingCase, "key-naming-case", "enforce key naming convention (snake|kebab|camel|pascal)")
boolVar(&opts.ArgsOnSepLines, "args-on-sep-lines", "enforce putting arguments on separate lines")
fset.Func("forbidden-keys", "enforce not using specific keys (comma-separated)", func(s string) error {
@@ -155,6 +172,13 @@ var attrFuncs = map[string]struct{}{
"log/slog.Any": {},
}
+// message styles.
+const (
+ styleLowercased = "lowercased"
+ styleCapitalized = "capitalized"
+)
+
+// key naming conventions.
const (
snakeCase = "snake"
kebabCase = "kebab"
@@ -190,6 +214,9 @@ func visit(pass *analysis.Pass, opts *Options, node ast.Node, stack []ast.Node)
}
name := fn.FullName()
+
+ checkDiscardHandler(opts, pass, name, call)
+
funcInfo, ok := slogFuncs[name]
if !ok {
return
@@ -223,9 +250,22 @@ func visit(pass *analysis.Pass, opts *Options, node ast.Node, stack []ast.Node)
}
msgPos := funcInfo.argsPos - 1
+
// NOTE: "With" functions have no message argument and must be skipped.
if opts.StaticMsg && msgPos >= 0 && !isStaticMsg(call.Args[msgPos]) {
- pass.Reportf(call.Pos(), "message should be a string literal or a constant")
+ pass.Reportf(call.Args[msgPos].Pos(), "message should be a string literal or a constant")
+ }
+
+ if opts.MsgStyle != "" && msgPos >= 0 {
+ if lit, ok := call.Args[msgPos].(*ast.BasicLit); ok && lit.Kind == token.STRING {
+ value, err := strconv.Unquote(lit.Value)
+ if err != nil {
+ panic("unreachable") // string literals are always quoted.
+ }
+ if ok := isValidMsgStyle(value, opts.MsgStyle); !ok {
+ pass.Reportf(call.Args[msgPos].Pos(), "message should be %s", opts.MsgStyle)
+ }
+ }
}
// NOTE: we assume that the arguments have already been validated by govet.
@@ -242,7 +282,6 @@ func visit(pass *analysis.Pass, opts *Options, node ast.Node, stack []ast.Node)
if typ == nil {
continue
}
-
switch typ.String() {
case "string":
keys = append(keys, args[i])
@@ -264,11 +303,13 @@ func visit(pass *analysis.Pass, opts *Options, node ast.Node, stack []ast.Node)
}
if opts.NoRawKeys {
- forEachKey(pass.TypesInfo, keys, attrs, func(key ast.Expr) {
- if selector, ok := key.(*ast.SelectorExpr); ok {
- key = selector.Sel // the key is defined in another package, e.g. pkg.ConstKey.
+ for key := range AllKeys(pass.TypesInfo, keys, attrs) {
+ if sel, ok := key.(*ast.SelectorExpr); ok {
+ key = sel.Sel // the key is defined in another package, e.g. pkg.ConstKey.
}
+
isConst := false
+
if ident, ok := key.(*ast.Ident); ok {
if obj := pass.TypesInfo.ObjectOf(ident); obj != nil {
if _, ok := obj.(*types.Const); ok {
@@ -276,18 +317,48 @@ func visit(pass *analysis.Pass, opts *Options, node ast.Node, stack []ast.Node)
}
}
}
+
if !isConst {
- pass.Reportf(call.Pos(), "raw keys should not be used")
+ pass.Reportf(key.Pos(), "raw keys should not be used")
}
- })
+ }
+ }
+
+ checkKeysNaming(opts, pass, keys, attrs)
+
+ if len(opts.ForbiddenKeys) > 0 {
+ for key := range AllKeys(pass.TypesInfo, keys, attrs) {
+ if name, ok := getKeyName(key); ok && slices.Contains(opts.ForbiddenKeys, name) {
+ pass.Reportf(key.Pos(), "%q key is forbidden and should not be used", name)
+ }
+ }
}
+ if opts.ArgsOnSepLines && areArgsOnSameLine(pass.Fset, call, keys, attrs) {
+ pass.Reportf(call.Pos(), "arguments should be put on separate lines")
+ }
+}
+
+func checkKeysNaming(opts *Options, pass *analysis.Pass, keys, attrs []ast.Expr) {
checkKeyNamingCase := func(caseFn func(string) string, caseName string) {
- forEachKey(pass.TypesInfo, keys, attrs, func(key ast.Expr) {
- if name, ok := getKeyName(key); ok && name != caseFn(name) {
- pass.Reportf(call.Pos(), "keys should be written in %s", caseName)
+ for key := range AllKeys(pass.TypesInfo, keys, attrs) {
+ name, ok := getKeyName(key)
+ if !ok || name == caseFn(name) {
+ return
}
- })
+
+ pass.Report(analysis.Diagnostic{
+ Pos: key.Pos(),
+ Message: fmt.Sprintf("keys should be written in %s", caseName),
+ SuggestedFixes: []analysis.SuggestedFix{{
+ TextEdits: []analysis.TextEdit{{
+ Pos: key.Pos(),
+ End: key.End(),
+ NewText: []byte(strconv.Quote(caseFn(name))),
+ }},
+ }},
+ })
+ }
}
switch opts.KeyNamingCase {
@@ -300,26 +371,50 @@ func visit(pass *analysis.Pass, opts *Options, node ast.Node, stack []ast.Node)
case pascalCase:
checkKeyNamingCase(strcase.ToPascal, "PascalCase")
}
+}
- if len(opts.ForbiddenKeys) > 0 {
- forEachKey(pass.TypesInfo, keys, attrs, func(key ast.Expr) {
- if name, ok := getKeyName(key); ok && slices.Contains(opts.ForbiddenKeys, name) {
- pass.Reportf(call.Pos(), "%q key is forbidden and should not be used", name)
- }
- })
+func checkDiscardHandler(opts *Options, pass *analysis.Pass, name string, call *ast.CallExpr) {
+ if !opts.go124 {
+ return
}
- if opts.ArgsOnSepLines && areArgsOnSameLine(pass.Fset, call, keys, attrs) {
- pass.Reportf(call.Pos(), "arguments should be put on separate lines")
+ if name != "log/slog.NewTextHandler" && name != "log/slog.NewJSONHandler" {
+ return
+ }
+
+ sel, ok := call.Args[0].(*ast.SelectorExpr)
+ if !ok {
+ return
+ }
+
+ obj := pass.TypesInfo.ObjectOf(sel.Sel)
+ if obj == nil {
+ return
+ }
+
+ if obj.Pkg().Name() != "io" || obj.Name() != "Discard" {
+ return
}
+
+ pass.Report(analysis.Diagnostic{
+ Pos: call.Pos(),
+ Message: "use slog.DiscardHandler instead",
+ SuggestedFixes: []analysis.SuggestedFix{{
+ TextEdits: []analysis.TextEdit{{
+ Pos: call.Pos(),
+ End: call.End(),
+ NewText: []byte("slog.DiscardHandler"),
+ }},
+ }},
+ })
}
func isGlobalLoggerUsed(info *types.Info, call ast.Expr) bool {
- selector, ok := call.(*ast.SelectorExpr)
+ sel, ok := call.(*ast.SelectorExpr)
if !ok {
return false
}
- ident, ok := selector.X.(*ast.Ident)
+ ident, ok := sel.X.(*ast.Ident)
if !ok {
return false
}
@@ -351,41 +446,89 @@ func isStaticMsg(msg ast.Expr) bool {
return msg.Kind == token.STRING
case *ast.Ident: // e.g. const msg = "msg"; slog.Info(msg)
return msg.Obj != nil && msg.Obj.Kind == ast.Con
+ case *ast.BinaryExpr: // e.g. slog.Info("x" + "y")
+ if msg.Op != token.ADD {
+ panic("unreachable") // only + can be applied to strings.
+ }
+ return isStaticMsg(msg.X) && isStaticMsg(msg.Y)
default:
return false
}
}
-func forEachKey(info *types.Info, keys, attrs []ast.Expr, fn func(key ast.Expr)) {
- for _, key := range keys {
- fn(key)
+func isValidMsgStyle(msg, style string) bool {
+ runes := []rune(msg)
+ if len(runes) < 2 {
+ return true
}
- for _, attr := range attrs {
- switch attr := attr.(type) {
- case *ast.CallExpr: // e.g. slog.Int()
- callee := typeutil.StaticCallee(info, attr)
- if callee == nil {
- continue
- }
- if _, ok := attrFuncs[callee.FullName()]; !ok {
- continue
+ first, second := runes[0], runes[1]
+
+ switch style {
+ case styleLowercased:
+ if unicode.IsLower(first) {
+ return true
+ }
+ if unicode.IsPunct(second) {
+ return true // e.g. "U.S.A."
+ }
+ return unicode.IsUpper(second) // e.g. "HTTP"
+ case styleCapitalized:
+ if unicode.IsUpper(first) {
+ return true
+ }
+ return unicode.IsUpper(second) // e.g. "iPhone"
+ default:
+ panic("unreachable")
+ }
+}
+
+func AllKeys(info *types.Info, keys, attrs []ast.Expr) iter.Seq[ast.Expr] {
+ return func(yield func(key ast.Expr) bool) {
+ for _, key := range keys {
+ if !yield(key) {
+ return
}
- fn(attr.Args[0])
+ }
+
+ for _, attr := range attrs {
+ switch attr := attr.(type) {
+ case *ast.CallExpr: // e.g. slog.Int()
+ callee := typeutil.StaticCallee(info, attr)
+ if callee == nil {
+ continue
+ }
+ if _, ok := attrFuncs[callee.FullName()]; !ok {
+ continue
+ }
- case *ast.CompositeLit: // slog.Attr{}
- switch len(attr.Elts) {
- case 1: // slog.Attr{Key: ...} | slog.Attr{Value: ...}
- if kv := attr.Elts[0].(*ast.KeyValueExpr); kv.Key.(*ast.Ident).Name == "Key" {
- fn(kv.Value)
+ if !yield(attr.Args[0]) {
+ return
}
- case 2: // slog.Attr{Key: ..., Value: ...} | slog.Attr{Value: ..., Key: ...} | slog.Attr{..., ...}
- if kv, ok := attr.Elts[0].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
- fn(kv.Value)
- } else if kv, ok := attr.Elts[1].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
- fn(kv.Value)
- } else {
- fn(attr.Elts[0])
+
+ case *ast.CompositeLit: // slog.Attr{}
+ switch len(attr.Elts) {
+ case 1: // slog.Attr{Key: ...} | slog.Attr{Value: ...}
+ if kv := attr.Elts[0].(*ast.KeyValueExpr); kv.Key.(*ast.Ident).Name == "Key" {
+ if !yield(kv.Value) {
+ return
+ }
+ }
+
+ case 2: // slog.Attr{Key: ..., Value: ...} | slog.Attr{Value: ..., Key: ...} | slog.Attr{..., ...}
+ if kv, ok := attr.Elts[0].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
+ if !yield(kv.Value) {
+ return
+ }
+ } else if kv, ok := attr.Elts[1].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
+ if !yield(kv.Value) {
+ return
+ }
+ } else {
+ if !yield(attr.Elts[0]) {
+ return
+ }
+ }
}
}
}
@@ -403,10 +546,9 @@ func getKeyName(key ast.Expr) (string, bool) {
}
}
if lit, ok := key.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- // string literals are always quoted.
value, err := strconv.Unquote(lit.Value)
if err != nil {
- panic("unreachable")
+ panic("unreachable") // string literals are always quoted.
}
return value, true
}
@@ -418,13 +560,9 @@ func areArgsOnSameLine(fset *token.FileSet, call ast.Expr, keys, attrs []ast.Exp
return false // special case: slog.Info("msg", "key", "value") is ok.
}
- l := len(keys) + len(attrs) + 1
- args := make([]ast.Expr, 0, l)
- args = append(args, call)
- args = append(args, keys...)
- args = append(args, attrs...)
+ args := slices.Concat([]ast.Expr{call}, keys, attrs)
- lines := make(map[int]struct{}, l)
+ lines := make(map[int]struct{}, len(args))
for _, arg := range args {
line := fset.Position(arg.Pos()).Line
if _, ok := lines[line]; ok {
diff --git a/vendor/github.com/Crocmagnon/fatcontext/LICENSE b/vendor/go.augendre.info/fatcontext/LICENSE
similarity index 100%
rename from vendor/github.com/Crocmagnon/fatcontext/LICENSE
rename to vendor/go.augendre.info/fatcontext/LICENSE
diff --git a/vendor/github.com/Crocmagnon/fatcontext/pkg/analyzer/analyzer.go b/vendor/go.augendre.info/fatcontext/pkg/analyzer/analyzer.go
similarity index 73%
rename from vendor/github.com/Crocmagnon/fatcontext/pkg/analyzer/analyzer.go
rename to vendor/go.augendre.info/fatcontext/pkg/analyzer/analyzer.go
index 42c06f4e..a611b645 100644
--- a/vendor/github.com/Crocmagnon/fatcontext/pkg/analyzer/analyzer.go
+++ b/vendor/go.augendre.info/fatcontext/pkg/analyzer/analyzer.go
@@ -1,3 +1,4 @@
+// Package analyzer contains everything related to the linter analysis.
package analyzer
import (
@@ -15,25 +16,31 @@ import (
"golang.org/x/tools/go/ast/inspector"
)
+// FlagCheckStructPointers is a possible flag for the analyzer.
+// Exported to make it usable in golangci-lint.
const FlagCheckStructPointers = "check-struct-pointers"
+// NewAnalyzer returns a fatcontext analyzer.
func NewAnalyzer() *analysis.Analyzer {
- r := &runner{}
+ rnnr := &runner{}
flags := flag.NewFlagSet("fatcontext", flag.ExitOnError)
- flags.BoolVar(&r.DetectInStructPointers, FlagCheckStructPointers, false,
+ flags.BoolVar(&rnnr.DetectInStructPointers, FlagCheckStructPointers, false,
"set to true to detect potential fat contexts in struct pointers")
return &analysis.Analyzer{
Name: "fatcontext",
Doc: "detects nested contexts in loops and function literals",
- Run: r.run,
+ Run: rnnr.run,
Flags: *flags,
Requires: []*analysis.Analyzer{inspect.Analyzer},
}
}
-var errUnknown = errors.New("unknown node type")
+var (
+ errUnknown = errors.New("unknown node type")
+ errInvalidAnalysis = errors.New("invalid analysis")
+)
const (
categoryInLoop = "nested context in loop"
@@ -47,7 +54,10 @@ type runner struct {
}
func (r *runner) run(pass *analysis.Pass) (interface{}, error) {
- inspctr := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+ inspctr, typeValid := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+ if !typeValid {
+ return nil, errInvalidAnalysis
+ }
nodeFilter := []ast.Node{
(*ast.ForStmt)(nil),
@@ -86,14 +96,18 @@ func (r *runner) run(pass *analysis.Pass) (interface{}, error) {
})
})
- return nil, nil
+ return nil, nil //nolint:nilnil // we have no result to send to other analyzers
}
func (r *runner) shouldIgnoreReport(category string) bool {
return category == categoryInStructPointer && !r.DetectInStructPointers
}
-func (r *runner) getSuggestedFixes(pass *analysis.Pass, assignStmt *ast.AssignStmt, category string) []analysis.SuggestedFix {
+func (r *runner) getSuggestedFixes(
+ pass *analysis.Pass,
+ assignStmt *ast.AssignStmt,
+ category string,
+) []analysis.SuggestedFix {
switch category {
case categoryInStructPointer, categoryUnsupported:
return nil
@@ -160,31 +174,9 @@ func getBody(node ast.Node) (*ast.BlockStmt, error) {
func findNestedContext(pass *analysis.Pass, node ast.Node, stmts []ast.Stmt) *ast.AssignStmt {
for _, stmt := range stmts {
// Recurse if necessary
- switch typedStmt := stmt.(type) {
- case *ast.BlockStmt:
- if found := findNestedContext(pass, node, typedStmt.List); found != nil {
- return found
- }
- case *ast.IfStmt:
- if found := findNestedContext(pass, node, typedStmt.Body.List); found != nil {
- return found
- }
- case *ast.SwitchStmt:
- if found := findNestedContext(pass, node, typedStmt.Body.List); found != nil {
- return found
- }
- case *ast.CaseClause:
- if found := findNestedContext(pass, node, typedStmt.Body); found != nil {
- return found
- }
- case *ast.SelectStmt:
- if found := findNestedContext(pass, node, typedStmt.Body.List); found != nil {
- return found
- }
- case *ast.CommClause:
- if found := findNestedContext(pass, node, typedStmt.Body); found != nil {
- return found
- }
+ stmtList := getStmtList(stmt)
+ if found := findNestedContext(pass, node, stmtList); found != nil {
+ return found
}
// Actually check for nested context
@@ -226,28 +218,48 @@ func findNestedContext(pass *analysis.Pass, node ast.Node, stmts []ast.Stmt) *as
return nil
}
-// render returns the pretty-print of the given node
+func getStmtList(stmt ast.Stmt) []ast.Stmt {
+ switch typedStmt := stmt.(type) {
+ case *ast.BlockStmt:
+ return typedStmt.List
+ case *ast.IfStmt:
+ return typedStmt.Body.List
+ case *ast.SwitchStmt:
+ return typedStmt.Body.List
+ case *ast.CaseClause:
+ return typedStmt.Body
+ case *ast.SelectStmt:
+ return typedStmt.Body.List
+ case *ast.CommClause:
+ return typedStmt.Body
+ }
+
+ return nil
+}
+
+// render returns the pretty-print of the given node.
func render(fset *token.FileSet, x interface{}) ([]byte, error) {
var buf bytes.Buffer
if err := printer.Fprint(&buf, fset, x); err != nil {
return nil, fmt.Errorf("printing node: %w", err)
}
+
return buf.Bytes(), nil
}
func isContextFunction(exp ast.Expr, fnName ...string) bool {
- call, ok := exp.(*ast.CallExpr)
- if !ok {
+ call, typeValid := exp.(*ast.CallExpr)
+ if !typeValid {
return false
}
- selector, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
+ selector, typeValid := call.Fun.(*ast.SelectorExpr)
+ if !typeValid {
return false
}
- ident, ok := selector.X.(*ast.Ident)
- if !ok {
+ ident, typeValid := selector.X.(*ast.Ident)
+ if !typeValid {
return false
}
@@ -275,16 +287,17 @@ func isWithinLoop(exp ast.Expr, node ast.Node, pass *analysis.Pass) bool {
func getRootIdent(pass *analysis.Pass, node ast.Node) *ast.Ident {
for {
- switch n := node.(type) {
+ switch typedNode := node.(type) {
case *ast.Ident:
- return n
+ return typedNode
case *ast.IndexExpr:
- node = n.X
+ node = typedNode.X
case *ast.SelectorExpr:
- if sel, ok := pass.TypesInfo.Selections[n]; ok && sel.Indirect() {
+ if sel, ok := pass.TypesInfo.Selections[typedNode]; ok && sel.Indirect() {
return nil // indirected (pointer) roots don't imply a (safe) copy
}
- node = n.X
+
+ node = typedNode.X
default:
return nil
}
@@ -292,9 +305,10 @@ func getRootIdent(pass *analysis.Pass, node ast.Node) *ast.Ident {
}
func isPointer(pass *analysis.Pass, exp ast.Node) bool {
- switch n := exp.(type) {
+ switch n := exp.(type) { //nolint:gocritic // Future-proofing with switch instead of if.
case *ast.SelectorExpr:
sel, ok := pass.TypesInfo.Selections[n]
+
return ok && sel.Indirect()
}
diff --git a/vendor/golang.org/x/mod/sumdb/dirhash/hash.go b/vendor/golang.org/x/mod/sumdb/dirhash/hash.go
new file mode 100644
index 00000000..117985ac
--- /dev/null
+++ b/vendor/golang.org/x/mod/sumdb/dirhash/hash.go
@@ -0,0 +1,135 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package dirhash defines hashes over directory trees.
+// These hashes are recorded in go.sum files and in the Go checksum database,
+// to allow verifying that a newly-downloaded module has the expected content.
+package dirhash
+
+import (
+ "archive/zip"
+ "crypto/sha256"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "slices"
+ "strings"
+)
+
+// DefaultHash is the default hash function used in new go.sum entries.
+var DefaultHash Hash = Hash1
+
+// A Hash is a directory hash function.
+// It accepts a list of files along with a function that opens the content of each file.
+// It opens, reads, hashes, and closes each file and returns the overall directory hash.
+type Hash func(files []string, open func(string) (io.ReadCloser, error)) (string, error)
+
+// Hash1 is the "h1:" directory hash function, using SHA-256.
+//
+// Hash1 is "h1:" followed by the base64-encoded SHA-256 hash of a summary
+// prepared as if by the Unix command:
+//
+// sha256sum $(find . -type f | sort) | sha256sum
+//
+// More precisely, the hashed summary contains a single line for each file in the list,
+// ordered by [slices.Sort] applied to the file names, where each line consists of
+// the hexadecimal SHA-256 hash of the file content,
+// two spaces (U+0020), the file name, and a newline (U+000A).
+//
+// File names with newlines (U+000A) are disallowed.
+func Hash1(files []string, open func(string) (io.ReadCloser, error)) (string, error) {
+ h := sha256.New()
+ files = append([]string(nil), files...)
+ slices.Sort(files)
+ for _, file := range files {
+ if strings.Contains(file, "\n") {
+ return "", errors.New("dirhash: filenames with newlines are not supported")
+ }
+ r, err := open(file)
+ if err != nil {
+ return "", err
+ }
+ hf := sha256.New()
+ _, err = io.Copy(hf, r)
+ r.Close()
+ if err != nil {
+ return "", err
+ }
+ fmt.Fprintf(h, "%x %s\n", hf.Sum(nil), file)
+ }
+ return "h1:" + base64.StdEncoding.EncodeToString(h.Sum(nil)), nil
+}
+
+// HashDir returns the hash of the local file system directory dir,
+// replacing the directory name itself with prefix in the file names
+// used in the hash function.
+func HashDir(dir, prefix string, hash Hash) (string, error) {
+ files, err := DirFiles(dir, prefix)
+ if err != nil {
+ return "", err
+ }
+ osOpen := func(name string) (io.ReadCloser, error) {
+ return os.Open(filepath.Join(dir, strings.TrimPrefix(name, prefix)))
+ }
+ return hash(files, osOpen)
+}
+
+// DirFiles returns the list of files in the tree rooted at dir,
+// replacing the directory name dir with prefix in each name.
+// The resulting names always use forward slashes.
+func DirFiles(dir, prefix string) ([]string, error) {
+ var files []string
+ dir = filepath.Clean(dir)
+ err := filepath.Walk(dir, func(file string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+ if info.IsDir() {
+ return nil
+ } else if file == dir {
+ return fmt.Errorf("%s is not a directory", dir)
+ }
+
+ rel := file
+ if dir != "." {
+ rel = file[len(dir)+1:]
+ }
+ f := filepath.Join(prefix, rel)
+ files = append(files, filepath.ToSlash(f))
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ return files, nil
+}
+
+// HashZip returns the hash of the file content in the named zip file.
+// Only the file names and their contents are included in the hash:
+// the exact zip file format encoding, compression method,
+// per-file modification times, and other metadata are ignored.
+func HashZip(zipfile string, hash Hash) (string, error) {
+ z, err := zip.OpenReader(zipfile)
+ if err != nil {
+ return "", err
+ }
+ defer z.Close()
+ var files []string
+ zfiles := make(map[string]*zip.File)
+ for _, file := range z.File {
+ files = append(files, file.Name)
+ zfiles[file.Name] = file
+ }
+ zipOpen := func(name string) (io.ReadCloser, error) {
+ f := zfiles[name]
+ if f == nil {
+ return nil, fmt.Errorf("file %q not found in zip", name) // should never happen
+ }
+ return f.Open()
+ }
+ return hash(files, zipOpen)
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/httpmux/httpmux.go b/vendor/golang.org/x/tools/go/analysis/passes/httpmux/httpmux.go
new file mode 100644
index 00000000..655b78fd
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/passes/httpmux/httpmux.go
@@ -0,0 +1,185 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package httpmux
+
+import (
+ "go/ast"
+ "go/constant"
+ "go/types"
+ "regexp"
+ "slices"
+ "strings"
+
+ "golang.org/x/mod/semver"
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/inspector"
+ "golang.org/x/tools/go/types/typeutil"
+ "golang.org/x/tools/internal/analysisinternal"
+ "golang.org/x/tools/internal/typesinternal"
+)
+
+const Doc = `report using Go 1.22 enhanced ServeMux patterns in older Go versions
+
+The httpmux analysis is active for Go modules configured to run with Go 1.21 or
+earlier versions. It reports calls to net/http.ServeMux.Handle and HandleFunc
+methods whose patterns use features added in Go 1.22, like HTTP methods (such as
+"GET") and wildcards. (See https://pkg.go.dev/net/http#ServeMux for details.)
+Such patterns can be registered in older versions of Go, but will not behave as expected.`
+
+var Analyzer = &analysis.Analyzer{
+ Name: "httpmux",
+ Doc: Doc,
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/httpmux",
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Run: run,
+}
+
+var inTest bool // So Go version checks can be skipped during testing.
+
+func run(pass *analysis.Pass) (any, error) {
+ if !inTest {
+ // Check that Go version is 1.21 or earlier.
+ if goVersionAfter121(goVersion(pass.Pkg)) {
+ return nil, nil
+ }
+ }
+ if !analysisinternal.Imports(pass.Pkg, "net/http") {
+ return nil, nil
+ }
+ // Look for calls to ServeMux.Handle or ServeMux.HandleFunc.
+ inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+
+ nodeFilter := []ast.Node{
+ (*ast.CallExpr)(nil),
+ }
+
+ inspect.Preorder(nodeFilter, func(n ast.Node) {
+ call := n.(*ast.CallExpr)
+ if isServeMuxRegisterCall(pass, call) {
+ pat, ok := stringConstantExpr(pass, call.Args[0])
+ if ok && likelyEnhancedPattern(pat) {
+ pass.ReportRangef(call.Args[0], "possible enhanced ServeMux pattern used with Go version before 1.22 (update go.mod file?)")
+ }
+ }
+ })
+ return nil, nil
+}
+
+// isServeMuxRegisterCall reports whether call is a static call to one of:
+// - net/http.Handle
+// - net/http.HandleFunc
+// - net/http.ServeMux.Handle
+// - net/http.ServeMux.HandleFunc
+// TODO(jba): consider expanding this to accommodate wrappers around these functions.
+func isServeMuxRegisterCall(pass *analysis.Pass, call *ast.CallExpr) bool {
+ fn := typeutil.StaticCallee(pass.TypesInfo, call)
+ if fn == nil {
+ return false
+ }
+ if analysisinternal.IsFunctionNamed(fn, "net/http", "Handle", "HandleFunc") {
+ return true
+ }
+ if !isMethodNamed(fn, "net/http", "Handle", "HandleFunc") {
+ return false
+ }
+ recv := fn.Type().(*types.Signature).Recv() // isMethodNamed() -> non-nil
+ isPtr, named := typesinternal.ReceiverNamed(recv)
+ return isPtr && analysisinternal.IsTypeNamed(named, "net/http", "ServeMux")
+}
+
+// isMethodNamed reports when a function f is a method,
+// in a package with the path pkgPath and the name of f is in names.
+//
+// (Unlike [analysisinternal.IsMethodNamed], it ignores the receiver type name.)
+func isMethodNamed(f *types.Func, pkgPath string, names ...string) bool {
+ if f == nil {
+ return false
+ }
+ if f.Pkg() == nil || f.Pkg().Path() != pkgPath {
+ return false // not at pkgPath
+ }
+ if f.Type().(*types.Signature).Recv() == nil {
+ return false // not a method
+ }
+ return slices.Contains(names, f.Name())
+}
+
+// stringConstantExpr returns expression's string constant value.
+//
+// ("", false) is returned if expression isn't a string
+// constant.
+func stringConstantExpr(pass *analysis.Pass, expr ast.Expr) (string, bool) {
+ lit := pass.TypesInfo.Types[expr].Value
+ if lit != nil && lit.Kind() == constant.String {
+ return constant.StringVal(lit), true
+ }
+ return "", false
+}
+
+// A valid wildcard must start a segment, and its name must be valid Go
+// identifier.
+var wildcardRegexp = regexp.MustCompile(`/\{[_\pL][_\pL\p{Nd}]*(\.\.\.)?\}`)
+
+// likelyEnhancedPattern reports whether the ServeMux pattern pat probably
+// contains either an HTTP method name or a wildcard, extensions added in Go 1.22.
+func likelyEnhancedPattern(pat string) bool {
+ if strings.Contains(pat, " ") {
+ // A space in the pattern suggests that it begins with an HTTP method.
+ return true
+ }
+ return wildcardRegexp.MatchString(pat)
+}
+
+func goVersionAfter121(goVersion string) bool {
+ if goVersion == "" { // Maybe the stdlib?
+ return true
+ }
+ version := versionFromGoVersion(goVersion)
+ return semver.Compare(version, "v1.21") > 0
+}
+
+func goVersion(pkg *types.Package) string {
+ // types.Package.GoVersion did not exist before Go 1.21.
+ if p, ok := any(pkg).(interface{ GoVersion() string }); ok {
+ return p.GoVersion()
+ }
+ return ""
+}
+
+var (
+ // Regexp for matching go tags. The groups are:
+ // 1 the major.minor version
+ // 2 the patch version, or empty if none
+ // 3 the entire prerelease, if present
+ // 4 the prerelease type ("beta" or "rc")
+ // 5 the prerelease number
+ tagRegexp = regexp.MustCompile(`^go(\d+\.\d+)(\.\d+|)((beta|rc)(\d+))?$`)
+)
+
+// Copied from pkgsite/internal/stdlib.VersionForTag.
+func versionFromGoVersion(goVersion string) string {
+ // Special cases for go1.
+ if goVersion == "go1" {
+ return "v1.0.0"
+ }
+ if goVersion == "go1.0" {
+ return ""
+ }
+ m := tagRegexp.FindStringSubmatch(goVersion)
+ if m == nil {
+ return ""
+ }
+ version := "v" + m[1]
+ if m[2] != "" {
+ version += m[2]
+ } else {
+ version += ".0"
+ }
+ if m[3] != "" {
+ version += "-" + m[4] + "." + m[5]
+ }
+ return version
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/analysis.go b/vendor/honnef.co/go/tools/quickfix/analysis.go
new file mode 100644
index 00000000..b877a910
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/analysis.go
@@ -0,0 +1,34 @@
+// Code generated by generate.go. DO NOT EDIT.
+
+package quickfix
+
+import (
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/quickfix/qf1001"
+ "honnef.co/go/tools/quickfix/qf1002"
+ "honnef.co/go/tools/quickfix/qf1003"
+ "honnef.co/go/tools/quickfix/qf1004"
+ "honnef.co/go/tools/quickfix/qf1005"
+ "honnef.co/go/tools/quickfix/qf1006"
+ "honnef.co/go/tools/quickfix/qf1007"
+ "honnef.co/go/tools/quickfix/qf1008"
+ "honnef.co/go/tools/quickfix/qf1009"
+ "honnef.co/go/tools/quickfix/qf1010"
+ "honnef.co/go/tools/quickfix/qf1011"
+ "honnef.co/go/tools/quickfix/qf1012"
+)
+
+var Analyzers = []*lint.Analyzer{
+ qf1001.SCAnalyzer,
+ qf1002.SCAnalyzer,
+ qf1003.SCAnalyzer,
+ qf1004.SCAnalyzer,
+ qf1005.SCAnalyzer,
+ qf1006.SCAnalyzer,
+ qf1007.SCAnalyzer,
+ qf1008.SCAnalyzer,
+ qf1009.SCAnalyzer,
+ qf1010.SCAnalyzer,
+ qf1011.SCAnalyzer,
+ qf1012.SCAnalyzer,
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/doc.go b/vendor/honnef.co/go/tools/quickfix/doc.go
new file mode 100644
index 00000000..16d67b3d
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/doc.go
@@ -0,0 +1,9 @@
+//go:generate go run ../generate.go
+
+// Package quickfix contains analyzes that implement code refactorings.
+// None of these analyzers produce diagnostics that have to be followed.
+// Most of the time, they only provide alternative ways of doing things,
+// requiring users to make informed decisions.
+//
+// None of these analyzes should fail a build, and they are likely useless in CI as a whole.
+package quickfix
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1001/qf1001.go b/vendor/honnef.co/go/tools/quickfix/qf1001/qf1001.go
new file mode 100644
index 00000000..65835717
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1001/qf1001.go
@@ -0,0 +1,124 @@
+package qf1001
+
+import (
+ "go/ast"
+ "go/types"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/go/ast/astutil"
+ "honnef.co/go/tools/pattern"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1001",
+ Run: CheckDeMorgan,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: "Apply De Morgan's law",
+ Since: "2021.1",
+ Severity: lint.SeverityHint,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var demorganQ = pattern.MustParse(`(UnaryExpr "!" expr@(BinaryExpr _ _ _))`)
+
+func CheckDeMorgan(pass *analysis.Pass) (interface{}, error) {
+ // TODO(dh): support going in the other direction, e.g. turning `!a && !b && !c` into `!(a || b || c)`
+
+ // hasFloats reports whether any subexpression is of type float.
+ hasFloats := func(expr ast.Expr) bool {
+ found := false
+ ast.Inspect(expr, func(node ast.Node) bool {
+ if expr, ok := node.(ast.Expr); ok {
+ if typ := pass.TypesInfo.TypeOf(expr); typ != nil {
+ if basic, ok := typ.Underlying().(*types.Basic); ok {
+ if (basic.Info() & types.IsFloat) != 0 {
+ found = true
+ return false
+ }
+ }
+ }
+ }
+ return true
+ })
+ return found
+ }
+
+ fn := func(node ast.Node, stack []ast.Node) {
+ matcher, ok := code.Match(pass, demorganQ, node)
+ if !ok {
+ return
+ }
+
+ expr := matcher.State["expr"].(ast.Expr)
+
+ // be extremely conservative when it comes to floats
+ if hasFloats(expr) {
+ return
+ }
+
+ n := astutil.NegateDeMorgan(expr, false)
+ nr := astutil.NegateDeMorgan(expr, true)
+ nc, ok := astutil.CopyExpr(n)
+ if !ok {
+ return
+ }
+ ns := astutil.SimplifyParentheses(nc)
+ nrc, ok := astutil.CopyExpr(nr)
+ if !ok {
+ return
+ }
+ nrs := astutil.SimplifyParentheses(nrc)
+
+ var bn, bnr, bns, bnrs string
+ switch parent := stack[len(stack)-2]; parent.(type) {
+ case *ast.BinaryExpr, *ast.IfStmt, *ast.ForStmt, *ast.SwitchStmt:
+ // Always add parentheses for if, for and switch. If
+ // they're unnecessary, go/printer will strip them when
+ // the whole file gets formatted.
+
+ bn = report.Render(pass, &ast.ParenExpr{X: n})
+ bnr = report.Render(pass, &ast.ParenExpr{X: nr})
+ bns = report.Render(pass, &ast.ParenExpr{X: ns})
+ bnrs = report.Render(pass, &ast.ParenExpr{X: nrs})
+
+ default:
+ // TODO are there other types where we don't want to strip parentheses?
+ bn = report.Render(pass, n)
+ bnr = report.Render(pass, nr)
+ bns = report.Render(pass, ns)
+ bnrs = report.Render(pass, nrs)
+ }
+
+ // Note: we cannot compare the ASTs directly, because
+ // simplifyParentheses might have rebalanced trees without
+ // affecting the rendered form.
+ var fixes []analysis.SuggestedFix
+ fixes = append(fixes, edit.Fix("Apply De Morgan's law", edit.ReplaceWithString(node, bn)))
+ if bn != bns {
+ fixes = append(fixes, edit.Fix("Apply De Morgan's law & simplify", edit.ReplaceWithString(node, bns)))
+ }
+ if bn != bnr {
+ fixes = append(fixes, edit.Fix("Apply De Morgan's law recursively", edit.ReplaceWithString(node, bnr)))
+ if bnr != bnrs {
+ fixes = append(fixes, edit.Fix("Apply De Morgan's law recursively & simplify", edit.ReplaceWithString(node, bnrs)))
+ }
+ }
+
+ report.Report(pass, node, "could apply De Morgan's law", report.Fixes(fixes...))
+ }
+
+ code.PreorderStack(pass, fn, (*ast.UnaryExpr)(nil))
+
+ return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1002/qf1002.go b/vendor/honnef.co/go/tools/quickfix/qf1002/qf1002.go
new file mode 100644
index 00000000..ff4bf9cd
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1002/qf1002.go
@@ -0,0 +1,145 @@
+package qf1002
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "strings"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/go/ast/astutil"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1002",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: "Convert untagged switch to tagged switch",
+ Text: `
+An untagged switch that compares a single variable against a series of
+values can be replaced with a tagged switch.`,
+ Before: `
+switch {
+case x == 1 || x == 2, x == 3:
+ ...
+case x == 4:
+ ...
+default:
+ ...
+}`,
+
+ After: `
+switch x {
+case 1, 2, 3:
+ ...
+case 4:
+ ...
+default:
+ ...
+}`,
+ Since: "2021.1",
+ Severity: lint.SeverityHint,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ fn := func(node ast.Node) {
+ swtch := node.(*ast.SwitchStmt)
+ if swtch.Tag != nil || len(swtch.Body.List) == 0 {
+ return
+ }
+
+ pairs := make([][]*ast.BinaryExpr, len(swtch.Body.List))
+ for i, stmt := range swtch.Body.List {
+ stmt := stmt.(*ast.CaseClause)
+ for _, cond := range stmt.List {
+ if !findSwitchPairs(pass, cond, &pairs[i]) {
+ return
+ }
+ }
+ }
+
+ var x ast.Expr
+ for _, pair := range pairs {
+ if len(pair) == 0 {
+ continue
+ }
+ if x == nil {
+ x = pair[0].X
+ } else {
+ if !astutil.Equal(x, pair[0].X) {
+ return
+ }
+ }
+ }
+ if x == nil {
+ // the switch only has a default case
+ if len(pairs) > 1 {
+ panic("found more than one case clause with no pairs")
+ }
+ return
+ }
+
+ edits := make([]analysis.TextEdit, 0, len(swtch.Body.List)+1)
+ for i, stmt := range swtch.Body.List {
+ stmt := stmt.(*ast.CaseClause)
+ if stmt.List == nil {
+ continue
+ }
+
+ var values []string
+ for _, binexpr := range pairs[i] {
+ y := binexpr.Y
+ if p, ok := y.(*ast.ParenExpr); ok {
+ y = p.X
+ }
+ values = append(values, report.Render(pass, y))
+ }
+
+ edits = append(edits, edit.ReplaceWithString(edit.Range{stmt.List[0].Pos(), stmt.Colon}, strings.Join(values, ", ")))
+ }
+ pos := swtch.Body.Lbrace
+ edits = append(edits, edit.ReplaceWithString(edit.Range{pos, pos}, " "+report.Render(pass, x)))
+ report.Report(pass, swtch, fmt.Sprintf("could use tagged switch on %s", report.Render(pass, x)),
+ report.Fixes(edit.Fix("Replace with tagged switch", edits...)))
+ }
+
+ code.Preorder(pass, fn, (*ast.SwitchStmt)(nil))
+ return nil, nil
+}
+
+func findSwitchPairs(pass *analysis.Pass, expr ast.Expr, pairs *[]*ast.BinaryExpr) bool {
+ binexpr, ok := astutil.Unparen(expr).(*ast.BinaryExpr)
+ if !ok {
+ return false
+ }
+ switch binexpr.Op {
+ case token.EQL:
+ if code.MayHaveSideEffects(pass, binexpr.X, nil) || code.MayHaveSideEffects(pass, binexpr.Y, nil) {
+ return false
+ }
+ // syntactic identity should suffice. we do not allow side
+ // effects in the case clauses, so there should be no way for
+ // values to change.
+ if len(*pairs) > 0 && !astutil.Equal(binexpr.X, (*pairs)[0].X) {
+ return false
+ }
+ *pairs = append(*pairs, binexpr)
+ return true
+ case token.LOR:
+ return findSwitchPairs(pass, binexpr.X, pairs) && findSwitchPairs(pass, binexpr.Y, pairs)
+ default:
+ return false
+ }
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1003/qf1003.go b/vendor/honnef.co/go/tools/quickfix/qf1003/qf1003.go
new file mode 100644
index 00000000..dd537f95
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1003/qf1003.go
@@ -0,0 +1,204 @@
+package qf1003
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "strings"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/go/ast/astutil"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1003",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: "Convert if/else-if chain to tagged switch",
+ Text: `
+A series of if/else-if checks comparing the same variable against
+values can be replaced with a tagged switch.`,
+ Before: `
+if x == 1 || x == 2 {
+ ...
+} else if x == 3 {
+ ...
+} else {
+ ...
+}`,
+
+ After: `
+switch x {
+case 1, 2:
+ ...
+case 3:
+ ...
+default:
+ ...
+}`,
+ Since: "2021.1",
+ Severity: lint.SeverityInfo,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ fn := func(node ast.Node, stack []ast.Node) {
+ if _, ok := stack[len(stack)-2].(*ast.IfStmt); ok {
+ // this if statement is part of an if-else chain
+ return
+ }
+ ifstmt := node.(*ast.IfStmt)
+
+ m := map[ast.Expr][]*ast.BinaryExpr{}
+ for item := ifstmt; item != nil; {
+ if item.Init != nil {
+ return
+ }
+ if item.Body == nil {
+ return
+ }
+
+ skip := false
+ ast.Inspect(item.Body, func(node ast.Node) bool {
+ if branch, ok := node.(*ast.BranchStmt); ok && branch.Tok != token.GOTO {
+ skip = true
+ return false
+ }
+ return true
+ })
+ if skip {
+ return
+ }
+
+ var pairs []*ast.BinaryExpr
+ if !findSwitchPairs(pass, item.Cond, &pairs) {
+ return
+ }
+ m[item.Cond] = pairs
+ switch els := item.Else.(type) {
+ case *ast.IfStmt:
+ item = els
+ case *ast.BlockStmt, nil:
+ item = nil
+ default:
+ panic(fmt.Sprintf("unreachable: %T", els))
+ }
+ }
+
+ var x ast.Expr
+ for _, pair := range m {
+ if len(pair) == 0 {
+ continue
+ }
+ if x == nil {
+ x = pair[0].X
+ } else {
+ if !astutil.Equal(x, pair[0].X) {
+ return
+ }
+ }
+ }
+ if x == nil {
+ // shouldn't happen
+ return
+ }
+
+ // We require at least two 'if' to make this suggestion, to
+ // avoid clutter in the editor.
+ if len(m) < 2 {
+ return
+ }
+
+ // Note that we insert the switch statement as the first text edit instead of the last one so that gopls has an
+ // easier time converting it to an LSP-conforming edit.
+ //
+ // Specifically:
+ // > Text edits ranges must never overlap, that means no part of the original
+ // > document must be manipulated by more than one edit. However, it is
+ // > possible that multiple edits have the same start position: multiple
+ // > inserts, or any number of inserts followed by a single remove or replace
+ // > edit. If multiple inserts have the same position, the order in the array
+ // > defines the order in which the inserted strings appear in the resulting
+ // > text.
+ //
+ // See https://go.dev/issue/63930
+ //
+ // FIXME this edit forces the first case to begin in column 0 because we ignore indentation. try to fix that.
+ edits := []analysis.TextEdit{edit.ReplaceWithString(edit.Range{ifstmt.If, ifstmt.If}, fmt.Sprintf("switch %s {\n", report.Render(pass, x)))}
+ for item := ifstmt; item != nil; {
+ var end token.Pos
+ if item.Else != nil {
+ end = item.Else.Pos()
+ } else {
+ // delete up to but not including the closing brace.
+ end = item.Body.Rbrace
+ }
+
+ var conds []string
+ for _, cond := range m[item.Cond] {
+ y := cond.Y
+ if p, ok := y.(*ast.ParenExpr); ok {
+ y = p.X
+ }
+ conds = append(conds, report.Render(pass, y))
+ }
+ sconds := strings.Join(conds, ", ")
+ edits = append(edits,
+ edit.ReplaceWithString(edit.Range{item.If, item.Body.Lbrace + 1}, "case "+sconds+":"),
+ edit.Delete(edit.Range{item.Body.Rbrace, end}))
+
+ switch els := item.Else.(type) {
+ case *ast.IfStmt:
+ item = els
+ case *ast.BlockStmt:
+ edits = append(edits, edit.ReplaceWithString(edit.Range{els.Lbrace, els.Lbrace + 1}, "default:"))
+ item = nil
+ case nil:
+ item = nil
+ default:
+ panic(fmt.Sprintf("unreachable: %T", els))
+ }
+ }
+ report.Report(pass, ifstmt, fmt.Sprintf("could use tagged switch on %s", report.Render(pass, x)),
+ report.Fixes(edit.Fix("Replace with tagged switch", edits...)),
+ report.ShortRange())
+ }
+ code.PreorderStack(pass, fn, (*ast.IfStmt)(nil))
+ return nil, nil
+}
+
+func findSwitchPairs(pass *analysis.Pass, expr ast.Expr, pairs *[]*ast.BinaryExpr) bool {
+ binexpr, ok := astutil.Unparen(expr).(*ast.BinaryExpr)
+ if !ok {
+ return false
+ }
+ switch binexpr.Op {
+ case token.EQL:
+ if code.MayHaveSideEffects(pass, binexpr.X, nil) || code.MayHaveSideEffects(pass, binexpr.Y, nil) {
+ return false
+ }
+ // syntactic identity should suffice. we do not allow side
+ // effects in the case clauses, so there should be no way for
+ // values to change.
+ if len(*pairs) > 0 && !astutil.Equal(binexpr.X, (*pairs)[0].X) {
+ return false
+ }
+ *pairs = append(*pairs, binexpr)
+ return true
+ case token.LOR:
+ return findSwitchPairs(pass, binexpr.X, pairs) && findSwitchPairs(pass, binexpr.Y, pairs)
+ default:
+ return false
+ }
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1004/qf1004.go b/vendor/honnef.co/go/tools/quickfix/qf1004/qf1004.go
new file mode 100644
index 00000000..27f04320
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1004/qf1004.go
@@ -0,0 +1,79 @@
+package qf1004
+
+import (
+ "fmt"
+ "go/ast"
+ "go/types"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/go/types/typeutil"
+ "honnef.co/go/tools/pattern"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1004",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: `Use \'strings.ReplaceAll\' instead of \'strings.Replace\' with \'n == -1\'`,
+ Since: "2021.1",
+ Severity: lint.SeverityHint,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var stringsReplaceAllQ = pattern.MustParse(`(Or
+ (CallExpr fn@(Symbol "strings.Replace") [_ _ _ lit@(IntegerLiteral "-1")])
+ (CallExpr fn@(Symbol "strings.SplitN") [_ _ lit@(IntegerLiteral "-1")])
+ (CallExpr fn@(Symbol "strings.SplitAfterN") [_ _ lit@(IntegerLiteral "-1")])
+ (CallExpr fn@(Symbol "bytes.Replace") [_ _ _ lit@(IntegerLiteral "-1")])
+ (CallExpr fn@(Symbol "bytes.SplitN") [_ _ lit@(IntegerLiteral "-1")])
+ (CallExpr fn@(Symbol "bytes.SplitAfterN") [_ _ lit@(IntegerLiteral "-1")]))`)
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ // XXX respect minimum Go version
+
+ // FIXME(dh): create proper suggested fix for renamed import
+
+ fn := func(node ast.Node) {
+ matcher, ok := code.Match(pass, stringsReplaceAllQ, node)
+ if !ok {
+ return
+ }
+
+ var replacement string
+ switch typeutil.FuncName(matcher.State["fn"].(*types.Func)) {
+ case "strings.Replace":
+ replacement = "strings.ReplaceAll"
+ case "strings.SplitN":
+ replacement = "strings.Split"
+ case "strings.SplitAfterN":
+ replacement = "strings.SplitAfter"
+ case "bytes.Replace":
+ replacement = "bytes.ReplaceAll"
+ case "bytes.SplitN":
+ replacement = "bytes.Split"
+ case "bytes.SplitAfterN":
+ replacement = "bytes.SplitAfter"
+ default:
+ panic("unreachable")
+ }
+
+ call := node.(*ast.CallExpr)
+ report.Report(pass, call.Fun, fmt.Sprintf("could use %s instead", replacement),
+ report.Fixes(edit.Fix(fmt.Sprintf("Use %s instead", replacement),
+ edit.ReplaceWithString(call.Fun, replacement),
+ edit.Delete(matcher.State["lit"].(ast.Node)))))
+ }
+ code.Preorder(pass, fn, (*ast.CallExpr)(nil))
+ return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1005/qf1005.go b/vendor/honnef.co/go/tools/quickfix/qf1005/qf1005.go
new file mode 100644
index 00000000..d859bfeb
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1005/qf1005.go
@@ -0,0 +1,118 @@
+package qf1005
+
+import (
+ "go/ast"
+ "go/constant"
+ "go/token"
+ "go/types"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/go/ast/astutil"
+ "honnef.co/go/tools/pattern"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1005",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: `Expand call to \'math.Pow\'`,
+ Text: `Some uses of \'math.Pow\' can be simplified to basic multiplication.`,
+ Before: `math.Pow(x, 2)`,
+ After: `x * x`,
+ Since: "2021.1",
+ Severity: lint.SeverityHint,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var mathPowQ = pattern.MustParse(`(CallExpr (Symbol "math.Pow") [x (IntegerLiteral n)])`)
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ fn := func(node ast.Node) {
+ matcher, ok := code.Match(pass, mathPowQ, node)
+ if !ok {
+ return
+ }
+
+ x := matcher.State["x"].(ast.Expr)
+ if code.MayHaveSideEffects(pass, x, nil) {
+ return
+ }
+ n, ok := constant.Int64Val(constant.ToInt(matcher.State["n"].(types.TypeAndValue).Value))
+ if !ok {
+ return
+ }
+
+ needConversion := false
+ if T, ok := pass.TypesInfo.Types[x]; ok && T.Value != nil {
+ info := types.Info{
+ Types: map[ast.Expr]types.TypeAndValue{},
+ }
+
+ // determine if the constant expression would have type float64 if used on its own
+ if err := types.CheckExpr(pass.Fset, pass.Pkg, x.Pos(), x, &info); err != nil {
+ // This should not happen
+ return
+ }
+ if T, ok := info.Types[x].Type.(*types.Basic); ok {
+ if T.Kind() != types.UntypedFloat && T.Kind() != types.Float64 {
+ needConversion = true
+ }
+ } else {
+ needConversion = true
+ }
+ }
+
+ var replacement ast.Expr
+ switch n {
+ case 0:
+ replacement = &ast.BasicLit{
+ Kind: token.FLOAT,
+ Value: "1.0",
+ }
+ case 1:
+ replacement = x
+ case 2, 3:
+ r := &ast.BinaryExpr{
+ X: x,
+ Op: token.MUL,
+ Y: x,
+ }
+ for i := 3; i <= int(n); i++ {
+ r = &ast.BinaryExpr{
+ X: r,
+ Op: token.MUL,
+ Y: x,
+ }
+ }
+
+ rc, ok := astutil.CopyExpr(r)
+ if !ok {
+ return
+ }
+ replacement = astutil.SimplifyParentheses(rc)
+ default:
+ return
+ }
+ if needConversion && n != 0 {
+ replacement = &ast.CallExpr{
+ Fun: &ast.Ident{Name: "float64"},
+ Args: []ast.Expr{replacement},
+ }
+ }
+ report.Report(pass, node, "could expand call to math.Pow",
+ report.Fixes(edit.Fix("Expand call to math.Pow", edit.ReplaceWithNode(pass.Fset, node, replacement))))
+ }
+ code.Preorder(pass, fn, (*ast.CallExpr)(nil))
+ return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1006/qf1006.go b/vendor/honnef.co/go/tools/quickfix/qf1006/qf1006.go
new file mode 100644
index 00000000..47d4dd0d
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1006/qf1006.go
@@ -0,0 +1,68 @@
+package qf1006
+
+import (
+ "go/ast"
+ "go/token"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/go/ast/astutil"
+ "honnef.co/go/tools/pattern"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1006",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: `Lift \'if\'+\'break\' into loop condition`,
+ Before: `
+for {
+ if done {
+ break
+ }
+ ...
+}`,
+
+ After: `
+for !done {
+ ...
+}`,
+ Since: "2021.1",
+ Severity: lint.SeverityHint,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkForLoopIfBreak = pattern.MustParse(`(ForStmt nil nil nil if@(IfStmt nil cond (BranchStmt "BREAK" nil) nil):_)`)
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ fn := func(node ast.Node) {
+ m, ok := code.Match(pass, checkForLoopIfBreak, node)
+ if !ok {
+ return
+ }
+
+ pos := node.Pos() + token.Pos(len("for"))
+ r := astutil.NegateDeMorgan(m.State["cond"].(ast.Expr), false)
+
+ // FIXME(dh): we're leaving behind an empty line when we
+ // delete the old if statement. However, we can't just delete
+ // an additional character, in case there closing curly brace
+ // is followed by a comment, or Windows newlines.
+ report.Report(pass, m.State["if"].(ast.Node), "could lift into loop condition",
+ report.Fixes(edit.Fix("Lift into loop condition",
+ edit.ReplaceWithString(edit.Range{pos, pos}, " "+report.Render(pass, r)),
+ edit.Delete(m.State["if"].(ast.Node)))))
+ }
+ code.Preorder(pass, fn, (*ast.ForStmt)(nil))
+ return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1007/qf1007.go b/vendor/honnef.co/go/tools/quickfix/qf1007/qf1007.go
new file mode 100644
index 00000000..62a339c7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1007/qf1007.go
@@ -0,0 +1,92 @@
+package qf1007
+
+import (
+ "go/ast"
+ "go/token"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/pattern"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1007",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: "Merge conditional assignment into variable declaration",
+ Before: `
+x := false
+if someCondition {
+ x = true
+}`,
+ After: `x := someCondition`,
+ Since: "2021.1",
+ Severity: lint.SeverityHint,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkConditionalAssignmentQ = pattern.MustParse(`(AssignStmt x@(Object _) ":=" assign@(Builtin b@(Or "true" "false")))`)
+var checkConditionalAssignmentIfQ = pattern.MustParse(`(IfStmt nil cond [(AssignStmt x@(Object _) "=" (Builtin b@(Or "true" "false")))] nil)`)
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ fn := func(node ast.Node) {
+ var body *ast.BlockStmt
+ switch node := node.(type) {
+ case *ast.FuncDecl:
+ body = node.Body
+ case *ast.FuncLit:
+ body = node.Body
+ default:
+ panic("unreachable")
+ }
+ if body == nil {
+ return
+ }
+
+ stmts := body.List
+ if len(stmts) < 2 {
+ return
+ }
+ for i, first := range stmts[:len(stmts)-1] {
+ second := stmts[i+1]
+ m1, ok := code.Match(pass, checkConditionalAssignmentQ, first)
+ if !ok {
+ continue
+ }
+ m2, ok := code.Match(pass, checkConditionalAssignmentIfQ, second)
+ if !ok {
+ continue
+ }
+ if m1.State["x"] != m2.State["x"] {
+ continue
+ }
+ if m1.State["b"] == m2.State["b"] {
+ continue
+ }
+
+ v := m2.State["cond"].(ast.Expr)
+ if m1.State["b"] == "true" {
+ v = &ast.UnaryExpr{
+ Op: token.NOT,
+ X: v,
+ }
+ }
+ report.Report(pass, first, "could merge conditional assignment into variable declaration",
+ report.Fixes(edit.Fix("Merge conditional assignment into variable declaration",
+ edit.ReplaceWithNode(pass.Fset, m1.State["assign"].(ast.Node), v),
+ edit.Delete(second))))
+ }
+ }
+ code.Preorder(pass, fn, (*ast.FuncDecl)(nil), (*ast.FuncLit)(nil))
+ return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1008/qf1008.go b/vendor/honnef.co/go/tools/quickfix/qf1008/qf1008.go
new file mode 100644
index 00000000..799db53d
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1008/qf1008.go
@@ -0,0 +1,156 @@
+package qf1008
+
+import (
+ "fmt"
+ "go/ast"
+ "go/types"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/go/ast/astutil"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1008",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: "Omit embedded fields from selector expression",
+ Since: "2021.1",
+ Severity: lint.SeverityHint,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ type Selector struct {
+ Node *ast.SelectorExpr
+ X ast.Expr
+ Fields []*ast.Ident
+ }
+
+ // extractSelectors extracts uninterrupted sequences of selector expressions.
+ // For example, for a.b.c().d.e[0].f.g three sequences will be returned: (X=a, X.b.c), (X=a.b.c(), X.d.e), and (X=a.b.c().d.e[0], X.f.g)
+ //
+ // It returns nil if the provided selector expression is not the root of a set of sequences.
+ // For example, for a.b.c, if node is b.c, no selectors will be returned.
+ extractSelectors := func(expr *ast.SelectorExpr) []Selector {
+ path, _ := astutil.PathEnclosingInterval(code.File(pass, expr), expr.Pos(), expr.Pos())
+ for i := len(path) - 1; i >= 0; i-- {
+ if el, ok := path[i].(*ast.SelectorExpr); ok {
+ if el != expr {
+ // this expression is a subset of the entire chain, don't look at it.
+ return nil
+ }
+ break
+ }
+ }
+
+ inChain := false
+ var out []Selector
+ for _, el := range path {
+ if expr, ok := el.(*ast.SelectorExpr); ok {
+ if !inChain {
+ inChain = true
+ out = append(out, Selector{X: expr.X})
+ }
+ sel := &out[len(out)-1]
+ sel.Fields = append(sel.Fields, expr.Sel)
+ sel.Node = expr
+ } else if inChain {
+ inChain = false
+ }
+ }
+ return out
+ }
+
+ fn := func(node ast.Node) {
+ expr := node.(*ast.SelectorExpr)
+
+ if _, ok := expr.X.(*ast.SelectorExpr); !ok {
+ // Avoid the expensive call to PathEnclosingInterval for the common 1-level deep selector, which cannot be shortened.
+ return
+ }
+
+ sels := extractSelectors(expr)
+ if len(sels) == 0 {
+ return
+ }
+
+ var edits []analysis.TextEdit
+ for _, sel := range sels {
+ fieldLoop:
+ for base, fields := pass.TypesInfo.TypeOf(sel.X), sel.Fields; len(fields) >= 2; base, fields = pass.TypesInfo.ObjectOf(fields[0]).Type(), fields[1:] {
+ hop1 := fields[0]
+ hop2 := fields[1]
+
+ // the selector expression might be a qualified identifier, which cannot be simplified
+ if base == types.Typ[types.Invalid] {
+ continue fieldLoop
+ }
+
+ // Check if we can skip a field in the chain of selectors.
+ // We can skip a field 'b' if a.b.c and a.c resolve to the same object and take the same path.
+ //
+ // We set addressable to true unconditionally because we've already successfully type-checked the program,
+ // which means either the selector doesn't need addressability, or it is addressable.
+ leftObj, leftLeg, _ := types.LookupFieldOrMethod(base, true, pass.Pkg, hop1.Name)
+
+ // We can't skip fields that aren't embedded
+ if !leftObj.(*types.Var).Embedded() {
+ continue fieldLoop
+ }
+
+ directObj, directPath, _ := types.LookupFieldOrMethod(base, true, pass.Pkg, hop2.Name)
+
+ // Fail fast if omitting the embedded field leads to a different object
+ if directObj != pass.TypesInfo.ObjectOf(hop2) {
+ continue fieldLoop
+ }
+
+ _, rightLeg, _ := types.LookupFieldOrMethod(leftObj.Type(), true, pass.Pkg, hop2.Name)
+
+ // Fail fast if the paths are obviously different
+ if len(directPath) != len(leftLeg)+len(rightLeg) {
+ continue fieldLoop
+ }
+
+ // Make sure that omitting the embedded field will take the same path to the final object.
+ // Multiple paths involving different fields may lead to the same type-checker object, causing different runtime behavior.
+ for i := range directPath {
+ if i < len(leftLeg) {
+ if leftLeg[i] != directPath[i] {
+ continue fieldLoop
+ }
+ } else {
+ if rightLeg[i-len(leftLeg)] != directPath[i] {
+ continue fieldLoop
+ }
+ }
+ }
+
+ e := edit.Delete(edit.Range{hop1.Pos(), hop2.Pos()})
+ edits = append(edits, e)
+ report.Report(pass, hop1, fmt.Sprintf("could remove embedded field %q from selector", hop1.Name),
+ report.Fixes(edit.Fix(fmt.Sprintf("Remove embedded field %q from selector", hop1.Name), e)))
+ }
+ }
+
+ // Offer to simplify all selector expressions at once
+ if len(edits) > 1 {
+ // Hack to prevent gopls from applying the Unnecessary tag to the diagnostic. It applies the tag when all edits are deletions.
+ edits = append(edits, edit.ReplaceWithString(edit.Range{node.Pos(), node.Pos()}, ""))
+ report.Report(pass, node, "could simplify selectors", report.Fixes(edit.Fix("Remove all embedded fields from selector", edits...)))
+ }
+ }
+ code.Preorder(pass, fn, (*ast.SelectorExpr)(nil))
+ return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1009/qf1009.go b/vendor/honnef.co/go/tools/quickfix/qf1009/qf1009.go
new file mode 100644
index 00000000..e9fe9fb2
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1009/qf1009.go
@@ -0,0 +1,51 @@
+package qf1009
+
+import (
+ "go/ast"
+ "go/token"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/pattern"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1009",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: `Use \'time.Time.Equal\' instead of \'==\' operator`,
+ Since: "2021.1",
+ Severity: lint.SeverityInfo,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var timeEqualR = pattern.MustParse(`(CallExpr (SelectorExpr lhs (Ident "Equal")) rhs)`)
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ // FIXME(dh): create proper suggested fix for renamed import
+
+ fn := func(node ast.Node) {
+ expr := node.(*ast.BinaryExpr)
+ if expr.Op != token.EQL {
+ return
+ }
+ if !code.IsOfTypeWithName(pass, expr.X, "time.Time") || !code.IsOfTypeWithName(pass, expr.Y, "time.Time") {
+ return
+ }
+ report.Report(pass, node, "probably want to use time.Time.Equal instead",
+ report.Fixes(edit.Fix("Use time.Time.Equal method",
+ edit.ReplaceWithPattern(pass.Fset, node, timeEqualR, pattern.State{"lhs": expr.X, "rhs": expr.Y}))))
+ }
+ code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
+ return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1010/qf1010.go b/vendor/honnef.co/go/tools/quickfix/qf1010/qf1010.go
new file mode 100644
index 00000000..2062d1f5
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1010/qf1010.go
@@ -0,0 +1,81 @@
+package qf1010
+
+import (
+ "go/ast"
+ "go/types"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/knowledge"
+ "honnef.co/go/tools/pattern"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1010",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: "Convert slice of bytes to string when printing it",
+ Since: "2021.1",
+ Severity: lint.SeverityHint,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var byteSlicePrintingQ = pattern.MustParse(`
+ (Or
+ (CallExpr
+ (Symbol (Or
+ "fmt.Print"
+ "fmt.Println"
+ "fmt.Sprint"
+ "fmt.Sprintln"
+ "log.Fatal"
+ "log.Fatalln"
+ "log.Panic"
+ "log.Panicln"
+ "log.Print"
+ "log.Println"
+ "(*log.Logger).Fatal"
+ "(*log.Logger).Fatalln"
+ "(*log.Logger).Panic"
+ "(*log.Logger).Panicln"
+ "(*log.Logger).Print"
+ "(*log.Logger).Println")) args)
+
+ (CallExpr (Symbol (Or
+ "fmt.Fprint"
+ "fmt.Fprintln")) _:args))`)
+
+var byteSlicePrintingR = pattern.MustParse(`(CallExpr (Ident "string") [arg])`)
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ fn := func(node ast.Node) {
+ m, ok := code.Match(pass, byteSlicePrintingQ, node)
+ if !ok {
+ return
+ }
+ args := m.State["args"].([]ast.Expr)
+ for _, arg := range args {
+ if !code.IsOfStringConvertibleByteSlice(pass, arg) {
+ continue
+ }
+ if types.Implements(pass.TypesInfo.TypeOf(arg), knowledge.Interfaces["fmt.Stringer"]) {
+ continue
+ }
+
+ fix := edit.Fix("Convert argument to string", edit.ReplaceWithPattern(pass.Fset, arg, byteSlicePrintingR, pattern.State{"arg": arg}))
+ report.Report(pass, arg, "could convert argument to string", report.Fixes(fix))
+ }
+ }
+ code.Preorder(pass, fn, (*ast.CallExpr)(nil))
+ return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1011/qf1011.go b/vendor/honnef.co/go/tools/quickfix/qf1011/qf1011.go
new file mode 100644
index 00000000..f77fdb9d
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1011/qf1011.go
@@ -0,0 +1,21 @@
+package qf1011
+
+import (
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/internal/sharedcheck"
+)
+
+func init() {
+ SCAnalyzer.Analyzer.Name = "QF1011"
+}
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: sharedcheck.RedundantTypeInDeclarationChecker("could", true),
+ Doc: &lint.RawDocumentation{
+ Title: "Omit redundant type from variable declaration",
+ Since: "2021.1",
+ Severity: lint.SeverityHint,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1012/qf1012.go b/vendor/honnef.co/go/tools/quickfix/qf1012/qf1012.go
new file mode 100644
index 00000000..430610bb
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1012/qf1012.go
@@ -0,0 +1,110 @@
+package qf1012
+
+import (
+ "fmt"
+ "go/ast"
+ "go/types"
+ "strings"
+
+ "honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/edit"
+ "honnef.co/go/tools/analysis/lint"
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/knowledge"
+ "honnef.co/go/tools/pattern"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+ Analyzer: &analysis.Analyzer{
+ Name: "QF1012",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ },
+ Doc: &lint.RawDocumentation{
+ Title: `Use \'fmt.Fprintf(x, ...)\' instead of \'x.Write(fmt.Sprintf(...))\'`,
+ Since: "2022.1",
+ Severity: lint.SeverityHint,
+ },
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+ checkWriteBytesSprintfQ = pattern.MustParse(`
+ (CallExpr
+ (SelectorExpr recv (Ident "Write"))
+ (CallExpr (ArrayType nil (Ident "byte"))
+ (CallExpr
+ fn@(Or
+ (Symbol "fmt.Sprint")
+ (Symbol "fmt.Sprintf")
+ (Symbol "fmt.Sprintln"))
+ args)
+ ))`)
+
+ checkWriteStringSprintfQ = pattern.MustParse(`
+ (CallExpr
+ (SelectorExpr recv (Ident "WriteString"))
+ (CallExpr
+ fn@(Or
+ (Symbol "fmt.Sprint")
+ (Symbol "fmt.Sprintf")
+ (Symbol "fmt.Sprintln"))
+ args))`)
+)
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ fn := func(node ast.Node) {
+ if m, ok := code.Match(pass, checkWriteBytesSprintfQ, node); ok {
+ recv := m.State["recv"].(ast.Expr)
+ recvT := pass.TypesInfo.TypeOf(recv)
+ if !types.Implements(recvT, knowledge.Interfaces["io.Writer"]) {
+ return
+ }
+
+ name := m.State["fn"].(*types.Func).Name()
+ newName := "F" + strings.TrimPrefix(name, "S")
+ msg := fmt.Sprintf("Use fmt.%s(...) instead of Write([]byte(fmt.%s(...)))", newName, name)
+
+ args := m.State["args"].([]ast.Expr)
+ fix := edit.Fix(msg, edit.ReplaceWithNode(pass.Fset, node, &ast.CallExpr{
+ Fun: &ast.SelectorExpr{
+ X: ast.NewIdent("fmt"),
+ Sel: ast.NewIdent(newName),
+ },
+ Args: append([]ast.Expr{recv}, args...),
+ }))
+ report.Report(pass, node, msg, report.Fixes(fix))
+ } else if m, ok := code.Match(pass, checkWriteStringSprintfQ, node); ok {
+ recv := m.State["recv"].(ast.Expr)
+ recvT := pass.TypesInfo.TypeOf(recv)
+ if !types.Implements(recvT, knowledge.Interfaces["io.StringWriter"]) {
+ return
+ }
+ // The type needs to implement both StringWriter and Writer.
+ // If it doesn't implement Writer, then we cannot pass it to fmt.Fprint.
+ if !types.Implements(recvT, knowledge.Interfaces["io.Writer"]) {
+ return
+ }
+
+ name := m.State["fn"].(*types.Func).Name()
+ newName := "F" + strings.TrimPrefix(name, "S")
+ msg := fmt.Sprintf("Use fmt.%s(...) instead of WriteString(fmt.%s(...))", newName, name)
+
+ args := m.State["args"].([]ast.Expr)
+ fix := edit.Fix(msg, edit.ReplaceWithNode(pass.Fset, node, &ast.CallExpr{
+ Fun: &ast.SelectorExpr{
+ X: ast.NewIdent("fmt"),
+ Sel: ast.NewIdent(newName),
+ },
+ Args: append([]ast.Expr{recv}, args...),
+ }))
+ report.Report(pass, node, msg, report.Fixes(fix))
+ }
+ }
+ code.Preorder(pass, fn, (*ast.CallExpr)(nil))
+ return nil, nil
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 92c6fe2c..701ae1f4 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -13,14 +13,14 @@ github.com/4meepo/tagalign
# github.com/Abirdcfly/dupword v0.1.3
## explicit; go 1.22.0
github.com/Abirdcfly/dupword
-# github.com/Antonboom/errname v1.0.0
-## explicit; go 1.22.1
+# github.com/Antonboom/errname v1.1.0
+## explicit; go 1.23.0
github.com/Antonboom/errname/pkg/analyzer
-# github.com/Antonboom/nilnil v1.0.1
-## explicit; go 1.22.0
+# github.com/Antonboom/nilnil v1.1.0
+## explicit; go 1.23.0
github.com/Antonboom/nilnil/pkg/analyzer
-# github.com/Antonboom/testifylint v1.5.2
-## explicit; go 1.22.1
+# github.com/Antonboom/testifylint v1.6.1
+## explicit; go 1.23.0
github.com/Antonboom/testifylint/analyzer
github.com/Antonboom/testifylint/internal/analysisutil
github.com/Antonboom/testifylint/internal/checkers
@@ -31,9 +31,6 @@ github.com/Antonboom/testifylint/internal/testify
## explicit; go 1.18
github.com/BurntSushi/toml
github.com/BurntSushi/toml/internal
-# github.com/Crocmagnon/fatcontext v0.7.1
-## explicit; go 1.22.0
-github.com/Crocmagnon/fatcontext/pkg/analyzer
# github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24
## explicit; go 1.13
github.com/Djarvur/go-err113
@@ -62,11 +59,20 @@ github.com/NYTimes/gziphandler
## explicit; go 1.23.0
github.com/OpenPeeDeeP/depguard/v2
github.com/OpenPeeDeeP/depguard/v2/internal/utils
+# github.com/alecthomas/chroma/v2 v2.17.2
+## explicit; go 1.22
+github.com/alecthomas/chroma/v2
+github.com/alecthomas/chroma/v2/formatters
+github.com/alecthomas/chroma/v2/formatters/html
+github.com/alecthomas/chroma/v2/formatters/svg
+github.com/alecthomas/chroma/v2/lexers
+github.com/alecthomas/chroma/v2/quick
+github.com/alecthomas/chroma/v2/styles
# github.com/alecthomas/go-check-sumtype v0.3.1
## explicit; go 1.22.0
github.com/alecthomas/go-check-sumtype
-# github.com/alexkohler/nakedret/v2 v2.0.5
-## explicit; go 1.21
+# github.com/alexkohler/nakedret/v2 v2.0.6
+## explicit; go 1.23.0
github.com/alexkohler/nakedret/v2
# github.com/alexkohler/prealloc v1.0.0
## explicit; go 1.15
@@ -74,7 +80,7 @@ github.com/alexkohler/prealloc/pkg
# github.com/alingse/asasalint v0.0.11
## explicit; go 1.18
github.com/alingse/asasalint
-# github.com/alingse/nilnesserr v0.1.2
+# github.com/alingse/nilnesserr v0.2.0
## explicit; go 1.22.0
github.com/alingse/nilnesserr
github.com/alingse/nilnesserr/internal/typeparams
@@ -135,6 +141,9 @@ github.com/aws/aws-sdk-go/service/sso/ssoiface
github.com/aws/aws-sdk-go/service/ssooidc
github.com/aws/aws-sdk-go/service/sts
github.com/aws/aws-sdk-go/service/sts/stsiface
+# github.com/aymanbagabas/go-osc52/v2 v2.0.1
+## explicit; go 1.16
+github.com/aymanbagabas/go-osc52/v2
# github.com/beorn7/perks v1.0.1
## explicit; go 1.11
github.com/beorn7/perks/quantile
@@ -147,17 +156,17 @@ github.com/blang/semver/v4
# github.com/blizzy78/varnamelen v0.8.0
## explicit; go 1.16
github.com/blizzy78/varnamelen
-# github.com/bombsimon/wsl/v4 v4.5.0
-## explicit; go 1.22
+# github.com/bombsimon/wsl/v4 v4.7.0
+## explicit; go 1.23
github.com/bombsimon/wsl/v4
-# github.com/breml/bidichk v0.3.2
-## explicit; go 1.22.0
+# github.com/breml/bidichk v0.3.3
+## explicit; go 1.23.0
github.com/breml/bidichk/pkg/bidichk
-# github.com/breml/errchkjson v0.4.0
-## explicit; go 1.22.0
+# github.com/breml/errchkjson v0.4.1
+## explicit; go 1.23.0
github.com/breml/errchkjson
-# github.com/butuzov/ireturn v0.3.1
-## explicit; go 1.18
+# github.com/butuzov/ireturn v0.4.0
+## explicit; go 1.23.0
github.com/butuzov/ireturn/analyzer
github.com/butuzov/ireturn/analyzer/internal/config
github.com/butuzov/ireturn/analyzer/internal/types
@@ -165,7 +174,7 @@ github.com/butuzov/ireturn/analyzer/internal/types
## explicit; go 1.19
github.com/butuzov/mirror
github.com/butuzov/mirror/internal/checker
-# github.com/catenacyber/perfsprint v0.8.2
+# github.com/catenacyber/perfsprint v0.9.1
## explicit; go 1.22.0
github.com/catenacyber/perfsprint/analyzer
# github.com/ccojocar/zxcvbn-go v1.0.2
@@ -196,11 +205,28 @@ github.com/cespare/xxhash/v2
# github.com/charithe/durationcheck v0.0.10
## explicit; go 1.14
github.com/charithe/durationcheck
+# github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc
+## explicit; go 1.18
+github.com/charmbracelet/colorprofile
+# github.com/charmbracelet/lipgloss v1.1.0
+## explicit; go 1.18
+github.com/charmbracelet/lipgloss
+# github.com/charmbracelet/x/ansi v0.8.0
+## explicit; go 1.18
+github.com/charmbracelet/x/ansi
+github.com/charmbracelet/x/ansi/kitty
+github.com/charmbracelet/x/ansi/parser
+# github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd
+## explicit; go 1.18
+github.com/charmbracelet/x/cellbuf
+# github.com/charmbracelet/x/term v0.2.1
+## explicit; go 1.18
+github.com/charmbracelet/x/term
# github.com/chavacava/garif v0.1.0
## explicit; go 1.16
github.com/chavacava/garif
-# github.com/ckaznocha/intrange v0.3.0
-## explicit; go 1.22
+# github.com/ckaznocha/intrange v0.3.1
+## explicit; go 1.23.0
github.com/ckaznocha/intrange
# github.com/coreos/go-semver v0.3.1
## explicit; go 1.8
@@ -213,7 +239,7 @@ github.com/coreos/go-systemd/v22/journal
## explicit; go 1.21
github.com/curioswitch/go-reassign
github.com/curioswitch/go-reassign/internal/analyzer
-# github.com/daixiang0/gci v0.13.5
+# github.com/daixiang0/gci v0.13.6
## explicit; go 1.21
github.com/daixiang0/gci/pkg/config
github.com/daixiang0/gci/pkg/format
@@ -224,6 +250,14 @@ github.com/daixiang0/gci/pkg/parse
github.com/daixiang0/gci/pkg/section
github.com/daixiang0/gci/pkg/specificity
github.com/daixiang0/gci/pkg/utils
+# github.com/dave/dst v0.27.3
+## explicit; go 1.18
+github.com/dave/dst
+github.com/dave/dst/decorator
+github.com/dave/dst/decorator/resolver
+github.com/dave/dst/decorator/resolver/gopackages
+github.com/dave/dst/decorator/resolver/gotypes
+github.com/dave/dst/dstutil
# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
## explicit
github.com/davecgh/go-spew/spew
@@ -233,6 +267,10 @@ github.com/denis-tingaikin/go-header
# github.com/distribution/reference v0.6.0
## explicit; go 1.20
github.com/distribution/reference
+# github.com/dlclark/regexp2 v1.11.5
+## explicit; go 1.13
+github.com/dlclark/regexp2
+github.com/dlclark/regexp2/syntax
# github.com/elastic/crd-ref-docs v0.1.0
## explicit; go 1.21
github.com/elastic/crd-ref-docs
@@ -261,8 +299,8 @@ github.com/fatih/structtag
# github.com/felixge/httpsnoop v1.0.4
## explicit; go 1.13
github.com/felixge/httpsnoop
-# github.com/firefart/nonamedreturns v1.0.5
-## explicit; go 1.18
+# github.com/firefart/nonamedreturns v1.0.6
+## explicit; go 1.23.0
github.com/firefart/nonamedreturns/analyzer
# github.com/fsnotify/fsnotify v1.9.0
## explicit; go 1.17
@@ -276,15 +314,15 @@ github.com/fxamacker/cbor/v2
github.com/fzipp/gocyclo
# github.com/gabriel-vasile/mimetype v1.4.9
## explicit; go 1.23.0
-# github.com/ghostiam/protogetter v0.3.9
+# github.com/ghostiam/protogetter v0.3.15
## explicit; go 1.22.0
github.com/ghostiam/protogetter
# github.com/go-bindata/go-bindata v3.1.2+incompatible
## explicit
github.com/go-bindata/go-bindata
github.com/go-bindata/go-bindata/go-bindata
-# github.com/go-critic/go-critic v0.12.0
-## explicit; go 1.22.0
+# github.com/go-critic/go-critic v0.13.0
+## explicit; go 1.23.0
github.com/go-critic/go-critic/checkers
github.com/go-critic/go-critic/checkers/internal/astwalk
github.com/go-critic/go-critic/checkers/internal/lintutil
@@ -397,158 +435,169 @@ github.com/golangci/go-printf-func-name/pkg/analyzer
# github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d
## explicit; go 1.22.0
github.com/golangci/gofmt/gofmt
-# github.com/golangci/golangci-lint v1.64.8
-## explicit; go 1.23.0
-github.com/golangci/golangci-lint/cmd/golangci-lint
-github.com/golangci/golangci-lint/internal/cache
-github.com/golangci/golangci-lint/internal/errorutil
-github.com/golangci/golangci-lint/internal/go/cache
-github.com/golangci/golangci-lint/internal/go/mmap
-github.com/golangci/golangci-lint/internal/go/quoted
-github.com/golangci/golangci-lint/internal/go/robustio
-github.com/golangci/golangci-lint/internal/x/tools/analysisflags
-github.com/golangci/golangci-lint/internal/x/tools/analysisinternal
-github.com/golangci/golangci-lint/internal/x/tools/diff
-github.com/golangci/golangci-lint/internal/x/tools/diff/lcs
-github.com/golangci/golangci-lint/pkg/commands
-github.com/golangci/golangci-lint/pkg/commands/internal
-github.com/golangci/golangci-lint/pkg/config
-github.com/golangci/golangci-lint/pkg/exitcodes
-github.com/golangci/golangci-lint/pkg/fsutils
-github.com/golangci/golangci-lint/pkg/goanalysis
-github.com/golangci/golangci-lint/pkg/goanalysis/load
-github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors
-github.com/golangci/golangci-lint/pkg/goformatters
-github.com/golangci/golangci-lint/pkg/goformatters/gci
-github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/config
-github.com/golangci/golangci-lint/pkg/goformatters/gci/internal/section
-github.com/golangci/golangci-lint/pkg/goformatters/gofmt
-github.com/golangci/golangci-lint/pkg/goformatters/gofumpt
-github.com/golangci/golangci-lint/pkg/goformatters/goimports
-github.com/golangci/golangci-lint/pkg/goformatters/internal
-github.com/golangci/golangci-lint/pkg/golinters
-github.com/golangci/golangci-lint/pkg/golinters/asasalint
-github.com/golangci/golangci-lint/pkg/golinters/asciicheck
-github.com/golangci/golangci-lint/pkg/golinters/bidichk
-github.com/golangci/golangci-lint/pkg/golinters/bodyclose
-github.com/golangci/golangci-lint/pkg/golinters/canonicalheader
-github.com/golangci/golangci-lint/pkg/golinters/containedctx
-github.com/golangci/golangci-lint/pkg/golinters/contextcheck
-github.com/golangci/golangci-lint/pkg/golinters/copyloopvar
-github.com/golangci/golangci-lint/pkg/golinters/cyclop
-github.com/golangci/golangci-lint/pkg/golinters/decorder
-github.com/golangci/golangci-lint/pkg/golinters/depguard
-github.com/golangci/golangci-lint/pkg/golinters/dogsled
-github.com/golangci/golangci-lint/pkg/golinters/dupl
-github.com/golangci/golangci-lint/pkg/golinters/dupword
-github.com/golangci/golangci-lint/pkg/golinters/durationcheck
-github.com/golangci/golangci-lint/pkg/golinters/err113
-github.com/golangci/golangci-lint/pkg/golinters/errcheck
-github.com/golangci/golangci-lint/pkg/golinters/errchkjson
-github.com/golangci/golangci-lint/pkg/golinters/errname
-github.com/golangci/golangci-lint/pkg/golinters/errorlint
-github.com/golangci/golangci-lint/pkg/golinters/exhaustive
-github.com/golangci/golangci-lint/pkg/golinters/exhaustruct
-github.com/golangci/golangci-lint/pkg/golinters/exptostd
-github.com/golangci/golangci-lint/pkg/golinters/fatcontext
-github.com/golangci/golangci-lint/pkg/golinters/forbidigo
-github.com/golangci/golangci-lint/pkg/golinters/forcetypeassert
-github.com/golangci/golangci-lint/pkg/golinters/funlen
-github.com/golangci/golangci-lint/pkg/golinters/gci
-github.com/golangci/golangci-lint/pkg/golinters/ginkgolinter
-github.com/golangci/golangci-lint/pkg/golinters/gocheckcompilerdirectives
-github.com/golangci/golangci-lint/pkg/golinters/gochecknoglobals
-github.com/golangci/golangci-lint/pkg/golinters/gochecknoinits
-github.com/golangci/golangci-lint/pkg/golinters/gochecksumtype
-github.com/golangci/golangci-lint/pkg/golinters/gocognit
-github.com/golangci/golangci-lint/pkg/golinters/goconst
-github.com/golangci/golangci-lint/pkg/golinters/gocritic
-github.com/golangci/golangci-lint/pkg/golinters/gocyclo
-github.com/golangci/golangci-lint/pkg/golinters/godot
-github.com/golangci/golangci-lint/pkg/golinters/godox
-github.com/golangci/golangci-lint/pkg/golinters/gofmt
-github.com/golangci/golangci-lint/pkg/golinters/gofumpt
-github.com/golangci/golangci-lint/pkg/golinters/goheader
-github.com/golangci/golangci-lint/pkg/golinters/goimports
-github.com/golangci/golangci-lint/pkg/golinters/gomoddirectives
-github.com/golangci/golangci-lint/pkg/golinters/gomodguard
-github.com/golangci/golangci-lint/pkg/golinters/goprintffuncname
-github.com/golangci/golangci-lint/pkg/golinters/gosec
-github.com/golangci/golangci-lint/pkg/golinters/gosimple
-github.com/golangci/golangci-lint/pkg/golinters/gosmopolitan
-github.com/golangci/golangci-lint/pkg/golinters/govet
-github.com/golangci/golangci-lint/pkg/golinters/grouper
-github.com/golangci/golangci-lint/pkg/golinters/iface
-github.com/golangci/golangci-lint/pkg/golinters/importas
-github.com/golangci/golangci-lint/pkg/golinters/inamedparam
-github.com/golangci/golangci-lint/pkg/golinters/ineffassign
-github.com/golangci/golangci-lint/pkg/golinters/interfacebloat
-github.com/golangci/golangci-lint/pkg/golinters/internal
-github.com/golangci/golangci-lint/pkg/golinters/intrange
-github.com/golangci/golangci-lint/pkg/golinters/ireturn
-github.com/golangci/golangci-lint/pkg/golinters/lll
-github.com/golangci/golangci-lint/pkg/golinters/loggercheck
-github.com/golangci/golangci-lint/pkg/golinters/maintidx
-github.com/golangci/golangci-lint/pkg/golinters/makezero
-github.com/golangci/golangci-lint/pkg/golinters/mirror
-github.com/golangci/golangci-lint/pkg/golinters/misspell
-github.com/golangci/golangci-lint/pkg/golinters/mnd
-github.com/golangci/golangci-lint/pkg/golinters/musttag
-github.com/golangci/golangci-lint/pkg/golinters/nakedret
-github.com/golangci/golangci-lint/pkg/golinters/nestif
-github.com/golangci/golangci-lint/pkg/golinters/nilerr
-github.com/golangci/golangci-lint/pkg/golinters/nilnesserr
-github.com/golangci/golangci-lint/pkg/golinters/nilnil
-github.com/golangci/golangci-lint/pkg/golinters/nlreturn
-github.com/golangci/golangci-lint/pkg/golinters/noctx
-github.com/golangci/golangci-lint/pkg/golinters/nolintlint
-github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal
-github.com/golangci/golangci-lint/pkg/golinters/nonamedreturns
-github.com/golangci/golangci-lint/pkg/golinters/nosprintfhostport
-github.com/golangci/golangci-lint/pkg/golinters/paralleltest
-github.com/golangci/golangci-lint/pkg/golinters/perfsprint
-github.com/golangci/golangci-lint/pkg/golinters/prealloc
-github.com/golangci/golangci-lint/pkg/golinters/predeclared
-github.com/golangci/golangci-lint/pkg/golinters/promlinter
-github.com/golangci/golangci-lint/pkg/golinters/protogetter
-github.com/golangci/golangci-lint/pkg/golinters/reassign
-github.com/golangci/golangci-lint/pkg/golinters/recvcheck
-github.com/golangci/golangci-lint/pkg/golinters/revive
-github.com/golangci/golangci-lint/pkg/golinters/rowserrcheck
-github.com/golangci/golangci-lint/pkg/golinters/sloglint
-github.com/golangci/golangci-lint/pkg/golinters/spancheck
-github.com/golangci/golangci-lint/pkg/golinters/sqlclosecheck
-github.com/golangci/golangci-lint/pkg/golinters/staticcheck
-github.com/golangci/golangci-lint/pkg/golinters/stylecheck
-github.com/golangci/golangci-lint/pkg/golinters/tagalign
-github.com/golangci/golangci-lint/pkg/golinters/tagliatelle
-github.com/golangci/golangci-lint/pkg/golinters/tenv
-github.com/golangci/golangci-lint/pkg/golinters/testableexamples
-github.com/golangci/golangci-lint/pkg/golinters/testifylint
-github.com/golangci/golangci-lint/pkg/golinters/testpackage
-github.com/golangci/golangci-lint/pkg/golinters/thelper
-github.com/golangci/golangci-lint/pkg/golinters/tparallel
-github.com/golangci/golangci-lint/pkg/golinters/unconvert
-github.com/golangci/golangci-lint/pkg/golinters/unparam
-github.com/golangci/golangci-lint/pkg/golinters/unused
-github.com/golangci/golangci-lint/pkg/golinters/usestdlibvars
-github.com/golangci/golangci-lint/pkg/golinters/usetesting
-github.com/golangci/golangci-lint/pkg/golinters/varnamelen
-github.com/golangci/golangci-lint/pkg/golinters/wastedassign
-github.com/golangci/golangci-lint/pkg/golinters/whitespace
-github.com/golangci/golangci-lint/pkg/golinters/wrapcheck
-github.com/golangci/golangci-lint/pkg/golinters/wsl
-github.com/golangci/golangci-lint/pkg/golinters/zerologlint
-github.com/golangci/golangci-lint/pkg/goutil
-github.com/golangci/golangci-lint/pkg/lint
-github.com/golangci/golangci-lint/pkg/lint/linter
-github.com/golangci/golangci-lint/pkg/lint/lintersdb
-github.com/golangci/golangci-lint/pkg/logutils
-github.com/golangci/golangci-lint/pkg/printers
-github.com/golangci/golangci-lint/pkg/report
-github.com/golangci/golangci-lint/pkg/result
-github.com/golangci/golangci-lint/pkg/result/processors
-github.com/golangci/golangci-lint/pkg/timeutils
+# github.com/golangci/golangci-lint/v2 v2.1.6
+## explicit; go 1.23.0
+github.com/golangci/golangci-lint/v2/cmd/golangci-lint
+github.com/golangci/golangci-lint/v2/internal/cache
+github.com/golangci/golangci-lint/v2/internal/errorutil
+github.com/golangci/golangci-lint/v2/internal/go/base
+github.com/golangci/golangci-lint/v2/internal/go/cache
+github.com/golangci/golangci-lint/v2/internal/go/cacheprog
+github.com/golangci/golangci-lint/v2/internal/go/mmap
+github.com/golangci/golangci-lint/v2/internal/go/quoted
+github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags
+github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal
+github.com/golangci/golangci-lint/v2/internal/x/tools/diff
+github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs
+github.com/golangci/golangci-lint/v2/pkg/commands
+github.com/golangci/golangci-lint/v2/pkg/commands/internal
+github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate
+github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader
+github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser
+github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr
+github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone
+github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo
+github.com/golangci/golangci-lint/v2/pkg/config
+github.com/golangci/golangci-lint/v2/pkg/exitcodes
+github.com/golangci/golangci-lint/v2/pkg/fsutils
+github.com/golangci/golangci-lint/v2/pkg/goanalysis
+github.com/golangci/golangci-lint/v2/pkg/goanalysis/load
+github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors
+github.com/golangci/golangci-lint/v2/pkg/goformat
+github.com/golangci/golangci-lint/v2/pkg/goformatters
+github.com/golangci/golangci-lint/v2/pkg/goformatters/gci
+github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/config
+github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section
+github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt
+github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt
+github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports
+github.com/golangci/golangci-lint/v2/pkg/goformatters/golines
+github.com/golangci/golangci-lint/v2/pkg/goformatters/internal
+github.com/golangci/golangci-lint/v2/pkg/golinters
+github.com/golangci/golangci-lint/v2/pkg/golinters/asasalint
+github.com/golangci/golangci-lint/v2/pkg/golinters/asciicheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk
+github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose
+github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader
+github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx
+github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/copyloopvar
+github.com/golangci/golangci-lint/v2/pkg/golinters/cyclop
+github.com/golangci/golangci-lint/v2/pkg/golinters/decorder
+github.com/golangci/golangci-lint/v2/pkg/golinters/depguard
+github.com/golangci/golangci-lint/v2/pkg/golinters/dogsled
+github.com/golangci/golangci-lint/v2/pkg/golinters/dupl
+github.com/golangci/golangci-lint/v2/pkg/golinters/dupword
+github.com/golangci/golangci-lint/v2/pkg/golinters/durationcheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/err113
+github.com/golangci/golangci-lint/v2/pkg/golinters/errcheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/errchkjson
+github.com/golangci/golangci-lint/v2/pkg/golinters/errname
+github.com/golangci/golangci-lint/v2/pkg/golinters/errorlint
+github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustive
+github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustruct
+github.com/golangci/golangci-lint/v2/pkg/golinters/exptostd
+github.com/golangci/golangci-lint/v2/pkg/golinters/fatcontext
+github.com/golangci/golangci-lint/v2/pkg/golinters/forbidigo
+github.com/golangci/golangci-lint/v2/pkg/golinters/forcetypeassert
+github.com/golangci/golangci-lint/v2/pkg/golinters/funcorder
+github.com/golangci/golangci-lint/v2/pkg/golinters/funlen
+github.com/golangci/golangci-lint/v2/pkg/golinters/gci
+github.com/golangci/golangci-lint/v2/pkg/golinters/ginkgolinter
+github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckcompilerdirectives
+github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoglobals
+github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoinits
+github.com/golangci/golangci-lint/v2/pkg/golinters/gochecksumtype
+github.com/golangci/golangci-lint/v2/pkg/golinters/gocognit
+github.com/golangci/golangci-lint/v2/pkg/golinters/goconst
+github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic
+github.com/golangci/golangci-lint/v2/pkg/golinters/gocyclo
+github.com/golangci/golangci-lint/v2/pkg/golinters/godot
+github.com/golangci/golangci-lint/v2/pkg/golinters/godox
+github.com/golangci/golangci-lint/v2/pkg/golinters/gofmt
+github.com/golangci/golangci-lint/v2/pkg/golinters/gofumpt
+github.com/golangci/golangci-lint/v2/pkg/golinters/goheader
+github.com/golangci/golangci-lint/v2/pkg/golinters/goimports
+github.com/golangci/golangci-lint/v2/pkg/golinters/golines
+github.com/golangci/golangci-lint/v2/pkg/golinters/gomoddirectives
+github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard
+github.com/golangci/golangci-lint/v2/pkg/golinters/goprintffuncname
+github.com/golangci/golangci-lint/v2/pkg/golinters/gosec
+github.com/golangci/golangci-lint/v2/pkg/golinters/gosmopolitan
+github.com/golangci/golangci-lint/v2/pkg/golinters/govet
+github.com/golangci/golangci-lint/v2/pkg/golinters/grouper
+github.com/golangci/golangci-lint/v2/pkg/golinters/iface
+github.com/golangci/golangci-lint/v2/pkg/golinters/importas
+github.com/golangci/golangci-lint/v2/pkg/golinters/inamedparam
+github.com/golangci/golangci-lint/v2/pkg/golinters/ineffassign
+github.com/golangci/golangci-lint/v2/pkg/golinters/interfacebloat
+github.com/golangci/golangci-lint/v2/pkg/golinters/internal
+github.com/golangci/golangci-lint/v2/pkg/golinters/intrange
+github.com/golangci/golangci-lint/v2/pkg/golinters/ireturn
+github.com/golangci/golangci-lint/v2/pkg/golinters/lll
+github.com/golangci/golangci-lint/v2/pkg/golinters/loggercheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/maintidx
+github.com/golangci/golangci-lint/v2/pkg/golinters/makezero
+github.com/golangci/golangci-lint/v2/pkg/golinters/mirror
+github.com/golangci/golangci-lint/v2/pkg/golinters/misspell
+github.com/golangci/golangci-lint/v2/pkg/golinters/mnd
+github.com/golangci/golangci-lint/v2/pkg/golinters/musttag
+github.com/golangci/golangci-lint/v2/pkg/golinters/nakedret
+github.com/golangci/golangci-lint/v2/pkg/golinters/nestif
+github.com/golangci/golangci-lint/v2/pkg/golinters/nilerr
+github.com/golangci/golangci-lint/v2/pkg/golinters/nilnesserr
+github.com/golangci/golangci-lint/v2/pkg/golinters/nilnil
+github.com/golangci/golangci-lint/v2/pkg/golinters/nlreturn
+github.com/golangci/golangci-lint/v2/pkg/golinters/noctx
+github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint
+github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal
+github.com/golangci/golangci-lint/v2/pkg/golinters/nonamedreturns
+github.com/golangci/golangci-lint/v2/pkg/golinters/nosprintfhostport
+github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest
+github.com/golangci/golangci-lint/v2/pkg/golinters/perfsprint
+github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc
+github.com/golangci/golangci-lint/v2/pkg/golinters/predeclared
+github.com/golangci/golangci-lint/v2/pkg/golinters/promlinter
+github.com/golangci/golangci-lint/v2/pkg/golinters/protogetter
+github.com/golangci/golangci-lint/v2/pkg/golinters/reassign
+github.com/golangci/golangci-lint/v2/pkg/golinters/recvcheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/revive
+github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint
+github.com/golangci/golangci-lint/v2/pkg/golinters/spancheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/staticcheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/tagalign
+github.com/golangci/golangci-lint/v2/pkg/golinters/tagliatelle
+github.com/golangci/golangci-lint/v2/pkg/golinters/testableexamples
+github.com/golangci/golangci-lint/v2/pkg/golinters/testifylint
+github.com/golangci/golangci-lint/v2/pkg/golinters/testpackage
+github.com/golangci/golangci-lint/v2/pkg/golinters/thelper
+github.com/golangci/golangci-lint/v2/pkg/golinters/tparallel
+github.com/golangci/golangci-lint/v2/pkg/golinters/unconvert
+github.com/golangci/golangci-lint/v2/pkg/golinters/unparam
+github.com/golangci/golangci-lint/v2/pkg/golinters/unused
+github.com/golangci/golangci-lint/v2/pkg/golinters/usestdlibvars
+github.com/golangci/golangci-lint/v2/pkg/golinters/usetesting
+github.com/golangci/golangci-lint/v2/pkg/golinters/varnamelen
+github.com/golangci/golangci-lint/v2/pkg/golinters/wastedassign
+github.com/golangci/golangci-lint/v2/pkg/golinters/whitespace
+github.com/golangci/golangci-lint/v2/pkg/golinters/wrapcheck
+github.com/golangci/golangci-lint/v2/pkg/golinters/wsl
+github.com/golangci/golangci-lint/v2/pkg/golinters/zerologlint
+github.com/golangci/golangci-lint/v2/pkg/goutil
+github.com/golangci/golangci-lint/v2/pkg/lint
+github.com/golangci/golangci-lint/v2/pkg/lint/linter
+github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb
+github.com/golangci/golangci-lint/v2/pkg/logutils
+github.com/golangci/golangci-lint/v2/pkg/printers
+github.com/golangci/golangci-lint/v2/pkg/report
+github.com/golangci/golangci-lint/v2/pkg/result
+github.com/golangci/golangci-lint/v2/pkg/result/processors
+github.com/golangci/golangci-lint/v2/pkg/timeutils
+# github.com/golangci/golines v0.0.0-20250217134842-442fd0091d95
+## explicit; go 1.22.0
+github.com/golangci/golines
# github.com/golangci/misspell v0.6.0
## explicit; go 1.21
github.com/golangci/misspell
@@ -558,8 +607,8 @@ github.com/golangci/plugin-module-register/register
# github.com/golangci/revgrep v0.8.0
## explicit; go 1.21
github.com/golangci/revgrep
-# github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed
-## explicit; go 1.20
+# github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e
+## explicit; go 1.23.0
github.com/golangci/unconvert
# github.com/google/btree v1.1.3
## explicit; go 1.18
@@ -675,8 +724,8 @@ github.com/imdario/mergo
# github.com/inconshreveable/mousetrap v1.1.0
## explicit; go 1.18
github.com/inconshreveable/mousetrap
-# github.com/jgautheron/goconst v1.7.1
-## explicit; go 1.13
+# github.com/jgautheron/goconst v1.8.1
+## explicit; go 1.16
github.com/jgautheron/goconst
# github.com/jingyugao/rowserrcheck v1.1.1
## explicit; go 1.13
@@ -708,8 +757,8 @@ github.com/kkHAIKE/contextcheck
# github.com/kulti/thelper v0.6.3
## explicit; go 1.18
github.com/kulti/thelper/pkg/analyzer
-# github.com/kunwardeep/paralleltest v1.0.10
-## explicit; go 1.17
+# github.com/kunwardeep/paralleltest v1.0.14
+## explicit; go 1.23.0
github.com/kunwardeep/paralleltest/pkg/paralleltest
# github.com/kylelemons/godebug v1.1.0
## explicit; go 1.11
@@ -717,7 +766,7 @@ github.com/kylelemons/godebug/diff
# github.com/lasiar/canonicalheader v1.1.2
## explicit; go 1.22.0
github.com/lasiar/canonicalheader
-# github.com/ldez/exptostd v0.4.2
+# github.com/ldez/exptostd v0.4.3
## explicit; go 1.22.0
github.com/ldez/exptostd
# github.com/ldez/gomoddirectives v0.6.1
@@ -730,7 +779,7 @@ github.com/ldez/grignotin/gomod
# github.com/ldez/tagliatelle v0.7.1
## explicit; go 1.22.0
github.com/ldez/tagliatelle
-# github.com/ldez/usetesting v0.4.2
+# github.com/ldez/usetesting v0.4.3
## explicit; go 1.22.0
github.com/ldez/usetesting
# github.com/leonklingele/grouper v1.1.2
@@ -741,8 +790,11 @@ github.com/leonklingele/grouper/pkg/analyzer/globals
github.com/leonklingele/grouper/pkg/analyzer/imports
github.com/leonklingele/grouper/pkg/analyzer/types
github.com/leonklingele/grouper/pkg/analyzer/vars
-# github.com/macabu/inamedparam v0.1.3
-## explicit; go 1.20
+# github.com/lucasb-eyer/go-colorful v1.2.0
+## explicit; go 1.12
+github.com/lucasb-eyer/go-colorful
+# github.com/macabu/inamedparam v0.2.0
+## explicit; go 1.23.0
github.com/macabu/inamedparam
# github.com/magiconair/properties v1.8.6
## explicit; go 1.13
@@ -752,6 +804,14 @@ github.com/magiconair/properties
github.com/mailru/easyjson/buffer
github.com/mailru/easyjson/jlexer
github.com/mailru/easyjson/jwriter
+# github.com/manuelarte/funcorder v0.2.1
+## explicit; go 1.23.0
+github.com/manuelarte/funcorder/analyzer
+github.com/manuelarte/funcorder/internal/astutils
+github.com/manuelarte/funcorder/internal/diag
+github.com/manuelarte/funcorder/internal/features
+github.com/manuelarte/funcorder/internal/fileprocessor
+github.com/manuelarte/funcorder/internal/models
# github.com/maratori/testableexamples v1.0.0
## explicit; go 1.19
github.com/maratori/testableexamples/pkg/testableexamples
@@ -776,8 +836,8 @@ github.com/maxbrunsfeld/counterfeiter/v6
github.com/maxbrunsfeld/counterfeiter/v6/arguments
github.com/maxbrunsfeld/counterfeiter/v6/command
github.com/maxbrunsfeld/counterfeiter/v6/generator
-# github.com/mgechev/revive v1.7.0
-## explicit; go 1.22.1
+# github.com/mgechev/revive v1.9.0
+## explicit; go 1.23.0
github.com/mgechev/revive/config
github.com/mgechev/revive/formatter
github.com/mgechev/revive/internal/astutils
@@ -811,6 +871,9 @@ github.com/monochromegane/go-gitignore
github.com/moricho/tparallel
github.com/moricho/tparallel/pkg/ssafunc
github.com/moricho/tparallel/pkg/ssainstr
+# github.com/muesli/termenv v0.16.0
+## explicit; go 1.17
+github.com/muesli/termenv
# github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
## explicit
github.com/munnerz/goautoneg
@@ -899,7 +962,7 @@ github.com/openshift/build-machinery-go/scripts
# github.com/pelletier/go-toml v1.9.5
## explicit; go 1.12
github.com/pelletier/go-toml
-# github.com/pelletier/go-toml/v2 v2.2.3
+# github.com/pelletier/go-toml/v2 v2.2.4
## explicit; go 1.21.0
github.com/pelletier/go-toml/v2
github.com/pelletier/go-toml/v2/internal/characters
@@ -912,8 +975,8 @@ github.com/pkg/errors
# github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
## explicit
github.com/pmezard/go-difflib/difflib
-# github.com/polyfloyd/go-errorlint v1.7.1
-## explicit; go 1.22.0
+# github.com/polyfloyd/go-errorlint v1.8.0
+## explicit; go 1.23.0
github.com/polyfloyd/go-errorlint/errorlint
# github.com/prometheus/client_golang v1.22.0
## explicit; go 1.22
@@ -939,8 +1002,8 @@ github.com/prometheus/common/model
github.com/prometheus/procfs
github.com/prometheus/procfs/internal/fs
github.com/prometheus/procfs/internal/util
-# github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1
-## explicit; go 1.19
+# github.com/quasilyte/go-ruleguard v0.4.4
+## explicit; go 1.22.0
github.com/quasilyte/go-ruleguard/internal/goenv
github.com/quasilyte/go-ruleguard/internal/golist
github.com/quasilyte/go-ruleguard/internal/xsrcimporter
@@ -984,8 +1047,9 @@ github.com/rogpeppe/go-internal/internal/syscall/windows
github.com/rogpeppe/go-internal/internal/syscall/windows/sysdll
github.com/rogpeppe/go-internal/lockedfile
github.com/rogpeppe/go-internal/lockedfile/internal/filelock
-# github.com/ryancurrah/gomodguard v1.3.5
-## explicit; go 1.22.0
+github.com/rogpeppe/go-internal/robustio
+# github.com/ryancurrah/gomodguard v1.4.1
+## explicit; go 1.23.0
github.com/ryancurrah/gomodguard
# github.com/ryanrolds/sqlclosecheck v0.5.1
## explicit; go 1.20
@@ -1004,7 +1068,7 @@ github.com/sashamelentyev/interfacebloat/pkg/analyzer
## explicit; go 1.20
github.com/sashamelentyev/usestdlibvars/pkg/analyzer
github.com/sashamelentyev/usestdlibvars/pkg/analyzer/internal/mapping
-# github.com/securego/gosec/v2 v2.22.2
+# github.com/securego/gosec/v2 v2.22.3
## explicit; go 1.23.0
github.com/securego/gosec/v2
github.com/securego/gosec/v2/analyzers
@@ -1020,9 +1084,6 @@ github.com/sirupsen/logrus
# github.com/sivchari/containedctx v1.0.3
## explicit; go 1.17
github.com/sivchari/containedctx
-# github.com/sivchari/tenv v1.12.1
-## explicit; go 1.22.0
-github.com/sivchari/tenv
# github.com/sonatard/noctx v0.1.0
## explicit; go 1.22.0
github.com/sonatard/noctx
@@ -1031,8 +1092,8 @@ github.com/sonatard/noctx/reqwithoutctx
# github.com/sourcegraph/go-diff v0.7.0
## explicit; go 1.14
github.com/sourcegraph/go-diff/diff
-# github.com/spf13/afero v1.12.0
-## explicit; go 1.21
+# github.com/spf13/afero v1.14.0
+## explicit; go 1.23.0
github.com/spf13/afero
github.com/spf13/afero/internal/common
github.com/spf13/afero/mem
@@ -1084,13 +1145,13 @@ github.com/subosito/gotenv
# github.com/tdakkota/asciicheck v0.4.1
## explicit; go 1.22.0
github.com/tdakkota/asciicheck
-# github.com/tetafro/godot v1.5.0
-## explicit; go 1.20
+# github.com/tetafro/godot v1.5.1
+## explicit; go 1.22
github.com/tetafro/godot
-# github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3
+# github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67
## explicit; go 1.12
github.com/timakin/bodyclose/passes/bodyclose
-# github.com/timonwong/loggercheck v0.10.1
+# github.com/timonwong/loggercheck v0.11.0
## explicit; go 1.22.0
github.com/timonwong/loggercheck
github.com/timonwong/loggercheck/internal/checkers
@@ -1098,8 +1159,8 @@ github.com/timonwong/loggercheck/internal/checkers/printf
github.com/timonwong/loggercheck/internal/rules
github.com/timonwong/loggercheck/internal/sets
github.com/timonwong/loggercheck/internal/stringutil
-# github.com/tomarrell/wrapcheck/v2 v2.10.0
-## explicit; go 1.21
+# github.com/tomarrell/wrapcheck/v2 v2.11.0
+## explicit; go 1.22.0
github.com/tomarrell/wrapcheck/v2/wrapcheck
# github.com/tommy-muehle/go-mnd/v2 v2.5.1
## explicit; go 1.12
@@ -1124,12 +1185,15 @@ github.com/uudashr/iface/unused
# github.com/x448/float16 v0.8.4
## explicit; go 1.11
github.com/x448/float16
-# github.com/xen0n/gosmopolitan v1.2.2
-## explicit; go 1.19
+# github.com/xen0n/gosmopolitan v1.3.0
+## explicit; go 1.23.0
github.com/xen0n/gosmopolitan
# github.com/xlab/treeprint v1.2.0
## explicit; go 1.13
github.com/xlab/treeprint
+# github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e
+## explicit; go 1.19
+github.com/xo/terminfo
# github.com/yagipy/maintidx v1.0.0
## explicit; go 1.17
github.com/yagipy/maintidx
@@ -1144,12 +1208,15 @@ github.com/ykadowak/zerologlint
# gitlab.com/bosi/decorder v0.4.2
## explicit; go 1.20
gitlab.com/bosi/decorder
-# go-simpler.org/musttag v0.13.0
-## explicit; go 1.20
+# go-simpler.org/musttag v0.13.1
+## explicit; go 1.23.0
go-simpler.org/musttag
-# go-simpler.org/sloglint v0.9.0
-## explicit; go 1.22.0
+# go-simpler.org/sloglint v0.11.0
+## explicit; go 1.23.0
go-simpler.org/sloglint
+# go.augendre.info/fatcontext v0.8.0
+## explicit; go 1.23.0
+go.augendre.info/fatcontext/pkg/analyzer
# go.etcd.io/etcd/api/v3 v3.5.21
## explicit; go 1.23.0
go.etcd.io/etcd/api/v3/authpb
@@ -1290,6 +1357,7 @@ golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/modfile
golang.org/x/mod/module
golang.org/x/mod/semver
+golang.org/x/mod/sumdb/dirhash
# golang.org/x/net v0.42.0
## explicit; go 1.23.0
golang.org/x/net/context
@@ -1392,6 +1460,7 @@ golang.org/x/tools/go/analysis/passes/errorsas
golang.org/x/tools/go/analysis/passes/fieldalignment
golang.org/x/tools/go/analysis/passes/findcall
golang.org/x/tools/go/analysis/passes/framepointer
+golang.org/x/tools/go/analysis/passes/httpmux
golang.org/x/tools/go/analysis/passes/httpresponse
golang.org/x/tools/go/analysis/passes/ifaceassert
golang.org/x/tools/go/analysis/passes/inspect
@@ -1649,6 +1718,19 @@ honnef.co/go/tools/internal/sharedcheck
honnef.co/go/tools/knowledge
honnef.co/go/tools/pattern
honnef.co/go/tools/printf
+honnef.co/go/tools/quickfix
+honnef.co/go/tools/quickfix/qf1001
+honnef.co/go/tools/quickfix/qf1002
+honnef.co/go/tools/quickfix/qf1003
+honnef.co/go/tools/quickfix/qf1004
+honnef.co/go/tools/quickfix/qf1005
+honnef.co/go/tools/quickfix/qf1006
+honnef.co/go/tools/quickfix/qf1007
+honnef.co/go/tools/quickfix/qf1008
+honnef.co/go/tools/quickfix/qf1009
+honnef.co/go/tools/quickfix/qf1010
+honnef.co/go/tools/quickfix/qf1011
+honnef.co/go/tools/quickfix/qf1012
honnef.co/go/tools/simple
honnef.co/go/tools/simple/s1000
honnef.co/go/tools/simple/s1001
@@ -2562,15 +2644,15 @@ k8s.io/utils/path
k8s.io/utils/pointer
k8s.io/utils/ptr
k8s.io/utils/trace
-# mvdan.cc/gofumpt v0.7.0
-## explicit; go 1.22
+# mvdan.cc/gofumpt v0.8.0
+## explicit; go 1.23.0
mvdan.cc/gofumpt/format
mvdan.cc/gofumpt/internal/govendor/go/doc/comment
mvdan.cc/gofumpt/internal/govendor/go/format
mvdan.cc/gofumpt/internal/govendor/go/printer
mvdan.cc/gofumpt/internal/version
-# mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f
-## explicit; go 1.21
+# mvdan.cc/unparam v0.0.0-20250301125049-0df0534333a4
+## explicit; go 1.23
mvdan.cc/unparam/check
# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2
## explicit; go 1.21
diff --git a/vendor/mvdan.cc/gofumpt/format/format.go b/vendor/mvdan.cc/gofumpt/format/format.go
index e81420cf..31322681 100644
--- a/vendor/mvdan.cc/gofumpt/format/format.go
+++ b/vendor/mvdan.cc/gofumpt/format/format.go
@@ -1036,7 +1036,13 @@ func (f *fumpter) shouldMergeAdjacentFields(f1, f2 *ast.Field) bool {
return false
}
- // Only merge if the types are equal.
+ // Only merge if the types that the syntax nodes represent are equal,
+ // e.g. two *ast.Ident nodes "int" are equal, but the two *ast.Ident nodes
+ // "string" and "bool" are not. Hence we use go-cmp to do deep comparisons
+ // while ignoring position information, as it is irrelevant.
+ //
+ // Note that we could in theory use go/types here, but in practice gofumpt
+ // needs to be fast, hence it shouldn't rely on expensive typechecking.
opt := cmp.Comparer(func(x, y token.Pos) bool { return true })
return cmp.Equal(f1.Type, f2.Type, opt)
}
@@ -1045,7 +1051,7 @@ var posType = reflect.TypeOf(token.NoPos)
// setPos recursively sets all position fields in the node v to pos.
func setPos(v reflect.Value, pos token.Pos) {
- if v.Kind() == reflect.Ptr {
+ if v.Kind() == reflect.Pointer {
v = v.Elem()
}
if !v.IsValid() {
@@ -1055,7 +1061,7 @@ func setPos(v reflect.Value, pos token.Pos) {
v.Set(reflect.ValueOf(pos))
}
if v.Kind() == reflect.Struct {
- for i := 0; i < v.NumField(); i++ {
+ for i := range v.NumField() {
setPos(v.Field(i), pos)
}
}
diff --git a/vendor/mvdan.cc/gofumpt/format/rewrite.go b/vendor/mvdan.cc/gofumpt/format/rewrite.go
index 9e5d4579..ec7a2e5d 100644
--- a/vendor/mvdan.cc/gofumpt/format/rewrite.go
+++ b/vendor/mvdan.cc/gofumpt/format/rewrite.go
@@ -89,7 +89,7 @@ func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
if p.Len() != v.Len() {
return false
}
- for i := 0; i < p.Len(); i++ {
+ for i := range p.Len() {
if !match(m, p.Index(i), v.Index(i)) {
return false
}
@@ -97,7 +97,7 @@ func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
return true
case reflect.Struct:
- for i := 0; i < p.NumField(); i++ {
+ for i := range p.NumField() {
if !match(m, p.Field(i), v.Field(i)) {
return false
}
diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/std.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/std.go
index 35e26abb..f73690a7 100644
--- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/std.go
+++ b/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/std.go
@@ -47,4 +47,5 @@ var stdPkgs = []string{
"unicode",
"unique",
"unsafe",
+ "weak",
}
diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/nodes.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/nodes.go
index b8c7dedf..c7d2b0f1 100644
--- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/nodes.go
+++ b/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/nodes.go
@@ -380,7 +380,7 @@ func (p *printer) parameters(fields *ast.FieldList, mode paramMode) {
if closing := p.lineFor(fields.Closing); 0 < prevLine && prevLine < closing {
p.print(token.COMMA)
p.linebreak(closing, 0, ignore, true)
- } else if mode == typeTParam && fields.NumFields() == 1 && combinesWithName(fields.List[0].Type) {
+ } else if mode == typeTParam && fields.NumFields() == 1 && combinesWithName(stripParensAlways(fields.List[0].Type)) {
// A type parameter list [P T] where the name P and the type expression T syntactically
// combine to another valid (value) expression requires a trailing comma, as in [P *T,]
// (or an enclosing interface as in [P interface(*T)]), so that the type parameter list
@@ -401,7 +401,7 @@ func (p *printer) parameters(fields *ast.FieldList, mode paramMode) {
// combinesWithName reports whether a name followed by the expression x
// syntactically combines to another valid (value) expression. For instance
// using *T for x, "name *T" syntactically appears as the expression x*T.
-// On the other hand, using P|Q or *P|~Q for x, "name P|Q" or name *P|~Q"
+// On the other hand, using P|Q or *P|~Q for x, "name P|Q" or "name *P|~Q"
// cannot be combined into a valid (value) expression.
func combinesWithName(x ast.Expr) bool {
switch x := x.(type) {
@@ -411,9 +411,7 @@ func combinesWithName(x ast.Expr) bool {
case *ast.BinaryExpr:
return combinesWithName(x.X) && !isTypeElem(x.Y)
case *ast.ParenExpr:
- // name(x) combines but we are making sure at
- // the call site that x is never parenthesized.
- panic("unexpected parenthesized expression")
+ return !isTypeElem(x.X)
}
return false
}
diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/printer.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/printer.go
index 11c056d6..a6c74c72 100644
--- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/printer.go
+++ b/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/printer.go
@@ -45,9 +45,9 @@ const (
)
type commentInfo struct {
- cindex int // current comment index
- comment *ast.CommentGroup // = printer.comments[cindex]; or nil
- commentOffset int // = printer.posFor(printer.comments[cindex].List[0].Pos()).Offset; or infinity
+ cindex int // index of the next comment
+ comment *ast.CommentGroup // = printer.comments[cindex-1]; or nil
+ commentOffset int // = printer.posFor(printer.comments[cindex-1].List[0].Pos()).Offset; or infinity
commentNewline bool // true if the comment group contains newlines
}
diff --git a/vendor/mvdan.cc/unparam/check/check.go b/vendor/mvdan.cc/unparam/check/check.go
index 2bda0130..38421a09 100644
--- a/vendor/mvdan.cc/unparam/check/check.go
+++ b/vendor/mvdan.cc/unparam/check/check.go
@@ -411,7 +411,7 @@ func (c *Checker) addImplementing(named *types.Named, iface *types.Interface) {
}
func findNamed(typ types.Type) *types.Named {
- switch typ := typ.(type) {
+ switch typ := types.Unalias(typ).(type) {
case *types.Pointer:
return findNamed(typ.Elem())
case *types.Named: